diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index 3c6f256..35ff0d4 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -251,7 +251,7 @@ - ๐Ÿ–ผ๏ธ **ํŒ€ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ ์‹œ์Šคํ…œ ์ถ”๊ฐ€** - **Team ํƒ€์ž… ํ™•์žฅ**: `coverImage?: string` ํ•„๋“œ ์ถ”๊ฐ€ - **Firebase Storage ์—…๋กœ๋“œ**: ์ด๋ฏธ์ง€ โ†’ Storage โ†’ ๊ณต๊ฐœ URL - - **TeamCoverImageUploader ์ปดํฌ๋„ŒํŠธ**: ๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ ์ง€์›, ๋ฏธ๋ฆฌ๋ณด๊ธฐ + - **ImageDropzone ์ปดํฌ๋„ŒํŠธ**: ๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ ์ง€์›, ๋ฏธ๋ฆฌ๋ณด๊ธฐ (๋ฒ”์šฉ ์ปดํฌ๋„ŒํŠธ) - **API Route**: POST/DELETE `/api/team/[teamId]/cover-image` - **TeamManager ๋ฉ”์„œ๋“œ**: `uploadCoverImage()`, `deleteCoverImage()` - **ํŒ€ ์ƒ์„ฑ**: ์ƒ์„ฑ ์‹œ ์ด๋ฏธ์ง€ ์„ ํƒ ๊ฐ€๋Šฅ (์„ ํƒ์ ) @@ -717,8 +717,9 @@ | **VisibilitySelector** | `VisibilitySelector.tsx` | ๐Ÿ†• **๊ณต๊ฐœ ๋ฒ”์œ„ ์„ ํƒ** (PUBLIC/TEAM/PRIVATE, RadioCard ๊ธฐ๋ฐ˜) | โœ… ์™„๋ฃŒ | | **VisibilityBadge** | `VisibilityBadge.tsx` | ๐Ÿ†• **๊ณต๊ฐœ ๋ฒ”์œ„ ๋ฐฐ์ง€** (์•„์ด์ฝ˜ + ๋ผ๋ฒจ, ์ƒ‰์ƒ๋ณ„ ๊ตฌ๋ถ„) | โœ… ์™„๋ฃŒ | | **InteractiveImageViewer** | `InteractiveImageViewer.tsx` | ๐Ÿ†• **์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์ด๋ฏธ์ง€ ๋ทฐ์–ด** (์™œ๊ณก ํšจ๊ณผ, ์• ๋‹ˆ๋ฉ”์ด์…˜, ์˜ค๋””์˜ค ๋ฐ˜์‘) | โœ… ์™„๋ฃŒ | -| **ImageDropzone** | `ImageDropzone.tsx` | ๐Ÿ†• **์ด๋ฏธ์ง€ ๋“œ๋กญ์กด** (๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ ์—…๋กœ๋“œ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, IndexedDB ์ €์žฅ, **4:3 ํฌ๋กญ ํ†ตํ•ฉ**) | โœ… ์™„๋ฃŒ | +| **ImageDropzone** | `ImageDropzone.tsx` | ๐Ÿ†• **๋ฒ”์šฉ ์ด๋ฏธ์ง€ ๋“œ๋กญ์กด** (๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ ์—…๋กœ๋“œ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, 4:3 ํฌ๋กญ ํ†ตํ•ฉ, ํ˜ธ๋ฒ„ ์˜ค๋ฒ„๋ ˆ์ด, ์‚ญ์ œ ๋ฒ„ํŠผ, AspectRatio ์ง€์›, ์ปค์Šคํ…€ ๋ผ๋ฒจ โ€” ๊ธ€์“ฐ๊ธฐ/ํŒ€ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ ๊ณต์šฉ) | โœ… ์™„๋ฃŒ | | **ImageCropper** | `ImageCropper.tsx` | ๐Ÿ†• **์ด๋ฏธ์ง€ ํฌ๋กญ ๋ชจ๋‹ฌ** (react-cropper ๊ธฐ๋ฐ˜, 4:3 ๊ณ ์ • ๋น„์œจ, ํšŒ์ „/ํ™•๋Œ€/์ถ•์†Œ, ์ตœ์†Œ 400x300) | โœ… ์™„๋ฃŒ | +| **CameraCaptureDialog** | `CameraCaptureDialog.tsx` | ๐Ÿ†• **์นด๋ฉ”๋ผ ์ดฌ์˜ ๋‹ค์ด์–ผ๋กœ๊ทธ** (GlassDialog ๊ธฐ๋ฐ˜, getUserMedia ์นด๋ฉ”๋ผ ์ŠคํŠธ๋ฆผ, 4:3 ํ”„๋ ˆ์ž„ ๊ฐ€์ด๋“œ ์˜ค๋ฒ„๋ ˆ์ด, ์ „/ํ›„๋ฉด ์นด๋ฉ”๋ผ ์ „ํ™˜, ์ดฌ์˜ ํ›„ ImageCropper ์—ฐ๋™, ๊ถŒํ•œ/๋ฏธ์ง€์› ์—๋Ÿฌ ์ฒ˜๋ฆฌ, ๋‹ค๊ตญ์–ด ์ง€์›) | โœ… ์™„๋ฃŒ | | **ImageFirstLayout** | `ImageFirstLayout.tsx` | ๐Ÿ†• **์ด๋ฏธ์ง€ ์šฐ์„  ๋ ˆ์ด์•„์›ƒ** (์ด๋ฏธ์ง€+์—๋””ํ„ฐ 2์ปฌ๋Ÿผ, ๋ฐ˜์‘ํ˜•) | โœ… ์™„๋ฃŒ | | **GenerateImageDialog** | `GenerateImageDialog.tsx` | ๐Ÿ†• **AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ Dialog** (4๋‹จ๊ณ„ ํ”Œ๋กœ์šฐ: ์žฅ๋ฉด ์ถ”์ถœ โ†’ ์žฅ๋ฉด ์„ ํƒ โ†’ ์ด๋ฏธ์ง€ ์ƒ์„ฑ โ†’ ๊ฒฐ๊ณผ ํ‘œ์‹œ) | โœ… ์™„๋ฃŒ | | ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ ์ ์ˆ˜ ํ‘œ์‹œ~~ | โŒ ์‚ญ์ œ๋จ (ํ•˜์ด๋ผ์ดํŠธ๋กœ ๋Œ€์ฒด) | @@ -865,7 +866,7 @@ | ์ปดํฌ๋„ŒํŠธ | ํŒŒ์ผ๋ช… | ์„ค๋ช… | ์ƒํƒœ | |---------|--------|------|------| | **TeamCard** | `TeamCard.tsx` | ๐Ÿ†• **ํŒ€ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ** (๋‚ด ํŒ€/๊ณต๊ฐœ ํŒ€ ๊ณต์šฉ, ์ปค๋ฒ„ ์ด๋ฏธ์ง€ 140px, ํŒ€ ์„ค๋ช… 2์ค„, ํŒ€ ์ฝ”๋“œ ์กฐ๊ฑด๋ถ€ ํ‘œ์‹œ, isOwner/onClick props) | โœ… ์™„๋ฃŒ | -| **TeamCoverImageUploader** | `TeamCoverImageUploader.tsx` | ๐Ÿ†• **ํŒ€ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ ์—…๋กœ๋”** (๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, 16:9 AspectRatio, 5MB ์ œํ•œ) | โœ… ์™„๋ฃŒ | +| ~~TeamCoverImageUploader~~ | ์‚ญ์ œ๋จ | ImageDropzone๋กœ ํ†ตํ•ฉ (๋ฒ”์šฉ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ปดํฌ๋„ŒํŠธ) | โœ… ์™„๋ฃŒ | | **TeamTopicManager** | `TeamTopicManager.tsx` | ํŒ€ ์ฃผ์ œ ๋ชฉ๋ก ๋ฐ ์ƒ์„ฑ/์‚ญ์ œ UI | โœ… ์™„๋ฃŒ | | **TeamAISettings** | `TeamAISettings.tsx` | ๐Ÿ†• **ํŒ€ AI ์„ค์ • ์ปดํฌ๋„ŒํŠธ** (2๋‹จ๊ณ„ ๊ณ„์ธต: ํŒ€ AI ๋งˆ์Šคํ„ฐ ์Šค์œ„์น˜ + AI ๊ธ€์“ฐ๊ธฐ ๋„์šฐ๋ฏธ, ํ”Œ๋žœ ์ œํ•œ ์ฒดํฌ, 3๊ฐ€์ง€ ์ƒํƒœ ํ”ผ๋“œ๋ฐฑ, VStack ๋ ˆ์ด์•„์›ƒ) | โœ… ์™„๋ฃŒ | | **AIConfigDialog** | `AIConfigDialog.tsx` | ๐Ÿ†• **AI ๋„์šฐ๋ฏธ ๊ณ ๊ธ‰ ์„ค์ • Dialog** (Slider, ์ปค์Šคํ…€ CheckboxCard) | โœ… ์™„๋ฃŒ | diff --git a/ROADMAP.md b/ROADMAP.md index 474e5ca..2c1928a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -161,6 +161,8 @@ | **AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ฐœ์„ ** | **์—๋Ÿฌ ์ฝ”๋“œ๋ณ„ ํ† ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ๋กœ์ง ๊ฐœ์„ , plan_not_supported/limit_exceeded/ai_disabled ๋“ฑ ์—๋Ÿฌ ์ฝ”๋“œ ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€, ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ 'selecting' ๋‹จ๊ณ„๋กœ ๋˜๋Œ์•„๊ฐ€๋Š” ๋กœ์ง ์œ ์ง€, ๋‹ค๊ตญ์–ด ์ง€์› (ko/en/ja)** | **2025-12-19** | | **์˜์กด์„ฑ ์—…๋ฐ์ดํŠธ** | **@ark-ui/react ๋ฐ @zag-js ํŒจํ‚ค์ง€ ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ (v1.29.1 โ†’ v1.31.1)** | **2025-12-19** | | **์ธํ„ฐ๋ž™์…˜ ํŽ˜์ด์ง€ UX ๋Œ€ํญ ๊ฐœ์„ ** | **7:3 ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ (์ด๋ฏธ์ง€ 70%, ์ปจํŠธ๋กค๋Ÿฌ 30%), ํ•œ ํ™”๋ฉด์—์„œ ์ด๋ฏธ์ง€ ๋ณด๋ฉด์„œ ํŽธ์ง‘ ๊ฐ€๋Šฅ, ์ปจํŠธ๋กค๋Ÿฌ ๋‚ด๋ถ€ ์Šคํฌ๋กค (์ปค์Šคํ…€ ์Šคํฌ๋กค๋ฐ”), InteractionHeader ์ปดํฌ๋„ŒํŠธ (IntersectionObserver + Sentinel ํŒจํ„ด, sticky header, glassmorphism ํšจ๊ณผ, ์ œ๋ชฉ ํฌ๊ธฐ ๋™์  ๋ณ€๊ฒฝ 2xlโ†’xl, ๋ฒ„ํŠผ ํ…์ŠคํŠธ ์ˆจ๊น€), framer-motion ์• ๋‹ˆ๋ฉ”์ด์…˜ (AnimatePresence, MotionBox/MotionVStack, ๋ชจ๋“œ ์ „ํ™˜/์˜์—ญ ์„ ํƒ ๋ถ€๋“œ๋Ÿฌ์šด ์ „ํ™˜, 0.2~0.3์ดˆ ease curve), ์˜์—ญ ๋ชฉ๋ก์„ ์ผ๋ฐ˜ ๋ชจ๋“œ์—์„œ๋„ ํ‘œ์‹œ (CustomAreaList, ๊ณ ๊ธ‰ ๋ชจ๋“œ์—์„œ๋งŒ CustomParameterPanel), ์—๋””ํ„ฐ ๋ฒ„ํŠผ ์šฐ์ธก ํŒจ๋„ ์ƒ๋‹จ ์ด๋™ (์ถ”๊ฐ€/์‚ญ์ œ/์ˆจ๊ธฐ๊ธฐ, ๊ฐ€๋กœ ๋ฐฐ์น˜ flex:1), Container maxW ํ™•์žฅ (1400pxโ†’95vw), ์ด๋ฏธ์ง€ ๋ฐ˜์‘ํ˜• ์ˆ˜์ • (InteractiveImageViewer width:100%, VStack maxH ์ œ๊ฑฐ, aspectRatio ์ถฉ๋Œ ํ•ด๊ฒฐ), ๋†’์ด ์ œํ•œ 80dvh (์šฐ์ธก๋งŒ ์Šคํฌ๋กค), ํƒ€์ž… ์ฒดํฌ ํ†ต๊ณผ** | **2025-12-24** | +| **ImageDropzone ๋ฒ”์šฉํ™”** | **ImageDropzone์„ ๋ฒ”์šฉ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฆฌํŒฉํ† ๋ง, TeamCoverImageUploader ์‚ญ์ œ ๋ฐ ํ†ตํ•ฉ, ์ƒˆ props ์ถ”๊ฐ€ (currentImageUrl, onDelete, containerAspectRatio, acceptedTypes, maxFileSize, labels, showHoverOverlay, label, helperText), document.getElementByIdโ†’useRef ์ „ํ™˜, ํŒ€ ์ƒ์„ฑ/๊ณต๊ฐœ์„ค์ •/๋ณด์•ˆ์„ค์ • 3๊ณณ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ๊ธฐ์กด ๊ธ€์“ฐ๊ธฐ 5๊ณณ์€ ๋ณ€๊ฒฝ ์—†์Œ (๋ชจ๋“  ์ƒˆ props optional + ๊ธฐ๋ณธ๊ฐ’ ๋™์ผ)** | **2026-02-26** | +| **ImageDropzone ์นด๋ฉ”๋ผ ์ดฌ์˜ ๊ธฐ๋Šฅ** | **CameraCaptureDialog ์ปดํฌ๋„ŒํŠธ ์‹ ๊ทœ ์ƒ์„ฑ (GlassDialog ๊ธฐ๋ฐ˜, getUserMedia ์นด๋ฉ”๋ผ ์ŠคํŠธ๋ฆผ, 4:3 ํ”„๋ ˆ์ž„ ๊ฐ€์ด๋“œ ์˜ค๋ฒ„๋ ˆ์ด, ์ „/ํ›„๋ฉด ์นด๋ฉ”๋ผ ์ „ํ™˜), ImageDropzone์— "์นด๋ฉ”๋ผ๋กœ ์ดฌ์˜" ๋ฒ„ํŠผ ์ถ”๊ฐ€ (ํŒŒ์ผ ์„ ํƒ๊ณผ ๋‚˜๋ž€ํžˆ ๋ฐฐ์น˜), ์ดฌ์˜ โ†’ ImageCropper ํฌ๋กญ ํ”Œ๋กœ์šฐ ์—ฐ๋™, ์นด๋ฉ”๋ผ ๊ถŒํ•œ ๊ฑฐ๋ถ€/๋ฏธ์ง€์› ์—๋Ÿฌ ์ฒ˜๋ฆฌ, ๋‹ค๊ตญ์–ด ์ง€์› (camera namespace ko/en/ja 7๊ฐœ ํ‚ค), ๋ชจ๋“  ์‚ฌ์šฉ์ฒ˜(๊ธ€์“ฐ๊ธฐ 5๊ณณ, ํŒ€ 3๊ณณ) ์ž๋™ ํ™œ์„ฑํ™”** | **2026-03-03** | ### ๐Ÿšง ์ง„ํ–‰ ์ค‘