diff --git a/package.json b/package.json index 27926ca..50357f0 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,16 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", "@egjs/react-infinitegrid": "^4.12.0", "@mui/icons-material": "^6.4.4", + "@mui/material": "^6.4.4", "@tailwindcss/vite": "^4.0.6", "@tanstack/react-query": "^5.66.0", "axios": "^1.7.9", + "gsap": "^3.12.7", + "pnpm": "^10.4.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router": "^7.1.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8732bcb..3c350ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,21 @@ importers: .: dependencies: + '@emotion/react': + specifier: ^11.14.0 + version: 11.14.0(@types/react@19.0.8)(react@18.3.1) + '@emotion/styled': + specifier: ^11.14.0 + version: 11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) '@egjs/react-infinitegrid': specifier: ^4.12.0 version: 4.12.0 '@mui/icons-material': specifier: ^6.4.4 - version: 6.4.4(@mui/material@6.4.4(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) + version: 6.4.4(@mui/material@6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) + '@mui/material': + specifier: ^6.4.4 + version: 6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tailwindcss/vite': specifier: ^4.0.6 version: 4.0.6(vite@6.1.0(jiti@2.4.2)(lightningcss@1.29.1)) @@ -23,6 +32,12 @@ importers: axios: specifier: ^1.7.9 version: 1.7.9 + gsap: + specifier: ^3.12.7 + version: 3.12.7 + pnpm: + specifier: ^10.4.1 + version: 10.4.1 react: specifier: ^18.3.1 version: 18.3.1 @@ -173,7 +188,10 @@ packages: resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} engines: {node: '>=6.9.0'} - '@cfcs/core@0.0.24': + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + +'@cfcs/core@0.0.24': resolution: {integrity: sha512-feB38qu+eDk0Pggh/yR7gjaNmvUYA2uCxHP3Pz2MLE4LZ/9jPdtu8bzCSI47yTEhWyZCF5Pk698hdz8IN2mTjA==} '@cfcs/core@0.0.5': @@ -206,18 +224,45 @@ packages: '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + '@emotion/is-prop-valid@1.3.1': + resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + '@emotion/memoize@0.9.0': resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + '@emotion/react@11.14.0': + resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + '@emotion/serialize@1.3.3': resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} '@emotion/sheet@1.4.0': resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + '@emotion/styled@11.14.0': + resolution: {integrity: sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + '@emotion/unitless@0.10.0': resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + '@emotion/use-insertion-effect-with-fallbacks@1.2.0': + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + '@emotion/utils@1.4.2': resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} @@ -909,6 +954,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} @@ -1035,6 +1083,10 @@ packages: axios@1.7.9: resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1098,6 +1150,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1105,6 +1160,10 @@ packages: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -1359,6 +1418,9 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1455,6 +1517,9 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + gsap@3.12.7: + resolution: {integrity: sha512-V4GsyVamhmKefvcAKaoy0h6si0xX7ogwBoBSs2CTJwt7luW0oZzC0LhdkyuKV8PJAXr7Yaj8pMjCKD4GJ+eEMg==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -1482,6 +1547,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1856,6 +1924,11 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + pnpm@10.4.1: + resolution: {integrity: sha512-x1O2w616+hOvOI+m2AgDWgCOMOqZk/WMZmPivF/yFnmqg02wlJhxKapNSIuG31f3tjSYGy+CfNysxpjMDPuIrw==} + engines: {node: '>=18.12'} + hasBin: true + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -1952,6 +2025,13 @@ packages: react-is@19.0.0: resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} + react-router-dom@7.1.5: + resolution: {integrity: sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + react-router@7.1.5: resolution: {integrity: sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==} engines: {node: '>=20.0.0'} @@ -2074,6 +2154,10 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + string.prototype.trim@1.2.10: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} @@ -2277,6 +2361,10 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2408,6 +2496,21 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@emotion/babel-plugin@11.13.5': + dependencies: + '@babel/helper-module-imports': 7.25.9 + '@babel/runtime': 7.26.9 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color '@cfcs/core@0.0.24': dependencies: '@egjs/component': 3.0.5 @@ -2457,8 +2560,28 @@ snapshots: '@emotion/hash@0.9.2': {} + '@emotion/is-prop-valid@1.3.1': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/memoize@0.9.0': {} + '@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 19.0.8 + transitivePeerDependencies: + - supports-color + '@emotion/serialize@1.3.3': dependencies: '@emotion/hash': 0.9.2 @@ -2469,8 +2592,27 @@ snapshots: '@emotion/sheet@1.4.0': {} + '@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@emotion/babel-plugin': 11.13.5 + '@emotion/is-prop-valid': 1.3.1 + '@emotion/react': 11.14.0(@types/react@19.0.8)(react@18.3.1) + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/utils': 1.4.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 19.0.8 + transitivePeerDependencies: + - supports-color + '@emotion/unitless@0.10.0': {} + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@18.3.1)': + dependencies: + react: 18.3.1 + '@emotion/utils@1.4.2': {} '@emotion/weak-memoize@0.4.0': {} @@ -2628,19 +2770,19 @@ snapshots: '@mui/core-downloads-tracker@6.4.4': {} - '@mui/icons-material@6.4.4(@mui/material@6.4.4(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@19.0.8)(react@18.3.1)': + '@mui/icons-material@6.4.4(@mui/material@6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@19.0.8)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.9 - '@mui/material': 6.4.4(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 19.0.8 - '@mui/material@6.4.4(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/material@6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.9 '@mui/core-downloads-tracker': 6.4.4 - '@mui/system': 6.4.3(@types/react@19.0.8)(react@18.3.1) + '@mui/system': 6.4.3(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) '@mui/types': 7.2.21(@types/react@19.0.8) '@mui/utils': 6.4.3(@types/react@19.0.8)(react@18.3.1) '@popperjs/core': 2.11.8 @@ -2653,6 +2795,8 @@ snapshots: react-is: 19.0.0 react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.0.8)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) '@types/react': 19.0.8 '@mui/private-theming@6.4.3(@types/react@19.0.8)(react@18.3.1)': @@ -2664,7 +2808,7 @@ snapshots: optionalDependencies: '@types/react': 19.0.8 - '@mui/styled-engine@6.4.3(react@18.3.1)': + '@mui/styled-engine@6.4.3(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.9 '@emotion/cache': 11.14.0 @@ -2673,12 +2817,15 @@ snapshots: csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.0.8)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) - '@mui/system@6.4.3(@types/react@19.0.8)(react@18.3.1)': + '@mui/system@6.4.3(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.9 '@mui/private-theming': 6.4.3(@types/react@19.0.8)(react@18.3.1) - '@mui/styled-engine': 6.4.3(react@18.3.1) + '@mui/styled-engine': 6.4.3(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.21(@types/react@19.0.8) '@mui/utils': 6.4.3(@types/react@19.0.8)(react@18.3.1) clsx: 2.1.1 @@ -2686,6 +2833,8 @@ snapshots: prop-types: 15.8.1 react: 18.3.1 optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.0.8)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1) '@types/react': 19.0.8 '@mui/types@7.2.21(@types/react@19.0.8)': @@ -2991,6 +3140,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/parse-json@4.0.2': {} + '@types/prop-types@15.7.14': {} '@types/react-dom@19.0.3(@types/react@19.0.8)': @@ -3171,6 +3322,12 @@ snapshots: transitivePeerDependencies: - debug + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.26.9 + cosmiconfig: 7.1.0 + resolve: 1.22.10 + balanced-match@1.0.2: {} brace-expansion@1.1.11: @@ -3235,10 +3392,20 @@ snapshots: concat-map@0.0.1: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} cookie@1.0.2: {} + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + cosmiconfig@8.3.6(typescript@5.7.3): dependencies: import-fresh: 3.3.1 @@ -3599,6 +3766,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-root@1.1.0: {} + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -3693,6 +3862,8 @@ snapshots: graphemer@1.4.0: {} + gsap@3.12.7: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -3715,6 +3886,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + ignore@5.3.2: {} import-fresh@3.3.1: @@ -4060,6 +4235,8 @@ snapshots: picomatch@4.0.2: {} + pnpm@10.4.1: {} + possible-typed-array-names@1.1.0: {} postcss@8.5.2: @@ -4098,6 +4275,12 @@ snapshots: react-is@19.0.0: {} + react-router-dom@7.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 7.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-router@7.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@types/cookie': 0.6.0 @@ -4274,6 +4457,8 @@ snapshots: source-map-js@1.2.1: {} + source-map@0.5.7: {} + string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 @@ -4488,6 +4673,8 @@ snapshots: yallist@3.1.1: {} + yaml@1.10.2: {} + yocto-queue@0.1.0: {} zustand@5.0.3(@types/react@19.0.8)(react@18.3.1): diff --git a/src/assets/images/go-to-letter-board.png b/src/assets/images/go-to-letter-board.png new file mode 100644 index 0000000..a97bb28 Binary files /dev/null and b/src/assets/images/go-to-letter-board.png differ diff --git a/src/assets/images/go-to-letter-box-new-letters.png b/src/assets/images/go-to-letter-box-new-letters.png new file mode 100644 index 0000000..0cc116a Binary files /dev/null and b/src/assets/images/go-to-letter-box-new-letters.png differ diff --git a/src/assets/images/go-to-letter-box.png b/src/assets/images/go-to-letter-box.png new file mode 100644 index 0000000..0ce80e1 Binary files /dev/null and b/src/assets/images/go-to-letter-box.png differ diff --git a/src/assets/images/go-to-random-letter.png b/src/assets/images/go-to-random-letter.png new file mode 100644 index 0000000..9e0d54f Binary files /dev/null and b/src/assets/images/go-to-random-letter.png differ diff --git a/src/assets/images/go-to-write.png b/src/assets/images/go-to-write.png new file mode 100644 index 0000000..d91b072 Binary files /dev/null and b/src/assets/images/go-to-write.png differ diff --git a/src/assets/images/home-left-mountain.png b/src/assets/images/home-left-mountain.png new file mode 100644 index 0000000..30e99bf Binary files /dev/null and b/src/assets/images/home-left-mountain.png differ diff --git a/src/assets/images/home-right-mountain-bottom.png b/src/assets/images/home-right-mountain-bottom.png new file mode 100644 index 0000000..05ab386 Binary files /dev/null and b/src/assets/images/home-right-mountain-bottom.png differ diff --git a/src/assets/images/home-right-mountain-top.png b/src/assets/images/home-right-mountain-top.png new file mode 100644 index 0000000..d66d971 Binary files /dev/null and b/src/assets/images/home-right-mountain-top.png differ diff --git a/src/assets/images/letter-1.png b/src/assets/images/letter-1.png new file mode 100644 index 0000000..adb4613 Binary files /dev/null and b/src/assets/images/letter-1.png differ diff --git a/src/assets/images/letter-2.png b/src/assets/images/letter-2.png new file mode 100644 index 0000000..df34f4d Binary files /dev/null and b/src/assets/images/letter-2.png differ diff --git a/src/assets/images/letter-3.png b/src/assets/images/letter-3.png new file mode 100644 index 0000000..31d9cb0 Binary files /dev/null and b/src/assets/images/letter-3.png differ diff --git a/src/assets/images/letter-4.png b/src/assets/images/letter-4.png new file mode 100644 index 0000000..6b4d82c Binary files /dev/null and b/src/assets/images/letter-4.png differ diff --git a/src/assets/images/random-cheer-bird.png b/src/assets/images/random-cheer-bird.png new file mode 100644 index 0000000..93de5ec Binary files /dev/null and b/src/assets/images/random-cheer-bird.png differ diff --git a/src/components/HomeButton.tsx b/src/components/HomeButton.tsx new file mode 100644 index 0000000..cc185e2 --- /dev/null +++ b/src/components/HomeButton.tsx @@ -0,0 +1,17 @@ +import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined'; +import { Link } from 'react-router'; + +export default function HomeButton() { + return ( + <> +
+ + + +
+ + ); +} diff --git a/src/pages/Home/components/FloatingLetters.tsx b/src/pages/Home/components/FloatingLetters.tsx new file mode 100644 index 0000000..b2e8a98 --- /dev/null +++ b/src/pages/Home/components/FloatingLetters.tsx @@ -0,0 +1,48 @@ +import { useEffect, useRef } from 'react'; +import gsap from 'gsap'; +import letter1 from '@/assets/images/letter-1.png'; +import letter2 from '@/assets/images/letter-2.png'; +import letter3 from '@/assets/images/letter-3.png'; +import letter4 from '@/assets/images/letter-4.png'; + +const images = [letter1, letter2, letter3, letter4]; + +const FloatingLetters = () => { + const lettersRef = useRef([]); + useEffect(() => { + if (!lettersRef.current) return; + + lettersRef.current.forEach((letter, index) => { + gsap.to(letter, { + // x: Math.random() * 50 - 40, + y: Math.random() * 20 - 40 + 'vh', // 위아래 이동 + rotation: Math.random() * 50 - 25, // 회전 + duration: Math.random() * 3 + 2, // 지속 시간 + repeat: -1, // 무한 반복 + yoyo: true, // 왕복 + ease: 'power1.inOut', + delay: index * 1, // 편지마다 시차 + }); + }); + }, []); + return ( + <> + {images.map((src, index) => ( + { + if (el) lettersRef.current[index] = el; + }} + className="absolute w-20 opacity-90" + style={{ + left: `${index * 30 + 30}px`, // 편지지 간격 + top: '60vh', + }} + /> + ))} + + ); +}; + +export default FloatingLetters; diff --git a/src/pages/Home/components/GoToLetterBoard.tsx b/src/pages/Home/components/GoToLetterBoard.tsx new file mode 100644 index 0000000..41d54cb --- /dev/null +++ b/src/pages/Home/components/GoToLetterBoard.tsx @@ -0,0 +1,17 @@ +import { Link } from 'react-router'; +import goToLetterBoard from '@/assets/images/go-to-letter-board.png'; + +const GoToLetterBoard = () => { + return ( +
+
+

게시판

+ + go to letter board + +
+
+ ); +}; + +export default GoToLetterBoard; diff --git a/src/pages/Home/components/GoToLetterBox.tsx b/src/pages/Home/components/GoToLetterBox.tsx new file mode 100644 index 0000000..691ed55 --- /dev/null +++ b/src/pages/Home/components/GoToLetterBox.tsx @@ -0,0 +1,24 @@ +import { Link } from 'react-router'; +import goToLetterBoxNewLetters from '@/assets/images/go-to-letter-box-new-letters.png'; +import goToLetterBox from '@/assets/images/go-to-letter-box.png'; + +const GoToLetterBox = () => { + //TODO : hasNewLetters 전역으로 상태 관리하기 + let hasNewLetters = true; + return ( +
+
+

내 편지함

+ + go to letter box + +
+
+ ); +}; + +export default GoToLetterBox; diff --git a/src/pages/Home/components/GoToRandomLetter.tsx b/src/pages/Home/components/GoToRandomLetter.tsx new file mode 100644 index 0000000..51db971 --- /dev/null +++ b/src/pages/Home/components/GoToRandomLetter.tsx @@ -0,0 +1,17 @@ +import { Link } from 'react-router'; +import goToRandomLetter from '@/assets/images/go-to-random-letter.png'; + +const GoToRandomLetter = () => { + return ( + <> +
+

고민편지 보러가기

+ + go to random letter + +
+ + ); +}; + +export default GoToRandomLetter; diff --git a/src/pages/Home/components/GoToWrite.tsx b/src/pages/Home/components/GoToWrite.tsx new file mode 100644 index 0000000..302cba7 --- /dev/null +++ b/src/pages/Home/components/GoToWrite.tsx @@ -0,0 +1,15 @@ +import { Link } from 'react-router'; +import goToWrite from '@/assets/images/go-to-write.png'; + +const GoToWrite = () => { + return ( +
+

속마음 나누기

+ + go to write + +
+ ); +}; + +export default GoToWrite; diff --git a/src/pages/Home/components/HomeBackgroundLeft.tsx b/src/pages/Home/components/HomeBackgroundLeft.tsx new file mode 100644 index 0000000..b8855e2 --- /dev/null +++ b/src/pages/Home/components/HomeBackgroundLeft.tsx @@ -0,0 +1,14 @@ +import BackgroundImageWrapper from '@/components/BackgroundImageWrapper'; +import homeLeftMountain from '@/assets/images/home-left-mountain.png'; + +const HomeBackgroundLeft = () => { + return ( + + ); +}; + +export default HomeBackgroundLeft; diff --git a/src/pages/Home/components/HomeBackgroundRightBottom.tsx b/src/pages/Home/components/HomeBackgroundRightBottom.tsx new file mode 100644 index 0000000..3833ac4 --- /dev/null +++ b/src/pages/Home/components/HomeBackgroundRightBottom.tsx @@ -0,0 +1,13 @@ +import BackgroundImageWrapper from '@/components/BackgroundImageWrapper'; +import homeRightMountainBottom from '@/assets/images/home-right-mountain-bottom.png'; +const HomeBackgroundRightBottom = () => { + return ( + + ); +}; + +export default HomeBackgroundRightBottom; diff --git a/src/pages/Home/components/HomeBackgroundRightTop.tsx b/src/pages/Home/components/HomeBackgroundRightTop.tsx new file mode 100644 index 0000000..4ce731e --- /dev/null +++ b/src/pages/Home/components/HomeBackgroundRightTop.tsx @@ -0,0 +1,13 @@ +import BackgroundImageWrapper from '@/components/BackgroundImageWrapper'; +import homeRightMountainTop from '@/assets/images/home-right-mountain-top.png'; +const HomeBackgroundRightTop = () => { + return ( + + ); +}; + +export default HomeBackgroundRightTop; diff --git a/src/pages/Home/components/HomeHeader.tsx b/src/pages/Home/components/HomeHeader.tsx new file mode 100644 index 0000000..3c1db95 --- /dev/null +++ b/src/pages/Home/components/HomeHeader.tsx @@ -0,0 +1,20 @@ +import { Link } from 'react-router'; + +import { AlarmIcon, PersonIcon } from '@/assets/icons'; + +const HomeHeader = () => { + return ( +
+
+ + + + + + +
+
+ ); +}; + +export default HomeHeader; diff --git a/src/pages/Home/components/HomeLeft.tsx b/src/pages/Home/components/HomeLeft.tsx new file mode 100644 index 0000000..0026be0 --- /dev/null +++ b/src/pages/Home/components/HomeLeft.tsx @@ -0,0 +1,18 @@ +import RandomCheer from './RandomCheer'; +import GoToWrite from './GoToWrite'; +import GoToRandomLetter from './GoToRandomLetter'; + +const HomeLeft = () => { + return ( +
+ + + +
+ ); +}; + +export default HomeLeft; diff --git a/src/pages/Home/components/HomeRight.tsx b/src/pages/Home/components/HomeRight.tsx new file mode 100644 index 0000000..226bf4e --- /dev/null +++ b/src/pages/Home/components/HomeRight.tsx @@ -0,0 +1,20 @@ +import FloatingLetters from './FloatingLetters'; +import GoToLetterBoard from './GoToLetterBoard'; +import GoToLetterBox from './GoToLetterBox'; +import NewLetterModal from './NewLetterModal'; + +const HomeRight = () => { + //TODO : hasNewLetters 전역으로 상태 관리할지 + let hasNewLetters = true; + + return ( +
+ {hasNewLetters && } + + + {hasNewLetters && } +
+ ); +}; + +export default HomeRight; diff --git a/src/pages/Home/components/LetterActions.tsx b/src/pages/Home/components/LetterActions.tsx new file mode 100644 index 0000000..0fa98ee --- /dev/null +++ b/src/pages/Home/components/LetterActions.tsx @@ -0,0 +1,52 @@ +import { useState } from 'react'; +import SendOutlinedIcon from '@mui/icons-material/SendOutlined'; +import DriveFileRenameOutlineOutlinedIcon from '@mui/icons-material/DriveFileRenameOutlineOutlined'; +import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'; +import ShowIncomingLettersModal from './ShowIncomingLettersModal'; +import ShowDraftModal from './ShowDraftModal'; +import ShowShareAccessModal from './ShowShareAccessModal'; + +const LetterActions = () => { + const [activeModal, setActiveModal] = useState< + null | 'incomingLetters' | 'draft' | 'shareAccess' + >(null); + + const arr: { title: 'incomingLetters' | 'draft' | 'shareAccess'; icon: React.ReactNode }[] = [ + { + title: 'incomingLetters', + icon: , + }, + { + title: 'draft', + icon: , + }, + { + title: 'shareAccess', + icon: , + }, + ]; + return ( +
+
+ {arr.map((item, index) => ( + + ))} +
+ {activeModal === 'incomingLetters' && ( + setActiveModal(null)} /> + )} + {activeModal === 'draft' && setActiveModal(null)} />} + {activeModal === 'shareAccess' && ( + setActiveModal(null)} /> + )} +
+ ); +}; + +export default LetterActions; diff --git a/src/pages/Home/components/LetterPreview.tsx b/src/pages/Home/components/LetterPreview.tsx new file mode 100644 index 0000000..37aaf23 --- /dev/null +++ b/src/pages/Home/components/LetterPreview.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const LetterPreview = () => { + return
LetterPreview
; +}; + +export default LetterPreview; diff --git a/src/pages/Home/components/NewLetterModal.tsx b/src/pages/Home/components/NewLetterModal.tsx new file mode 100644 index 0000000..40c1c41 --- /dev/null +++ b/src/pages/Home/components/NewLetterModal.tsx @@ -0,0 +1,13 @@ +import { useState } from 'react'; + +const NewLetterModal = () => { + const [newLetterCount, setNewLetterCount] = useState(0); + + return ( +

+ {newLetterCount}통의 편지가 도착했어요! +

+ ); +}; + +export default NewLetterModal; diff --git a/src/pages/Home/components/RandomCheer.tsx b/src/pages/Home/components/RandomCheer.tsx new file mode 100644 index 0000000..758ff82 --- /dev/null +++ b/src/pages/Home/components/RandomCheer.tsx @@ -0,0 +1,31 @@ +import { useState } from 'react'; +import { RANDOM_CHEER_LIST } from '../constants'; +import randomCheerBird from '@/assets/images/random-cheer-bird.png'; + +const RandomCheer = () => { + const getRandomCheer = (): string => { + const randomIndex = Math.floor(Math.random() * RANDOM_CHEER_LIST.length); + return RANDOM_CHEER_LIST[randomIndex]; + }; + + const [randomCheer, setRandomCheer] = useState(getRandomCheer()); + + return ( +
+
setRandomCheer(getRandomCheer())} + > +

{randomCheer}

+
+
+ random cheer bird +
+ ); +}; + +export default RandomCheer; diff --git a/src/pages/Home/components/ShowDraftModal.tsx b/src/pages/Home/components/ShowDraftModal.tsx new file mode 100644 index 0000000..8028cfa --- /dev/null +++ b/src/pages/Home/components/ShowDraftModal.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import ModalBg from '@/assets/images/modal-yellow.png'; +import ModalOverlay from '@/components/ModalOverlay'; + +import DeleteOutlineRoundedIcon from '@mui/icons-material/DeleteOutlineRounded'; + +interface ShowDraftModalProps { + children?: React.ReactNode; + onClose: () => void; +} + +const DUMMY_DRAFT = [ + { id: 1, title: '취업 때문에 고민이 많아요!!' }, + { id: 2, title: '배고파서 죽을 거 같아요 😭' }, + { id: 3, title: '개발하니까 밖에 나갈 일이 없어서 너무 심심하고 피곤해요' }, + { id: 4, title: '마라샹궈 먹고 싶어요' }, +]; + +const ShowDraftModal = ({ onClose }: ShowDraftModalProps) => { + return ( + +
+

+ 임시저장된 편지가 있어요! +

+
+
+ +
+

임시저장 편지

+

로그아웃 시 임시 저장된 편지는 사라집니다

+
+
+ {DUMMY_DRAFT.map((draft) => ( +
+

{draft.title}

+
+ +
+
+ ))} +
+
+
+
+
+ ); +}; + +export default ShowDraftModal; diff --git a/src/pages/Home/components/ShowIncomingLettersModal.tsx b/src/pages/Home/components/ShowIncomingLettersModal.tsx new file mode 100644 index 0000000..aa1c7ab --- /dev/null +++ b/src/pages/Home/components/ShowIncomingLettersModal.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import ModalBg from '@/assets/images/modal-yellow.png'; +import ModalOverlay from '@/components/ModalOverlay'; + +interface ShowIncomingLettersModalProps { + children?: React.ReactNode; + onClose: () => void; +} + +const DUMMY_INCOMING_LETTERS = [ + { id: 1, title: '취업 때문에 고민이 많아요!!', time: '12:00:00' }, + { id: 2, title: '배고파서 죽을 거 같아요 😭', time: '00:00:03' }, + { id: 3, title: '개발하니까 밖에 나갈 일이 없어서 너무 심심하고 피곤해요', time: '00:00:03' }, + { id: 4, title: '마라샹궈 먹고 싶어요', time: '00:00:03' }, +]; + +const ShowIncomingLettersModal = ({ onClose }: ShowIncomingLettersModalProps) => { + return ( + +
+

+ 따숨 배달부가 따숨이의 답장을 배달 중이에요! +

+
+
+ +
+

오고 있는 편지

+

시간은 실제 시간을 기반으로 책정됩니다.

+
+
+ {DUMMY_INCOMING_LETTERS.map((letter) => ( +
+

{letter.title}

+

{letter.time}

+
+ ))} +
+
+
+
+
+ ); +}; + +export default ShowIncomingLettersModal; diff --git a/src/pages/Home/components/ShowShareAccessModal.tsx b/src/pages/Home/components/ShowShareAccessModal.tsx new file mode 100644 index 0000000..0c86e2b --- /dev/null +++ b/src/pages/Home/components/ShowShareAccessModal.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import ModalBg from '@/assets/images/modal-yellow.png'; +import ModalOverlay from '@/components/ModalOverlay'; + +interface ShowShareAccessModalProps { + children?: React.ReactNode; + onClose: () => void; +} + +const DUMMY_SHARE_ACCESS = [ + { id: 1, zip_code: '235EA' }, + { id: 2, zip_code: '711PO' }, + { id: 3, zip_code: '105CF' }, + { id: 4, zip_code: '299EB' }, +]; + +const ShowShareAccessModal = ({ onClose }: ShowShareAccessModalProps) => { + return ( + +
+

+ 공유 요청이 왔어요! +

+
+
+ +
+

게시판 공유 승인하기

+

+ 따숨님과 주고받은 추억을 게시판에 공유하고 싶으신 분이 있어요. 클릭해서 확인하고, + 허락 여부를 체크해주세요! +

+
+
+ {DUMMY_SHARE_ACCESS.map((access) => ( +
+

{access.zip_code}님의 공유 요청

+
+ ))} +
+
+
+
+
+ ); +}; + +export default ShowShareAccessModal; diff --git a/src/pages/Home/components/SpecialLetterBanner.tsx b/src/pages/Home/components/SpecialLetterBanner.tsx new file mode 100644 index 0000000..9994763 --- /dev/null +++ b/src/pages/Home/components/SpecialLetterBanner.tsx @@ -0,0 +1,23 @@ +import CampaignOutlinedIcon from '@mui/icons-material/CampaignOutlined'; + +const SpecialLetterBanner = () => { + const DUMMY_SPECIAL_LETTER_BANNER = + '11월 15일은 수능! 고생하는 수험생들을 위해 응원의 편지를 적어주세요!'; + + return ( +
+
+
+ +
+
+ + {DUMMY_SPECIAL_LETTER_BANNER} + +
+
+
+ ); +}; + +export default SpecialLetterBanner; diff --git a/src/pages/Home/constants/index.ts b/src/pages/Home/constants/index.ts new file mode 100644 index 0000000..a2e0fd8 --- /dev/null +++ b/src/pages/Home/constants/index.ts @@ -0,0 +1,45 @@ +export const RANDOM_CHEER_LIST: string[] = [ + '오늘도 화이팅!☀️', + '오늘도 수고 많았어요. ☕', + '괜찮아요, 다 잘 될 거예요. 💙', + '혼자가 아니에요. 🤗', + '잠시 쉬어가도 괜찮아요. 🍃', + '있는 그대로도 충분해요. 🫂', + '분명 나아질 거예요. 🌈', + '천천히 가도 돼요. 👣', + '지금도 충분히 잘하고 있어요. 💕', + '항상 응원하고 있어요! 😊', + '조금만 더 힘내봐요. 🌟', + '기대도 괜찮아요. 🎈', + '좋은 날이 올 거예요. ✨', + '너무 잘하고 있어요! 💪', + '따숨님의 노력은 언젠가 빛날 거예요. 🌟', + '하루하루 조금씩 나아지고 있어요. ⏳', + '매일 조금씩 성장하고 있어요. 🌱', + '세상은 따숨님을 기다리고 있어요. 🌍', + '힘들 땐 잠시 멈추어도 괜찮아요. ⏸️', + '오늘도 멋진 하루가 될 거예요. 🌅', + '모든 순간이 소중해요. 🌸', + '이 순간이 따숨님의 노력의 결과예요. 🎯', + '항상 자기 자신을 사랑해주세요. ❤️', + '모든 일은 시간이 해결해줄 거예요. ⏳', + '따숨님은 이미 충분히 잘하고 있어요. 🏅', + '끝까지 가면 꿈이 이루어져요. 🌠', + '오늘도 행복한 하루 되세요. 🌞', + '따숨님의 열정이 빛나고 있어요. 🔥', + '내일은 오늘보다 더 나을 거예요. 🌟', + '모든 것이 끝난 후 웃을 수 있을 거예요. 😁', + '자신감을 가지고 계속 나아가세요. 🚀', + '세상에서 가장 중요한 건 따숨님이에요. 💖', + '따숨님의 미소가 세상을 밝게 해요. 😄', + '한 걸음씩, 천천히 가도 괜찮아요. 👟', + '지금 그 길이 바로 올바른 길이에요. 🛣️', + '작은 변화가 큰 차이를 만들어낼 거예요. 🔄', + '오늘도 모든 것이 가능해요. 💫', + '따숨님의 열정이 승리로 이어질 거예요. 🏆', + '힘들 때일수록 더 강해지는 거예요. 💥', + '따숨님은 강하고 대단한 사람이에요! 💪', + '따숨님은 충분히 잘하고 있어요. 🥇', + '모든 것은 시간이 지나면 잘 될 거예요. ⏳', + '도전이 결국 성공으로 이어질 거예요! 🏅', +]; diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index b2f0bf4..e66481f 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -1,5 +1,38 @@ +import HomeLeft from './components/HomeLeft'; +import HomeRight from './components/HomeRight'; +import HomeHeader from './components/HomeHeader'; +import SpecialLetterBanner from './components/SpecialLetterBanner'; +import LetterActions from './components/LetterActions'; +import HomeButton from '@/components/HomeButton'; +import HomeBackgroundLeft from './components/HomeBackgroundLeft'; +import HomeBackgroundRightBottom from './components/HomeBackgroundRightBottom'; +import HomeBackgroundRightTop from './components/HomeBackgroundRightTop'; +import useViewport from '@/hooks/useViewport'; + const HomePage = () => { - return
HomePage
; + useViewport(); + return ( +
+ + + + +
+
+ + +
+ +
+ + + +
+
+ + +
+ ); }; export default HomePage; diff --git a/src/styles/animations.css b/src/styles/animations.css index 218f2ee..a3e366a 100644 --- a/src/styles/animations.css +++ b/src/styles/animations.css @@ -54,6 +54,19 @@ } } + /* SpecialLetterBanner 애니메이션 */ + --animate-marquee: marquee 10s linear infinite; + + @keyframes marquee { + 0% { + transform: translateX(10%); + } + + 100% { + transform: translateX(-100%); + } + } + /* onBoarding */ /* comment floating */ @keyframes float {