Skip to content
Merged

Dev #32

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7d914d0
style(ui): improve character save card and fix login name persist
Hyunseong0303 Feb 28, 2026
c18e23c
docs: update PR template with card UI and login logic changes
Hyunseong0303 Feb 28, 2026
cac8fa1
Merge remote-tracking branch 'origin/dev' into feature/ui-save-card-iโ€ฆ
Hyunseong0303 Feb 28, 2026
9a52c32
fix(ui): dynamically bind character avatarUrl instead of hardcoding dโ€ฆ
Hyunseong0303 Feb 28, 2026
f1eb5e9
merge: resolve PR #27 conflicts with latest dev
ark1st Mar 1, 2026
2001484
feat: add paginated character and settlement API clients
ark1st Mar 1, 2026
0bb920a
feat: implement infinite scroll for member and settlement lists
ark1st Mar 1, 2026
d2b98c2
Merge pull request #27 from GC-MapleWind/feature/ui-save-card-improve
ark1st Mar 1, 2026
1dfcaee
Merge pull request #29 from GC-MapleWind/feat/pagination-infinite-sync
ark1st Mar 1, 2026
68c0437
Merge branch 'dev' into feature/ui-save-card-improve: Resolve conflicts
Hyunseong0303 Mar 1, 2026
0528ec9
Fix: Restore CharacterCard image size and original layout while keepiโ€ฆ
Hyunseong0303 Mar 1, 2026
9875e18
Revert CharacterCard to origin/dev state
Hyunseong0303 Mar 1, 2026
75a6892
feat: Apply requested UI updates for frontend
Hyunseong0303 Mar 1, 2026
a203ed8
docs: Update PR template with recent UI changes
Hyunseong0303 Mar 1, 2026
6eb709c
chore: Remove debug temporary login info
Hyunseong0303 Mar 1, 2026
c769969
chore: add new icons for UI
Hyunseong0303 Mar 1, 2026
4af46b5
docs: overwrite PR template with new session details
Hyunseong0303 Mar 1, 2026
0d8ed8f
fix: resolve PR review comments and improve asset naming
Hyunseong0303 Mar 1, 2026
aaeb193
style: ensure original aspect ratio for team message images
Hyunseong0303 Mar 1, 2026
acc9778
feat: add SEO meta tags and use thumbnail.png as og:image
Hyunseong0303 Mar 1, 2026
21c3cd2
feat: update favicon to MSGS_Favicon.ico
Hyunseong0303 Mar 1, 2026
93f5cd2
fix: fallback settlements loading and preserve team message line breaks
ark1st Mar 1, 2026
50899c3
refactor: clean up static directory and normalize icon filenames
Hyunseong0303 Mar 1, 2026
9511ada
Merge pull request #31 from GC-MapleWind/fix/member-page-fallback-andโ€ฆ
ark1st Mar 1, 2026
9b98a8d
docs: update pull request template
Hyunseong0303 Mar 1, 2026
a69e7a7
chore: commit changes before pulling dev
Hyunseong0303 Mar 1, 2026
7b8e188
fix: resolve merge conflict and fix syntax error in team-message page
Hyunseong0303 Mar 1, 2026
6296dd6
chore: clean up temporary build and check files
Hyunseong0303 Mar 1, 2026
d6a5869
Merge pull request #30 from GC-MapleWind/feature/frontend-ui-updates
ark1st Mar 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 19 additions & 26 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
## ๐Ÿ“‹ ์ž‘์—… ๋‚ด์šฉ
- **์ž์ฒด SVG ์•„์ด์ฝ˜ ๋ Œ๋”๋ง ์ ์šฉ**: `Lucide` ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถ€๋ถ„ ์ œ๊ฑฐํ•˜๊ณ , ์ž์ฒด ์—์…‹(`static/images/icons/`)์„ ์ด์šฉํ•ด ํ—ค๋”, ํ†ก ํŽ˜์ด์ง€, ๋กœ๊ทธ์ธ ๋ชจ๋‹ฌ ๋‚ด ์•„์ด์ฝ˜์„ ์ปค์Šคํ…€ SVG `<img>` ํƒœ๊ทธ๋กœ ์ „๋ฉด ๊ต์ฒด
- **๊ฒฐ์‚ฐ ๋‚ด์šฉ ๋ฐ ์šด์˜ํŒ€ ํ•œ๋งˆ๋”” ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ๋ณด์™„**: ๋ผ๋ฒจ ํ…์ŠคํŠธ(ํš๋“ ์ผ์ž, ์ง์ฑ…, ์ƒ์„ธ ๋‚ด์šฉ)์— ๊ณ ์ • ๋„ˆ๋น„(`w-[72px]`), ์ขŒ์ธก ์ •๋ ฌ, ์ค„๋ฐ”๊ฟˆ ๋ฐฉ์ง€(`whitespace-nowrap`), ์ถ•์†Œ ๋ฐฉ์ง€(`shrink-0`)๋ฅผ ์ ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ ๊ธธ์ด์— ๋”ฐ๋ฅธ UI ์ฐŒ๊ทธ๋Ÿฌ์ง ์™„๋ฒฝ ๋ฐฉ์ง€
- **๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก ๋„ค๋น„๊ฒŒ์ด์…˜(Top Bar) ๊ฐœ์„ **: ์ขŒ์ธก ๋’ค๋กœ ๊ฐ€๊ธฐ ์š”์†Œ์™€ ์šฐ์ธก ๋กœ๊ทธ์•„์›ƒ ๋ฒ„ํŠผ ์กด์žฌ ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ "๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก" ํƒ€์ดํ‹€์ด ํ™”๋ฉด ์ •์ค‘์•™์— ์œ„์น˜ํ•˜๋„๋ก `absolute text-center` ์ œ์–ด ๋ฐ ๋ฐฐ๊ฒฝ ๋ถ„๋ฆฌ
- **๋‹จํ’๋ฐ”๋žŒ ๋กœ๊ทธ์ธ ํŒ์—… ๋ฐ Input Box ์ ‘๊ทผ์„ฑ/UI ๊ฐ•ํ™”**:
- ์ด๋ฆ„/ํ•™๋ฒˆ `InputBox` ํฌ์ปค์Šค ์‹œ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ์ด์ค‘ ์•„์›ƒ๋ผ์ธ ๋ฒ„๊ทธ(`focus:outline-none focus:ring-0`) ์ œ๊ฑฐ ๋ฐ ๋‚ด๋ถ€ ๋ฐฐ๊ฒฝ์ƒ‰ ์œ ์ง€, ํ…Œ๋‘๋ฆฌ๋งŒ ์ „ํ™˜๋˜๋„๋ก ํ”ฝ์Šค
- ๋ชจ๋‹ฌ ํŒ์—… ์ƒ๋‹จ "๋‹จํ’๋ฐ”๋žŒ" ํ…์ŠคํŠธ ํƒ€์ดํ‹€์„ `logo-text-white.svg` ์ด๋ฏธ์ง€๋กœ ๊ต์ฒดํ•˜๊ณ  ๊ทธ๋ฆผ์ž ํšจ๊ณผ ์ œ๊ฑฐ ์š”์†Œ ๊ฐ„๊ฒฉ(Gap, Margin) ๋ฏธ์„ธ ์กฐ์ •
- ์ด๋ฆ„ ์ €์žฅ ์ปค์Šคํ…€ ์ฒดํฌ๋ฐ•์Šค(`<label>` ํ™•์žฅ) ์ ์šฉ์„ ํ†ตํ•œ ํด๋ฆญ ์ ‘๊ทผ์„ฑ(์ƒํ˜ธ์ž‘์šฉ) ํ† ๊ธ€ ์ด์Šˆ ํ•ด๊ฒฐ ๋ฐ `check-enable/disable.svg` ์ƒํƒœ ๋™๊ธฐํ™”
- **์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์ž„์‹œ ์ œ์™ธ**: ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ ์Šค์ฝ”ํ”„์—์„œ ์ œ์™ธ๋จ์— ๋”ฐ๋ผ ๋ชจ๋‹ฌ ๋ฐ ๋ฉ”์ธ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋‚ด Kauth ์—ฐ๋™ ๋กœ์ง๊ณผ ๊ด€๋ จ UI ๋ฒ„ํŠผ ์ „์ฒด ์ฃผ์„ ์ฒ˜๋ฆฌ
- **์šด์˜ํŒ€ ํ•œ๋งˆ๋”” ์ƒ์„ธ UI ๋™๊ธฐํ™”**: `team-message` ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์„ ๊ธฐ์กด ๊ฒฐ์‚ฐ ์ƒ์„ธ(`msg`) ํŽ˜์ด์ง€์™€ ์™„๋ฒฝํžˆ ํ†ต์ผ (ํฐ์ƒ‰ ์ปจํ…Œ์ด๋„ˆ ๋ฐฐ๊ฒฝ ๋ถ„๋ฆฌ, ํ•˜๋‹จ๋ถ€ ๊ฐ ์„น์…˜๋ณ„ ๊ฐ€๋กœ ๊ตฌ๋ถ„์„  ์ถ”๊ฐ€, ํŒจ๋”ฉ ๋ฐ ์—ฌ๋ฐฑ ์ˆ˜์น˜ ์ผ์น˜)
- **์‚ฌ์ด๋“œ๋ฐ” ํ‘ธํ„ฐ ๋””์ž์ธ ๊ฐœํŽธ**: ๊ธฐ์กด "๋ฉ”์ƒ๊ฒฐ์‚ฐ ๊ธฐ๋ก" ํƒ€์ดํ‹€ ํ…์ŠคํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ํ•˜๋‹จ์— ๋ณ„ ๋ชจ์–‘ ์•„์ด์ฝ˜(`Simbol Logo`)๊ณผ ์ „์ฒด ๊ธฐ๋ก ๊ธฐ๊ฐ„ ํ…์ŠคํŠธ๋งŒ ๋ณ‘๋ ฌ ๋ฐฐ์น˜ํ•˜์—ฌ ์‹ฌํ”Œํ•˜๊ฒŒ ๊ฐœ์„ 
- **๋กœ๊ทธ์ธ ํŒ์—… UI ๊ฐœ์„ **: ์ด๋ฆ„ ์ž…๋ ฅ ํผ ๋‚ด ๋ถˆํ•„์š”ํ•œ ๋งž์ถค๋ฒ• ๊ฒ€์‚ฌ(๋นจ๊ฐ„ ์ค„) ๋ฐ ์›น ๋ธŒ๋ผ์šฐ์ € ์ž๋™์™„์„ฑ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹จํ’๋ฐ”๋žŒ `InputBox` ์ปดํฌ๋„ŒํŠธ์— `spellcheck="false"`, `autocomplete="off"` ์ผ๊ด„ ์ ์šฉ
- **์šด์˜ํŒ€ ์ „์šฉ ๋ผ๋ฒจ๋ง ํ•„ํ„ฐ๋ง**: `member` ์บ๋ฆญํ„ฐ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ์บ๋ฆญํ„ฐ๊ฐ€ '์šด์˜ํŒ€'์ผ ๊ฒฝ์šฐ ๊ธฐ์กด์˜ "๋ ˆ๋ฒจ/์„œ๋ฒ„/์ง์—…" ์ž๋ฆฌ๊ฐ€ ์•„๋‹Œ **"13๊ธฐ / ๊ฐ€์ฒœ๋Œ€ํ•™๊ต / ์šด์˜ํŒ€"**์œผ๋กœ ๊ฐ•์ œ ํ‘œ์‹œ๋˜๋„๋ก ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ ๊ฐœ์„ 
- **๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก ๋””์ž์ธ ๊ฐœ์„ **: ํ†ก ํ•˜๋‹จ์˜ ์ „์†ก ๋ฒ„ํŠผ ํ™”์‚ดํ‘œ ์•„์ด์ฝ˜์„ ํฐ์ƒ‰ ํˆฌ๋ช… ๋ฒ„์ „(`Send, Color=White copy.svg`) ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ๊ต์ฒดํ•˜์—ฌ ๋ฐฐ๊ฒฝ ํ†ค์˜ค๋ฒ„ ๋ฐฉ์ง€ ๋ฐ ์‹œ์ธ์„ฑ ํ™•๋ณด
- **๋ฉ”์ธ ์บ๋ฆญํ„ฐ ์นด๋“œ ๋น„์œจ ์™„๋ฒฝ ๋ณต๊ตฌ**: ์ด์ „ ๋ณ‘ํ•ฉ ๋ฐ ๊ตฌ์กฐ ๋ณ€๊ฒฝ ๊ณผ์ •์—์„œ ํ›ผ์†๋๋˜ ์›๋ž˜ ์บ๋ฆญํ„ฐ ์„œํƒ ๋”ฉ ์ด๋ฏธ์ง€ CSS ๋น„์œจ ์†์„ฑ(`h-40 w-3/4 aspect-[5/6] object-cover`)๋“ค์„ ์›๋ž˜ ์ปค๋ฐ‹๋Œ€๋กœ ๋˜๋Œ๋ฆฌ๊ณ , ๊ฐ€์žฅ์ž๋ฆฌ๊ฐ€ ์„ ๋ช…ํ•˜๊ฒŒ ๋ Œ๋”๋ง๋˜๋„๋ก `image-rendering: pixelated`๋งŒ ํ•จ๊ป˜ ์ ์šฉ

## ๐ŸŽฏ ๊ด€๋ จ ์ด์Šˆ
Closes #(์ด์Šˆ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”)
- ์—†์Œ

## ๐Ÿค– ์‚ฌ์šฉํ•œ Prompt
- "์š”์ฒญํ•˜์‹  ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋˜ 13๊ฐœ์˜ SVG ์•„์ด์ฝ˜๋“ค์„ ๊ธฐ์กด Lucide ์•„์ด์ฝ˜ ๋Œ€์‹  ๊ฐ UI ์ปดํฌ๋„ŒํŠธ์— ์•Œ๋งž๊ฒŒ ๊ต์ฒด ๋ฐฐ์น˜ํ•ด๋ผ."
- "msg/[id] ํŽ˜์ด์ง€ ์ƒ์„ธ ๋‚ด์šฉ ๋ผ๋ฒจ์ด ์šฐ์ธก ๊ธด ํ…์ŠคํŠธ์— ์˜ํ•ด ์ฐŒ๊ทธ๋Ÿฌ์ง€์ง€ ์•Š๋„๋ก flex-shrink-0๋ฅผ ์ ์šฉํ•˜๊ณ , w-[72px] ๊ณ ์ • ๋„ˆ๋น„ ๋ฐ ํ…์ŠคํŠธ ์ขŒ์ธก ์ •๋ ฌ, ์ค„๋ฐ”๊ฟˆ ๋ฐฉ์ง€๋ฅผ ๊ฑธ์–ด๋ผ."
- "๋กœ๊ทธ์ธ ๋ชจ๋‹ฌ ๋‚ด ํ•™๋ฒˆ Input Box์˜ X ๋ฒ„ํŠผ์„ ์ˆจ๊ธฐ๊ณ , ์š”์†Œ ๊ฐ„ ๊ฐ„๊ฒฉ์„ 4px, 8px ๋“ฑ์œผ๋กœ UI ํ†ต์ผ์„ฑ์„ ์ง€์ผœ ์กฐ์ •ํ•˜๋ผ."
- "ํƒ‘๋ฐ”์˜ '๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก' ์ œ๋ชฉ์ด ์ˆ˜ํ‰ ์ •์ค‘์•™์— ์˜ค๋„๋ก absolute ๋งตํ•‘ํ•˜๊ณ , ์šฐ์ธก์— ๋กœ๊ทธ์ธ ์ƒํƒœ์ผ ๋•Œ๋งŒ ๋ Œ๋”๋ง๋˜๋Š” '๋กœ๊ทธ์•„์›ƒ' ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜๋ผ."
- "Input Box ํฌ์ปค์Šค ์‹œ ๊ธฐ์กด ์ฃผํ™ฉ์ƒ‰ ๋ฐฐ๊ฒฝ์€ ์œ ์ง€ํ•˜๋˜ 1px ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜๋งŒ ํฐ์ƒ‰์œผ๋กœ ์ฆ‰๊ฐ ๋ณ€ํ™”ํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ์ด์ค‘ ๋ง(ring) ์•„์›ƒ๋ผ์ธ ๋ฐœ์ƒ ๋ฒ„๊ทธ๋ฅผ ์—†์• ๋ผ."
- "์ด๋ฆ„ ์ €์žฅ ์ฒดํฌ๋ฐ•์Šค์˜ ์•„์ด์ฝ˜/ํด๋ฆญ ์˜์—ญ ์ ‘๊ทผ์„ฑ์„ ๋†’์ด๋„๋ก label ๋ž˜ํ•‘ ๊ตฌ์กฐ๋ฅผ ๊ฐœ์„ ํ•˜์—ฌ ํ…์ŠคํŠธ๋‚˜ ์•„์ด์ฝ˜ ๋ถ€๋ถ„์„ ๋ˆŒ๋Ÿฌ๋„ ์ƒํƒœ๊ฐ€ ์ •์ƒ ๋ณ€๊ฒฝ๋˜๋„๋ก ์ˆ˜์ •ํ•˜๋ผ."
- "๊ธฐํš ์ƒ ์ด๋ฒˆ ๊ตฌํ˜„์—์„œ ์ œ์™ธ๋œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ด€๋ จ ๋ฒ„ํŠผ UI์™€ ์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜ ๋กœ์ง๋“ค์„ ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ์—์„œ ์ฃผ์„ ์ฒ˜๋ฆฌํ•ด๋ผ."
- "team-message/[id] ํŽ˜์ด์ง€์˜ UI๋ฅผ ๊ธฐ์ค€์ด ๋˜๋Š” msg/[id] ํŽ˜์ด์ง€์˜ ๋””์ž์ธ ์š”์†Œ์™€ ์™„๋ฒฝํ•˜๊ฒŒ ํ†ต์ผํ•˜๋„๋ก ์ˆ˜์ •ํ•ด๋ผ. ์ปจํ…Œ์ด๋„ˆ ํฐ๋ฐฐ๊ฒฝ ๋‚˜๋ˆ„๊ธฐ, hr ๊ตฌ๋ถ„์„  ์—ฌ๋ฐฑ ๋“ฑ"
- "๋ฉ”์ธ ํ™”๋ฉด ์บ๋ฆญํ„ฐ ์ด๋ฏธ์ง€๋“ค์˜ ํฌ๊ธฐ๊ฐ€ ์ž‘์•„์ง€๊ณ  ๋ฐฐ์น˜๊ฐ€ ์–ด๊ธ‹๋‚˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ์›๋ณธ ์ฝ”๋“œ ๊ตฌ์กฐ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ์™„๋ฒฝํžˆ ํ†ต์ผ์‹œํ‚ค๊ณ  ํ”ฝ์…€ํ™” ์œ ์ง€ํ•ด"
- "์šด์˜ํŒ€ ํ•œ๋งˆ๋””๋ฅผ ํ•„ํ„ฐ๋ง ํ•ด์„œ '๋ ˆ๋ฒจ/์„œ๋ฒ„/์ง์—…' ์ž๋ฆฌ์— '13๊ธฐ/๊ฐ€์ฒœ๋Œ€ํ•™๊ต/์šด์˜ํŒ€'์œผ๋กœ ํ‘œ์‹œ๋˜๊ฒŒ ํ•ด์ค˜."
- "์‚ฌ์ด๋“œ๋ฐ” ํ•˜๋‹จ '๋ฉ”์ƒ๊ฒฐ์‚ฐ ๊ธฐ๋ก' ํ…์ŠคํŠธ ์ œ๊ฑฐํ•˜๊ณ  ์‹ฌ๋ณผ ๋กœ๊ณ  svg๋ž‘ ๋‚ ์งœ ๊ธฐ๊ฐ„ ๋ฐฐ์น˜ํ•ด ์ค˜"
- "๋กœ๊ทธ์ธ ํŒ์—…์˜ ์ด๋ฆ„ ์ž…๋ ฅ ์นธ์— ํ…์ŠคํŠธ ์ž…๋ ฅํ•˜๋ฉด ๋นจ๊ฐ„ ์ค„ ์ณ์ง€๋Š” ๊ฑฐ ์—†์•จ ์ˆ˜ ์žˆ์–ด? autocomplete ๊บผ ์ค˜"
- "๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก์˜ ์ „์†ก ๋ฒ„ํŠผ ์•„์ด์ฝ˜ ์ปฌ๋Ÿฌ ํ™”์ดํŠธ ์‚ฌ๋ณธ ์Šค๋‹ˆํŽซ์œผ๋กœ ๋ณ€๊ฒฝํ•ด ์ค˜ (`send-icon-white.svg`)"

## โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ
- [x] ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธ ์™„๋ฃŒ
- [x] ํƒ€์ž… ์—๋Ÿฌ ์—†์Œ (`npm run check`)
- [x] Linter ํ†ต๊ณผ
- [x] ๋ชจ๋ฐ”์ผ ๋ฐ˜์‘ํ˜• ํ™•์ธ
- [ ] ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์š”์ฒญ ์™„๋ฃŒ
- [x] ๋กœ์ปฌ์—์„œ ๊ฐœ๋ฐœํ™˜๊ฒฝ ์ž‘๋™ ํ…Œ์ŠคํŠธ ์™„๋ฃŒ (npm run dev)
- [x] ํƒ€์ž… ๋ฐ ์ถฉ๋Œ ์—๋Ÿฌ ์—†์Œ (`npm run check`, FastAPI ๋ฐฑ์—”๋“œ ๋ฆฐํ„ฐ ํ†ต๊ณผ)
- [x] UI/UX ๋ Œ๋”๋ง ํ™•์ธ (Pixelated, Overflow ๋“ฑ)
- [ ] ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์š”์ฒญ ๋ฐ dev ๋ธŒ๋žœ์น˜ ๋ณ‘ํ•ฉ

## ๐Ÿ“ธ ์Šคํฌ๋ฆฐ์ƒท (์„ ํƒ)
<!-- UI ๋ณ€๊ฒฝ ์ „/ํ›„ ํ˜น์€ ๊ตฌํ˜„ ์™„๋ฃŒ๋œ ํ†ก ํŽ˜์ด์ง€/๋ ˆ์ด์•„์›ƒ ์Šคํฌ๋ฆฐ์ƒท์„ ์ฒจ๋ถ€ํ•ด์ฃผ์„ธ์š” -->


<!-- UI ๋ณ€๊ฒฝ ์ „/ํ›„ ์บก์ฒ˜ ํ™”๋ฉด ํ˜น์€ ์ปดํฌ๋„ŒํŠธ ์ด๋ฏธ์ง€๋ฅผ ์ฒจ๋ถ€ํ•ด์ฃผ์„ธ์š” -->

## ๐Ÿ’ฌ ํŠน์ด์‚ฌํ•ญ
- ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ด€๋ จ ๋กœ์ง(`handleKakaoLogin`) ๋ฐ ํ”„๋ก ํŠธ ๋ฒ„ํŠผ UI๋Š” ํŒŒ์ผ ๋‚ด๋ถ€์— ์ฃผ์„ ํ˜•ํƒœ๋กœ ๋ณด์กดํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. (ํ•„์š” ์‹œ ์ถ”ํ›„ ์ฃผ์„๋งŒ ํ•ด์ œํ•ด ์žฌํ™œ์šฉ ๊ฐ€๋Šฅ)
- ๋ชจ๋ฐ”์ผ ๋ทฐํฌํŠธ์—์„œ `InputBox` ๋ฐ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ํ„ฐ์น˜ ์‹œ ๋ชจ๋ฐ”์ผ ๋ธŒ๋ผ์šฐ์ €์˜ ๊ธฐ๋ณธ ์Œ์˜(Highlight)์ด ๊ฒน์น˜์ง€ ์•Š๊ฒŒ ์กฐ์น˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
- ์ž„์‹œ ๋””๋ฒ„๊น… ์šฉ๋„๋กœ ๊ธฐ์žฌํ•ด ๋‘” ํ•˜๋“œ์ฝ”๋”ฉ ๊ฐ’(๊น€๋‹จ๋ฐ”, ํ•™๋ฒˆ ๋“ฑ) ์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๋ชจ๋‘ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดˆ๊ธฐํ™”(`""`) ๋ฐ ์‚ญ์ œํ•˜์˜€์Šต๋‹ˆ๋‹ค.

---

Expand Down
Binary file added dpbr_front/app/check_output.txt
Binary file not shown.
45 changes: 31 additions & 14 deletions dpbr_front/app/src/app.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" as="style" crossorigin
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>๋‹จํ’๋ฐ”๋žŒ</title>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/images/icons/MSGS_Favicon.ico" />
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" as="style" crossorigin
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸ  Major

๋ชจ๋ฐ”์ผ ํ™•๋Œ€๋ฅผ ๋ง‰๋Š” viewport ์„ค์ •์€ ์ ‘๊ทผ์„ฑ ์ด์Šˆ์ž…๋‹ˆ๋‹ค.

์คŒ ๋น„ํ™œ์„ฑํ™”๋Š” ์ €์‹œ๋ ฅ ์‚ฌ์šฉ์ž ์ž‘์—…์„ ๋ง‰์„ ์ˆ˜ ์žˆ์–ด ์ œ๊ฑฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

โ™ฟ ์ œ์•ˆ ํŒจ์น˜
-	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+	<meta name="viewport" content="width=device-width, initial-scale=1" />
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
๐Ÿค– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dpbr_front/app/src/app.html` at line 10, Remove the zoom-locking attributes
from the <meta name="viewport"> tag in app.html: replace the current content
attribute ("width=device-width, initial-scale=1, maximum-scale=1,
user-scalable=no") with a permissive viewport (e.g., "width=device-width,
initial-scale=1") so users can pinch-zoom; locate the <meta name="viewport">
element in app.html and edit its content value accordingly to restore
accessibility for low-vision users.

<title>๋‹จํ’๋ฐ”๋žŒ</title>

<!-- SEO & Metadata -->
<meta name="description" content="๋‹จํ’๋ฐ”๋žŒ 13๊ธฐ ๋ฉ”์ƒ๊ฒฐ์‚ฐ - ๋‹น์‹ ์˜ ๋ฉ”์ดํ”Œ ์—ฌ์ •์„ ๊ธฐ๋กํ•˜์„ธ์š”." />
<meta property="og:type" content="website" />
<meta property="og:title" content="๋‹จํ’๋ฐ”๋žŒ" />
<meta property="og:description" content="๋‹จํ’๋ฐ”๋žŒ 13๊ธฐ ๋ฉ”์ƒ๊ฒฐ์‚ฐ - ๋‹น์‹ ์˜ ๋ฉ”์ดํ”Œ ์—ฌ์ •์„ ๊ธฐ๋กํ•˜์„ธ์š”." />
<meta property="og:image" content="%sveltekit.assets%/images/thumbnail.png" />
<meta property="og:url" content="https://gc-maplewind.github.io/MSGS_13_F/" />

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="๋‹จํ’๋ฐ”๋žŒ" />
<meta name="twitter:description" content="๋‹จํ’๋ฐ”๋žŒ 13๊ธฐ ๋ฉ”์ƒ๊ฒฐ์‚ฐ - ๋‹น์‹ ์˜ ๋ฉ”์ดํ”Œ ์—ฌ์ •์„ ๊ธฐ๋กํ•˜์„ธ์š”." />
<meta name="twitter:image" content="%sveltekit.assets%/images/thumbnail.png" />
Comment on lines +13 to +24
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

SEO ๋ฉ”ํƒ€ ํƒœ๊ทธ(description, og:*, twitter:*)๋ฅผ app.html์— ์ •์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋™์ผํ•œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์–ด SEO์— ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ํŽ˜์ด์ง€์˜ ์ฝ˜ํ…์ธ ์— ๋งž๋Š” ๋™์ ์ธ ๋ฉ”ํƒ€ ํƒœ๊ทธ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋กœ์ง์„ ์ตœ์ƒ์œ„ +layout.svelte ํŒŒ์ผ๋กœ ์˜ฎ๊ธฐ๊ณ  <svelte:head>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€๋ณ„๋กœ ์ ์ ˆํ•œ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, og:url์€ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ URL์„ ๋™์ ์œผ๋กœ ๋ฐ˜์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


%sveltekit.head%
</head>

<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>

</html>
75 changes: 65 additions & 10 deletions dpbr_front/app/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ interface SettlementResponse {
acquired_at: string;
}

interface CharactersPaginationResponse {
items: CharacterResponse[];
total: number;
page: number;
limit: number;
}

interface SettlementsPaginationResponse {
items: SettlementResponse[];
total: number;
page: number;
limit: number;
}

interface CommentResponse {
id: number;
user_id: number | null;
Expand Down Expand Up @@ -185,7 +199,27 @@ async function apiCall<T>(endpoint: string, options?: RequestInit): Promise<T> {
export async function getCharacters(): Promise<Character[]> {
const data = await apiCall<CharacterResponse[]>('/characters');

return data.map((char) => ({
return data.map(mapCharacterResponse);
}

export async function getCharactersPaginated(
page: number = 1,
limit: number = 10
): Promise<{ items: Character[]; total: number; page: number; limit: number }> {
const data = await apiCall<CharactersPaginationResponse>(
`/characters/pagination?page=${page}&limit=${limit}`
);

return {
items: data.items.map(mapCharacterResponse),
total: data.total,
page: data.page,
limit: data.limit
};
}

function mapCharacterResponse(char: CharacterResponse): Character {
return {
id: char.id.toString(),
name: char.name,
nickname: char.detail_txt || char.name,
Expand All @@ -194,7 +228,18 @@ export async function getCharacters(): Promise<Character[]> {
job: char.job,
club: '๋‹จํ’๋ฐ”๋žŒ',
server: char.server
}));
};
}

function mapSettlementResponse(settlement: SettlementResponse): SettlementItem {
return {
id: settlement.id.toString(),
characterId: settlement.character_id.toString(),
title: settlement.title,
description: settlement.description || '',
imageUrl: settlement.img_url ? `${getApiBaseUrl()}${settlement.img_url}` : '/default-avatar.png',
acquiredAt: settlement.acquired_at
};
}

/**
Expand Down Expand Up @@ -228,14 +273,24 @@ export async function getSettlementsByCharacterId(characterId: string): Promise<
`/characters/${characterId}/settlements`
);

return data.map((settlement) => ({
id: settlement.id.toString(),
characterId: settlement.character_id.toString(),
title: settlement.title,
description: settlement.description || '',
imageUrl: settlement.img_url ? `${getApiBaseUrl()}${settlement.img_url}` : '/default-avatar.png',
acquiredAt: settlement.acquired_at
}));
return data.map(mapSettlementResponse);
}

export async function getSettlementsByCharacterIdPaginated(
characterId: string,
page: number = 1,
limit: number = 10
): Promise<{ items: SettlementItem[]; total: number; page: number; limit: number }> {
const data = await apiCall<SettlementsPaginationResponse>(
`/characters/${characterId}/settlements/pagination?page=${page}&limit=${limit}`
);

return {
items: data.items.map(mapSettlementResponse),
total: data.total,
page: data.page,
limit: data.limit
};
}

/**
Expand Down
77 changes: 48 additions & 29 deletions dpbr_front/app/src/lib/components/BottomSheetLogin.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
let studentIdInputRef: HTMLDivElement | undefined = $state();
let dialogEl: HTMLDivElement | undefined = $state();

// ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ƒํƒœ
let errorMessage = $state("");

// ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์œ„ํ•œ ์ƒํƒœ
let isVisible = $state(false);

Expand All @@ -32,24 +35,24 @@
isVisible = true;
}, 10);

const savedName = getSavedName();
if (savedName) {
name = savedName.slice(0, 3);
saveName = true;
}
const savedName = getSavedName();
if (savedName) {
name = savedName.slice(0, 3);
saveName = true;
}

dialogEl?.focus();
const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape") {
handleClose();
}
};
dialogEl?.focus();
const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape") {
handleClose();
}
};

window.addEventListener("keydown", handleEscape);
return () => {
window.removeEventListener("keydown", handleEscape);
};
});
window.addEventListener("keydown", handleEscape);
return () => {
window.removeEventListener("keydown", handleEscape);
};
});

function handleClose(e?: Event) {
e?.stopPropagation();
Expand Down Expand Up @@ -106,7 +109,10 @@
*/

function showToastMessage(message?: string) {
toast.show(message || "์ด๋ฆ„ ๋˜๋Š” ํ•™๋ฒˆ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.");
errorMessage = message || "์ด๋ฆ„ ๋˜๋Š” ํ•™๋ฒˆ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.";
setTimeout(() => {
errorMessage = "";
}, 3000);
}

// Focus/Blur ํ•ธ๋“ค๋Ÿฌ๋“ค
Expand Down Expand Up @@ -158,7 +164,7 @@
tabindex="-1"
>
<div
class="w-full h-[72%] bg-gradient-to-b from-[#FCDDA5] to-[#F1A470] rounded-t-3xl pt-4 pb-8 px-6 flex flex-col items-center shadow-lg transition-transform duration-300 {isVisible
class="w-full shrink-0 h-[72vh] bg-gradient-to-b from-[#FCDDA5] to-[#F1A470] rounded-t-3xl pt-4 pb-8 px-6 flex flex-col items-center shadow-lg transition-transform duration-300 {isVisible
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

๋ชจ๋ฐ”์ผ ๋ธŒ๋ผ์šฐ์ €์—์„œ vh ๋‹จ์œ„๋Š” ์ฃผ์†Œ ํ‘œ์‹œ์ค„์ด๋‚˜ ๊ฐ€์ƒ ํ‚ค๋ณด๋“œ์˜ ๋“ฑ์žฅ์— ๋”ฐ๋ผ ๋ทฐํฌํŠธ ๋†’์ด๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ ˆ์ด์•„์›ƒ ๋ณ€๊ฒฝ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์ด ํŠน์ • UI ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด, vh ๋‹จ์œ„ ์‚ฌ์šฉ์˜ ์ž ์žฌ์ ์ธ ๋ถ€์ž‘์šฉ์„ ๊ณ ๋ คํ•˜์—ฌ ์žฌ๊ฒ€ํ† ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

? 'translate-y-0'
: 'translate-y-full'}"
onclick={(e) => e.stopPropagation()}
Expand All @@ -167,7 +173,7 @@
<div class="w-full flex justify-end">
<button onclick={handleClose} class="text-white p-2">
<img
src="/images/icons/name=Close, Color=White.svg"
src="/images/icons/close-icon-white.svg"
alt="๋‹ซ๊ธฐ"
class="w-6 h-6"
draggable="false"
Expand Down Expand Up @@ -226,14 +232,27 @@
</div>

<!-- ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ -->
<Button
label="๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก ์ž…์žฅ"
variant="primary"
buttonState={isLoading ? "disabled" : "default"}
onClick={handleLogin}
type="button"
class="bg-white !text-[#F87C56] hover:bg-white/90 font-medium py-[14px] rounded-lg"
/>
<div class="relative w-full">
{#if errorMessage}
<div
class="absolute bottom-[calc(100%+8px)] left-0 w-full flex justify-center z-[60] pointer-events-none"
>
<span
class="bg-black/60 text-white text-[15px] px-5 py-2.5 rounded-3xl shadow-md font-medium whitespace-nowrap pointer-events-auto"
>
{errorMessage}
</span>
</div>
{/if}
<Button
label="๋ฉ”์ƒ๊ฒฐ์‚ฐ ํ†ก ์ž…์žฅ"
variant="primary"
buttonState={isLoading ? "disabled" : "default"}
onClick={handleLogin}
type="button"
class="bg-white !text-[#F87C56] hover:bg-white/90 font-medium py-[14px] rounded-lg w-full"
/>
</div>

<!-- ์ด๋ฆ„ ์ €์žฅ ์ฒดํฌ๋ฐ•์Šค -->
<label class="flex items-center gap-2 cursor-pointer mt-2 mb-2">
Expand All @@ -248,14 +267,14 @@
>
{#if saveName}
<img
src="/images/icons/name=check-enable, Color=White.svg"
src="/images/icons/check-enable-icon.svg"
alt="์ €์žฅ ํ™œ์„ฑํ™”"
class="w-full h-full"
draggable="false"
/>
{:else}
<img
src="/images/icons/name=check-disable, Color=White.svg"
src="/images/icons/check-disable-icon.svg"
alt="์ €์žฅ ๋น„ํ™œ์„ฑํ™”"
class="w-full h-full"
draggable="false"
Expand Down
Loading
Loading