diff --git a/frontend/src/pages/curriculum/CurriculumPage.js b/frontend/src/pages/curriculum/CurriculumPage.js index 2d68bf6..3454589 100644 --- a/frontend/src/pages/curriculum/CurriculumPage.js +++ b/frontend/src/pages/curriculum/CurriculumPage.js @@ -331,6 +331,8 @@ function CrownIcon() { function HonorOfFame({ isAdmin }) { const [mvp, setMvp] = useState(null); const [form, setForm] = useState(null); + const [isOpen, setIsOpen] = useState(false); + const [isEditing, setIsEditing] = useState(false); const [saving, setSaving] = useState(false); const fetchMvp = async () => { @@ -352,6 +354,16 @@ function HonorOfFame({ isAdmin }) { ]; const filledEntries = entries.filter(e => mvp[e.key] && mvp[e.key].trim()); + const handleEditStart = () => { + setForm(mvp); + setIsEditing(true); + }; + + const handleCancel = () => { + setForm(mvp); + setIsEditing(false); + }; + const handleSave = async () => { setSaving(true); try { @@ -360,6 +372,7 @@ function HonorOfFame({ isAdmin }) { body: JSON.stringify(form), }); await fetchMvp(); + setIsEditing(false); } catch (e) { } finally { setSaving(false); @@ -368,38 +381,60 @@ function HonorOfFame({ isAdmin }) { return (
-
- - 과제 MVP 명예의 전당 - +
setIsOpen(p => !p)}> +
+ + 과제 MVP 명예의 전당 + +
+ toggle
+
- {!isAdmin && filledEntries.length > 0 && ( -
- {filledEntries.map(e => ( -
- {e.label}: {mvp[e.key]} -
- ))} -
- )} + {isOpen && ( +
+ {!isEditing && ( + <> + {filledEntries.length > 0 ? ( +
+ {filledEntries.map(e => ( +
+ {e.label}: {mvp[e.key]} +
+ ))} +
+ ) : ( +
아직 등록된 MVP가 없어요
+ )} + {isAdmin && ( + + )} + + )} - {isAdmin && ( -
- {entries.map(e => ( -
- - setForm({ ...form, [e.key]: ev.target.value })} - /> + {isAdmin && isEditing && ( +
+ {entries.map(e => ( +
+ + setForm({ ...form, [e.key]: ev.target.value })} + /> +
+ ))} +
+ + +
- ))} - + )}
)}
diff --git a/frontend/src/pages/curriculum/CurriculumPage.module.css b/frontend/src/pages/curriculum/CurriculumPage.module.css index 666dc18..430e1e1 100644 --- a/frontend/src/pages/curriculum/CurriculumPage.module.css +++ b/frontend/src/pages/curriculum/CurriculumPage.module.css @@ -65,20 +65,30 @@ border: 1px solid #eee; border-radius: 20px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); - display: flex; - flex-direction: column; - align-items: center; - text-align: center; box-sizing: border-box; } +.honorHeader { + display: grid; + grid-template-columns: 14px 1fr 14px; + align-items: center; + gap: 10px; + cursor: pointer; +} + .honorTitleRow { + grid-column: 2; display: flex; align-items: center; justify-content: center; gap: 10px; } +.honorHeader .toggleIcon { + grid-column: 3; + justify-self: end; +} + .crownIcon { width: 22px; height: 22px; @@ -93,12 +103,18 @@ color: var(--black); } +.honorBody { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + .honorList { display: flex; flex-direction: column; align-items: center; gap: 6px; - margin-top: 16px; } .honorItem { @@ -113,12 +129,35 @@ color: var(--dark); } +.honorEmpty { + font-family: var(--font-main); + font-size: 0.9rem; + color: #aaa; +} + +.honorEditBtn { + margin-top: 14px; + padding: 6px 20px; + background: transparent; + border: 1.5px solid var(--dark); + border-radius: 10px; + color: var(--dark); + font-family: var(--font-main); + font-size: 0.85rem; + cursor: pointer; +} + +.honorEditBtn:hover { + background: var(--dark); + color: var(--white); + transition: all ease-in-out 0.2s; +} + .honorEditList { display: flex; flex-direction: column; align-items: stretch; gap: 10px; - margin-top: 20px; width: 100%; max-width: 360px; } @@ -151,23 +190,45 @@ .honorEditInput:focus { border-color: var(--dark); } +.honorEditBtns { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin-top: 10px; +} + .honorSaveBtn { - margin: 10px auto 0; - padding: 8px 30px; + padding: 6px 20px; background: transparent; border: 1.5px solid var(--dark); border-radius: 10px; color: var(--dark); font-family: var(--font-main); - font-size: 0.9rem; - font-weight: 600; + font-size: 0.85rem; cursor: pointer; - transition: all 0.2s; } -.honorSaveBtn:hover { background: var(--dark); color: var(--white); } +.honorSaveBtn:hover { + background: var(--dark); + color: var(--white); + transition: all ease-in-out 0.2s; +} .honorSaveBtn:disabled { opacity: 0.6; cursor: default; } +.honorCancelBtn { + padding: 6px 20px; + background: transparent; + border: none; + color: #aaa; + font-family: var(--font-main); + font-size: 0.85rem; + cursor: pointer; +} + +.honorCancelBtn:hover { color: #777; } +.honorCancelBtn:disabled { opacity: 0.6; cursor: default; } + /* 카드 행 */ .cardsRow { margin: 0 auto;