diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c656f8..671e6b5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,15 @@ dependencies: '@trivago/prettier-plugin-sort-imports': specifier: ^4.3.0 version: 4.3.0(prettier@3.2.5) + '@woowa-babble/random-nickname': + specifier: ^1.0.2 + version: 1.0.2 axios: specifier: ^1.6.8 version: 1.6.8 + babel-plugin-styled-components: + specifier: ^2.1.4 + version: 2.1.4(@babel/core@7.24.5)(styled-components@6.1.8) eslint-config-prettier: specifier: ^9.1.0 version: 9.1.0(eslint@8.57.0) @@ -94,6 +100,14 @@ devDependencies: packages: + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + /@babel/code-frame@7.24.2: resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} @@ -102,6 +116,34 @@ packages: picocolors: 1.0.0 dev: false + /@babel/compat-data@7.24.4: + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/core@7.24.5: + resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helpers': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/generator@7.17.7: resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} engines: {node: '>=6.9.0'} @@ -121,6 +163,24 @@ packages: jsesc: 2.5.2 dev: false + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.4 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: false + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -141,6 +201,39 @@ packages: '@babel/types': 7.24.5 dev: false + /@babel/helper-module-imports@7.24.3: + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5): + resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.24.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-validator-identifier': 7.24.5 + dev: false + + /@babel/helper-plugin-utils@7.24.5: + resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-simple-access@7.24.5: + resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + /@babel/helper-split-export-declaration@7.24.5: resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} engines: {node: '>=6.9.0'} @@ -158,6 +251,22 @@ packages: engines: {node: '>=6.9.0'} dev: false + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helpers@7.24.5: + resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/highlight@7.24.5: resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} engines: {node: '>=6.9.0'} @@ -176,6 +285,16 @@ packages: '@babel/types': 7.17.0 dev: false + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + dev: false + /@babel/template@7.24.0: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} @@ -203,6 +322,24 @@ packages: - supports-color dev: false + /@babel/traverse@7.24.5: + resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/types@7.17.0: resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} @@ -1008,6 +1145,10 @@ packages: - '@swc/helpers' dev: true + /@woowa-babble/random-nickname@1.0.2: + resolution: {integrity: sha512-7wdR7s0T6D3aDZROTgaFvA9aP8h9L2OtKHUPselBa3goBe8mweJD7oBub2urs/lJjy/4djqYdkJBEf3lETuG1Q==} + dev: false + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1071,6 +1212,21 @@ packages: - debug dev: false + /babel-plugin-styled-components@2.1.4(@babel/core@7.24.5)(styled-components@6.1.8): + resolution: {integrity: sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==} + peerDependencies: + styled-components: '>= 2' + dependencies: + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-module-imports': 7.24.3 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + lodash: 4.17.21 + picomatch: 2.3.1 + styled-components: 6.1.8(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@babel/core' + dev: false + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1095,6 +1251,17 @@ packages: dependencies: fill-range: 7.0.1 + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001620 + electron-to-chromium: 1.4.774 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.0) + dev: false + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: false @@ -1114,6 +1281,10 @@ packages: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} dev: false + /caniuse-lite@1.0.30001620: + resolution: {integrity: sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==} + dev: false + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1188,6 +1359,10 @@ packages: resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} dev: false + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1315,6 +1490,10 @@ packages: jake: 10.9.1 dev: false + /electron-to-chromium@1.4.774: + resolution: {integrity: sha512-132O1XCd7zcTkzS3FgkAzKmnBuNJjK8WjcTtNuoylj7MYbqw5eXehjQ5OK91g0zm7OTKIPeaAG4CPoRfD9M1Mg==} + dev: false + /entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: false @@ -1349,6 +1528,11 @@ packages: '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: false + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1614,6 +1798,11 @@ packages: requiresBuild: true optional: true + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: false + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1787,6 +1976,12 @@ packages: /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: false + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: @@ -1833,6 +2028,12 @@ packages: tslib: 2.6.2 dev: false + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: false + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -1907,6 +2108,10 @@ packages: he: 1.2.0 dev: false + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: false + /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: @@ -1985,6 +2190,10 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + dev: false + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -2186,6 +2395,11 @@ packages: loose-envify: 1.4.0 dev: false + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: false + /semver@7.6.0: resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} @@ -2366,6 +2580,17 @@ packages: engines: {node: '>= 10.0.0'} dev: false + /update-browserslist-db@1.0.16(browserslist@4.23.0): + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.1 + dev: false + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -2465,6 +2690,10 @@ packages: /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: false + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true diff --git a/src/assets/likelionknu.png b/src/assets/likelionknu.png new file mode 100644 index 0000000..c3fcccf Binary files /dev/null and b/src/assets/likelionknu.png differ diff --git a/src/components/display/CommentInfo.styled.ts b/src/components/display/CommentInfo.styled.ts index f68ad31..868ec2a 100644 --- a/src/components/display/CommentInfo.styled.ts +++ b/src/components/display/CommentInfo.styled.ts @@ -17,11 +17,15 @@ export const CommentList = styled.div` display: flex; flex-direction: column; gap: 15px; - width: 95%; + width: 90%; div > hr { margin-top: 38px; border: 1px solid #dddddd; } + + div:last-child > div + hr { + display: none; + } `; export const CommentContainer = styled.div``; diff --git a/src/components/display/Countdown.tsx b/src/components/display/Countdown.tsx index 6ffbf38..2a6e8f8 100644 --- a/src/components/display/Countdown.tsx +++ b/src/components/display/Countdown.tsx @@ -1,15 +1,26 @@ import { Text } from "@/components/typography/Text"; import { useCountdown } from "@/hooks/useCountdown"; +import { useFestivalCountdown } from "@/hooks/useFestivalCountdown"; import { CountdownContainer } from "./Countdown.styled"; interface ICountdown { targetDate: Date; + onCountdownEnd: () => void; + endDate: Date; + onFestivalEnd: () => void; } -export const Countdown: React.FC = ({ targetDate }) => { +export const Countdown: React.FC = ({ targetDate, onCountdownEnd, endDate, onFestivalEnd }) => { const displayTime = useCountdown(targetDate); + const displayEndTime = useCountdown(endDate); + const { isCountdownFinished, isFestivalOver } = useFestivalCountdown( + targetDate, + endDate, + onCountdownEnd, + onFestivalEnd, + ); const dateOptions: Intl.DateTimeFormatOptions = { year: "numeric", @@ -19,22 +30,42 @@ export const Countdown: React.FC = ({ targetDate }) => { const timeOptions: Intl.DateTimeFormatOptions = { hour: "2-digit", minute: "2-digit", - hour12: false, }; return ( - - 축제까지 남은 시간 - - - {displayTime} - - - UTC+9 | {targetDate.toLocaleDateString("ko-KR", dateOptions)}{" "} - {targetDate.toLocaleTimeString("en-US", timeOptions)} - + {isFestivalOver ? ( + + 2024년 축제가 종료되었습니다.
다음 대동제를 기대해주세요! +
+ ) : isCountdownFinished ? ( + <> + + 대동제가 끝나기까지 남은 시간 + + + {displayEndTime} + + + UTC+9 | {endDate.toLocaleDateString("ko-KR", dateOptions)}{" "} + {endDate.toLocaleTimeString("en-US", timeOptions)} + + + ) : ( + <> + + 축제까지 남은 시간 + + + {displayTime} + + + UTC+9 | {targetDate.toLocaleDateString("ko-KR", dateOptions)}{" "} + {targetDate.toLocaleTimeString("en-US", timeOptions)} + + + )}
); }; diff --git a/src/components/layout/Footer.styled.ts b/src/components/layout/Footer.styled.ts index c1b4a4d..98ed9ce 100644 --- a/src/components/layout/Footer.styled.ts +++ b/src/components/layout/Footer.styled.ts @@ -14,11 +14,23 @@ export const TopBorder = styled.div` margin: 0 auto 50px; `; +export const LogoWrapper = styled.div` + display: flex; + justify-content: center; + align-items: center; + gap: 15px; +`; + export const Logo = styled.img` width: 100px; height: auto; `; +export const LogoLikeLion = styled.img` + width: 150px; + height: auto; +`; + export const EventName = styled.h3` margin: 20px 0 10px 0; `; diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index 9711d64..fc51f29 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -1,15 +1,30 @@ import React from "react"; +import { FaTimes } from "react-icons/fa"; -import { FooterContainer, Logo, EventName, LegalLinks, TopBorder, LegalText } from "@/components/layout/Footer.styled"; +import { + FooterContainer, + Logo, + LogoLikeLion, + EventName, + LogoWrapper, + LegalLinks, + TopBorder, + LegalText, +} from "@/components/layout/Footer.styled"; import { Text } from "@/components/typography/Text"; import logo from "@/assets/hapuruna.png"; +import logolikelionknu from "@/assets/likelionknu.png"; const Footer: React.FC = () => { return ( - + + + + + 2024 경북대학교 대동제 diff --git a/src/components/navigation/Navigation.tsx b/src/components/navigation/Navigation.tsx index 3cdc6ec..6967ddf 100644 --- a/src/components/navigation/Navigation.tsx +++ b/src/components/navigation/Navigation.tsx @@ -52,7 +52,7 @@ const Navigation: React.FC = () => { - handleNavLinkClick("/booth")}>부스 별 지도 + handleNavLinkClick("/booth")}>부스별 지도 handleNavLinkClick("/guests")}>Special Guest diff --git a/src/config/api.ts b/src/config/api.ts index bd339fb..6c381b7 100644 --- a/src/config/api.ts +++ b/src/config/api.ts @@ -2,6 +2,7 @@ import axios from "axios"; export const api = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL as string, + timeout: 10000, }); export class HTTPException extends Error { diff --git a/src/constants/contributors.json b/src/constants/contributors.json index a078a76..e97aca1 100644 --- a/src/constants/contributors.json +++ b/src/constants/contributors.json @@ -4,7 +4,7 @@ "dept": "컴퓨터학부 20", "role": "멋쟁이사자처럼 12기 회장", "photo": "daegun", - "description": ["지도 페이지 개발", "기여한 부분 2", "기여한 부분 3"], + "description": ["축제 지도 제작", "부스 리스트 페이지 구현", "부스 상세 페이지 구현"], "contact": { "instagram": "toothless.kid", "github": "toothlessdev" @@ -16,7 +16,7 @@ "dept": "컴퓨터학부 21", "role": "멋쟁이사자처럼 12기 운영진", "photo": "hyoeun", - "description": ["웹 페이지 디자인", "기여한 부분 2", "기여한 부분 3"], + "description": ["웹 페이지 디자인", "부스 상세 페이지 구현", "Special Guest 페이지 구현"], "contact": { "instagram": "hyon__er", "github": "Hyoeunkh" @@ -28,7 +28,7 @@ "dept": "컴퓨터학부 19", "role": "멋쟁이사자처럼 12기 운영진", "photo": "dongpil", - "description": ["웹 페이지 디자인", "기여한 부분 2", "기여한 부분 3"], + "description": ["웹 페이지 디자인", "부스 상세 페이지 구현"], "contact": { "instagram": "j0_dph", "github": "eastfilmm" @@ -40,7 +40,7 @@ "dept": "컴퓨터학부 21", "role": "멋쟁이사자처럼 12기 운영진", "photo": "junhyeok", - "description": ["메인 페이지 개발", "만든이들 페이지 개발 2", "웹 페이지 디자인"], + "description": ["메인 페이지 개발", "만든이들 페이지 개발", "웹 페이지 디자인"], "contact": { "instagram": "junyeokk_", "linkedin": "junhyeokchae", @@ -53,7 +53,7 @@ "dept": "컴퓨터학부 20", "role": "멋쟁이사자처럼 12기 운영진", "photo": "donggun", - "description": ["기여한 부분 1", "기여한 부분 2", "기여한 부분 3"], + "description": ["DB 구축 및 관리", "개발 및 운영", "서버 배포"], "contact": { "instagram": "thismovinggun", "github": "himodu" @@ -65,7 +65,7 @@ "dept": "컴퓨터학부 19", "role": "멋쟁이사자처럼 12기 운영진", "photo": "jiwoong", - "description": ["기여한 부분 1", "기여한 부분 2", "기여한 부분 3"], + "description": ["정보 수집 및 제공", "데이터 설계"], "contact": { "instagram": "dnd._.hihi", "github": "wldnd2" @@ -77,7 +77,7 @@ "dept": "컴퓨터학부 20", "role": "멋쟁이사자처럼 12기 운영진", "photo": "jeongsik", - "description": ["기여한 부분 1", "기여한 부분 2", "기여한 부분 3"], + "description": ["DB 구축 및 관리", "개발 및 운영", "홍보 포스터 작성"], "contact": { "instagram": "siksik__choi", "github": "siksik-Choi" diff --git a/src/constants/timetable.json b/src/constants/timetable.json index 140106c..b8a7d2e 100644 --- a/src/constants/timetable.json +++ b/src/constants/timetable.json @@ -18,7 +18,7 @@ "5.22": { "대운동장": [ { "time": "17:00 ~ ", "event": "2일차 무대 관객 입장" }, - { "time": "18:00 ~ 20:30", "event": "학생 공연 7개 팀" }, + { "time": "18:00 ~ 20:30", "event": "KROCK Us: 청춘결전 - 가요 부문" }, { "time": "20:30 ~ 21:10", "event": "하하 축하공연" }, { "time": "21:20 ~ 22:00", "event": "QWER 축하공연" }, { "time": "22:10 ~ 23:10", "event": "10CM 축하공연" } @@ -35,11 +35,11 @@ { "time": "17:00 ~ ", "event": "3일차 무대 관객 입장" }, { "time": "17:30 ~ 19:00", "event": "전한길 선생님 초청 강연" }, { "time": "19:00 ~ 19:40", "event": "로이킴 축하공연" }, - { "time": "19:40 ~ 21:10", "event": "학생 공연 7개 팀" }, - { "time": "21:20 ~ 21:30", "event": "대동제 메이킹 영상 및 불꽃놀이 진행" }, - { "time": "21:30 ~ 22:10", "event": "폴블랑코 축하공연" }, + { "time": "19:40 ~ 21:20", "event": "KROCK Us: 청춘결전 - 퍼포먼스 부문" }, + { "time": "21:30 ~ 21:40", "event": "<우리의 마음은 영원히 불타오른다> 불꽃쇼" }, + { "time": "21:40 ~ 22:10", "event": "폴블랑코 축하공연" }, { "time": "22:10 ~ 22:40", "event": "이영현(빅마마) 축하공연" }, - { "time": "22:40 ~ 22:50", "event": "로이킴 축하공연" } + { "time": "22:40 ~ 22:50", "event": "대동제 폐회식 진행" } ], "소운동장, 복지관": [{ "time": "08:00 ~ 전량 소진", "event": "재적생 ZONE 팔찌 배부" }], "다목적구장": [{ "time": "12:30 ~ 20:00", "event": "픽셀 아케이드: 인간컬링,\n인간 러쉬아워, 병뚜껑 게임" }], diff --git a/src/hooks/useCountdown.ts b/src/hooks/useCountdown.ts index 06d538a..23b1a1c 100644 --- a/src/hooks/useCountdown.ts +++ b/src/hooks/useCountdown.ts @@ -15,6 +15,13 @@ const calculateTimeLeft = (targetDate: Date) => { minutes: Math.floor((difference / 1000 / 60) % 60), seconds: Math.floor((difference / 1000) % 60), }; + } else { + timeLeft = { + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + }; } return timeLeft; diff --git a/src/hooks/useFestivalCountdown.ts b/src/hooks/useFestivalCountdown.ts new file mode 100644 index 0000000..4b7e3f0 --- /dev/null +++ b/src/hooks/useFestivalCountdown.ts @@ -0,0 +1,35 @@ +import { useState, useEffect } from "react"; + +export const useFestivalCountdown = ( + targetDate: Date, + endDate: Date, + onCountdownEnd: () => void, + onFestivalEnd: () => void, +) => { + const [isCountdownFinished, setIsCountdownFinished] = useState(false); + const [isFestivalOver, setIsFestivalOver] = useState(false); + + useEffect(() => { + const checkCountdown = () => { + const currentTime = new Date().getTime(); + const targetTime = targetDate.getTime(); + const endTime = endDate.getTime(); + + if (currentTime >= targetTime && !isCountdownFinished) { + setIsCountdownFinished(true); + onCountdownEnd(); + } + + if (currentTime >= endTime && !isFestivalOver) { + setIsFestivalOver(true); + onFestivalEnd(); + } + }; + + const interval = setInterval(checkCountdown, 1000); + + return () => clearInterval(interval); + }, [targetDate, endDate, onCountdownEnd, onFestivalEnd, isCountdownFinished, isFestivalOver]); + + return { isCountdownFinished, isFestivalOver }; +}; diff --git a/src/pages/BoothDetailPage.styled.tsx b/src/pages/BoothDetailPage.styled.tsx index 162d9be..cdb42fe 100644 --- a/src/pages/BoothDetailPage.styled.tsx +++ b/src/pages/BoothDetailPage.styled.tsx @@ -11,6 +11,8 @@ export const DetailPageWrapper = styled.div` justify-content: center; align-items: center; + word-break: keep-all; + p { width: 90%; } @@ -78,3 +80,18 @@ export const SubBtn = styled.button` export const SendImg = styled.img` width: 50%; `; + +export const ScrollTopButton = styled.button` + position: fixed; + bottom: 80px; + right: 20px; + background: #5d5a88; + color: #fff; + border: none; + border-radius: 50%; + width: 60px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; +`; diff --git a/src/pages/BoothDetailPage.tsx b/src/pages/BoothDetailPage.tsx index bba81fb..929f0d3 100644 --- a/src/pages/BoothDetailPage.tsx +++ b/src/pages/BoothDetailPage.tsx @@ -7,10 +7,12 @@ import { CommentList } from "@/components/display/CommentInfo.styled"; import { CommentContainer } from "@/components/display/CommentInfo.styled"; import { Title } from "@/components/display/CommentInfo.styled"; import { Loader } from "@/components/feedback/Loader"; +import { Pagination } from "@/components/navigation/Pagination"; import { Paragraph } from "@/components/typography/Paragraph"; import { Text } from "@/components/typography/Text"; import { DetailPageWrapper, SubBtn, ContentContainer, SendImg, BottomBox } from "@/pages/BoothDetailPage.styled"; +import { ScrollTopButton } from "@/pages/BoothDetailPage.styled"; import { useBoothDetail } from "@/services/booth/booth.hooks"; import { useComment } from "@/services/comment/comment.hooks"; @@ -20,7 +22,6 @@ import sendImg from "@/assets/send.png"; import { parseCreatedDate } from "@/utils/parseCreatedDate"; import { CommentHeader } from "./BoothListPage.styled"; -import { ScrollTopButton } from "./TimeTablePage.styled"; export default function BoothDetailPage() { const { isPending, boothDetail } = useBoothDetail(); @@ -56,12 +57,7 @@ export default function BoothDetailPage() { - - 댓글 - <Text size="m" weight="bold" variant="#3F3A6C"> - {0} - </Text> - + 댓글 @@ -109,6 +105,8 @@ export default function BoothDetailPage() { + + diff --git a/src/pages/BoothListPage.styled.ts b/src/pages/BoothListPage.styled.ts index bf0884d..06592cb 100644 --- a/src/pages/BoothListPage.styled.ts +++ b/src/pages/BoothListPage.styled.ts @@ -30,9 +30,12 @@ export const VisibleList = styled(motion.ul)` `; export const CommentHeader = styled.div` - width: 100%; + width: 90%; margin: 10px 0px; margin-bottom: 30px; + padding: 10px 0px; + padding-top: 30px; + border-top: 2px solid #ddd; display: flex; justify-content: center; diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index ab6f501..f928d15 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -13,6 +13,8 @@ import { userService } from "@/services/user/user.service"; import mainPageImage from "@/assets/main_page.jpg"; export default function HomePage() { + const [isCountdownFinished, setIsCountdownFinished] = useState(false); + const [isFestivalOver, setIsFestivalOver] = useState(false); const quickAccessRef = useRef(null); const [totalUser, setTotalUser] = useState(undefined); @@ -27,6 +29,9 @@ export default function HomePage() { }); }, []); + const festivalStartDate = new Date("2024-05-21T00:00:00"); + const festivalEndDate = new Date("2024-05-23T22:40:00"); + return ( <> @@ -41,9 +46,18 @@ export default function HomePage() { {/* 카운트다운 */} - 대동제가 곧 시작됩니다 + {isFestivalOver + ? "축제가 종료되었습니다." + : isCountdownFinished + ? "축제가 진행중입니다!" + : "대동제가 곧 시작됩니다"} - + setIsCountdownFinished(true)} + endDate={festivalEndDate} + onFestivalEnd={() => setIsFestivalOver(true)} + /> {/* 빠른 시작 */}