Skip to content

Commit 292f861

Browse files
committed
Merge branch 'develop' into feature/QA
2 parents 300b7bf + 5f5cea2 commit 292f861

File tree

12 files changed

+474
-367
lines changed

12 files changed

+474
-367
lines changed

README.md

Lines changed: 147 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,148 @@
1-
# Wine
2-
(프로젝트 설명)
3-
4-
## 목표
5-
- 목표: 프로젝트 완성
6-
7-
## 팀원 정보 및 역할
8-
- 준열: 팀 리딩, 랜딩 페이지, 와인 상세 페이지
9-
- 휘태: 로그인, 회원가입, 리뷰 남기기/와인 등록하기 모달
10-
- 연수: 마이페이지(내가 등록한 와인), notion 문서화
11-
- 지권: 마이페이지(내가 쓴 후기)
12-
- 정훈: 와인 목록 페이지
13-
14-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)
15-
16-
## Core Time
17-
- 데일리 스크럼
18-
- 월요일: 오후 3시
19-
- 화요일 일요일: 오후 1시 30분 (20~30분 진행)
20-
- 집중 코딩 (모각코)
21-
- 9:00 ~ 18:00 (zep 활용)
22-
23-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)
24-
25-
## Branch 전략
1+
# 🍷 WHYNE
2+
<div><img width="1800" height="600" alt="image" src="https://github.com/user-attachments/assets/cd2abace-5bfc-4243-ad41-b7944bbd4f45" /></div>
3+
4+
5+
<br>
6+
7+
## 📖 프로젝트 소개
8+
> WHYNE은 사용자가 다양한 와인 리뷰를 확인하고, 구매 여부를 쉽게 판단할 수 있는 와인 리뷰 플랫폼입니다.
9+
10+
11+
<br>
12+
13+
## 🎯 목표
14+
15+
> 주어진 요구사항을 충족하는 것을 넘어, 경쟁력 있는 특별한 UI / UX를 도입하고, 사용자에게 최적의 와인 선택 경험을 제공하는 것
16+
17+
<br>
18+
19+
## 👥 팀 소개
20+
21+
<span align="right">
22+
23+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)
24+
25+
</span>
26+
27+
<div align="center">
28+
29+
|팀장 |팀원 |팀원 |팀원 |
30+
|:---:|:---:|:---:|:---:|
31+
| <div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; background: white;"><img src="https://raw.githubusercontent.com/Tarikul-Islam-Anik/Animated-Fluent-Emojis/master/Emojis/Animals/Dove.png" width="80" height="80" alt="🕊️"/><br><b><a href="https://github.com/junye0l">김준열</a></b><br><img src="https://img.shields.io/badge/ISTJ-50C878?style=for-the-badge&logoColor=white" alt="ISTJ"/><br><code>FE</code></div> | <div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; background: white;"><img src="https://raw.githubusercontent.com/Tarikul-Islam-Anik/Animated-Fluent-Emojis/master/Emojis/Animals/Bat.png" width="80" height="80" alt="🦇"/><br><b><a href="https://github.com/wlrnjs">서지권</a></b><br><img src="https://img.shields.io/badge/INTJ-5C0091?style=for-the-badge&logoColor=white" alt="INTJ"/><br><code>FE</code></div> | <div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; background: white;"><img src="https://raw.githubusercontent.com/Tarikul-Islam-Anik/Animated-Fluent-Emojis/master/Emojis/Animals/Baby%20Chick.png" width="80" height="80" alt="🐣"/><br><b><a href="https://github.com/suuuuya">이연수</a></b><br><img src="https://img.shields.io/badge/INFP-9B59B6?style=for-the-badge&logoColor=white" alt="INFP"/><br><code>FE</code></div> | <div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; background: white;"><img src="https://raw.githubusercontent.com/Tarikul-Islam-Anik/Animated-Fluent-Emojis/master/Emojis/Animals/Black%20Cat.png" width="80" height="80" alt="🐈‍⬛"/><br><b><a href="https://github.com/Imhwitae">황휘태</a></b><br><img src="https://img.shields.io/badge/ISTJ-E74C3C?style=for-the-badge&logoColor=white" alt="ISTJ"/><br><code>FE</code></div> |
32+
33+
</div>
34+
35+
<br>
36+
37+
## 🐜 역할 분담
38+
39+
<span align="right">
40+
41+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)
42+
43+
</span>
44+
45+
| 팀원 | 역할 | 담당 기능 및 공통 컴포넌트 |
46+
| --- | --- | --- |
47+
| 김준열 | 팀장 | - 프로젝트 셋팅 <br> - 랜딩 페이지 <br> - 와인 상세 페이지 <br> - taste 컴포넌트 <br> - 리뷰 등록/수정 모달 <br> - 무한스크롤 <br> - 토스트 |
48+
| 서지권 | 팀원 | - 마이페이지(내가 쓴 후기)<br> - 헤더 컴포넌트 <br> - 드롭다운 컴포넌트<br> - chip 컴포넌트<br> - Flavor 컴포넌트<br> - 프로필 컴포넌트<br> - 검색 필터 컴포넌트<br> - 챗봇 |
49+
| 이연수 | 팀원 | - notion 문서화 및 배너 제작, 디자인 수정<br>- 아이콘 컴포넌트<br>- 버튼 컴포넌트<br>- 별점 컴포넌트<br>- 카드 컴포넌트<br>- 캐러셀 컴포넌트<br>- 마이페이지(내가 등록한 와인)<br>- 와인 목록 페이지(이 달의 추천 와인, 와인 항목)<br>- 스켈레톤 UI<br>- 폰트 최적화|
50+
| 황휘태 | 팀원 | - 로그인 페이지<br>- 회원가입 페이지<br>- next.js middleware<br>- 와인 등록/수정하기 모달<br>- 삭제하기 모달<br>- 인풋 컴포넌트<br>- 와인 타입 컴포넌트<br>- 에러 바운더리<br>- 이미지 최적화 |
51+
52+
<br>
53+
54+
## 📌 데일리 팀 스크럼
55+
> 원활한 소통을 위해 매일 진행하며, 의미 없는 시간이 되지 않도록 **노션 문서화**로 기록합니다.
56+
57+
#### 🗓️ 시간표
58+
59+
| 요일 | 시간 |
60+
| :-------------: | :-------: |
61+
| 월요일 | **15:00** |
62+
| 화요일 ~ 일요일 | **13:30** |
63+
64+
<br>
65+
66+
## ⏰ Core Time
67+
> 실시간 이슈 공유를 위해 ZEP 플랫폼을 활용한 온라인 모각코 진행
68+
69+
#### 🕘 시간
70+
매일 09:00 ~ 18:00
71+
72+
<br>
73+
74+
## ⛓️ Branch 전략
75+
76+
77+
<span align="right">
78+
79+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EB%B8%8C%EB%9E%9C%EC%B9%98-%EC%BB%A8%EB%B2%A4%EC%85%98)
80+
81+
</span>
82+
2683
- `main` → 배포
2784
- `develop` → 통합 브랜치
2885
- `feature/*`, `design/*`, `chore/*` → 작업 브랜치 → PR → develop → main
2986

30-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EB%B8%8C%EB%9E%9C%EC%B9%98-%EC%BB%A8%EB%B2%A4%EC%85%98)
87+
<br>
88+
89+
## 🧩 기술 스택
90+
91+
<span align="right">
92+
93+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%83%9D)
94+
95+
</span>
96+
97+
98+
| 구분 | 사용 기술 | 비고 |
99+
|------|------------|------|
100+
| **Framework** | Next.js (v15), React (v19) | 메인 프레임워크, App Router 기반 |
101+
| **Language** | TypeScript (v5) | 정적 타입 시스템 |
102+
| **Styling** | Tailwind CSS, tailwind-merge | 반응형 및 유틸리티 클래스 관리 |
103+
| **Server State / Data Fetching** | React Query (TanStack v5), Axios | 서버 데이터 캐싱 및 API 통신 |
104+
| **Form Handling** | React Hook Form | 입력값 검증 및 폼 상태 관리 |
105+
| **UI / Animation** | GSAP, Swiper, React Toastify, React Loading Skeleton | 인터랙션, 캐러셀, 알림, 로딩 처리 |
106+
| **Chat UI** | Chat UI Kit (chatscope) | 챗봇 인터페이스 구성 |
107+
| **Utility** | Lodash, clsx, class-variance-authority | 유틸 함수 및 클래스 병합 |
108+
| **Authentication / Cookie** | cookies-next | 로그인 상태 및 쿠키 관리 |
109+
| **Build / Deploy** | Vercel | 정적 배포 및 CI/CD 환경 |
110+
| **Design System / Docs** | Storybook, Chromatic | 컴포넌트 문서화 및 시각 테스트 |
111+
| **Quality / Linting** | ESLint, Prettier, Husky, lint-staged | 코드 품질 및 커밋 훅 관리 |
112+
| **Collaboration** | GitHub, Notion, Figma, Discoard, Zep | 버전 관리 및 협업 툴 |
31113

32-
## 기술 스택
33-
- Next.js, React, TypeScript
34-
- Tailwind CSS
35-
- Storybook
36-
- husky + lint-staged
37-
- Vercel (배포)
114+
<br>
38115

39-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%83%9D)
116+
## 🤖 깃허브 액션
40117

41-
## 깃허브 액션
42-
- Vercel 배포
43-
- Chromatic으로 Storybook 배포 (develop 기준)
118+
<span align="right">
119+
120+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EA%B9%83%ED%97%88%EB%B8%8C-%EC%95%A1%EC%85%98)
44121

45-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%EA%B9%83%ED%97%88%EB%B8%8C-%EC%95%A1%EC%85%98)
122+
</span>
123+
124+
- Vercel 배포
125+
- Chromatic으로 Storybook 배포 (develop 기준)
126+
127+
<br>
128+
129+
## 🗒️ 프로젝트 관리
130+
131+
<span align="right">
132+
133+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A6%AC)
134+
135+
</span>
46136

47-
## 프로젝트 관리
48137
- README: 프로젝트 개요 / 기술 스택 / 실행 방법
49138
- Wiki: 세부 규칙, 가이드 문서, 브랜치 룰
50139
- Notion: 회의록, 멘토링 피드백, 참고 자료
51140
- GitHub Project: 일정 / TODO 관리
52141

53-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A6%AC)
142+
<br>
143+
144+
## ⚙️ 실행 방법
54145

55-
## 실행 방법
56146
```bash
57147
# 패키지 설치
58148
npm install
@@ -67,7 +157,15 @@ npm run storybook
67157
NEXT_PUBLIC_API_URL=http://localhost:4000
68158
```
69159

70-
## 폴더 구조
160+
<br>
161+
162+
## 📂 폴더 구조
163+
164+
<span align="right">
165+
166+
🔗 [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0)
167+
168+
</span>
71169

72170
```bash
73171
src
@@ -81,9 +179,12 @@ src
81179
┣ types # 전역 타입 정의 (TypeScript 인터페이스, 타입)
82180
┗ utils # 공통 유틸리티 함수
83181
```
84-
> [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki/%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0)
85182

86-
## 바로가기
87-
- [배포 바로가기](https://google.com/)
88-
- [스토리북 바로가기](https://68d3998e0b054d1207706cbb-tzevsxkvcq.chromatic.com/?path=/docs/my-profile-accountitem--docs)
89-
- [Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)
183+
<br>
184+
185+
## 🔎 바로가기
186+
187+
188+
- [🚀 배포 바로가기](https://wine-phi-olive.vercel.app/)
189+
- [✨ 스토리북 바로가기](https://68d3998e0b054d1207706cbb-rwsgeadjmd.chromatic.com/?path=/story/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%ED%8C%85-%ED%8F%B0%ED%8A%B8-%EC%BB%AC%EB%9F%AC--font-color)
190+
- [📖 Wiki 바로가기](https://github.com/Team-3-2/Wine/wiki)

src/app/register/[id]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const Page = async ({ params }: { params: Promise<{ id: string }> }) => {
4242
return (
4343
<div
4444
className={cn(
45-
"bg-gray-200 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat px-[16px] py-[35px]",
45+
"flex-center min-h-screen bg-gray-200 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat px-[16px] py-[35px]",
4646
"tablet:py-[70px]",
4747
"pc:py-[70px]"
4848
)}

src/app/reviews/[reviewId]/edit/page.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { cn } from "@/lib/utils";
34
import { useRouter, useParams } from "next/navigation";
45
import { useEffect } from "react";
56
import ReviewFormClient from "@/app/wines/[id]/_components/wine-review-form/review-form-client";
@@ -16,8 +17,20 @@ export default function EditPage() {
1617
if (!reviewId) return null;
1718

1819
return (
19-
<main className="min-h-screen bg-gray-100 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat">
20-
<section className="container mx-auto flex max-w-[460px] flex-col gap-10 py-12 pt-24 tablet:max-w-[740px] pc:max-w-[1020px]">
20+
<main
21+
className={cn(
22+
"flex-center min-h-screen bg-gray-200 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat py-[35px]",
23+
"tablet:py-[70px]",
24+
"pc:py-[70px]"
25+
)}
26+
>
27+
<section
28+
className={cn(
29+
"container mt-[60px] flex flex-col gap-10 rounded-2xl bg-white px-[16px] py-8",
30+
"tablet:max-w-[480px]",
31+
"pc:max-w-[480px]"
32+
)}
33+
>
2134
<h1 className="text-heading-lg">리뷰 수정</h1>
2235
<ReviewFormClient
2336
reviewId={reviewId}

src/app/reviews/[reviewId]/write/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function WritePage() {
1919
return (
2020
<main
2121
className={cn(
22-
"min-h-screen bg-gray-100 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat py-[35px]",
22+
"flex-center min-h-screen bg-gray-200 bg-[url('/images/common/bg-main.png')] bg-cover bg-no-repeat py-[35px]",
2323
"tablet:py-[70px]",
2424
"pc:py-[70px]"
2525
)}

src/app/wines/[id]/_components/wine-detail/wine-detail-content.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@ const WineDetailContent = ({ wineId }: WineDetailContentProps) => {
4040

4141
return (
4242
<main className="min-h-screen bg-white">
43-
{/* 헤더 */}
4443
<section className="rounded-b-none bg-[url('/images/wines/bg-recommended.png')] bg-cover bg-repeat pt-[60px] tablet:rounded-b-none tablet:pt-[70px] pc:rounded-b-[88px] pc:pt-[70px]">
4544
<WineHeader wine={wine} />
4645
</section>
4746

48-
{/* 맛/향 섹션 */}
4947
<section className="mb-0 mt-12 bg-white tablet:mb-0 tablet:mt-16 pc:mb-12 pc:mt-16">
5048
<div className="container">
5149
<div className="flex flex-col gap-12 tablet:gap-20 pc:flex-row pc:gap-32">
@@ -66,12 +64,10 @@ const WineDetailContent = ({ wineId }: WineDetailContentProps) => {
6664
</div>
6765
</section>
6866

69-
{/* 구분선 */}
7067
<div className="container">
7168
<hr className="mt-[-5px] border-t border-gray-300 tablet:mt-0 pc:mt-0" />
7269
</div>
7370

74-
{/* 리뷰 섹션 */}
7571
<section className="bg-white pb-12 pt-14 tablet:pt-14 pc:pt-14">
7672
<div className="container">
7773
<ReviewSection

src/app/wines/[id]/_components/wine-review-form/review-form.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export default function ReviewForm({
3838
image: wineImage,
3939
} = wine;
4040

41-
// 상태 관리
4241
const [rating, setRating] = useState(0);
4342
const [content, setContent] = useState("");
4443
const [selectedAromas, setSelectedAromas] = useState<AromaKey[]>([]);
@@ -68,7 +67,6 @@ export default function ReviewForm({
6867
}
6968
}, [initialData]);
7069

71-
// 맛 변경 핸들러
7270
const handleTasteChange = (index: number, newLevel: GaugeLevel) => {
7371
const newTastes = [...tastes];
7472
newTastes[index].data = newLevel;
@@ -114,7 +112,6 @@ export default function ReviewForm({
114112

115113
if (hasError) return;
116114

117-
// 데이터 생성
118115
const reviewData: ReviewBase = {
119116
rating,
120117
lightBold: tastes[0].data,
@@ -140,15 +137,12 @@ export default function ReviewForm({
140137
className
141138
)}
142139
>
143-
{/* 모든 컨텐츠 */}
144140
<div className="flex flex-col gap-8">
145-
{/* 와인 정보 */}
146141
<div>
147142
<WineInfo name={wineName} region={wineRegion} image={wineImage} />
148143
<div className="mt-4 border-t border-gray-300" />
149144
</div>
150145

151-
{/* 별점 선택 */}
152146
<div className="flex items-center gap-4">
153147
<label className="text-body-sm text-gray-500">별점 선택</label>
154148
<RatingInput
@@ -158,7 +152,6 @@ export default function ReviewForm({
158152
/>
159153
</div>
160154

161-
{/* 후기 입력 */}
162155
<div>
163156
<textarea
164157
value={content}
@@ -189,7 +182,6 @@ export default function ReviewForm({
189182
</div>
190183
</div>
191184

192-
{/* 와인의 맛 */}
193185
<div>
194186
<label className="mb-4 block text-heading-md">
195187
와인의 맛은 어떤가요?
@@ -201,7 +193,6 @@ export default function ReviewForm({
201193
/>
202194
</div>
203195

204-
{/* 향 선택 */}
205196
<div className="tablet:pb-12 pc:pb-12">
206197
<label className="mb-4 block text-heading-md">
207198
기억에 남는 향이 있나요?
@@ -219,7 +210,6 @@ export default function ReviewForm({
219210
</div>
220211
</div>
221212

222-
{/* 버튼 */}
223213
<PageModalBtnWrapper>
224214
<Button
225215
onClick={handleSubmit}

0 commit comments

Comments
 (0)