From 7d0a8e979bc6fba9d168437c711301aa88609d8c Mon Sep 17 00:00:00 2001 From: NEWJIN <109906670+newjinlee@users.noreply.github.com> Date: Wed, 31 Jul 2024 02:14:50 +0900 Subject: [PATCH] =?UTF-8?q?FE-20=20=F0=9F=94=80=20=EB=9E=9C=EB=94=A9?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B5=9C=EC=8B=A0=ED=99=94=20(#1?= =?UTF-8?q?22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๐Ÿ”€๊ฒ€์ƒ‰ ํŽ˜์ด์ง€ ๋ฉ”์ธ ๋จธ์ง€ (#107) * ๐Ÿ’„FE-33 ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€ UI (#10) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * โœจFeat: SearchBar UI ์ดˆ์•ˆ ์™„์„ฑ * styles: tailwind css ํฐํŠธ ์‚ฌ์ด์ฆˆ ์ถ”๊ฐ€ * feat: RecentSearches UI ์ดˆ์•ˆ ์™„์„ฑ * ๏ฟฝstyles: SearchResults UI ์ˆ˜์ • * ๏ฟฝstyles: RecentSearches UI ์ˆ˜์ • * โœจstyles: ๋ฐ˜์‘ํ˜• UI ์ถ”๊ฐ€ * FE-33 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> * FE-65 โœจ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ธฐ๋Šฅ (#51) * FE-65 โœจfeat: ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-65 โœจfeat: ๊ฒ€์ƒ‰๋ฐ”์™€ ์—ฐ๋™ํ•˜์—ฌ ์ฆ‰์‹œ ๋ฐ˜์˜๋˜๋„๋ก ์ˆ˜์ • * FE-65 โœจfeat: debounce๋ฅผ ์œ„ํ•œ lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ * FE-65 โœจfeat: debounce ๊ธฐ๋Šฅ ์ ์šฉ(++lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) * FE-65 โœจfeat: useEffectt๋กœ debouncedSearchํ•จ์ˆ˜ ์˜์กด์„ฑ ์„ค์ • * FE-65 โœจfeat: useCallback ๋Œ€์‹  useRef๋กœ ๋ณ€๊ฒฝ * FE-65 โœจfix:: debounce ๊ธฐ๋Šฅ ์ œ๊ฑฐ(๋ถˆํ•„์š”) * FE-65 โœจfeat: focus๋  ๋•Œ placeholder ์‚ฌ๋ผ์ง€๊ฒŒ ์ˆ˜์ • ๋ฐ UI ์ˆ˜์ • * FE-65 โœจfeat: isInitialMount ์„ ์–ธ ๋ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-65 โœจfix: ์ฃผ์„ ์ˆ˜์ • * FE-65 โœจfeat: ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ํด๋ฆญ ์‹œ ๊ทธ ๊ฒ€์ƒ‰์–ด๋กœ ๊ฒ€์ƒ‰๋˜๋Š” ๊ธฐ๋Šฅ * FE-65 styles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ธฐ๋Šฅ (#73) * FE-74 fix: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ญ์ œ * FE-74 โœจfeat: ํ…Œ์ŠคํŠธ ์šฉ api ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ * FE-74 โœจfeat: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-74 โœจfix: ์ค‘๋ณต๋œ key, href ์ œ๊ฑฐ ๋ฐ ๊ทœ์น™ ๋ฌด์‹œ ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจtest: ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ * FE-74 โœจfeat: ๊ฒ€์ƒ‰์–ด ํ•˜์ด๋ผ์ดํŒ… ๋ฐ ์ˆœ์„œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-74 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ api ํŒŒ์ผ ์‚ญ์ œ * FE-74 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจfix: ๋ฉ˜ํ† ๋ง ๋‚ด์šฉ ์ฃผ์„์œผ๋กœ ์ถ”๊ฐ€ * FE-32 ๐Ÿ”€ epic๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#77) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> * FE-75 โœจ๋ฌดํ•œ ์Šคํฌ๋กค, ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ URL์— ์ €์žฅ ๊ธฐ๋Šฅ ๊ตฌํ˜„ (#104) * FE-75 โœจstyles: tailwind .config ํŒŒ์ผ ๋ฉ”์ธ๊ณผ ํ†ตํ•ฉ * FE-75 โœจfeat: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ Header ์ถ”๊ฐ€ * FE-75 โœจrefactor: useMemo ์‚ฌ์šฉ * FE-75 โœจfeat: URL์— ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์ €์žฅ * FE-75 โœจstyles: ๋กœ๋”ฉ ์Šคํƒ€์ผ ๊ตฌํ˜„ * FE-75 โœจfeat: ์‹ค์ œ api ์ถ”๊ฐ€ * FE-75 โœจfeat: api ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-75 โœจfeat: ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„ * FE-75 โœจfix: ์˜์กด์„ฑ ๋ฐฐ์—ด์—์„œ ๋กœ๋”ฉ ์ƒํƒœ ์ œ๊ฑฐ * FE-75 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-75 โœจfeat:: ์‚ฌ์šฉ์ž๋งˆ๋‹ค ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€๊ฒฝ * FE-75 โœจfix: ๊ฒ€์ƒ‰ ์ „ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋„๋ก ์ˆ˜์ • * FE-32 ๐Ÿ”€๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#105) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * .http ํŒŒ์ผ ์‚ญ์ œ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๐Ÿ”€๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#110) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * .http ํŒŒ์ผ ์‚ญ์ œ * merge main --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๊ฒ€์ƒ‰ํŽ˜์ด์ง€ ๋ฉ”์ธ ์ถฉ๋Œ ์ˆ˜์ • (#112) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋งˆ์ดํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#100) * FE-34 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ํ”„๋กœํ•„ ์ˆ˜์ • ๊ธฐ๋Šฅ (#53) * FE-34 :lipstick: ๋งˆ์ดํŽ˜์ด์ง€ UI ์ดˆ๊ธฐ์ž‘์—… * FE-34 :sparkles: ๋‚ด ์ •๋ณด ์กฐํšŒ API ์—ฐ๋™ * FE-34 :lipstick: shadcn/ui Dialog ์„ค์น˜ * FE-34 :sparkles: ํ”„๋กœํ•„ ์ˆ˜์ • API ์—ฐ๋™ * FE-34 :sparkles: ์ด๋ฏธ์ง€ ์‹คํŒจ ํ† ์ŠคํŠธ ์ถ”๊ฐ€ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ์บ˜๋ฆฐ๋” ์ถœ๋ ฅ ํ•จ์ˆ˜ (#58) * FE-36 :lipstick: ๊ฐ์ •๋‹ฌ๋ ฅ UI * FE-36 :sparkles: ์บ˜๋ฆฐ๋” ํ•จ์ˆ˜ ์ƒ์„ฑ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ (#65) * FE-36 :lipstick: ๊ฐ์ •๋‹ฌ๋ ฅ UI * FE-36 :sparkles: ์บ˜๋ฆฐ๋” ํ•จ์ˆ˜ ์ƒ์„ฑ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ: ์˜ค๋Š˜ ๋‚ ์งœ ํ‘œ์‹œ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ์›” ๋ณ„ ๊ฐ์ •๋กœ๊ทธ ์กฐํšŒ API ์—ฐ๋™ * FE-36 :sparkles: ์›”๋ณ„ ๊ฐ์ • ๋กœ๊ทธ ํ•ด๋‹น ๋‚ ์งœ์— ์ถœ๋ ฅ * FE-36 :lipstick: ๋‹ฌ๋ ฅ css ์ˆ˜์ • * FE-36 :art: ๋งˆ์ดํŽ˜์ด์ง€ ์บ˜๋ฆฐ๋” ํ—ค๋” ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ ํ•„ํ„ฐ๊ธฐ๋Šฅ * FE-27 :twisted_rightwards_arrows: ์—ํ”ฝ ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#81) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋งˆ์ดํŽ˜์ด์ง€ ์—ํ”ฝ ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#85) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#86) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-37 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •์ฐจํŠธ (#89) * FE-37 :recycle: ์›”๋ณ„ ๊ฐ์ •๋กœ๊ทธ ์กฐํšŒ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง * FE-37 :sparkles: ๊ฐ์ • ์ฐจํŠธ * FE-37 :hammer: ์ƒ์ˆ˜ ์ปจ๋ฒค์…˜ ์ˆ˜์ • * FE-27 :twisted_rightwards_arrows: ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#99) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :hammer: ์ถฉ๋Œ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-27 :hammer: ์ถฉ๋Œ๋‚ด์—ญ ์ˆ˜์ • * FE-27 :twisted_rightwards_arrows: ์ถฉ๋Œ์˜ค๋ฅ˜ ์ˆ˜์ • --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN * FE-27 :twisted_rightwards_arrows: ๋งˆ์ดํŽ˜์ด์ง€ ์ตœ์‹ ํ™” (#102) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN * FE-27 :twisted_rightwards_arrows: ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#111) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ Co-authored-by: JeonYumin <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN * FE-27 :twisted_rightwards_arrows: ์ถฉ๋Œ์—๋Ÿฌ ์ˆ˜์ • (#113) Co-authored-by: morrison --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ Co-authored-by: MOON Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: kich555 <79491683+kich555@users.noreply.github.com> Co-authored-by: morrison * FE-51 ๐Ÿ”จ ๊ณต์šฉ api ์ˆ˜์ • ๋ฐ ์ตœ์‹ ํ™” (#119) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) * FE-51 ๐Ÿ”จ ์˜ค๋Š˜์˜ ๊ฐ์ • ๊ด€๋ จ ์ˆ˜์ • (#115) * FE-51 :hammer: ๊ฐ์ • ์˜์–ด์ด๋ฆ„ ์ˆ˜์ • * FE-51 :hammer: postEmotion ํ† ํฐ ์ œ๊ฑฐ * FE-51 ๐Ÿ”€ ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#117) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๐Ÿ”€๊ฒ€์ƒ‰ ํŽ˜์ด์ง€ ๋ฉ”์ธ ๋จธ์ง€ (#107) * ๐Ÿ’„FE-33 ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€ UI (#10) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * โœจFeat: SearchBar UI ์ดˆ์•ˆ ์™„์„ฑ * styles: tailwind css ํฐํŠธ ์‚ฌ์ด์ฆˆ ์ถ”๊ฐ€ * feat: RecentSearches UI ์ดˆ์•ˆ ์™„์„ฑ * ๏ฟฝstyles: SearchResults UI ์ˆ˜์ • * ๏ฟฝstyles: RecentSearches UI ์ˆ˜์ • * โœจstyles: ๋ฐ˜์‘ํ˜• UI ์ถ”๊ฐ€ * FE-33 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * FE-33 fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * fix: build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> * FE-65 โœจ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ธฐ๋Šฅ (#51) * FE-65 โœจfeat: ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-65 โœจfeat: ๊ฒ€์ƒ‰๋ฐ”์™€ ์—ฐ๋™ํ•˜์—ฌ ์ฆ‰์‹œ ๋ฐ˜์˜๋˜๋„๋ก ์ˆ˜์ • * FE-65 โœจfeat: debounce๋ฅผ ์œ„ํ•œ lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ * FE-65 โœจfeat: debounce ๊ธฐ๋Šฅ ์ ์šฉ(++lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) * FE-65 โœจfeat: useEffectt๋กœ debouncedSearchํ•จ์ˆ˜ ์˜์กด์„ฑ ์„ค์ • * FE-65 โœจfeat: useCallback ๋Œ€์‹  useRef๋กœ ๋ณ€๊ฒฝ * FE-65 โœจfix:: debounce ๊ธฐ๋Šฅ ์ œ๊ฑฐ(๋ถˆํ•„์š”) * FE-65 โœจfeat: focus๋  ๋•Œ placeholder ์‚ฌ๋ผ์ง€๊ฒŒ ์ˆ˜์ • ๋ฐ UI ์ˆ˜์ • * FE-65 โœจfeat: isInitialMount ์„ ์–ธ ๋ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-65 โœจfix: ์ฃผ์„ ์ˆ˜์ • * FE-65 โœจfeat: ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ํด๋ฆญ ์‹œ ๊ทธ ๊ฒ€์ƒ‰์–ด๋กœ ๊ฒ€์ƒ‰๋˜๋Š” ๊ธฐ๋Šฅ * FE-65 styles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ธฐ๋Šฅ (#73) * FE-74 fix: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ญ์ œ * FE-74 โœจfeat: ํ…Œ์ŠคํŠธ ์šฉ api ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ * FE-74 โœจfeat: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-74 โœจfix: ์ค‘๋ณต๋œ key, href ์ œ๊ฑฐ ๋ฐ ๊ทœ์น™ ๋ฌด์‹œ ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจtest: ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ * FE-74 โœจfeat: ๊ฒ€์ƒ‰์–ด ํ•˜์ด๋ผ์ดํŒ… ๋ฐ ์ˆœ์„œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-74 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ api ํŒŒ์ผ ์‚ญ์ œ * FE-74 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-74 โœจfix: ๋ฉ˜ํ† ๋ง ๋‚ด์šฉ ์ฃผ์„์œผ๋กœ ์ถ”๊ฐ€ * FE-32 ๐Ÿ”€ epic๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#77) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> * FE-75 โœจ๋ฌดํ•œ ์Šคํฌ๋กค, ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ URL์— ์ €์žฅ ๊ธฐ๋Šฅ ๊ตฌํ˜„ (#104) * FE-75 โœจstyles: tailwind .config ํŒŒ์ผ ๋ฉ”์ธ๊ณผ ํ†ตํ•ฉ * FE-75 โœจfeat: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ Header ์ถ”๊ฐ€ * FE-75 โœจrefactor: useMemo ์‚ฌ์šฉ * FE-75 โœจfeat: URL์— ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์ €์žฅ * FE-75 โœจstyles: ๋กœ๋”ฉ ์Šคํƒ€์ผ ๊ตฌํ˜„ * FE-75 โœจfeat: ์‹ค์ œ api ์ถ”๊ฐ€ * FE-75 โœจfeat: api ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-75 โœจfeat: ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„ * FE-75 โœจfix: ์˜์กด์„ฑ ๋ฐฐ์—ด์—์„œ ๋กœ๋”ฉ ์ƒํƒœ ์ œ๊ฑฐ * FE-75 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-75 โœจfeat:: ์‚ฌ์šฉ์ž๋งˆ๋‹ค ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€๊ฒฝ * FE-75 โœจfix: ๊ฒ€์ƒ‰ ์ „ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋„๋ก ์ˆ˜์ • * FE-32 ๐Ÿ”€๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#105) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * .http ํŒŒ์ผ ์‚ญ์ œ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๐Ÿ”€๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#110) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ * build ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ์ค‘ * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * .http ํŒŒ์ผ ์‚ญ์ œ * merge main --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-32 ๊ฒ€์ƒ‰ํŽ˜์ด์ง€ ๋ฉ”์ธ ์ถฉ๋Œ ์ˆ˜์ • (#112) * .nvmrc ๋ฒ„์ „ ์ˆ˜์ • * ํฐํŠธ ๋ฐ ๊ณต์šฉ์ปฌ๋Ÿฌ ์ถ”๊ฐ€ (#6) * font-family ์ถ”๊ฐ€ * tailwind common color ์ถ”๊ฐ€ * color ๋ช… ๋ณ€๊ฒฝ * lang ์ˆ˜์ • --------- Co-authored-by: ์ „์œ ๋ฏผ * :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ shadcn ui ์ถ”๊ฐ€ (#7) * :lipstick: Feat: shadcn-ui init * :lipstick: Feat: add toast ui * Feat: add textarea ui * Feat: add switch ui * Feat: add radio-group ui * Feat: add label ui * Feat: add input ui * Feat: add form ui * Feat: add button ui * Feat: add dropdown-menu ui * Feat: add card ui * Feat: add badge ui * Feat: add avatar ui * Feat: add alert dialog ui * Chore: add eslint rules * Chore: add shadcn ui * FE-48 ๐Ÿ“ฐ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ face emoji svg ํŒŒ์ผ ์ƒ์„ฑ * FE-48 :art: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ƒ์„ฑ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • * FE-48 :lipstick: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ ui ์ˆ˜์ • * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์นด๋“œ ํด๋ฆญ ์ด๋ฒคํŠธ ๊ตฌํ˜„ - EmotionIconCardContainer๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ (Clicked<->UnClicked) * FE-48 ๐Ÿ“ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ช…ํ™•ํ•œ ์˜๋ฏธ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-48 :sparkles: ๊ฐ์ • ์ด๋ชจํ‹ฐ์ฝ˜ ์ƒํƒœ ๋ณ€ํ™” ๋™๊ธฐํ™” ๊ตฌ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „ํ™˜๋˜๊ณ , ๋‹ค๋ฅธ ์นด๋“œ์˜ ์ƒํƒœ๋„ ๋™๊ธฐํ™”๋˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-48 :sparkles: EmotionSelector ์ปดํฌ๋„ŒํŠธ ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ตฌํ˜„ useMediaQuery ํ›… ์ƒ์„ฑ: ํ™”๋ฉด์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ * FE-48 :fire: ์ถœ๋ ฅ ํ™•์ธ์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ * FE-48 :hammer: EmotionTypes ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ emotion ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ตฌํ˜„ * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ui ๊ตฌํ˜„ tailwind css๋ฅผ ํ™•์žฅํ•ด ์ค„๋ฌด๋Šฌ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ๊ตฌํ˜„ * FE-59 :sparkles: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๋ฐ˜์‘ํ˜„ ๋””์ž์ธ ๊ตฌํ˜„ * FE-59 :lipstick: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ๊ธ€์”จ์ฒด ์ ์šฉ * FE-59 :fire: ์—ํ”ผ๊ทธ๋žจ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-59 :fire: ํ…Œ์ŠคํŠธ ํ”์  ์‚ญ์ œ * FE-58 :sparkles: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋Œ“๊ธ€ ์นด๋“œ ๊ธฐ๋ณธ ui ๊ตฌํ˜„ * FE-58 :lipstick: ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ * FE-58 :fire: ๋Œ“๊ธ€ ์นด๋“œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-58 :lips: ๋Œ“๊ธ€ ์นด๋“œ ๊ด€๋ จ ์ธํ„ฐํŽ˜์ด์Šค, ์Šคํƒ€์ผ ๋ถ„๋ฆฌ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-50 โœจ๊ณต์šฉ์ปดํฌ๋„ŒํŠธ ํ—ค๋” ๊ตฌํ˜„ (#19) * FE-5050โœจ feat: ํ—ค๋” ๋ถ€๋ถ„ ๊ธฐ๋Šฅ ์ดˆ์•ˆ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”๊ฐ€ * FE-50 โœจstyles: ์ฃผ์„ ์ถ”์ถ”๊ฐ€ * FE-5050 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfeat: ๊ณต์œ  ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ ๋ฐ ํ˜„์žฌ URL ๋ณต์‚ฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-50 โœจstyles: U์…‹ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น ์ง€๋”๋ผ๋„ ์•ˆ๋ฌด๋„ˆ์ง€๊ฒŒ UI ์ˆ˜์ • * FE-50 โœจcomment: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ * FE-50 โœจfix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-50 โœจfix: ํ•จ์ˆ˜๋ช… ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ * FE-50 โœจfix: types ํด๋”์— interface ์ •์˜ * FE-50 fix: build ์˜ค๋ฅ˜ ์ˆ˜์ • * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * FE-61 ๐Ÿ”จ eslint ๊ทœ์น™ ์ˆ˜์ • * FE-61 ๐Ÿ”ฅ InteractiveEmotionIconCard ์‚ญ์ œ ๋‹จ์ˆœ ๋ž˜ํ•‘ ๊ธฐ๋Šฅ๋ฐ–์— ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ญ์ œ / emotionselector์—์„œ emotioniconcard๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * FE-61 ๐Ÿ”จ EpigramCard ์‚ฌ์ด์ฆˆ ์žฌ์ •์˜ base -> xs๋กœ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 ๐Ÿ”จ CommentCard ํƒ€์ž… ๋‚ด๋ถ€ ์ •์˜ * FE-61 :truck: ๊ฐ์ • ์นด๋“œ ํด๋” ๊ตฌ์กฐ ๋ณ€๊ฒฝ * FE-61 ๐Ÿ“ ๊ฐ์ • ์นด๋“œ, ๊ฐ์ • ์…€๋ ‰ํ„ฐ ์ฃผ์„ ์ถ”๊ฐ€ * FE-61 :fire: ๋Œ“๊ธ€ ์นด๋“œ ๋””ํดํŠธ ํ”„๋กญ ์‚ญ์ œ * FE-62 โœจfix: ์ฃผ์„ ์ˆ˜์ • ๋ฐ ํƒ€์ž… ์ˆ˜์ • (#27) * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐํšŒ API (#34) * FE-52 feat: api schema ์ž‘์„ฑ * FE-52 โœจfeat: getEpigrams api ์ž‘์„ฑ * FE-522 โœจfix: default export๋กœ ๋ณ€๊ฒฝ * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ * FE-52 โœจfeat: BaseUrl, TeamID ์ƒ์ˆ˜ ์ถ”๊ฐ€ ๋ฐ axios baseTRL ์ˆ˜์ • * FE-52 โœจfix: schema ๋ฐ apis ํŒŒ์ผ ์ˆ˜์ • * FE-52 โœจtest: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: .envํŒŒ์ผ ์ƒ์„ฑ ๋ฐ BaseURL ์ˆ˜์ • * FE-52 โœจfix: limit ํƒ€์ž… ์ˆ˜์ •(optional ์‚ญ์ œ) * FE-52 โœจtext: ํ…Œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‚ญ์ œ * FE-52 โœจfix: api GET์š”์ฒญ ์ฃผ์†Œ ์ˆ˜์ •('epigrams' -> '/epigrams') * FE-53 :sparkles: ๊ฐ์ •์ด๋ชจํ‹ฐ์ฝ˜ ์ €์žฅ ์Šคํ‚ค๋งˆ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ api ์ƒ์„ฑ * FE-53 :sparkles: getMe ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ * FE-53 :sparkles: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ * FE-53 :sparkles: ๊ฐ์ • ์ €์žฅ ํ›„ ํ† ์ŠคํŠธ ์•Œ๋ฆผ ํ‘œ์‹œ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ api ์ƒ์„ฑ * FE-53 :hammer: ๊ฐ์ • ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€ +) post, get ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ํ•œ์˜ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ด๋™ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ ์ •์˜ * FE-53 :sparkles: ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ํ•จ์ˆ˜ ์ ์šฉ * FE-53 :truck: ์˜ค๋Š˜์˜ ๊ฐ์ • type ์ด๋ฆ„ ๋ณ€๊ฒฝ * FE-53 :sparkles: useMutation ํ›… ์‚ฌ์šฉ * FE-53 :memo: EmotionSelector ์ฃผ์„ ์ถ”๊ฐ€ * FE-53 :fire: api ํ•จ์ˆ˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„ ์ œ๊ฑฐ * FE-53 :hammer: useQuery๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋Š˜์˜ ๊ฐ์ • ์กฐํšŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๋ผ ํ•จ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API (#84) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-56 :sparkles: ๋Œ“๊ธ€ ์ˆ˜์ • API --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-57 :sparkles: ๋Œ“๊ธ€ ์‚ญ์ œ API (#88) * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (#93) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ์ตœ์‹ ํ™” (์ถฉ๋Œ์ˆ˜์ •) (#98) --------- Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: MOON Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: JeonYumin94 <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: NEWJIN Co-authored-by: NEWJIN <109906670+newjinlee@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋งˆ์ดํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#100) * FE-34 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ํ”„๋กœํ•„ ์ˆ˜์ • ๊ธฐ๋Šฅ (#53) * FE-34 :lipstick: ๋งˆ์ดํŽ˜์ด์ง€ UI ์ดˆ๊ธฐ์ž‘์—… * FE-34 :sparkles: ๋‚ด ์ •๋ณด ์กฐํšŒ API ์—ฐ๋™ * FE-34 :lipstick: shadcn/ui Dialog ์„ค์น˜ * FE-34 :sparkles: ํ”„๋กœํ•„ ์ˆ˜์ • API ์—ฐ๋™ * FE-34 :sparkles: ์ด๋ฏธ์ง€ ์‹คํŒจ ํ† ์ŠคํŠธ ์ถ”๊ฐ€ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ์บ˜๋ฆฐ๋” ์ถœ๋ ฅ ํ•จ์ˆ˜ (#58) * FE-36 :lipstick: ๊ฐ์ •๋‹ฌ๋ ฅ UI * FE-36 :sparkles: ์บ˜๋ฆฐ๋” ํ•จ์ˆ˜ ์ƒ์„ฑ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ (#65) * FE-36 :lipstick: ๊ฐ์ •๋‹ฌ๋ ฅ UI * FE-36 :sparkles: ์บ˜๋ฆฐ๋” ํ•จ์ˆ˜ ์ƒ์„ฑ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ: ์˜ค๋Š˜ ๋‚ ์งœ ํ‘œ์‹œ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ์›” ๋ณ„ ๊ฐ์ •๋กœ๊ทธ ์กฐํšŒ API ์—ฐ๋™ * FE-36 :sparkles: ์›”๋ณ„ ๊ฐ์ • ๋กœ๊ทธ ํ•ด๋‹น ๋‚ ์งœ์— ์ถœ๋ ฅ * FE-36 :lipstick: ๋‹ฌ๋ ฅ css ์ˆ˜์ • * FE-36 :art: ๋งˆ์ดํŽ˜์ด์ง€ ์บ˜๋ฆฐ๋” ํ—ค๋” ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ * FE-36 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •๋‹ฌ๋ ฅ ํ•„ํ„ฐ๊ธฐ๋Šฅ * FE-27 :twisted_rightwards_arrows: ์—ํ”ฝ ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#81) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋งˆ์ดํŽ˜์ด์ง€ ์—ํ”ฝ ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#85) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-27 :twisted_rightwards_arrows: ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#86) * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ * FE-37 :sparkles: ๋งˆ์ดํŽ˜์ด์ง€ ๊ฐ์ •์ฐจํŠธ (#89) * FE-37 :recycle: ์›”๋ณ„ ๊ฐ์ •๋กœ๊ทธ ์กฐํšŒ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง * FE-37 :sparkles: ๊ฐ์ • ์ฐจํŠธ * FE-37 :hammer: ์ƒ์ˆ˜ ์ปจ๋ฒค์…˜ ์ˆ˜์ • * FE-27 :twisted_rightwards_arrows: ๋ธŒ๋žœ์น˜ ์ตœ์‹ ํ™” (#99) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :lipstick: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ * :lipstick: ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋กœ๊ณ  ์ถ”๊ฐ€ * :lipstick: ํšŒ์›๊ฐ€์ž… ui ์ถ”๊ฐ€ * :sparkles: ํšŒ์›๊ฐ€์ž… ์Šคํ‚ค๋งˆ ์ •์˜ * :heavy_plus_sign: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์Šคํ‚ค๋งˆ ์ ์šฉ * :lipstick: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋œฐ ๋•Œ ๋ผ๋ฒจ, ์ธํ’‹๋„ ๊ฐ™์€ ์—๋Ÿฌ ์ƒ‰๊น” ์ถ”๊ฐ€ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•œ ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ * :memo: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋”ฐ๋ฅธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ ์ฒ˜๋ฆฌ * :fire: AuthLayout ์‚ญ์ œ * :art: ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋ธŒ๋ผ์šฐ์ € ํ™•๋Œ€์‹œ ui ๊นจ์ง ์ˆ˜์ • * :truck: ์ •๊ทœํ‘œํ˜„์‹ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :sparkles: ํšŒ์›๊ฐ€์ž… ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ํšŒ์›๊ฐ€์ž… api ์ƒ์„ฑ * :sparkles: useRegisterMutation hook ์ƒ์„ฑ * :zap: ํšŒ์›๊ฐ€์ž… ํผ์— mutaion hook ์ ์šฉ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :zap: isAxiosError๋กœ ๋ณ€๊ฒฝ * FE-29 :twisted_rightwards_arrows: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋จธ์ง€ ์š”์ฒญ (#39) * :heavy_plus_sign: ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ถ”๊ฐ€ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ * :lipstick: ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ UI ์ƒ์„ฑ ๋ฐ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ * FE-60 :sparkles: react hook form, zod ์ถ”๊ฐ€ * FE-60 :lipstick: ๋กœ๊ทธ์ธ ํผ ์Šคํƒ€์ผ ์ˆ˜์ • - ํ…์ŠคํŠธ ์ธํ’‹ ํ…Œ๋‘๋ฆฌ - ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ * FE-60 :recycle: ๋กœ๊ทธ์ธ ์Šคํ‚ค๋งˆ ๋ถ„๋ฆฌ * :sparkles: ๋กœ๊ทธ์ธ ์‘๋‹ต ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ * :sparkles: ๋กœ๊ทธ์ธ api ์ƒ์„ฑ * :sparkles: ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๊ด€ํ•œ ์ธํ„ฐ์…‰ํ„ฐ ์ถ”๊ฐ€ * :sparkles: useSignin mutation hook ์ƒ์„ฑ * :zap: useSignin hook ๋กœ๊ทธ์ธ ํผ์— ์ ์šฉ * :fire: AuthLayout ์‚ญ์ œ * :art: onSubmit ํ•จ์ˆ˜ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ * :recycle: ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹  ๋กœ์ง ๊ฐœ์„  * :recycle: postSignin api ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์‚ญ์ œ * :fire: useSignin hook ์‚ญ์ œ * :truck: useSigninMutation hook์œผ๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ฐ ํŒŒ์ผ ์ด๋™ * :sparkles: Toaster ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ * :sparkles: toast๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ * :twisted_rightwards_arrows: ์ถฉ๋Œ ํ•ด๊ฒฐ * :bug: postSignup ํ•จ์ˆ˜ ์ถ”๊ฐ€ * :bug: postSignin ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ์‹ ์ˆ˜์ • * :wrench: lint ์ˆ˜์ • * :sparkles: oauth api ์ƒ์„ฑ * FE-71 ๐Ÿ”€ ์—ํ”ผ๊ทธ๋žจ ์ž‘์„ฑ ํŽ˜์ด์ง€ (#71) * FE-64๐Ÿ’„ ๊ธ€์ž‘์„ฑ ํŽ˜์ด์ง€ UI์ถ”๊ฐ€ (#44) * FE-72 โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ (#52) * FE-72โœจ ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ ์Šคํ‚ค๋งˆ ์ถ”๊ฐ€ * FE-72โœจ formํƒœ๊ทธ Form์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ * FE-72โœจ ํƒœ๊ทธ ์ €์žฅ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก api์—ฐ๋™ * FE-72โœจ ์—ํ”ผ๊ทธ๋žจ ๋“ฑ๋ก์‹œ ํ•ด๋‹น ์—ํ”ผ๊ทธ๋žจ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ * FE-72โœจ ๋“ฑ๋ก ์ค‘์ผ๋•Œ์˜ ๋กœ์ง์ถ”๊ฐ€ * FE-72โœจ toast-> alert-dailog๋กœ ๋ณ€๊ฒฝ * FE-72๐Ÿ“ TODO์ฃผ์„ ์ถ”๊ฐ€ --------- Co-authored-by: ์šฐ์ง€์„ * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ (#66) * FE-73โ™ป๏ธ Tag๊ด€๋ฆฌ ํ•จ์ˆ˜ ํ›…์œผ๋กœ ๋ถ„๋ฆฌ * FE-73โœจ RadioGroup ๋กœ์ง ์ˆ˜์ • * FE-73โœจ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ €์ž ๋ณธ์ธ ์„ ํƒ์‹œ์˜ ๋กœ์ง ๋ณ€๊ฒฝ * FE-73โœจ ์ค‘๋ณต ํƒœ๊ทธ ๊ฒ€์‚ฌ ๋กœ์ง ์ถ”๊ฐ€ * FE-73โ™ป๏ธ ์ถœ์ฒ˜ ์œ ํšจ์„ฑ(optional)๊ฒ€์‚ฌ ์ˆ˜์ • * FE-73โœจ ํ•„์ˆ˜ํ•ญ๋ชฉ ์ž…๋ ฅํ–ˆ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” * FE-73๐Ÿ› ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ ์ง€์› ์„๋•Œ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”๋˜์žˆ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • * FE-73๐Ÿ› useEffect ์˜์กด์„ฑ๋ฐฐ์—ด lint problem ํ•ด๊ฒฐ * FE-73๐Ÿ› url์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์•ˆ๋œจ๋Š” ๋ฒ„๊ทธ ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * FE-71โ™ป๏ธ epic๋ธŒ๋žœ์น˜ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ (#76) * FE-71โ™ป๏ธ token,interceptor ๋กœ์ง ์ˆ˜์ • * FE-71โ™ป๏ธ AddEpigram ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜ * FE-71๐Ÿ”ฅ ํ…Œ์ŠคํŠธ์šฉ ์ƒ์„ธํŽ˜์ด์ง€ ์‚ญ์ œ * FE-71โ™ป๏ธ onKeyDown -> onKeyUp ์ˆ˜์ • --------- Co-authored-by: ์šฐ์ง€์„ * :sparkles: ์นด์นด์˜คํ†ก ๋ฆฌ๋””๋ ‰ํŠธ uri ์„ค์ • * :sparkles: useKakaoLogin mutation hook ์ƒ์„ฑ * :zap: ๋„ค์ด๋ฒ„ ๊ตฌ๊ธ€ ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋งํฌ ์„ค์ • * :recycle: ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ • * FE-51 :twisted_rightwards_arrows: ๊ณต์šฉ API ๋จธ์ง€ ์š”์ฒญ (#92) * FE-52 โœจ์—ํ”ผ๊ทธ๋žจ ๋ชฉ๋ก์กฐโ€ฆ --------- Co-authored-by: MOON <50370479+jangmoonwon@users.noreply.github.com> Co-authored-by: MOON Co-authored-by: imsoohyeok <160010477+imsoohyeok@users.noreply.github.com> Co-authored-by: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Co-authored-by: ์šฐ์ง€์„ Co-authored-by: JeonYumin <40783675+JeonYumin94@users.noreply.github.com> Co-authored-by: ์ „์œ ๋ฏผ Co-authored-by: kich555 <79491683+kich555@users.noreply.github.com> Co-authored-by: morrison --- .eslintrc.js | 2 + .vscode/settings.json | 5 +- next.config.mjs | 17 + package-lock.json | 686 ++++++++++++++++++- package.json | 14 +- public/ProfileTestImage.jpg | Bin 0 -> 92716 bytes public/favicon.ico | Bin 25931 -> 0 bytes public/icon/BW/AngryFaceBWIcon.svg | 19 + public/icon/BW/HeartFaceBWIcon.svg | 13 + public/icon/BW/SadFaceBWIcon.svg | 14 + public/icon/BW/SmileFaceBWIcon.svg | 13 + public/icon/BW/ThinkFaceBWIcon.svg | 11 + public/icon/Color/AngryFaceColorIcon.svg | 19 + public/icon/Color/HeartFaceColorIcon.svg | 13 + public/icon/Color/SadFaceColorIcon.svg | 14 + public/icon/Color/SmileFaceColorIcon.svg | 13 + public/icon/Color/ThinkFaceColorIcon.svg | 11 + public/icon/arrow-bottom-icon.svg | 5 + public/icon/arrow-left-icon.svg | 5 + public/icon/arrow-right-icon.svg | 5 + public/icon/profile-icon.svg | 6 + public/icon/search-icon.svg | 6 + public/icon/share-icon.svg | 7 + public/lg.svg | 5 + public/logo-google.svg | 15 + public/logo-kakao.svg | 13 + public/logo-naver.svg | 5 + public/md.svg | 6 + public/next.svg | 1 - public/vercel.svg | 1 - src/apis/.http | 0 src/apis/add.ts | 9 + src/apis/auth.ts | 12 + src/apis/emotion.ts | 12 + src/apis/epigramComment.ts | 46 ++ src/apis/getEmotion.ts | 25 + src/apis/getEpigrams.ts | 12 + src/apis/index.ts | 86 ++- src/apis/oauth.ts | 11 + src/apis/postEmotion.ts | 15 + src/apis/queries.ts | 8 + src/apis/user.ts | 15 +- src/components/Card/CommentCard.tsx | 51 ++ src/components/Card/EpigramCard.tsx | 63 ++ src/components/Emotion/EmotionCard.tsx | 113 +++ src/components/Emotion/EmotionSaveToast.tsx | 34 + src/components/Emotion/EmotionSelector.tsx | 111 +++ src/components/Header/Header.tsx | 119 ++++ src/components/index.tsx | 0 src/components/search/RecentSearches.tsx | 43 ++ src/components/search/SearchBar.tsx | 58 ++ src/components/search/SearchResults.tsx | 101 +++ src/components/ui/dialog.tsx | 65 ++ src/hooks/epigramQueryHook.ts | 24 + src/hooks/useCalendar.ts | 67 ++ src/hooks/useDeleteCommentHook.ts | 31 + src/hooks/useGetEmotion.ts | 13 + src/hooks/useGetEpigramsHooks.ts | 13 + src/hooks/useKakaoLogin.ts | 42 ++ src/hooks/useMediaQuery.ts | 19 + src/hooks/usePatchCommentHook.ts | 32 + src/hooks/usePostEmotion.ts | 11 + src/hooks/useRegisterMutation.ts | 77 +++ src/hooks/useSignInMutation.ts | 22 + src/hooks/useTagManagementHook.ts | 47 ++ src/hooks/userQueryHooks.ts | 16 +- src/pageLayout/Epigram/AddEpigram.tsx | 316 +++++++++ src/pageLayout/MypageLayout/MyPageLayout.tsx | 47 ++ src/pageLayout/SearchLayout/SearchLayout.tsx | 114 +++ src/pageLayout/index.ts | 0 src/pages/_app.tsx | 2 + src/pages/addEpigram.tsx | 7 + src/pages/auth/SignIn.tsx | 99 +++ src/pages/auth/SignUp.tsx | 129 ++++ src/pages/auth/redirect/kakao/index.tsx | 18 + src/pages/mypage/index.tsx | 5 + src/pages/search/index.tsx | 8 + src/schema/addEpigram.ts | 44 ++ src/schema/auth.ts | 50 ++ src/schema/comment.ts | 44 ++ src/schema/emotion.ts | 43 ++ src/schema/epigram.ts | 30 + src/schema/epigrams.ts | 33 + src/schema/user.ts | 17 +- src/styles/CommentCardStyles.ts | 44 ++ src/types/emotion.ts | 30 + src/types/epigram.types.ts | 24 + src/types/user.ts | 13 + src/user/ui-profile/Calendar.tsx | 96 +++ src/user/ui-profile/CalendarHeader.tsx | 58 ++ src/user/ui-profile/Chart.tsx | 96 +++ src/user/ui-profile/EmotionMonthlyLogs.tsx | 40 ++ src/user/ui-profile/Profile.tsx | 41 ++ src/user/ui-profile/ProfileEdit.tsx | 140 ++++ src/user/utill/constants.ts | 20 + src/user/utill/fileNameChange.ts | 8 + src/utils/emotionMap.ts | 23 + tsconfig.json | 1 + 98 files changed, 3976 insertions(+), 31 deletions(-) create mode 100644 public/ProfileTestImage.jpg delete mode 100644 public/favicon.ico create mode 100644 public/icon/BW/AngryFaceBWIcon.svg create mode 100644 public/icon/BW/HeartFaceBWIcon.svg create mode 100644 public/icon/BW/SadFaceBWIcon.svg create mode 100644 public/icon/BW/SmileFaceBWIcon.svg create mode 100644 public/icon/BW/ThinkFaceBWIcon.svg create mode 100644 public/icon/Color/AngryFaceColorIcon.svg create mode 100644 public/icon/Color/HeartFaceColorIcon.svg create mode 100644 public/icon/Color/SadFaceColorIcon.svg create mode 100644 public/icon/Color/SmileFaceColorIcon.svg create mode 100644 public/icon/Color/ThinkFaceColorIcon.svg create mode 100644 public/icon/arrow-bottom-icon.svg create mode 100644 public/icon/arrow-left-icon.svg create mode 100644 public/icon/arrow-right-icon.svg create mode 100644 public/icon/profile-icon.svg create mode 100644 public/icon/search-icon.svg create mode 100644 public/icon/share-icon.svg create mode 100644 public/lg.svg create mode 100644 public/logo-google.svg create mode 100644 public/logo-kakao.svg create mode 100644 public/logo-naver.svg create mode 100644 public/md.svg delete mode 100644 public/next.svg delete mode 100644 public/vercel.svg create mode 100644 src/apis/.http create mode 100644 src/apis/add.ts create mode 100644 src/apis/auth.ts create mode 100644 src/apis/emotion.ts create mode 100644 src/apis/epigramComment.ts create mode 100644 src/apis/getEmotion.ts create mode 100644 src/apis/getEpigrams.ts create mode 100644 src/apis/oauth.ts create mode 100644 src/apis/postEmotion.ts create mode 100644 src/components/Card/CommentCard.tsx create mode 100644 src/components/Card/EpigramCard.tsx create mode 100644 src/components/Emotion/EmotionCard.tsx create mode 100644 src/components/Emotion/EmotionSaveToast.tsx create mode 100644 src/components/Emotion/EmotionSelector.tsx create mode 100644 src/components/Header/Header.tsx create mode 100644 src/components/index.tsx create mode 100644 src/components/search/RecentSearches.tsx create mode 100644 src/components/search/SearchBar.tsx create mode 100644 src/components/search/SearchResults.tsx create mode 100644 src/components/ui/dialog.tsx create mode 100644 src/hooks/epigramQueryHook.ts create mode 100644 src/hooks/useCalendar.ts create mode 100644 src/hooks/useDeleteCommentHook.ts create mode 100644 src/hooks/useGetEmotion.ts create mode 100644 src/hooks/useGetEpigramsHooks.ts create mode 100644 src/hooks/useKakaoLogin.ts create mode 100644 src/hooks/useMediaQuery.ts create mode 100644 src/hooks/usePatchCommentHook.ts create mode 100644 src/hooks/usePostEmotion.ts create mode 100644 src/hooks/useRegisterMutation.ts create mode 100644 src/hooks/useSignInMutation.ts create mode 100644 src/hooks/useTagManagementHook.ts create mode 100644 src/pageLayout/Epigram/AddEpigram.tsx create mode 100644 src/pageLayout/MypageLayout/MyPageLayout.tsx create mode 100644 src/pageLayout/SearchLayout/SearchLayout.tsx create mode 100644 src/pageLayout/index.ts create mode 100644 src/pages/addEpigram.tsx create mode 100644 src/pages/auth/SignIn.tsx create mode 100644 src/pages/auth/SignUp.tsx create mode 100644 src/pages/auth/redirect/kakao/index.tsx create mode 100644 src/pages/mypage/index.tsx create mode 100644 src/pages/search/index.tsx create mode 100644 src/schema/addEpigram.ts create mode 100644 src/schema/auth.ts create mode 100644 src/schema/comment.ts create mode 100644 src/schema/emotion.ts create mode 100644 src/schema/epigram.ts create mode 100644 src/schema/epigrams.ts create mode 100644 src/styles/CommentCardStyles.ts create mode 100644 src/types/emotion.ts create mode 100644 src/types/epigram.types.ts create mode 100644 src/types/user.ts create mode 100644 src/user/ui-profile/Calendar.tsx create mode 100644 src/user/ui-profile/CalendarHeader.tsx create mode 100644 src/user/ui-profile/Chart.tsx create mode 100644 src/user/ui-profile/EmotionMonthlyLogs.tsx create mode 100644 src/user/ui-profile/Profile.tsx create mode 100644 src/user/ui-profile/ProfileEdit.tsx create mode 100644 src/user/utill/constants.ts create mode 100644 src/user/utill/fileNameChange.ts create mode 100644 src/utils/emotionMap.ts diff --git a/.eslintrc.js b/.eslintrc.js index cb854af6..a373fb94 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,6 +30,8 @@ module.exports = { 'react/jsx-props-no-spreading': 'off', 'no-use-before-define': 'off', '@typescript-eslint/no-use-before-define': ['off'], + "react/require-default-props": 'off', + "react/self-closing-comp": 'off', }, settings: { react: { diff --git a/.vscode/settings.json b/.vscode/settings.json index d5bfa7d4..a9d3f305 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -64,5 +64,8 @@ } ] } - } + }, + "cSpell.words": [ + "clsx" + ] } diff --git a/next.config.mjs b/next.config.mjs index d5456a15..49ba09f8 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,6 +1,23 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, + images: { + domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com', 'localhost'], + remotePatterns: [ + { + protocol: 'https', + hostname: 'via.placeholder.com', + port: '', + pathname: '/**', + }, + ], + }, + rewrites: async () => [ + { + source: '/api/proxy/:path*', + destination: 'https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/:path*', + }, + ], }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 92e0a253..ce9380b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@lukemorales/query-key-factory": "^1.3.4", "@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-radio-group": "^1.2.0", @@ -23,21 +24,27 @@ "axios": "^1.7.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "formik": "^2.4.6", "lucide-react": "^0.402.0", "next": "14.2.4", "qs": "^6.12.2", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.52.1", + "react-toastify": "^10.0.5", + "sharp": "^0.33.4", "tailwind-merge": "^2.4.0", "tailwindcss-animate": "^1.0.7", + "yup": "^1.4.0", "zod": "^3.23.8" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.50.0", - "@types/node": "^20", + "@types/lodash": "^4.17.7", + "@types/node": "^20.14.10", "@types/qs": "^6.9.15", - "@types/react": "^18", + "@types/react": "^18.3.3", "@types/react-dom": "^18", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", @@ -56,8 +63,8 @@ "postcss": "8.4.39", "prettier": "^3.2.5", "prettier-eslint": "^16.3.0", - "tailwindcss": "3.4.4", - "typescript": "^5" + "tailwindcss": "^3.4.4", + "typescript": "^5.5.3" }, "engines": { "node": ">=20.15.0" @@ -74,6 +81,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@emnapi/runtime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", + "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -251,6 +267,437 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", + "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz", + "integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", + "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", + "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", + "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", + "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", + "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", + "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", + "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz", + "integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz", + "integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz", + "integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.31", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz", + "integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz", + "integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz", + "integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz", + "integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.1.1" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz", + "integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz", + "integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1475,16 +1922,31 @@ "react": "^18 || ^19" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1493,8 +1955,7 @@ "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "devOptional": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/qs": { "version": "6.9.15", @@ -1506,7 +1967,6 @@ "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -2295,6 +2755,18 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2311,6 +2783,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2378,8 +2859,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2438,6 +2918,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -2493,6 +2982,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -2534,6 +3031,14 @@ "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -3695,6 +4200,30 @@ "node": ">= 6" } }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -4020,6 +4549,19 @@ "node": ">= 0.4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/husky": { "version": "9.0.11", "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", @@ -4149,6 +4691,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -4679,8 +5226,12 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -5697,6 +6248,11 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -5767,6 +6323,11 @@ "react": "^18.3.1" } }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, "node_modules/react-hook-form": { "version": "7.52.1", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.1.tgz", @@ -5855,6 +6416,18 @@ } } }, + "node_modules/react-toastify": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -6090,7 +6663,6 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -6129,6 +6701,45 @@ "node": ">= 0.4" } }, + "node_modules/sharp": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", + "integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.0" + }, + "engines": { + "libvips": ">=8.15.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.4", + "@img/sharp-darwin-x64": "0.33.4", + "@img/sharp-libvips-darwin-arm64": "1.0.2", + "@img/sharp-libvips-darwin-x64": "1.0.2", + "@img/sharp-libvips-linux-arm": "1.0.2", + "@img/sharp-libvips-linux-arm64": "1.0.2", + "@img/sharp-libvips-linux-s390x": "1.0.2", + "@img/sharp-libvips-linux-x64": "1.0.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2", + "@img/sharp-libvips-linuxmusl-x64": "1.0.2", + "@img/sharp-linux-arm": "0.33.4", + "@img/sharp-linux-arm64": "0.33.4", + "@img/sharp-linux-s390x": "0.33.4", + "@img/sharp-linux-x64": "0.33.4", + "@img/sharp-linuxmusl-arm64": "0.33.4", + "@img/sharp-linuxmusl-x64": "0.33.4", + "@img/sharp-wasm32": "0.33.4", + "@img/sharp-win32-ia32": "0.33.4", + "@img/sharp-win32-x64": "0.33.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6176,6 +6787,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6571,6 +7190,16 @@ "node": ">=0.8" } }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6582,6 +7211,11 @@ "node": ">=8.0" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -7074,6 +7708,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yup": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", + "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", diff --git a/package.json b/package.json index fd0a12f9..450b39fe 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@lukemorales/query-key-factory": "^1.3.4", "@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-radio-group": "^1.2.0", @@ -28,21 +29,26 @@ "axios": "^1.7.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "formik": "^2.4.6", "lucide-react": "^0.402.0", "next": "14.2.4", "qs": "^6.12.2", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.52.1", + "react-toastify": "^10.0.5", + "sharp": "^0.33.4", "tailwind-merge": "^2.4.0", "tailwindcss-animate": "^1.0.7", + "yup": "^1.4.0", "zod": "^3.23.8" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.50.0", - "@types/node": "^20", + "@types/node": "^20.14.10", "@types/qs": "^6.9.15", - "@types/react": "^18", + "@types/react": "^18.3.3", "@types/react-dom": "^18", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", @@ -61,7 +67,7 @@ "postcss": "8.4.39", "prettier": "^3.2.5", "prettier-eslint": "^16.3.0", - "tailwindcss": "3.4.4", - "typescript": "^5" + "tailwindcss": "^3.4.4", + "typescript": "^5.5.3" } } diff --git a/public/ProfileTestImage.jpg b/public/ProfileTestImage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d7e85d8e9fe1ceda40f7614ac8a11e137f33b3c GIT binary patch literal 92716 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

>PF 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 CvJr&< literal 0 HcmV?d00001 diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 718d6fea4835ec2d246af9800eddb7ffb276240c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m diff --git a/public/icon/BW/AngryFaceBWIcon.svg b/public/icon/BW/AngryFaceBWIcon.svg new file mode 100644 index 00000000..c499add3 --- /dev/null +++ b/public/icon/BW/AngryFaceBWIcon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/icon/BW/HeartFaceBWIcon.svg b/public/icon/BW/HeartFaceBWIcon.svg new file mode 100644 index 00000000..5702c0f9 --- /dev/null +++ b/public/icon/BW/HeartFaceBWIcon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/icon/BW/SadFaceBWIcon.svg b/public/icon/BW/SadFaceBWIcon.svg new file mode 100644 index 00000000..90df96bd --- /dev/null +++ b/public/icon/BW/SadFaceBWIcon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/icon/BW/SmileFaceBWIcon.svg b/public/icon/BW/SmileFaceBWIcon.svg new file mode 100644 index 00000000..58be6715 --- /dev/null +++ b/public/icon/BW/SmileFaceBWIcon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/icon/BW/ThinkFaceBWIcon.svg b/public/icon/BW/ThinkFaceBWIcon.svg new file mode 100644 index 00000000..2ac21adc --- /dev/null +++ b/public/icon/BW/ThinkFaceBWIcon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icon/Color/AngryFaceColorIcon.svg b/public/icon/Color/AngryFaceColorIcon.svg new file mode 100644 index 00000000..ca6e754a --- /dev/null +++ b/public/icon/Color/AngryFaceColorIcon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/icon/Color/HeartFaceColorIcon.svg b/public/icon/Color/HeartFaceColorIcon.svg new file mode 100644 index 00000000..9db0bbd0 --- /dev/null +++ b/public/icon/Color/HeartFaceColorIcon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/icon/Color/SadFaceColorIcon.svg b/public/icon/Color/SadFaceColorIcon.svg new file mode 100644 index 00000000..58e96e31 --- /dev/null +++ b/public/icon/Color/SadFaceColorIcon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/icon/Color/SmileFaceColorIcon.svg b/public/icon/Color/SmileFaceColorIcon.svg new file mode 100644 index 00000000..3e66c738 --- /dev/null +++ b/public/icon/Color/SmileFaceColorIcon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/icon/Color/ThinkFaceColorIcon.svg b/public/icon/Color/ThinkFaceColorIcon.svg new file mode 100644 index 00000000..0e2bab7d --- /dev/null +++ b/public/icon/Color/ThinkFaceColorIcon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icon/arrow-bottom-icon.svg b/public/icon/arrow-bottom-icon.svg new file mode 100644 index 00000000..8e0e4d20 --- /dev/null +++ b/public/icon/arrow-bottom-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icon/arrow-left-icon.svg b/public/icon/arrow-left-icon.svg new file mode 100644 index 00000000..a54a7cb4 --- /dev/null +++ b/public/icon/arrow-left-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icon/arrow-right-icon.svg b/public/icon/arrow-right-icon.svg new file mode 100644 index 00000000..dc5959d5 --- /dev/null +++ b/public/icon/arrow-right-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icon/profile-icon.svg b/public/icon/profile-icon.svg new file mode 100644 index 00000000..e7109ea6 --- /dev/null +++ b/public/icon/profile-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/icon/search-icon.svg b/public/icon/search-icon.svg new file mode 100644 index 00000000..02de48b2 --- /dev/null +++ b/public/icon/search-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/icon/share-icon.svg b/public/icon/share-icon.svg new file mode 100644 index 00000000..4d1c6d03 --- /dev/null +++ b/public/icon/share-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/lg.svg b/public/lg.svg new file mode 100644 index 00000000..a4d3364f --- /dev/null +++ b/public/lg.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/logo-google.svg b/public/logo-google.svg new file mode 100644 index 00000000..5b169484 --- /dev/null +++ b/public/logo-google.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/logo-kakao.svg b/public/logo-kakao.svg new file mode 100644 index 00000000..f546e64d --- /dev/null +++ b/public/logo-kakao.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/logo-naver.svg b/public/logo-naver.svg new file mode 100644 index 00000000..dbec93dd --- /dev/null +++ b/public/logo-naver.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/md.svg b/public/md.svg new file mode 100644 index 00000000..9ada4505 --- /dev/null +++ b/public/md.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28c..00000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f84222..00000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/apis/.http b/src/apis/.http new file mode 100644 index 00000000..e69de29b diff --git a/src/apis/add.ts b/src/apis/add.ts new file mode 100644 index 00000000..66a6b010 --- /dev/null +++ b/src/apis/add.ts @@ -0,0 +1,9 @@ +import { AddEpigramRequestType, AddEpigramResponseType } from '@/schema/addEpigram'; +import httpClient from '.'; + +const postEpigram = async (request: AddEpigramRequestType): Promise => { + const response = await httpClient.post('/epigrams', request); + return response.data; +}; + +export default postEpigram; diff --git a/src/apis/auth.ts b/src/apis/auth.ts new file mode 100644 index 00000000..e13efb7d --- /dev/null +++ b/src/apis/auth.ts @@ -0,0 +1,12 @@ +import type { PostSigninRequestType, PostSigninResponseType, PostSignUpRequestType, PostSignUpResponseType } from '@/schema/auth'; +import httpClient from '.'; + +export const postSignin = async (request: PostSigninRequestType): Promise => { + const response = await httpClient.post('/auth/signIn', request); + return response.data; +}; + +export const postSignup = async (request: PostSignUpRequestType): Promise => { + const response = await httpClient.post('/auth/signUp', request); + return response.data; +}; diff --git a/src/apis/emotion.ts b/src/apis/emotion.ts new file mode 100644 index 00000000..8158e5a1 --- /dev/null +++ b/src/apis/emotion.ts @@ -0,0 +1,12 @@ +import { GetMonthlyEmotionLogsRequestType, GetMonthlyEmotionLogsResponseType } from '@/schema/emotion'; + +import httpClient from '.'; + +const getMonthlyEmotionLogs = async (request: GetMonthlyEmotionLogsRequestType): Promise => { + const response = await httpClient.get(`/emotionLogs/monthly`, { + params: request, + }); + return response.data; +}; + +export default getMonthlyEmotionLogs; diff --git a/src/apis/epigramComment.ts b/src/apis/epigramComment.ts new file mode 100644 index 00000000..4368fb9a --- /dev/null +++ b/src/apis/epigramComment.ts @@ -0,0 +1,46 @@ +import httpClient from '@/apis/index'; +import { CommentRequestSchema, CommentRequestType, CommentResponseSchema, CommentResponseType } from '@/schema/comment'; +import { PostCommentRequest, PatchCommentRequest } from '@/types/epigram.types'; + +export const getEpigramComments = async (params: CommentRequestType): Promise => { + try { + // ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ + const validatedParams = CommentRequestSchema.parse(params); + + const { id, limit, cursor } = validatedParams; + + // NOTE: URL์˜ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉ + // NOTE : cursor๊ฐ’์ด ์žˆ๋‹ค๋ฉด ?limit=3&cursor=100, ์—†๋‹ค๋ฉด ?limit=3,(์ˆซ์ž๋Š” ์ž„์˜๋กœ ์ง€์ •ํ•œ ๊ฒƒ) + const queryParams = new URLSearchParams({ + limit: limit.toString(), + ...(cursor !== undefined && { cursor: cursor.toString() }), + }); + + const response = await httpClient.get(`/epigrams/${id}/comments?${queryParams.toString()}`); + + // ์‘๋‹ต ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ + const validatedData = CommentResponseSchema.parse(response.data); + + return validatedData; + } catch (error) { + if (error instanceof Error) { + throw new Error(`๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค: ${error.message}`); + } + throw error; + } +}; + +export const postComment = async (commentData: PostCommentRequest) => { + const response = await httpClient.post('/comments', commentData); + return response.data; +}; + +export const patchComment = async (commentId: number, commentData: PatchCommentRequest) => { + const response = await httpClient.patch(`/comments/${commentId}`, commentData); + return response.data; +}; + +export const deleteComment = async (commentId: number) => { + const response = await httpClient.delete(`/comments/${commentId}`); + return response.data; +}; diff --git a/src/apis/getEmotion.ts b/src/apis/getEmotion.ts new file mode 100644 index 00000000..044ff3c3 --- /dev/null +++ b/src/apis/getEmotion.ts @@ -0,0 +1,25 @@ +import { EmotionType } from '@/types/emotion'; +import type { GetEmotionResponseType } from '@/schema/emotion'; +import { translateEmotionToKorean } from '@/utils/emotionMap'; +import httpClient from '.'; +import { getMe } from './user'; + +const getEmotion = async (): Promise => { + const user = await getMe(); + if (!user) { + throw new Error('๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.'); + } + + const response = await httpClient.get('/emotionLogs/today', { + params: { userId: user.id }, + }); + + if (response.status === 204) { + return null; // No content + } + + const koreanEmotion = translateEmotionToKorean(response.data.emotion); + return koreanEmotion; +}; + +export default getEmotion; diff --git a/src/apis/getEpigrams.ts b/src/apis/getEpigrams.ts new file mode 100644 index 00000000..9685bc60 --- /dev/null +++ b/src/apis/getEpigrams.ts @@ -0,0 +1,12 @@ +import { GetEpigramsParamsType, GetEpigramsResponseType, GetEpigramsResponse } from '@/schema/epigrams'; +import httpClient from '.'; + +const getEpigrams = async (params: GetEpigramsParamsType): Promise => { + const response = await httpClient.get(`/epigrams`, { params }); + + // ๋ฐ์ดํ„ฐ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ + const parsedResponse = GetEpigramsResponse.parse(response.data); + return parsedResponse; +}; + +export default getEpigrams; diff --git a/src/apis/index.ts b/src/apis/index.ts index 29949fc2..0a4b7625 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -1,10 +1,94 @@ import axios from 'axios'; import qs from 'qs'; +// NOTE: axios ์„ ์–ธ const httpClient = axios.create({ baseURL: process.env.NEXT_PUBLIC_BASE_URL, - headers: { 'Content-Type': 'application/json' }, paramsSerializer: (parameters) => qs.stringify(parameters, { arrayFormat: 'repeat', encode: false }), }); +// NOTE: eslint-disable no-param-reassign ๋ฏธํ•ด๊ฒฐ๋กœ ์ธํ•œ ์„ค์ • +httpClient.interceptors.request.use((config) => { + const accessToken = localStorage.getItem('accessToken'); + /* eslint-disable no-param-reassign */ + if (accessToken) config.headers.Authorization = `Bearer ${accessToken}`; + /* eslint-enable no-param-reassign */ + return config; +}); + +httpClient.interceptors.response.use( + (response) => response, + + (error) => { + if (error.response && error.response.status === 401) { + const refreshToken = localStorage.getItem('refreshToken'); + + if (!refreshToken) { + window.location.href = '/auth/SignIn'; + return Promise.reject(error); + } + + return httpClient + .post('/auth/refresh-token', null, { + headers: { Authorization: `Bearer ${refreshToken}` }, + }) + .then((response) => { + const { accessToken, refreshToken: newRefreshToken } = response.data; + localStorage.setItem('accessToken', accessToken); + localStorage.setItem('refreshToken', newRefreshToken); + + const originalRequest = error.config; + return httpClient(originalRequest); + }) + .catch(() => { + window.location.href = '/auth/SignIn'; + return Promise.reject(error); + }); + } + return Promise.reject(error); + }, +); + export default httpClient; + +// NOTE: eslint-disable no-param-reassign ๋ฏธํ•ด๊ฒฐ๋กœ ์ธํ•œ ์„ค์ • +httpClient.interceptors.request.use((config) => { + const accessToken = localStorage.getItem('accessToken'); + /* eslint-disable no-param-reassign */ + if (accessToken) config.headers.Authorization = `Bearer ${accessToken}`; + /* eslint-enable no-param-reassign */ + return config; +}); + +httpClient.interceptors.response.use( + (response) => response, + + (error) => { + if (error.response && error.response.status === 401) { + const refreshToken = localStorage.getItem('refreshToken'); + + if (!refreshToken) { + window.location.href = '/auth/SignIn'; + return Promise.reject(error); + } + + return httpClient + .post('/auth/refresh-token', null, { + headers: { Authorization: `Bearer ${refreshToken}` }, + }) + .then((response) => { + const { accessToken, refreshToken: newRefreshToken } = response.data; + localStorage.setItem('accessToken', accessToken); + localStorage.setItem('refreshToken', newRefreshToken); + + const originalRequest = error.config; + return httpClient(originalRequest); + }) + .catch(() => { + window.location.href = '/auth/SignIn'; + return Promise.reject(error); + }); + } + return Promise.reject(error); + }, +); diff --git a/src/apis/oauth.ts b/src/apis/oauth.ts new file mode 100644 index 00000000..ae6bd068 --- /dev/null +++ b/src/apis/oauth.ts @@ -0,0 +1,11 @@ +import axios from 'axios'; + +const postOauth = async (code: string) => { + const response = await axios.post(`${process.env.NEXT_PUBLIC_BASE_URL}/auth/signIn/KAKAO`, { + redirectUri: process.env.NEXT_PUBLIC_REDIRECT_URI, + token: code, + }); + return response.data; +}; + +export default postOauth; diff --git a/src/apis/postEmotion.ts b/src/apis/postEmotion.ts new file mode 100644 index 00000000..168a8c13 --- /dev/null +++ b/src/apis/postEmotion.ts @@ -0,0 +1,15 @@ +import { EmotionType } from '@/types/emotion'; +import type { PostEmotionRequestType, PostEmotionResponseType } from '@/schema/emotion'; +import { translateEmotionToEnglish } from '@/utils/emotionMap'; +import httpClient from '.'; + +const postEmotion = async (emotion: EmotionType): Promise => { + const englishEmotion = translateEmotionToEnglish(emotion); + const request: PostEmotionRequestType = { emotion: englishEmotion }; + + const response = await httpClient.post('/emotionLogs/today', request); + + return response.data; +}; + +export default postEmotion; diff --git a/src/apis/queries.ts b/src/apis/queries.ts index 1f84081c..0010c375 100644 --- a/src/apis/queries.ts +++ b/src/apis/queries.ts @@ -1,6 +1,8 @@ import { createQueryKeyStore } from '@lukemorales/query-key-factory'; import { GetUserRequestType } from '@/schema/user'; +import { GetMonthlyEmotionLogsRequestType } from '@/schema/emotion'; import { getMe, getUser } from './user'; +import getMonthlyEmotionLogs from './emotion'; const quries = createQueryKeyStore({ user: { @@ -13,6 +15,12 @@ const quries = createQueryKeyStore({ queryFn: () => getUser(request), }), }, + emotion: { + getMonthlyEmotionLogs: (request: GetMonthlyEmotionLogsRequestType) => ({ + queryKey: ['getMonthlyEmotionLogs', request], + queryFn: () => getMonthlyEmotionLogs(request), + }), + }, }); export default quries; diff --git a/src/apis/user.ts b/src/apis/user.ts index 395b0167..5f924dea 100644 --- a/src/apis/user.ts +++ b/src/apis/user.ts @@ -1,18 +1,25 @@ -import type { GetUserReponseType, GetUserRequestType, PatchMeRequestType } from '@/schema/user'; +import type { GetUserResponseType, GetUserRequestType, PatchMeRequestType, PostPresignedUrlRequestType, PostPresignedUrlResponseType } from '@/schema/user'; import httpClient from '.'; -export const getMe = async (): Promise => { +export const getMe = async (): Promise => { const response = await httpClient.get('/users/me'); return response.data; }; -export const getUser = async (request: GetUserRequestType): Promise => { +export const getUser = async (request: GetUserRequestType): Promise => { const { id } = request; const response = await httpClient.get(`/users/${id}`); return response.data; }; -export const updateMe = async (request: PatchMeRequestType): Promise => { +export const updateMe = async (request: PatchMeRequestType): Promise => { const response = await httpClient.patch('/users/me', { ...request }); return response.data; }; + +export const createPresignedUrl = async (request: PostPresignedUrlRequestType): Promise => { + const formData = new FormData(); + formData.append('image', request.image); + const response = await httpClient.post('/images/upload', formData); + return response.data; +}; diff --git a/src/components/Card/CommentCard.tsx b/src/components/Card/CommentCard.tsx new file mode 100644 index 00000000..a58f0e6f --- /dev/null +++ b/src/components/Card/CommentCard.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import Image from 'next/image'; +import { sizeStyles, textSizeStyles, gapStyles, paddingStyles, contentWidthStyles } from '@/styles/CommentCardStyles'; + +export interface CommentCardProps { + status: 'edit' | 'complete'; +} + +function CommentCard({ status }: CommentCardProps) { + return ( +

+
+
+
+ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€{' '} +
+
+
+
+
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + ์ง€ํ‚ฌ๊ณผ ํ•˜์ด๋“œ +
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + 1์‹œ๊ฐ„ ์ „ +
+
+ {status === 'edit' && ( +
+
์ˆ˜์ •
+
์‚ญ์ œ
+
+ )} +
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + ์˜ค๋Š˜ ํ•˜๋ฃจ ์šฐ์šธํ–ˆ์—ˆ๋Š”๋ฐ ๋•๋ถ„์— ๋งŽ์€ ํž˜ ์–ป๊ณ  ๊ฐ‘๋‹ˆ๋‹ค. ์—ฐ๊ธˆ์ˆ ์‚ฌ ์ฑ… ๋‹ค์‹œ ์‚ฌ์„œ ์˜ค๋žœ๋งŒ์— ์ฝ์–ด๋ด์•ผ๊ฒ ์–ด์š”! +
+
+
+
+ ); +} + +export default CommentCard; diff --git a/src/components/Card/EpigramCard.tsx b/src/components/Card/EpigramCard.tsx new file mode 100644 index 00000000..07ceb392 --- /dev/null +++ b/src/components/Card/EpigramCard.tsx @@ -0,0 +1,63 @@ +import React from 'react'; + +// figma ์ƒ์œผ๋กœ๋Š” sm ~ 3xl ์‚ฌ์ด์ฆˆ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š”๋ฐ, tailwind ํ™˜๊ฒฝ์„ ๋ฐ˜์˜ํ•ด +// xs ~ 2xl ์œผ๋กœ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. +const sizeStyles = { + xs: 'w-[286px] max-h-[132px]', + sm: 'sm:w-[312px] sm:max-h-[152px]', + md: 'md:w-[384px] md:max-h-[180px]', + lg: 'lg:w-[540px] lg:max-h-[160px]', + xl: 'xl:w-[640px] xl:max-h-[196px]', + '2xl': '2xl:w-[744px] 2xl:max-h-[196px]', +}; + +const textSizeStyles = { + xs: 'text-xs', + sm: 'sm:text-sm', + md: 'md:text-base', + lg: 'lg:text-xl', + xl: 'xl:text-2xl', + '2xl': '2xl:text-2xl', +}; + +function EpigramCard() { + return ( +
+
+ {/* eslint-disable-next-line */} +
{/* ์ค„๋ฌด๋Šฌ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋น„์–ด์žˆ๋Š” div๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. */} +
+
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + ์˜ค๋žซ๋™์•ˆ ๊ฟˆ์„ ๊ทธ๋ฆฌ๋Š” ์‚ฌ๋žŒ์€ ๋งˆ์นจ๋‚ด ๊ทธ ๊ฟˆ์„ ๋‹ฎ์•„ ๊ฐ„๋‹ค. +
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */}- ์•™๋“œ๋ ˆ ๋ง๋กœ - +
+
+
+
+
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + #๋‚˜์•„๊ฐ€์•ผํ• ๋•Œ +
+
+ {/* ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. */} + #๊ฟˆ์„์ด๋ฃจ๊ณ ์‹ถ์„๋•Œ +
+
+
+ ); +} + +export default EpigramCard; diff --git a/src/components/Emotion/EmotionCard.tsx b/src/components/Emotion/EmotionCard.tsx new file mode 100644 index 00000000..74134281 --- /dev/null +++ b/src/components/Emotion/EmotionCard.tsx @@ -0,0 +1,113 @@ +/* + 1๊ฐœ์˜ ๊ฐ์ • ์•„์ด์ฝ˜ ์นด๋“œ๋ฅผ ๋žœ๋”๋ง ํ•ฉ๋‹ˆ๋‹ค. + ์•„์ด์ฝ˜์˜ ํƒ€์ž…, ์ƒํƒœ, ํฌ๊ธฐ, ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + ์•„์ด์ฝ˜ ํƒ€์ž…๊ณผ ์ƒํƒœ์— ๋”ฐ๋ผ ์•„์ด์ฝ˜์˜ ๋ชจ์–‘๊ณผ ์Šคํƒ€์ผ์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. + */ + +import React from 'react'; +import cn from '@/lib/utils'; +import Image from 'next/image'; +import { EmotionIconCardProps } from '@/types/emotion'; + +// ์•„์ด์ฝ˜ ํŒŒ์ผ ๊ฒฝ๋กœ ๋งคํ•‘ +const iconPaths = { + Color: { + ๊ฐ๋™: '/icon/Color/HeartFaceColorIcon.svg', + ๊ธฐ์จ: '/icon/Color/SmileFaceColorIcon.svg', + ๊ณ ๋ฏผ: '/icon/Color/ThinkFaceColorIcon.svg', + ์Šฌํ””: '/icon/Color/SadFaceColorIcon.svg', + ๋ถ„๋…ธ: '/icon/Color/AngryFaceColorIcon.svg', + }, + BW: { + ๊ฐ๋™: '/icon/BW/HeartFaceBWIcon.svg', + ๊ธฐ์จ: '/icon/BW/SmileFaceBWIcon.svg', + ๊ณ ๋ฏผ: '/icon/BW/ThinkFaceBWIcon.svg', + ์Šฌํ””: '/icon/BW/SadFaceBWIcon.svg', + ๋ถ„๋…ธ: '/icon/BW/AngryFaceBWIcon.svg', + }, +}; + +// EmotionIconCard ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ์„ ์–ธ +function EmotionIconCard({ iconType = '๊ฐ๋™', state = 'Default', size = 'sm', onClick }: EmotionIconCardProps) { + // ํฌ๊ธฐ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • + let sizeClass = ''; + let iconSizeClass = ''; + let textSizeClass = ''; + switch (size) { + case 'lg': + sizeClass = 'w-20 h-28'; + iconSizeClass = 'w-12 h-12'; + textSizeClass = 'text-base leading-relaxed'; + break; + case 'md': + sizeClass = 'w-16 h-24'; + iconSizeClass = 'w-10 h-10'; + textSizeClass = 'text-sm leading-normal'; + break; + case 'sm': + default: + sizeClass = 'w-14 h-21'; + iconSizeClass = 'w-8 h-8'; + textSizeClass = 'text-xs leading-tight'; + break; + } + + // ์ƒํƒœ์— ๋”ฐ๋ฅธ ์•„์ด์ฝ˜ ๊ฒฝ๋กœ ์„ค์ • + const iconPath = state === 'Clicked' || state === 'Default' ? iconPaths.Color[iconType] : iconPaths.BW[iconType]; + + // ์ƒํƒœ์— ๋”ฐ๋ฅธ ํด๋ž˜์Šค ์„ค์ • + let borderClass = ''; + const textColorClass = 'text-neutral-400'; + let backgroundClass = 'bg-slate-400/20'; + let textVisibilityClass = ''; + + if (state === 'Clicked') { + textVisibilityClass = 'hidden'; + backgroundClass = 'bg-transparent'; + + // iconType์— ๋”ฐ๋ผ ๋‹ค๋ฅธ border ์ƒ‰์ƒ์„ ์„ค์ • + switch (iconType) { + case '๊ฐ๋™': + borderClass = 'border-4 border-illust-yellow'; + break; + case '๊ธฐ์จ': + borderClass = 'border-4 border-illust-green'; + break; + case '๊ณ ๋ฏผ': + borderClass = 'border-4 border-illust-purple'; + break; + case '์Šฌํ””': + borderClass = 'border-4 border-illust-blue'; + break; + case '๋ถ„๋…ธ': + borderClass = 'border-4 border-illust-red'; + break; + default: + borderClass = 'border-4 border-sub_blue_1'; + break; + } + } + + return ( +
{ + if (e.key === 'Enter' || e.key === ' ') { + if (onClick) { + onClick(); + } + } + }} + > +
+ {iconType} +
+
{iconType}
+
+ ); +} + +export default EmotionIconCard; diff --git a/src/components/Emotion/EmotionSaveToast.tsx b/src/components/Emotion/EmotionSaveToast.tsx new file mode 100644 index 00000000..e7d24105 --- /dev/null +++ b/src/components/Emotion/EmotionSaveToast.tsx @@ -0,0 +1,34 @@ +/* + * ์˜ค๋Š˜์˜ ๊ฐ์ •์„ ์„ ํƒํ•˜๋ฉด ํ‘œ์‹œ๋˜๋Š” toast์ž…๋‹ˆ๋‹ค. + * ๊ฐ์ •์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋งˆ์ดํŽ˜์ด์ง€๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. + */ + +import React, { useEffect } from 'react'; +import { useToast } from '@/components/ui/use-toast'; +import { ToastAction } from '@/components/ui/toast'; +import { useRouter } from 'next/router'; + +interface EmotionSaveToastProps { + iconType: string; +} + +function EmotionSaveToast({ iconType }: EmotionSaveToastProps) { + const { toast } = useToast(); + const router = useRouter(); + + useEffect(() => { + toast({ + title: '์˜ค๋Š˜์˜ ๊ฐ์ •์ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', + description: `์˜ค๋Š˜์˜ ๊ฐ์ •: ${iconType}`, + action: ( + router.push('/mypage')}> + ํ™•์ธํ•˜๊ธฐ + + ), + }); + }, [iconType, toast, router]); + + return null; +} + +export default EmotionSaveToast; diff --git a/src/components/Emotion/EmotionSelector.tsx b/src/components/Emotion/EmotionSelector.tsx new file mode 100644 index 00000000..4375c3ca --- /dev/null +++ b/src/components/Emotion/EmotionSelector.tsx @@ -0,0 +1,111 @@ +import React, { useState, useEffect } from 'react'; +import useMediaQuery from '@/hooks/useMediaQuery'; +import EmotionIconCard from '@/components/Emotion/EmotionCard'; +import { EmotionType, EmotionState } from '@/types/emotion'; +import usePostEmotion from '@/hooks/usePostEmotion'; +import { useGetEmotion } from '@/hooks/useGetEmotion'; +import EmotionSaveToast from './EmotionSaveToast'; + +/** + * EmotionSelector ์ปดํฌ๋„ŒํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ EmotionIconCard๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  + * ์‚ฌ์šฉ์ž์˜ ์˜ค๋Š˜์˜ ๊ฐ์ •์„ ์„ ํƒํ•˜๊ณ  ์ €์žฅํ•˜๊ณ  ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. + */ +function EmotionSelector() { + // ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ์œ„ํ•œ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ ํ›… + const isTablet = useMediaQuery('(min-width: 768px) and (max-width: 1024px)'); + const isMobile = useMediaQuery('(max-width: 767px)'); + + // ๊ฐ์ • ์นด๋“œ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ useState ํ›… + const [states, setStates] = useState>({ + ๊ฐ๋™: 'Default', + ๊ธฐ์จ: 'Default', + ๊ณ ๋ฏผ: 'Default', + ์Šฌํ””: 'Default', + ๋ถ„๋…ธ: 'Default', + }); + + // ํ˜„์žฌ ์„ ํƒ๋œ ๊ฐ์ •์„ ๊ด€๋ฆฌํ•˜๋Š” useState ํ›… + const [selectedEmotion, setSelectedEmotion] = useState(null); + // ์˜ค๋Š˜์˜ ๊ฐ์ •์„ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ํ›… + const { data: emotion, error: getError, isLoading: isGetLoading } = useGetEmotion(); + // ๊ฐ์ •์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ›… + const postEmotionMutation = usePostEmotion(); + + // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” useEffect ํ›… + // ์˜ค๋Š˜์˜ ๊ฐ์ •์„ ์กฐํšŒํ•˜๊ณ  ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. + useEffect(() => { + if (emotion) { + setStates((prevStates) => ({ + ...prevStates, + [emotion]: 'Clicked', + })); + } + }, [emotion]); + + /** + * ๊ฐ์ • ์นด๋“œ ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ + * ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ์ • ์นด๋“œ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + * ํด๋ฆญ๋œ ๊ฐ์ • ์นด๋“œ๋ฅผ 'Clicked' ์ƒํƒœ๋กœ ์„ค์ •ํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์นด๋“œ๋Š” 'Unclicked' ์ƒํƒœ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + * ๊ฐ์ •์„ ์„œ๋ฒ„์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. + * @param iconType - ํด๋ฆญ๋œ ๊ฐ์ •์˜ ํƒ€์ž… + */ + const handleCardClick = async (iconType: EmotionType) => { + setStates((prevStates) => { + const newStates = { ...prevStates }; + + if (prevStates[iconType] === 'Clicked') { + // ํ˜„์žฌ ํด๋ฆญ๋œ ์นด๋“œ๊ฐ€ ๋‹ค์‹œ ํด๋ฆญ๋˜๋ฉด ๋ชจ๋“  ์นด๋“œ๋ฅผ Default๋กœ ์„ค์ • + Object.keys(newStates).forEach((key) => { + newStates[key as EmotionType] = 'Default'; + }); + } else { + // ํ•˜๋‚˜์˜ ์นด๋“œ๊ฐ€ ํด๋ฆญ๋˜๋ฉด ๊ทธ ์นด๋“œ๋งŒ Clicked, ๋‚˜๋จธ์ง€๋Š” Unclicked๋กœ ์„ค์ • + Object.keys(newStates).forEach((key) => { + newStates[key as EmotionType] = key === iconType ? 'Clicked' : 'Unclicked'; + }); + } + + return newStates; + }); + + // ์˜ค๋Š˜์˜ ๊ฐ์ • ์ €์žฅ + postEmotionMutation.mutate(iconType, { + onSuccess: (_, clickedIconType) => { + setSelectedEmotion(clickedIconType); + }, + onError: (error: unknown) => { + // eslint-disable-next-line + console.error(error); + }, + }); + }; + + // ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ์œ„ํ•œ ์นด๋“œ ํฌ๊ธฐ ์„ค์ • + let containerClass = 'w-[544px] h-[136px] gap-4'; + let cardSize: 'lg' | 'md' | 'sm' = 'lg'; + + if (isTablet) { + containerClass = 'w-[352px] h-[96px] gap-2'; + cardSize = 'md'; + } else if (isMobile) { + containerClass = 'w-[312px] h-[84px] gap-2'; + cardSize = 'sm'; + } + + if (isGetLoading) return

Loading...

; + if (getError) return

{getError.message}

; + + return ( + <> +
+ {(['๊ฐ๋™', '๊ธฐ์จ', '๊ณ ๋ฏผ', '์Šฌํ””', '๋ถ„๋…ธ'] as const).map((iconType) => ( + handleCardClick(iconType)} /> + ))} +
+ {/* ๊ฐ์ •์ด ์„ ํƒ๋˜์—ˆ์„ ๋•Œ ํ† ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ */} + {selectedEmotion && } + + ); +} + +export default EmotionSelector; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx new file mode 100644 index 00000000..d342347f --- /dev/null +++ b/src/components/Header/Header.tsx @@ -0,0 +1,119 @@ +import React from 'react'; +import { useRouter } from 'next/router'; +import Image from 'next/image'; +import { useToast } from '../ui/use-toast'; +import LOGO_ICON from '../../../public/epigram-icon.png'; +import ARROW_LEFT_ICON from '../../../public/icon/arrow-left-icon.svg'; +import PROFILE_ICON from '../../../public/icon/profile-icon.svg'; +import SEARCH_ICON from '../../../public/icon/search-icon.svg'; +import SHARE_ICON from '../../../public/icon/share-icon.svg'; + +// NOTE ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ”๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ปดํฌ๋„ŒํŠธ ์ž…๋‹ˆ๋‹ค. +// NOTE ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ Props๋ฅผ ๋ฐ›์•„ ์›ํ•˜๋Š” ์Šคํƒ€์ผ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +// NOTE ์‚ฌ์šฉ ์˜ˆ์‹œ +// NOTE
+// NOTE
{}} />; +// NOTE icon: 'back'์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ routerPage์˜ ๊ฐ’์„ ๋ฌด์กฐ๊ฑด ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. +// NOTE isLogo={false}์ผ ๊ฒฝ์šฐ insteadOfLogo์˜ ๊ฐ’์„ ๋ฌด์กฐ๊ฑด ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. +// NOTE isButton ์ผ ๊ฒฝ์šฐ textInButton์˜ ๊ฐ’์„ ๋ฌด์กฐ๊ฑด ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. +// NOTE SHARE_ICON ์ถ”๊ฐ€ ์‹œ ํ† ์ŠคํŠธ ๊ธฐ๋Šฅ๋„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์•„๋ž˜ ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”. + +export interface HeaderProps { + icon: 'back' | 'search' | ''; + routerPage: string; + isLogo: boolean; + insteadOfLogo: string; + isProfileIcon: boolean; + isShareIcon: boolean; + isButton: boolean; + textInButton: string; + disabled: boolean; + onClick: (e: React.MouseEvent) => void; +} + +function Header({ isLogo, icon, insteadOfLogo, isButton, isProfileIcon, isShareIcon, textInButton, routerPage, disabled, onClick }: HeaderProps) { + const router = useRouter(); + const { toast } = useToast(); + + // ํŽ˜์ด์ง€ ์ด๋™ ํ•จ์ˆ˜ + const handleNavigateTo = (path: string) => { + router.push(path); + }; + + // ํ˜„์žฌ ๋งํฌ ๋ณต์‚ฌ ํ•จ์ˆ˜ + const handleCopyToClipboard = async () => { + try { + // ํ˜„์žฌ URL ๊ฐ€์ ธ์˜ค๊ธฐ + const currentURL = window.location.href; + // ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌํ•˜๊ธฐ + await navigator.clipboard.writeText(currentURL); + toast({ + title: '์„ฑ๊ณต', + description: '๋งํฌ๊ฐ€ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!', + }); + } catch (err) { + toast({ + title: '์‹คํŒจ', + description: '๋งํฌ ๋ณต์‚ฌ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.', + variant: 'destructive', + }); + } + }; + + return ( + + ); +} + +export default Header; diff --git a/src/components/index.tsx b/src/components/index.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/search/RecentSearches.tsx b/src/components/search/RecentSearches.tsx new file mode 100644 index 00000000..0b71f086 --- /dev/null +++ b/src/components/search/RecentSearches.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +interface RecentSearchesProps { + searches: string[]; + onSearch: (search: string) => void; + onClear: () => void; +} + +function RecentSearches({ searches, onSearch, onClear }: RecentSearchesProps) { + const handleSearchClick = (search: string) => { + onSearch(search); + }; + + const handleClearAll = () => { + onClear(); + }; + + return ( +
+
+ ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด + +
+
+
+ {searches.map((search) => ( + + ))} +
+
+
+ ); +} + +export default RecentSearches; diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx new file mode 100644 index 00000000..accf11f1 --- /dev/null +++ b/src/components/search/SearchBar.tsx @@ -0,0 +1,58 @@ +import React, { useState, useEffect } from 'react'; +import Image from 'next/image'; +import SEARCH_ICON from '../../../public/md.svg'; + +// TODO react-hook-form ์‚ฌ์šฉ + +interface SearchBarProps { + onSearch: (search: string) => void; + currentSearch: string; +} + +function SearchBar({ onSearch, currentSearch }: SearchBarProps) { + const [searchInput, setSearchInput] = useState(''); + const [isFocused, setIsFocused] = useState(false); + + const handleChange = (e: React.ChangeEvent) => { + setSearchInput(e.target.value); + }; + + const handleFocus = () => { + setIsFocused(true); + }; + + const handleBlur = () => { + setIsFocused(false); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (searchInput.trim()) { + onSearch(searchInput); + setSearchInput(''); + } + }; + + // ์ตœ๊ทผ ๊ฒ€์ƒ‰์–ด ํด๋ฆญ ์‹œ setSearchInput ์ƒํƒœ ์—…๋ฐ์ดํŠธ + useEffect(() => { + setSearchInput(currentSearch); + }, [currentSearch]); + + return ( +
+ + +
+ ); +} + +export default SearchBar; diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx new file mode 100644 index 00000000..8ecb893a --- /dev/null +++ b/src/components/search/SearchResults.tsx @@ -0,0 +1,101 @@ +import React, { useMemo } from 'react'; +import Link from 'next/link'; +import { GetEpigramsResponseType } from '@/schema/epigrams'; + +// TODO highlightedSections์˜ key ์„ค์ • ๋ถ€๋ถ„์— ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์ด ์ƒ๊ฐ๋‚˜๋ฉด ๋ณ€๊ฒฝ + +interface SearchResultsProps { + results: GetEpigramsResponseType | null; + query: string; + isLoading: boolean; +} + +// ํ…์ŠคํŠธ ํ•˜์ด๋ผ์ดํŒ… ํ•จ์ˆ˜ +function handleHighlightText(text: string, highlight: string) { + if (!highlight.trim()) { + return text; + } + + // ๊ฒ€์ƒ‰์–ด(highlight)๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋‚˜๋ˆ”(g: ์ค‘๋ณต O, i: ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ X) + const highlightedSections = text.split(new RegExp(`(${highlight})`, 'gi')); + + // ๊ฒ€์ƒ‰์–ด์™€ ๋น„๊ตํ•ด์„œ ๊ฐ™์œผ๋ฉด ํ•˜์ด๋ผ์ดํŒ…, ๋‹ค๋ฅด๋ฉด ๊ทธ๋ƒฅ ๋ฐ˜ํ™˜ + return ( + <> + {highlightedSections.map((section, index) => { + const key = `${section}-${index}-${section.length}`; + return section.toLowerCase() === highlight.toLowerCase() ? ( + + {section} + + ) : ( + section + ); + })} + + ); +} + +function SearchResults({ results, query, isLoading }: SearchResultsProps) { + // ํƒœ๊ทธ์™€ ๋‚ด์šฉ ์ˆœ์„œ๋กœ ์ •๋ ฌ - ํ•ญ์ƒ useMemo๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , results๊ฐ€ null์ธ ๊ฒฝ์šฐ ๋นˆ ๋ฐฐ์—ด ๋ฐ˜ํ™˜ + const sortedResults = useMemo(() => { + if (!results) return []; + return results.list.sort((a, b) => { + const aHasTag = a.tags.some((tag) => tag.name.includes(query)); + const bHasTag = b.tags.some((tag) => tag.name.includes(query)); + + if (aHasTag && !bHasTag) return -1; + if (!aHasTag && bHasTag) return 1; + return 0; + }); + }, [results, query]); + + const filteredResults = useMemo( + () => sortedResults.filter((item) => item.content.includes(query) || item.author.includes(query) || item.tags.some((tag) => tag.name.includes(query))), + [sortedResults, query], + ); + + if (isLoading) { + return ( +
+
+ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘ ์ž…๋‹ˆ๋‹ค... +
+
+ ); + } + + if (!results || filteredResults.length === 0) { + return ( +
+
+ ํ•ด๋‹น ๊ฒ€์ƒ‰์–ด์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +
+
+ ); + } + + return ( +
+ {filteredResults.map((item) => ( + +
+
+ {handleHighlightText(item.content, query)} + - {handleHighlightText(item.author, query)} - +
+
+ {item.tags.map((tag) => ( + + {handleHighlightText(`#${tag.name}`, query)} + + ))} +
+
+ + ))} +
+ ); +} + +export default SearchResults; diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 00000000..f44152fd --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,65 @@ +import * as React from 'react'; +import * as DialogPrimitive from '@radix-ui/react-dialog'; +import { X } from 'lucide-react'; + +import cn from '@/lib/utils'; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +function DialogHeader({ className, ...props }: React.HTMLAttributes) { + return
; +} +DialogHeader.displayName = 'DialogHeader'; + +function DialogFooter({ className, ...props }: React.HTMLAttributes) { + return
; +} +DialogFooter.displayName = 'DialogFooter'; + +const DialogTitle = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription }; diff --git a/src/hooks/epigramQueryHook.ts b/src/hooks/epigramQueryHook.ts new file mode 100644 index 00000000..e2ca6679 --- /dev/null +++ b/src/hooks/epigramQueryHook.ts @@ -0,0 +1,24 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { AddEpigramFormType, AddEpigramResponseType } from '@/schema/addEpigram'; +import { MutationOptions } from '@/types/query'; +import postEpigram from '@/apis/add'; +import { AxiosError } from 'axios'; + +// TODO: ์—ํ”ผ๊ทธ๋žจ ์ˆ˜์ •๊ณผ ์‚ญ์ œ์—๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ›… ์ˆ˜์ • ์˜ˆ์ • + +const useAddEpigram = (options?: MutationOptions) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (newEpigram: AddEpigramFormType) => postEpigram(newEpigram), + ...options, + onSuccess: (...args) => { + queryClient.invalidateQueries({ queryKey: ['epigrams'] }); + if (options?.onSuccess) { + options.onSuccess(...args); + } + }, + }); +}; + +export default useAddEpigram; diff --git a/src/hooks/useCalendar.ts b/src/hooks/useCalendar.ts new file mode 100644 index 00000000..44afc6a6 --- /dev/null +++ b/src/hooks/useCalendar.ts @@ -0,0 +1,67 @@ +import { getDaysInMonth } from 'date-fns'; +import { CALENDAR_LENGTH, DAY_OF_WEEK } from '../user/utill/constants'; + +interface CalendarData { + weekCalendarList: number[][]; // ์ฃผ๋ณ„ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ +} + +// ์ด์ „ ๋‹ฌ์˜ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ +const getPreviousDays = (firstDayOfCurrentMonth: Date, totalPrevMonthDays: number): number[] => + // ํ˜„์žฌ ์›”์˜ ์ฒซ ๋ฒˆ์งธ ๋‚ ์˜ ์š”์ผ์„ ๊ธฐ์ค€์œผ๋กœ ์ด์ „ ๋‹ฌ์˜ ๋‚ ์งœ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ + Array.from({ length: firstDayOfCurrentMonth.getDay() }, (_, index) => totalPrevMonthDays - firstDayOfCurrentMonth.getDay() + index + 1); +// ํ˜„์žฌ ์›”์˜ ๋‚ ์งœ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ +const getCurrentDays = (totalMonthDays: number): number[] => Array.from({ length: totalMonthDays }, (_, i) => i + 1); // 1๋ถ€ํ„ฐ totalMonthDays๊นŒ์ง€์˜ ๋ฐฐ์—ด ์ƒ์„ฑ +// ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ +const getNextDays = (currentDayList: number[], prevDayList: number[]): number[] => { + // ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ + const nextDayCount = CALENDAR_LENGTH - currentDayList.length - prevDayList.length; + return Array.from({ length: Math.max(nextDayCount, 0) }, (_, index) => index + 1); +}; + +const useCalendar = (currentDate: Date): CalendarData => { + // ํ˜„์žฌ ์›”์˜ ์ด ๋‚ ์งœ ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ด + const totalMonthDays = getDaysInMonth(currentDate); + + // ์ด์ „ ๋‹ฌ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐ + const prevMonthLastDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), 0); + // ์ด์ „ ๋‹ฌ์˜ ์ด ๋‚ ์งœ ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ด + const totalPrevMonthDays = getDaysInMonth(prevMonthLastDate); + + // ํ˜„์žฌ ์›”์˜ ์ฒซ ๋ฒˆ์งธ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐ + const firstDayOfCurrentMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1); + // ์ด์ „ ๋‹ฌ์˜ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ + const prevDayList = getPreviousDays(firstDayOfCurrentMonth, totalPrevMonthDays); + // ํ˜„์žฌ ์›”์˜ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ + const currentDayList = getCurrentDays(totalMonthDays); + // ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ + const nextDayList = getNextDays(currentDayList, prevDayList); + + // ์ „์ฒด ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ (์ด์ „ / ํ˜„์žฌ / ๋‹ค์Œ ๋‹ฌ ๋‚ ์งœ ํฌํ•จ) + const currentCalendarList = [...prevDayList, ...currentDayList, ...nextDayList]; + + // ์ฃผ๋ณ„๋กœ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ถ„ํ•  + const weekCalendarList: number[][] = []; + currentCalendarList.forEach((currDate, index) => { + const chunkIndex = Math.floor(index / DAY_OF_WEEK); + if (!weekCalendarList[chunkIndex]) { + weekCalendarList[chunkIndex] = []; // ์ฃผ ๋ฐฐ์—ด์ด ์—†์œผ๋ฉด ์ดˆ๊ธฐํ™” + } + weekCalendarList[chunkIndex].push(currDate); // ๋ˆ„์ ๊ฐ’ ๋ฐ˜ํ™˜ + }); + + // NOTE: ํ•œ ๋‹ฌ์ด 5์ฃผ ์ผ ์ˆ˜๋„, 6์ฃผ ์ผ ์ˆ˜๋„ ์žˆ์„ ๋•Œ 5์ฃผ์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ๋‹ฌ์— ํ•„์š”์—†๋Š” ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ๊ฐ€ ์ถœ๋ ฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— (CALENDAR_LENGTH๋ฅผ ์ตœ๋Œ€์น˜์ธ 42๋กœ ์žก์•„์„œ) ๋งˆ์ง€๋ง‰ ์ฃผ์˜ ์ฒซ ๋ฒˆ์งธ ์ˆซ์ž๊ฐ€ 10์ดํ•˜์˜ ๋‚ ์งœ๋กœ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ๋ฐฐ์—ด์„ ์‚ญ์ œํ•˜๋„๋ก ์ถ”๊ฐ€. + // TODO: ์ถ”ํ›„ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ๋ณ€๊ฒฝ ํ•  ์˜ˆ์ • + if (weekCalendarList.length > 0) { + const lastWeek = weekCalendarList[weekCalendarList.length - 1]; + if (lastWeek[0] <= 10) { + weekCalendarList.pop(); + } + } + + // ์บ˜๋ฆฐ๋” ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ + return { + weekCalendarList, // ์ฃผ๋ณ„ ๋‚ ์งœ ๋ฆฌ์ŠคํŠธ + }; +}; + +export default useCalendar; diff --git a/src/hooks/useDeleteCommentHook.ts b/src/hooks/useDeleteCommentHook.ts new file mode 100644 index 00000000..006019b5 --- /dev/null +++ b/src/hooks/useDeleteCommentHook.ts @@ -0,0 +1,31 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { deleteComment } from '@/apis/epigramComment'; +import { toast } from '@/components/ui/use-toast'; + +const useDeleteCommentMutation = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (commentId: number) => deleteComment(commentId), + onSuccess: () => { + // ๋Œ“๊ธ€ ๋ชฉ๋ก ์ฟผ๋ฆฌ ๋ฌดํšจํ™” + queryClient.invalidateQueries({ queryKey: ['epigramComments'] }); + + // ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ + toast({ + title: '๋Œ“๊ธ€ ์‚ญ์ œ ์„ฑ๊ณต', + description: '๋Œ“๊ธ€์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', + }); + }, + onError: (error) => { + // ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ + toast({ + title: '๋Œ“๊ธ€ ์‚ญ์ œ ์‹คํŒจ', + description: `๋Œ“๊ธ€ ์‚ญ์ œ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: ${error instanceof Error ? error.message : '์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜'}`, + variant: 'destructive', + }); + }, + }); +}; + +export default useDeleteCommentMutation; diff --git a/src/hooks/useGetEmotion.ts b/src/hooks/useGetEmotion.ts new file mode 100644 index 00000000..e8555101 --- /dev/null +++ b/src/hooks/useGetEmotion.ts @@ -0,0 +1,13 @@ +import quries from '@/apis/queries'; +import getEmotion from '@/apis/getEmotion'; +import { EmotionType } from '@/types/emotion'; +import { GetMonthlyEmotionLogsRequestType } from '@/schema/emotion'; +import { useQuery } from '@tanstack/react-query'; + +export const useMonthlyEmotionLogs = (requset: GetMonthlyEmotionLogsRequestType) => useQuery(quries.emotion.getMonthlyEmotionLogs(requset)); + +export const useGetEmotion = () => + useQuery({ + queryKey: ['emotion'], + queryFn: getEmotion, + }); diff --git a/src/hooks/useGetEpigramsHooks.ts b/src/hooks/useGetEpigramsHooks.ts new file mode 100644 index 00000000..04c5554c --- /dev/null +++ b/src/hooks/useGetEpigramsHooks.ts @@ -0,0 +1,13 @@ +import { useQuery } from '@tanstack/react-query'; +import getEpigrams from '@/apis/getEpigrams'; +import { GetEpigramsResponseType } from '@/schema/epigrams'; + +const useEpigrams = (query: string, page: number, limit: number = 10) => + useQuery({ + queryKey: ['epigrams', query, page, limit], + queryFn: () => getEpigrams({ keyword: query, limit, cursor: page * limit }), + enabled: !!query, + staleTime: 5 * 60 * 1000, // ๋ฐ์ดํ„ฐ ์‹ ์„ ๋„ ์„ค์ • + }); + +export default useEpigrams; diff --git a/src/hooks/useKakaoLogin.ts b/src/hooks/useKakaoLogin.ts new file mode 100644 index 00000000..14d8d81b --- /dev/null +++ b/src/hooks/useKakaoLogin.ts @@ -0,0 +1,42 @@ +import postOauth from '@/apis/oauth'; +import { toast } from '@/components/ui/use-toast'; +import { useMutation } from '@tanstack/react-query'; +import { isAxiosError } from 'axios'; +import { useRouter } from 'next/router'; + +const useKakaoLogin = () => { + const router = useRouter(); + + return useMutation({ + mutationFn: async (code: string) => { + const result = await postOauth(code); + localStorage.setItem('accessToken', result.accessToken); + localStorage.setItem('refreshToken', result.refreshToken); + return result; + }, + onSuccess: () => { + router.push('/'); + }, + onError: (error) => { + if (isAxiosError(error)) { + const status = error.response?.status; + + if (!status) return; + + if (status === 400) { + toast({ description: '์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' }); + router.push('/auth/SignIn'); + return; + } + + if (status >= 500) { + toast({ description: '์„œ๋ฒ„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' }); + } + } + + toast({ description: '์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.', className: 'bg-state-error text-white font-semibold' }); + }, + }); +}; + +export default useKakaoLogin; diff --git a/src/hooks/useMediaQuery.ts b/src/hooks/useMediaQuery.ts new file mode 100644 index 00000000..899c0fce --- /dev/null +++ b/src/hooks/useMediaQuery.ts @@ -0,0 +1,19 @@ +import { useState, useEffect } from 'react'; + +function useMediaQuery(query: string): boolean { + const [matches, setMatches] = useState(false); + + useEffect(() => { + const media = window.matchMedia(query); + if (media.matches !== matches) { + setMatches(media.matches); + } + const listener = () => setMatches(media.matches); + media.addEventListener('change', listener); + return () => media.removeEventListener('change', listener); + }, [matches, query]); + + return matches; +} + +export default useMediaQuery; diff --git a/src/hooks/usePatchCommentHook.ts b/src/hooks/usePatchCommentHook.ts new file mode 100644 index 00000000..b215624d --- /dev/null +++ b/src/hooks/usePatchCommentHook.ts @@ -0,0 +1,32 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { patchComment } from '@/apis/epigramComment'; +import { PatchCommentRequest } from '@/types/epigram.types'; +import { toast } from '@/components/ui/use-toast'; + +const usePatchCommentMutation = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: ({ commentId, ...commentData }: { commentId: number } & PatchCommentRequest) => patchComment(commentId, commentData), + onSuccess: () => { + // ๋Œ“๊ธ€ ๋ชฉ๋ก ์ฟผ๋ฆฌ ๋ฌดํšจํ™” + queryClient.invalidateQueries({ queryKey: ['epigramComments'] }); + + // ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ + toast({ + title: '๋Œ“๊ธ€ ์ˆ˜์ • ์„ฑ๊ณต', + description: '๋Œ“๊ธ€์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', + }); + }, + onError: (error) => { + // ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ + toast({ + title: '๋Œ“๊ธ€ ์ˆ˜์ • ์‹คํŒจ', + description: `๋Œ“๊ธ€ ์ˆ˜์ • ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: ${error instanceof Error ? error.message : '์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜'}`, + variant: 'destructive', + }); + }, + }); +}; + +export default usePatchCommentMutation; diff --git a/src/hooks/usePostEmotion.ts b/src/hooks/usePostEmotion.ts new file mode 100644 index 00000000..f13540ae --- /dev/null +++ b/src/hooks/usePostEmotion.ts @@ -0,0 +1,11 @@ +import { useMutation } from '@tanstack/react-query'; +import postEmotion from '@/apis/postEmotion'; +import { EmotionType } from '@/types/emotion'; +import { PostEmotionResponseType } from '@/schema/emotion'; + +const usePostEmotion = () => + useMutation({ + mutationFn: postEmotion, + }); + +export default usePostEmotion; diff --git a/src/hooks/useRegisterMutation.ts b/src/hooks/useRegisterMutation.ts new file mode 100644 index 00000000..8cbe5fe7 --- /dev/null +++ b/src/hooks/useRegisterMutation.ts @@ -0,0 +1,77 @@ +import { postSignup } from '@/apis/auth'; +import { toast } from '@/components/ui/use-toast'; +import { useMutation } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; +import { isAxiosError } from 'axios'; + +const useRegisterMutation = () => { + const router = useRouter(); + + return useMutation({ + mutationFn: postSignup, + onSuccess: (data) => { + localStorage.setItem('accessToken', data.accessToken); + localStorage.setItem('refreshToken', data.refreshToken); + router.push('/'); + }, + onError: (error) => { + if (isAxiosError(error)) { + const { status, data } = error.response || {}; + + if (!status) return; + + if (status === 400) { + const errorMessage = data?.message || '์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ ๊ฐ’์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.'; + + if (errorMessage.includes('์ด๋ฏธ ์‚ฌ์šฉ์ค‘์ธ ์ด๋ฉ”์ผ')) { + toast({ + description: '์ด๋ฏธ ์‚ฌ์šฉ์ค‘์ธ ์ด๋ฉ”์ผ์ž…๋‹ˆ๋‹ค.', + className: 'border-state-error text-state-error font-semibold', + }); + return; + } + + toast({ + description: errorMessage, + className: 'border-state-error text-state-error font-semibold', + }); + return; + } + + if (status === 500) { + const errorMessage = data?.message || '์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.'; + + // NOTE: swagger ๋ฌธ์„œ์—์„œ ์ค‘๋ณต๋œ ๋‹‰๋„ค์ž„์€ 500์—๋Ÿฌ์™€ ํ•จ๊ป˜ "Internal Server Error" ๋ฉ”์‹œ์ง€๋กœ ์‘๋‹ต ์˜ด + if (errorMessage.includes('Internal Server Error')) { + toast({ + description: '์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋‹‰๋„ค์ž„์ž…๋‹ˆ๋‹ค.', + className: 'border-state-error text-state-error font-semibold', + }); + return; + } + + toast({ + description: errorMessage, + className: 'border-state-error text-state-error font-semibold', + }); + return; + } + + if (status >= 500) { + toast({ + description: '์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.', + className: 'border-state-error text-state-error font-semibold', + }); + return; + } + + toast({ + description: '์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.', + className: 'border-state-error text-state-error font-semibold', + }); + } + }, + }); +}; + +export default useRegisterMutation; diff --git a/src/hooks/useSignInMutation.ts b/src/hooks/useSignInMutation.ts new file mode 100644 index 00000000..2f4ebb5e --- /dev/null +++ b/src/hooks/useSignInMutation.ts @@ -0,0 +1,22 @@ +import { postSignin } from '@/apis/auth'; +import { toast } from '@/components/ui/use-toast'; +import { useMutation } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; + +const useSigninMutation = () => { + const router = useRouter(); + + return useMutation({ + mutationFn: postSignin, + onSuccess: (data) => { + localStorage.setItem('accessToken', data.accessToken); + localStorage.setItem('refreshToken', data.refreshToken); + router.push('/'); + }, + onError: () => { + toast({ description: '์ด๋ฉ”์ผ ํ˜น์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.', className: 'border-state-error text-state-error font-semibold' }); + }, + }); +}; + +export default useSigninMutation; diff --git a/src/hooks/useTagManagementHook.ts b/src/hooks/useTagManagementHook.ts new file mode 100644 index 00000000..dd0082de --- /dev/null +++ b/src/hooks/useTagManagementHook.ts @@ -0,0 +1,47 @@ +import { useState } from 'react'; +import { UseFormSetValue, UseFormGetValues, UseFormSetError } from 'react-hook-form'; +import { AddEpigramFormType } from '@/schema/addEpigram'; + +// NOTE: setError๋ฉ”์„œ๋“œ๋กœ FormField์— ์—๋Ÿฌ ์„ค์ • ๊ฐ€๋Šฅ +const useTagManagement = ({ + setValue, + getValues, + setError, +}: { + setValue: UseFormSetValue; + getValues: UseFormGetValues; + setError: UseFormSetError; +}) => { + const [currentTag, setCurrentTag] = useState(''); + + const handleAddTag = () => { + if (!currentTag || currentTag.length > 10) { + return; + } + const currentTags = getValues('tags') || []; + + if (currentTags.length >= 3) { + return; + } + if (currentTags.includes(currentTag)) { + setError('tags', { type: 'manual', message: '์ด๋ฏธ ์ €์žฅ๋œ ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค.' }); + return; + } + + setValue('tags', [...currentTags, currentTag]); + setCurrentTag(''); + setError('tags', { type: 'manual', message: '' }); + }; + + const handleRemoveTag = (tagToRemove: string) => { + const currentTags = getValues('tags') || []; + setValue( + 'tags', + currentTags.filter((tag) => tag !== tagToRemove), + ); + }; + + return { currentTag, setCurrentTag, handleAddTag, handleRemoveTag }; +}; + +export default useTagManagement; diff --git a/src/hooks/userQueryHooks.ts b/src/hooks/userQueryHooks.ts index 7c28fe75..f5043b15 100644 --- a/src/hooks/userQueryHooks.ts +++ b/src/hooks/userQueryHooks.ts @@ -1,6 +1,6 @@ import quries from '@/apis/queries'; -import { updateMe } from '@/apis/user'; -import { GetUserReponseType, GetUserRequestType, PatchMeRequestType } from '@/schema/user'; +import { updateMe, createPresignedUrl } from '@/apis/user'; +import { GetUserRequestType, PatchMeRequestType, PostPresignedUrlRequestType, PostPresignedUrlResponseType } from '@/schema/user'; import { MutationOptions } from '@/types/query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; @@ -8,7 +8,7 @@ export const useMeQuery = () => useQuery(quries.user.getMe()); export const useUserQuery = (requset: GetUserRequestType) => useQuery(quries.user.getUser(requset)); -export const useUpdateMe = (options: MutationOptions) => { +export const useUpdateMe = (options: MutationOptions) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (request: PatchMeRequestType) => updateMe(request), @@ -21,3 +21,13 @@ export const useUpdateMe = (options: MutationOptions) => { }, }); }; + +// presignedUrl ์ƒ์„ฑ +export const useCreatePresignedUrl = (options?: MutationOptions) => + useMutation({ + mutationFn: (request: PostPresignedUrlRequestType) => createPresignedUrl(request), + ...options, + onSuccess: (data: PostPresignedUrlResponseType) => + // ์ด๋ฏธ์ง€ URL ๋ฐ˜ํ™˜ + data.url, + }); diff --git a/src/pageLayout/Epigram/AddEpigram.tsx b/src/pageLayout/Epigram/AddEpigram.tsx new file mode 100644 index 00000000..f314c730 --- /dev/null +++ b/src/pageLayout/Epigram/AddEpigram.tsx @@ -0,0 +1,316 @@ +import React, { KeyboardEvent, useCallback, useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import Header from '@/components/Header/Header'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; +import { Textarea } from '@/components/ui/textarea'; +import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'; +import { AddEpigramFormSchema, AddEpigramFormType } from '@/schema/addEpigram'; +import useAddEpigram from '@/hooks/epigramQueryHook'; +import { useRouter } from 'next/router'; +import { AlertDialog, AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog'; +import useTagManagement from '@/hooks/useTagManagementHook'; +import { useMeQuery } from '@/hooks/userQueryHooks'; + +function AddEpigram() { + const router = useRouter(); + const { data: userData, isPending, isError } = useMeQuery(); + const [isAlertOpen, setIsAlertOpen] = useState(false); + const [alertContent, setAlertContent] = useState({ title: '', description: '' }); + const [selectedAuthorOption, setSelectedAuthorOption] = useState('directly'); // ๊ธฐ๋ณธ๊ฐ’์„ 'directly'๋กœ ์„ค์ • + const [isFormValid, setIsFormValid] = useState(false); + + const form = useForm({ + resolver: zodResolver(AddEpigramFormSchema), + defaultValues: { + content: '', + author: '', + referenceTitle: '', + referenceUrl: '', + tags: [], + }, + }); + + // NOTE: ํ•„์ˆ˜ํ•ญ๋ชฉ๋“ค์— ๊ฐ’์ด ๋“ค์–ด์žˆ๋Š”์ง€ ํ™•์ธ ํ•จ์ˆ˜ + const checkFormEmpty = useCallback(() => { + const { content, author, tags } = form.getValues(); + return content.trim() !== '' && author.trim() !== '' && tags.length > 0; + }, [form]); + + // NOTE: form๊ฐ’์ด ๋ณ€๊ฒฝ๋ ๋•Œ ํ•„์ˆ˜ํ•ญ๋ชฉ๋“ค์ด ๋“ค์–ด์žˆ๋Š”์ง€ ํ™•์ธ + const watchForm = useCallback(() => { + setIsFormValid(checkFormEmpty()); + }, [checkFormEmpty]); + + useEffect(() => { + const subscription = form.watch(watchForm); + return () => subscription.unsubscribe(); + }, [form, watchForm]); + + const { currentTag, setCurrentTag, handleAddTag, handleRemoveTag } = useTagManagement({ + setValue: form.setValue, + getValues: form.getValues, + setError: form.setError, + }); + const addEpigramMutation = useAddEpigram({ + onSuccess: () => { + setAlertContent({ + title: '๋“ฑ๋ก ์™„๋ฃŒ', + description: '๋“ฑ๋ก์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', + }); + setIsAlertOpen(true); + form.reset(); + }, + onError: () => { + setAlertContent({ + title: '๋“ฑ๋ก ์‹คํŒจ', + description: '๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.', + }); + setIsAlertOpen(true); + }, + }); + + const handleAlertClose = () => { + setIsAlertOpen(false); + if (alertContent.title === '๋“ฑ๋ก ์™„๋ฃŒ') { + router.push(`/epigram/${addEpigramMutation.data?.id}`); + } + }; + + const AUTHOR_OPTIONS = [ + { value: 'directly', label: '์ง์ ‘ ์ž…๋ ฅ' }, + { value: 'unknown', label: '์•Œ ์ˆ˜ ์—†์Œ' }, + { value: 'me', label: '๋ณธ์ธ' }, + ]; + + // NOTE: default๋ฅผ ์ง์ ‘ ์ž…๋ ฅ์œผ๋กœ ์„ค์ • + // NOTE: ๋ณธ์ธ์„ ์„ ํƒ ์‹œ ์œ ์ €์˜ nickname์ด ๋“ค์–ด๊ฐ + const handleAuthorChange = async (value: string) => { + setSelectedAuthorOption(value); + let authorValue: string; + + switch (value) { + case 'unknown': + authorValue = '์•Œ ์ˆ˜ ์—†์Œ'; + break; + case 'me': + if (isPending) { + authorValue = '๋กœ๋”ฉ ์ค‘...'; + } else if (userData) { + authorValue = userData.nickname; + } else { + authorValue = '๋ณธ์ธ (์ •๋ณด ์—†์Œ)'; + } + break; + default: + authorValue = ''; + } + form.setValue('author', authorValue); + }; + + if (isPending) { + return
์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...
; + } + + if (isError) { + return
์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจ ํ•ด์ฃผ์„ธ์š”.
; + } + + // NOTE: ํƒœ๊ทธ๋ฅผ ์ €์žฅํ•˜๋ ค๊ณ  ํ• ๋•Œ enterํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ํผ์ œ์ถœ์ด ๋˜๋Š”๊ฑธ ๋ฐฉ์ง€ + const handleKeyUp = (e: KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault(); + handleAddTag(); + } + }; + + // NOTE: url์™€title์€ ํ•„์ˆ˜ ํ•ญ๋ชฉ์ด ์•„๋‹ˆ๋ผ์„œ ๋นˆ์นธ์œผ๋กœ ์ œ์ถœํ•  ๋•Œ ํ•ญ๋ชฉ์—์„œ ์ œ์™ธ + const handleSubmit = (data: AddEpigramFormType) => { + const submitData = { ...data }; + + if (!submitData.referenceUrl) { + delete submitData.referenceUrl; + } + + if (!submitData.referenceTitle) { + delete submitData.referenceTitle; + } + + addEpigramMutation.mutate(submitData); + }; + + return ( + <> +
{}} /> +
+
+ + ( + + + ๋‚ด์šฉ + * + + +