gather-here / gather_here

λ‚΄λ°°μΊ  React-5κΈ° μ΅œμ’…ν”„λ‘œμ νŠΈ B-12μ‘°
https://www.gatherhere.dev/all
Other
0 stars 5 forks source link

πŸ’» @gather_here

gather_here λŒ€ν‘œμ΄λ―Έμ§€

πŸ“– μ†Œκ°œ 및 κ°œμš”

frontend μ„œλΉ„μŠ€ μ†Œκ°œ frontend

πŸ† μš°μˆ˜μƒ μˆ˜μƒ - [내일배움캠프 React 5κΈ°] (2024)

Group 4


✨ @gather_here κ΅¬κ²½ν•˜κΈ°

λͺ©μ°¨ - [νŒ€ μ†Œκ°œ](#teamintro) - [아킀텍쳐](#architecture) - [ERD](#erd) - [μ£Όμš” 기술](#skill) - [기술적 μ˜μ‚¬κ²°μ •](#technical) - [ν”„λ‘œμ νŠΈ ꡬ쑰](#structure) - [UI](#ui) - [νŠΈλŸ¬λΈ”μŠˆνŒ…](#troubleshooting)

1.πŸ“’ νŒ€ μ†Œκ°œ

μ•ˆλ…•ν•˜μ„Έμš”! 5λͺ…μ˜ ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμžμ™€ 1λͺ…μ˜ λ””μžμ΄λ„ˆλ‘œ κ΅¬μ„±λœ κ²Œλ” νžˆμ–΄νŒ€μž…λ‹ˆλ‹€.
`κ²Œλ” νžˆμ–΄`λŠ” 각기 λ‹€λ₯Έ μ—­λŸ‰μ„ 가진 μš°λ¦¬κ°€ λͺ¨μ—¬, ν˜‘μ—…μ˜ μ‹œλ„ˆμ§€λ₯Ό κ·ΉλŒ€ν™” μ‹œν‚¨λ‹€ λΌλŠ” 의미λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€.
항상 μƒˆλ‘œμš΄ κ°€λŠ₯성을 λ°œκ²¬ν•˜λŠ” νŒ€μž…λ‹ˆλ‹€! 🀲πŸ”₯

πŸ‘‘κΉ€μ˜λ²” πŸ’»μ‘°μ€μ˜ πŸ”Žμ΄ν•˜λ¦„ πŸ’‘κΉ€μ„±μ€€ πŸͺ„이보아 πŸŽ¨μ „μ •ν˜„
Team%20Leader FrontEnd Deputy%20Leader FrontEnd Development%20Leader FrontEnd WorkManagement FrontEnd Communication%20Leader FrontEnd Design%20Leader Designer
μ˜€ν”ˆμ±„νŒ…
μΊ˜λ¦°λ”
(행사 일정)
IT 행사
검색기λŠ₯
κΈ€μž‘μ„± νŽ˜μ΄μ§€
λ””ν…ŒμΌ νŽ˜μ΄μ§€
뢁마크
메인 νŽ˜μ΄μ§€
μŠ¬λΌμ΄λ“œ
λ””μžμΈ QA
적용
μ†Œμ…œ 둜그인
둜그인 섀문폼
λ§ˆμ΄νŽ˜μ΄μ§€
λ°˜μ‘ν˜• 해더
곡톡 μ»΄ν¬λ„ŒνŠΈ
λ””μžμΈκ΄€λ ¨
μ†Œν†΅
μ›Ή λ””μžμΈ
λͺ¨λ°”일 λ””μžμΈ
μ»΄ν¬λ„ŒνŠΈ
둜고 μ œμž‘
github:
kubap
github:
Eunyoung
github:
Hareum
github:
SungJoon
github:
Boa
blog:
Junghyun

2. πŸ—Β μ•„ν‚€ν…μ³

image

3. πŸ“šΒ ERD

image

4.πŸ€μ£Όμš” 기술

둜그인 - μ†Œμ…œλ‘œκ·ΈμΈ(ꡬ글, 카카였, κΉƒν—ˆλΈŒ)으둜 κ°„νŽΈν•˜κ²Œ λ‘œκ·ΈμΈμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. - 처음 μ†Œμ…œλ‘œκ·ΈμΈμ„ ν•˜λŠ” μœ μ €λŠ” κ°„λ‹¨ν•œ 정보λ₯Ό λ°›μŠ΅λ‹ˆλ‹€. - 이미 ν•œλ²ˆ 정보λ₯Ό λ°›μ•˜λ˜ 기쑴의 μœ μ €μ˜ κ²½μš°μ— μ†Œμ…œλ‘œκ·ΈμΈμ„ ν•˜κ²Œλ˜λ©΄ λ°”λ‘œ λ©”μΈνŽ˜μ΄μ§€λ‘œ μ΄λ™ν•©λ‹ˆλ‹€. - μ΄λŸ¬ν•œ μ ˆμ°¨κ°€ 번거둭게 λŠκ»΄μ§€λŠ” μœ μ €λ“€μ„ μœ„ν•œ κ±΄λ„ˆλ›°κΈ° κΈ°λŠ₯은 νšŒμ›μ—κ²Œ default dataλ₯Ό μ£Όμ–΄μ„œ λ‚˜μ€‘μ— ν•„μš”μ‹œ λ§ˆμ΄νŽ˜μ΄μ§€μ—μ„œ λ”°λ‘œ 정보λ₯Ό μΆ”κ°€ν•  수 있게 λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. - κ°„λ‹¨ν•œ 정보λ₯Ό λ°›λŠ” λ§ˆμ§€λ§‰ λ‹¨κ³„λ‘œμ„œ λ‹‰λ„€μž„μ€ ν•„μˆ˜λ‘œ λ°›μœΌλ©°, 쀑볡체크와 곡백체크λ₯Ό ν•©λ‹ˆλ‹€. - 포트폴리였 μ£Όμ†Œλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ URL은 μ„ νƒμ‚¬ν•­μœΌλ‘œμ„œ μž‘μ„±ν•˜μ§€ μ•Šκ³  λ„˜μ–΄κ°€λ©΄ λ‹€μ‹œ ν•œ 번 μ•Œλ¦Όμ°½μœΌλ‘œ 확인을 거치고 λ‚˜μ„œ ν”„λ‘œν•„ μ €μž₯을 ν•  수 있게 λ©λ‹ˆλ‹€. - ν”„λ‘œν•„ μ €μž₯을 ν†΅ν•΄μ„œ μ΅œμ’…μ μœΌλ‘œ DB에 μœ μ €μ˜ 정보가 μ €μž₯되면 λ§ˆμ§€λ§‰ WelcomeνŽ˜μ΄μ§€λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
곡고 메인 - 검색기λŠ₯ - 전체 / μŠ€ν„°ν‹° / ν”„λ‘œμ νŠΈ / IT행사 λΆ„λ₯˜ - κ²Œμ‹œλ¬Ό 리슀트 : IT행사λ₯Ό μ œμ™Έν•œ λͺ¨λ“  νƒ­μ˜ 전체 κ²Œμ‹œλ¬Όμ„ μ΅œμ‹ κΈ€ 순으둜 λ³΄μ—¬μ€Œ - μ‚¬μ΄λ“œ μš”μ†Œ - μΊ˜λ¦°λ” : 행사가 μžˆλŠ” 일자λ₯Ό ν‘œμ‹œν•΄μ£Όκ³ , ν•΄λ‹Ή 포인터λ₯Ό ν΄λ¦­ν•˜λ©΄ 미리보기둜 정보λ₯Ό 보여주고, ν† κΈ€λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ 행사일정이 리슀트둜 λ³΄μ—¬μ§€κ²Œ λ©λ‹ˆλ‹€. - μ˜€ν”ˆν†‘ : λ‘œκ·ΈμΈν•œ λͺ¨λ“  μœ μ €λ“€μ΄ μ°Έμ—¬ν•  수 μžˆλŠ” μ±„νŒ…λ°©μž…λ‹ˆλ‹€. - μŠ€ν„°λ”” / ν”„λ‘œμ νŠΈ / IT행사 νŽ˜μ΄μ§€μ—μ„œλŠ” λ§ˆκ°μž„λ°•ν•œ κ²Œμ‹œλ¬Όμ„ μΊλŸ¬μ…€λ‘œ λ³΄μ—¬μ€Œ - 직ꡰ / 방식 / 지역 / κΈ°κ°„ ν•„ν„°λ‘œ μ‚¬μš©μžκ°€ μ›ν•˜λŠ” κΈ€λ§Œ μ„ νƒν•˜μ—¬ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
κΈ€ μž‘μ„± νŽ˜μ΄μ§€ - μ‚¬μš©μžκ°€ μ‚¬λžŒμ„ κ΅¬ν•˜κ³  싢은 μŠ€ν„°λ””/ ν”„λ‘œμ νŠΈλ₯Ό μ›ν•˜λŠ” 직ꡰ, μŠ€νƒ 등에 맞게 μ„ νƒν•˜μ—¬ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. - μž„μ‹œμ €μž₯ κΈ°λŠ₯을 κ΅¬ν˜„ν•΄ μœ μ €κ°€ κΈ€μ“°κΈ° ν™”λ©΄μ—μ„œ μ΄νƒˆν•΄μ•Ό ν•  경우 μž„μ‹œμ €μž₯ λ²„νŠΌμ„ λˆ„λ₯Έλ‹€λ©΄ 이후에 κΈ€μ“°κΈ° νŽ˜μ΄μ§€μ— λ“€μ–΄μ™”μ„λ•Œ ν•΄λ‹Ή μ‹œμ μ˜ 데이터λ₯Ό λ‹€μ‹œ 뢈러올 수 있게 ν–ˆμŠ΅λ‹ˆλ‹€. - 본인이 μ“΄ κΈ€μ—μ„œ μˆ˜μ •ν•˜κΈ° λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ μž‘μ„±ν–ˆλ˜ ν•„λ“œκ°’ κ·ΈλŒ€λ‘œ λ‹€μ‹œ μž‘μ„± νŽ˜μ΄μ§€μ—μ„œ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
곡고 μƒμ„ΈνŽ˜μ΄μ§€ - 상세 νŽ˜μ΄μ§€μ—μ„œ ν™•μΈν•˜κ³  싢은 곡고의 상세 정보듀을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. - κ³΅μœ ν•˜κΈ° λ²„νŠΌμœΌλ‘œ url 볡사λ₯Ό, 뢁마크 λ²„νŠΌμœΌλ‘œ 관심글 μ €μž₯을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. - 본인이 μ“΄ 글인 경우 뢁마크 μ˜†μ— λ²„νŠΌμ„ λ”°λ‘œ λ§Œλ“€μ–΄ κ²Œμ‹œκΈ€ μˆ˜μ •, μ‚­μ œκ°€ κ°€λŠ₯ν•˜κ²Œ ν–ˆμŠ΅λ‹ˆλ‹€. - 본인이 μ“΄ 글이 아닐 경우 ν•΄λ‹Ή λ²„νŠΌμ€ λ…ΈμΆœλ˜μ§€ μ•Šκ²Œ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
행사 메인 - 행사 정보쀑 마감이 μž„λ°•ν•œ 행사λ₯Ό μƒλ‹¨μ—μ„œ μŠ¬λΌμ΄λ“œλ‘œ λ³Ό 수 있게 κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. - 행사 정보λ₯Ό 리슀트 ν˜•μ‹μœΌλ‘œ νŽΈν•˜κ²Œ λ³Ό 수 μžˆλ“œλ‘ κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
행사 상세 - 상세 νŽ˜μ΄μ§€μ—μ„œ ν₯λ―ΈμžˆλŠ” ν–‰μ‚¬μ˜ 상세 정보λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. - κ³΅μœ ν•˜κΈ° λ²„νŠΌμœΌλ‘œ url 볡사λ₯Ό, 뢁마크 λ²„νŠΌμœΌλ‘œ 관심글 μ €μž₯을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. - μ‹ μ²­ν•˜κΈ° λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ ν•΄λ‹Ή μ‚¬μ΄νŠΈμ˜ μ‹ μ²­ νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•©λ‹ˆλ‹€.
λ§ˆμ΄νŽ˜μ΄μ§€ - λ§ˆμ΄νŽ˜μ΄μ§€ λ„€λΉ„κ²Œμ΄μ…˜ - λ§ˆμ΄νŽ˜μ΄μ§€ 내에 λ”°λ‘œ λ„€λΉ„κ²Œμ΄μ…˜μ΄ μžˆμ–΄, λ§ˆμ΄νŽ˜μ΄μ§€ 정보λ₯Ό νŽΈν•˜κ²Œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. - ν”„λ‘œν•„ 사진 μˆ˜μ • - 직ꡰ별 μ•„μ΄μ½˜μœΌλ‘œ μ„€μ • : `gather_here`만의 9개의 직ꡰ μ•„μ΄μ½˜μœΌλ‘œ ν”„λ‘œν•„ 사진 섀정이 κ°€λŠ₯ν•©λ‹ˆλ‹€. - ν”„λ‘œν•„ λ³€κ²½ : μ‚¬μš©μžκ°€ μ›ν•˜λŠ” ν”„λ‘œν•„ μ‚¬μ§„μœΌλ‘œλ„ μ„€μ • κ°€λŠ₯ν•©λ‹ˆλ‹€. - 내정보 μˆ˜μ • - νšŒμ›κ°€μž…μ‹œ μž…λ ₯ν•œ 정보 μˆ˜μ • : νšŒμ›κ°€μž…μ‹œ μž…λ ₯ν•œ 정보λ₯Ό μ–Έμ œλ“ μ§€ μˆ˜μ • κ°€λŠ₯ν•©λ‹ˆλ‹€. - λ‚΄ μž‘μ„±κΈ€ - λ‚΄ μž‘μ„±κΈ€ 확인 : λ‚΄ μž‘μ„±κΈ€μ„ ν•œλˆˆμ— λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. - λ‚΄ μž‘μ„±κΈ€ μˆ˜μ •, μ‚­μ œ : λ‚΄ μž‘μ„±κΈ€ μΉ΄λ“œλ₯Ό ν˜Έλ²„ν•˜λ©΄ μˆ˜μ •λ²„νŠΌ, μ‚­μ œλ²„νŠΌμ΄ λ‚˜νƒ€λ‚˜, λ°”λ‘œ μˆ˜μ •,μ‚­μ œ κ°€λŠ₯ν•©λ‹ˆλ‹€. - λ‚΄ 관심글 - λ‚΄ 관심글 확인 : λ‚΄κ°€ λΆλ§ˆν¬ν•œ κ²Œμ‹œκΈ€μ„ μŠ€ν„°λ””/ ν”„λ‘œμ νŠΈ / IT 행사 λ³„λ‘œ ν•œλˆˆμ— λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

5.🧩 기술적 μ˜μ‚¬κ²°μ •

ν”„λ ˆμž„μ›Œν¬

Next.jsλŠ” νŽ˜μ΄μ§€ κ°„ μ½”λ“œλ₯Ό μžλ™μœΌλ‘œ λΆ„ν• ν•˜μ—¬ 초기 λ‘œλ”© μ‹œκ°„μ„ μ€„μ—¬μ€λ‹ˆλ‹€. 특히, Next.js의 App RouterλŠ” μ„œλ²„ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ§€μ›ν•˜λ©°, κΈ°μ‘΄ νŽ˜μ΄μ§€ λΌμš°ν„°λ³΄λ‹€ 더 μœ μ—°ν•˜κ³  λ‹€μ–‘ν•œ κΈ°λŠ₯을 μ œκ³΅ν•΄μ€λ‹ˆλ‹€. μ‹€μ‹œκ°„ 데이터 톡신이 μ€‘μš”ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” 이 κΈ°λŠ₯듀이 μ„±λŠ₯ μ΅œμ ν™”μ— 큰 도움이 λ©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 이유둜, 동적인 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” 데 μ΅œμ ν™”λœ Next.js App Routerλ₯Ό ν”„λ ˆμž„μ›Œν¬λ‘œ μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

μƒνƒœ 관리

Zustandλ₯Ό μ„ νƒν•œ μ΄μœ λŠ” κ°„λ‹¨ν•œ μ„€μ •κ³Ό 직관적인 μ½”λ“œλ‘œ λΉ λ₯΄κ³  μ‰½κ²Œ μƒνƒœ 관리λ₯Ό κ΅¬ν˜„ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. ZustandλŠ” μ „μ—­ μƒνƒœμ™€ 둜컬 μƒνƒœλ₯Ό μœ μ—°ν•˜κ²Œ 관리할 수 μžˆμ–΄ λ³΅μž‘ν•œ μƒνƒœ 관리 κ΅¬μ‘°μ—μ„œλ„ νš¨μœ¨μ μž…λ‹ˆλ‹€. React μ™Έμ˜ ν™˜κ²½μ—μ„œλ„ 적용 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— ν™•μž₯μ„±κ³Ό μœ μ—°μ„±μ„ λ™μ‹œμ— μ œκ³΅ν•©λ‹ˆλ‹€.

Context APIλŠ” ν”„λ‘œμ νŠΈμ—μ„œ users ν…Œμ΄λΈ”μ˜ 정보λ₯Ό μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈμ—μ„œ κ³΅μœ ν•΄μ•Ό ν–ˆκΈ° λ•Œλ¬Έμ— μ „μ—­ μƒνƒœ 관리 λ„κ΅¬λ‘œ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. μ™ΈλΆ€ 라이브러리 없이 κ°„λ‹¨ν•˜κ²Œ μ„€μ •ν•  수 있으며, νŠΉμ • μ»΄ν¬λ„ŒνŠΈ 트리 λ‚΄μ—μ„œ μƒνƒœλ₯Ό κ³΅μœ ν•˜κ³  μ—…λ°μ΄νŠΈν•˜λŠ” 데 맀우 μ ν•©ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ λ³΅μž‘μ„±μ„ 쀄이고 데이터 κ΄€λ¦¬μ˜ 일관성을 μœ μ§€ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ°μ΄ν„°λ² μ΄μŠ€

SupabaseλŠ” λ°±μ—”λ“œ ꡬ성에 ν•„μš”ν•œ μ‹œκ°„μ„ 크게 λ‹¨μΆ•μ‹œμΌœμ€λ‹ˆλ‹€. λ˜ν•œ μ‹€μ‹œκ°„ 데이터 동기화 κΈ°λŠ₯κ³Ό λ‹€μ–‘ν•œ λ°μ΄ν„°λ² μ΄μŠ€ κΈ°λŠ₯을 μ œκ³΅ν•˜μ—¬ 생산성과 κΈ°λŠ₯성을 λ™μ‹œμ— 확보할 수 μžˆμŠ΅λ‹ˆλ‹€. ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμžκ°€ λ°±μ—”λ“œ ꡬ성에 μ‰½κ²Œ μ ‘κ·Όν•  수 μžˆλ„λ‘ λ„μ™€μ£ΌλŠ” Supabaseλ₯Ό μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

μŠ€νƒ€μΌλ§

Tailwind CSSλŠ” 좔가적인 CSS 파일 없이도 μœ μ§€λ³΄μˆ˜κ°€ μš©μ΄ν•˜λ©°, 직관적인 클래슀 λ„€μ΄λ°μœΌλ‘œ λΉ λ₯Έ μŠ€νƒ€μΌλ§μ„ μ§€μ›ν•©λ‹ˆλ‹€. 쑰건뢀 μŠ€νƒ€μΌλ§μ΄ 쉽고, Next.jsμ™€μ˜ ν˜Έν™˜μ„±λ„ λ›°μ–΄λ‚˜κΈ° λ•Œλ¬Έμ— 효율적인 κ°œλ°œμ„ μœ„ν•΄ μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

ν˜‘μ—… 도ꡬ

GitHubλŠ” λΆ„μ‚°λœ νŒ€ ν™˜κ²½μ—μ„œ 효율적인 버전 관리와 ν˜‘μ—…μ„ κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€. CI/CD 톡합, μ˜€ν”ˆμ†ŒμŠ€ μƒνƒœκ³„, μ½”λ“œ 리뷰 및 이슈 관리 κΈ°λŠ₯을 톡해 개발 μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ΅œμ ν™”ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

FigmaλŠ” μ‹€μ‹œκ°„ ν˜‘μ—…κ³Ό λ””μžμΈ μ‹œμŠ€ν…œ 관리λ₯Ό μ§€μ›ν•˜λŠ” κ°•λ ₯ν•œ UI/UX λ„κ΅¬μž…λ‹ˆλ‹€. ν΄λΌμš°λ“œ 기반으둜 μ–Έμ œ μ–΄λ””μ„œλ‚˜ 접근이 κ°€λŠ₯ν•˜λ©°, λ””μžμ΄λ„ˆμ™€ 개발자 κ°„ μ›ν™œν•œ ν˜‘μ—…μ„ 도와 λ””μžμΈ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ΅œμ ν™”ν•©λ‹ˆλ‹€.

ExcalidrawλŠ” μ†μœΌλ‘œ κ·Έλ¦° λ“―ν•œ 직관적인 λ‹€μ΄μ–΄κ·Έλž¨ μž‘μ„± λ„κ΅¬λ‘œ, μ‹€μ‹œκ°„ ν˜‘μ—… κΈ°λŠ₯을 톡해 아이디어λ₯Ό λΉ λ₯΄κ²Œ μ‹œκ°ν™”ν•˜κ³  κ³΅μœ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ˜€ν”ˆμ†ŒμŠ€μ΄κΈ° λ•Œλ¬Έμ— 자유둭게 μ‚¬μš©ν•˜κ³  ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

개발 μ–Έμ–΄

TypeScriptλŠ” νƒ€μž… μ§€μ •μœΌλ‘œ 인해 μ½”λ“œμ˜ μ•ˆμ •μ„±μ„ λ†’μ—¬μ£Όκ³ , λŸ°νƒ€μž„ 였λ₯˜λ₯Ό μ€„μ—¬μ€λ‹ˆλ‹€. μžλ™μ™„μ„± κΈ°λŠ₯κ³Ό νƒ€μž… 기반 검증 덕뢄에 ν˜‘μ—… μ‹œ 개발 생산성을 크게 ν–₯μƒμ‹œν‚΅λ‹ˆλ‹€. μ½”λ“œμ˜ μ•ˆμ „μ„±κ³Ό μœ μ§€λ³΄μˆ˜μ„± μΈ‘λ©΄μ—μ„œ TypeScriptλ₯Ό μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

배포 μ„œλΉ„μŠ€

Vercel은 λΉ λ₯΄κ³  κ°„νŽΈν•œ 배포λ₯Ό μ§€μ›ν•˜λ©°, μ„œλ²„λ¦¬μŠ€ ν™˜κ²½μ—μ„œ μžλ™μœΌλ‘œ μŠ€μΌ€μΌλ§λ˜μ–΄ μ„±λŠ₯이 μš°μˆ˜ν•©λ‹ˆλ‹€. Next.jsμ™€μ˜ μ™„λ²½ν•œ 톡합을 톡해 μ΅œμ‹  μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ†μ‰½κ²Œ 개발, 배포, μ΅œμ ν™”ν•  수 μžˆμ–΄ 개발자 κ²½ν—˜μ„ κ·ΉλŒ€ν™”ν•©λ‹ˆλ‹€.

6.πŸ“¦ν”„λ‘œμ νŠΈ ꡬ쑰

β”œβ”€ public
β”‚  β”œβ”€ assets
β”‚  β”‚  β”œβ”€ gif
β”‚  β”‚  β”œβ”€ header
β”‚  β”‚  β”œβ”€ mypage
β”‚  β”‚  β”œβ”€ arrowsmall.svg
β”‚  β”‚  β”œβ”€ back.svg
β”‚  β”‚  β”œβ”€ blank.svg
β”‚  β”‚  β”œβ”€ cardarrow.svg
β”‚  β”‚  β”œβ”€ delete.svg
β”‚  β”‚  β”œβ”€ down.svg
β”‚  β”‚  β”œβ”€ toastcancel.svg
β”‚  β”‚  β”œβ”€ toastcheck.svg
β”‚  β”‚  └─ top.svg
β”‚  β”œβ”€ Calender
β”‚  β”œβ”€ Chat
β”‚  β”œβ”€ Common
β”‚  β”œβ”€ Detail
β”‚  β”œβ”€ Favicon
β”‚  β”œβ”€ logos
β”‚  β”œβ”€ Main
β”‚  β”œβ”€ MyPage
β”‚  └─ Post
β”œβ”€ src
β”‚  β”œβ”€ app
β”‚  β”‚  β”œβ”€ (auth)
β”‚  β”‚  β”œβ”€ (mainpage)
β”‚  β”‚  β”œβ”€ api
β”‚  β”‚  β”œβ”€ eventsdetail
β”‚  β”‚  β”œβ”€ maindetail
β”‚  β”‚  β”œβ”€ mypage
β”‚  β”‚  β”œβ”€ post
β”‚  β”‚  β”œβ”€ favicon.ico
β”‚  β”‚  β”œβ”€ globals.css
β”‚  β”‚  β”œβ”€ layout.tsx
β”‚  β”‚  β”œβ”€ not-found.tsx
β”‚  β”‚  └─ page.tsx
β”‚  β”œβ”€ assets
β”‚  β”‚  β”œβ”€ loadingBar.json
β”‚  β”‚  └─ loadingSpinner.json
β”‚  β”œβ”€ components
β”‚  β”‚  β”œβ”€ Common
β”‚  β”‚  β”œβ”€ EventsDetail
β”‚  β”‚  β”œβ”€ Layout
β”‚  β”‚  β”œβ”€ Login
β”‚  β”‚  β”œβ”€ MainDetail
β”‚  β”‚  β”œβ”€ MainPage
β”‚  β”‚  β”œβ”€ MyPage
β”‚  β”‚  β”œβ”€ Post
β”‚  β”‚  └─ Signup
β”‚  β”œβ”€ fonts
β”‚  β”œβ”€ hooks
β”‚  β”œβ”€ lib
β”‚  β”œβ”€ provider
β”‚  β”œβ”€ store
β”‚  β”œβ”€ types
β”‚  β”œβ”€ utils
β”‚  β”œβ”€ middleware.ts
β”‚  β”œβ”€ supabase
β”‚  β”œβ”€ .env.local
β”‚  β”œβ”€ .eslintrc.json
β”‚  β”œβ”€ .gitignore
β”‚  β”œβ”€ .nvmrc
β”‚  β”œβ”€ .prettierrc
β”‚  β”œβ”€ next-env.d.ts
β”‚  β”œβ”€ next.config.mjs
β”‚  β”œβ”€ package-lock.json
β”‚  β”œβ”€ package.json
β”‚  β”œβ”€ postcss.config.mjs
β”‚  β”œβ”€ README.md
β”‚  β”œβ”€ tailwind.config.ts
β”‚  └─ tsconfig.json

7. 🎨 UI

μ‹œμž‘ν•˜κΈ°, λ©”μΈνŽ˜μ΄μ§€ κ²Œμ‹œλ¬Ό 리슀트

ν”„λ‘œμ νŠΈ κ²°κ³Ό 1

IT 행사, λ©”μΈνŽ˜μ΄μ§€ μ±„νŒ…, PR μ„Ήμ…˜

ν”„λ‘œμ νŠΈ κ²°κ³Ό 2 ν”„λ‘œμ νŠΈ κ²°κ³Ό 3

λ§ˆμ΄νŽ˜μ΄μ§€

ν”„λ‘œμ νŠΈ κ²°κ³Ό 4

8.πŸ”¨ νŠΈλŸ¬λΈ” μŠˆνŒ…

react-select둜 닀쀑 선택을 κ΅¬ν˜„ν•˜λ©° server와 client의 idκ°€ λ‹€λ₯Έ 이슈

이슈 λ°œμƒ

ν•΄κ²°μ±…

둜그인 ν›„ signupFormμ—μ„œ DB에 정보저μž₯ 없이 νƒˆμΆœν•˜λ©΄ μƒκΈ°λŠ” 이슈

이슈 λ°œμƒ

ν•΄κ²°μ±…

Next.js 배포 ν›„ λ°œμƒν•œ hydration 였λ₯˜

이슈 λ°œμƒ

ν•΄κ²°μ±…

const ItEventCardLong: NextPage<EventsCardProps> = ({ post }) => {
  const deadlineDate = new Date(post.date_done);
  const daysLeft = Math.ceil(
    (deadlineDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)
  );
  const displayDaysLeft = daysLeft === 0 ? "D-day" : `D-${daysLeft}`;

  return (
    <ul className="flex items-center">
      <li>
        <span className="label-secondary rounded-full text-baseS  px-3 py-1.5 mr-1">
          {displayDaysLeft}
        </span>
      </li>
      <li className="text-baseS  text-labelNormal ml-2">
        <time dateTime="YYYY-MM-DD">
          {dayjs(post.date_start).format("YYYY-MM-DD")}
        </time>
      </li>
    </ul>
  );
};
const ItEventCardShort: NextPage<EventsCardProps> = ({ post }) => {
  const { user: currentUser } = useUser();
  const [isClient, setIsClient] = useState<boolean>(false);
  const today = dayjs();
  const deadlineDate = dayjs(post.date_done);
  // const daysLeft = Math.ceil((deadlineDate.unix() - now.unix()) / (1000 * 60 * 60 * 24));
  const daysLeft = today.diff(deadlineDate, "d", true);
  const displayDaysLeft =
    daysLeft === 0 ? "D-day" : daysLeft < 0 ? `D${daysLeft.toFixed(0)}` : `D+${Math.ceil(daysLeft)}`;

  useEffect(() => {
    setIsClient(true);

    return () => {
      setIsClient(false);
    };
  }, []);

  return (
    {isClient ? (
        <ul className="flex justify-between items-center">
        <li>
            <span className="label-secondary rounded-full text-baseS px-3 py-1.5">{displayDaysLeft}</span>
        </li>
        <li>
            <time dateTime={post.date_done} className="text-baseS text-labelNormal">
            {dayjs(post.date_done).format("YYYY-MM-DD")}
            </time>
        </li>

        <LikeButton eventId={post.event_id} currentUser={currentUser} />
        </ul>
) : null})
}