diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 1fc3d14..348965a 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -20,11 +20,11 @@ export default function App() { } /> } /> } /> - } /> + } /> {/* 동적 기능 페이지 */} - } /> + } /> ) diff --git a/frontend/src/components/Checkbox.jsx b/frontend/src/components/Checkbox.jsx new file mode 100644 index 0000000..56f4669 --- /dev/null +++ b/frontend/src/components/Checkbox.jsx @@ -0,0 +1,29 @@ +/** + * 커스텀 체크박스 + * ...} /> + */ +export default function Checkbox({ checked, onChange, disabled, className = '', size = 'md' }) { + const sizeCls = size === 'sm' ? 'w-4 h-4' : 'w-5 h-5' + const iconSize = size === 'sm' ? 'text-[10px]' : 'text-xs' + + return ( + + ) +} diff --git a/frontend/src/components/Select.jsx b/frontend/src/components/Select.jsx new file mode 100644 index 0000000..2b8082d --- /dev/null +++ b/frontend/src/components/Select.jsx @@ -0,0 +1,69 @@ +import { useEffect, useRef, useState } from 'react' + +/** + * 커스텀 드롭다운 셀렉트 + * setName(e.target.value)} + placeholder="예: 검은 마법사" + className={inputCls} + /> + + + {/* 이미지 */} + + + + + {/* 난이도 */} + +
+ {DIFFICULTIES.map((d) => { + const v = difficulties[d.key] + const priceErr = errors[`price_${d.key}`] + return ( +
+
+ {/* 체크박스 + 난이도 이미지 (이미지 클릭으로도 토글 가능) */} +
updateDifficulty(d.key, { enabled: !v.enabled })} + > + updateDifficulty(d.key, { enabled: checked })} + /> + {d.label} { e.currentTarget.style.display = 'none' }} + /> +
+ + {/* 가격 */} +
+
+ updateDifficulty(d.key, { crystal_price: e.target.value })} + disabled={!v.enabled} + placeholder="결정 가격" + className={`w-full rounded-lg border bg-gray-900 pl-4 pr-28 py-2 text-sm outline-none focus:border-emerald-500/50 disabled:opacity-50 disabled:cursor-not-allowed transition ${ + priceErr ? 'border-red-500/40' : 'border-white/10' + }`} + /> + {v.crystal_price && v.enabled && ( + + {formatMeso(Number(v.crystal_price))} + + )} +
+
+ + {/* 최대 인원 */} +