'use client'; import { useActionState, useEffect, useRef, useState } from 'react'; import { FoxButton } from '@fox/core/components/fox-button'; import { FoxFormLabel } from '@fox/core/components/fox-form-label'; import { FoxHelperText } from '@fox/core/components/fox-helper-text'; import { FoxInput } from '@fox/core/components/fox-input'; import { FoxModal } from '@fox/core/components/fox-modal'; import { FoxRadio } from '@fox/core/components/fox-radio'; import { FoxRadioGroup } from '@fox/core/components/fox-radio-group'; import { FoxSelect } from '@fox/core/components/fox-select'; import { FoxTextArea } from '@fox/core/components/fox-text-area'; import { submitFormAction } from '@/app/_hooks/submit-form-action'; import { useFeedback } from '@/app/_hooks/use-feedback'; import { DESCRIPTION_MAX_LENGTH, INITIAL_POINT_STANDARD_FORM_STATE, } from '@/lib/domain/point-standard-form'; import type { PointStandard } from '@/lib/domain/point-standard'; import type { CommonCode } from '@/lib/domain/common-code'; import { createPointStandardAction, updatePointStandardAction, } from '../_actions'; import styles from './point-standard-form.module.scss'; interface PointStandardFormModalProps { /** 수정 대상. 없으면 등록이다. */ standard?: PointStandard; /** 공통코드 `CODE_GROUP.pointEvent` — 등록의 이벤트 선택지(기획 ① "등록된 코드중에서 선택"). */ eventCodes: readonly CommonCode[]; onClose: () => void; } export function PointStandardFormModal({ standard, eventCodes, onClose, }: PointStandardFormModalProps) { const isCreate = standard === undefined; const { showToast } = useFeedback(); const formRef = useRef(null); const [state, formAction, isPending] = useActionState( isCreate ? createPointStandardAction : updatePointStandardAction, INITIAL_POINT_STANDARD_FORM_STATE ); const [eventCode, setEventCode] = useState( standard?.eventCode ?? eventCodes[0]?.code ?? '' ); const [isDuplicable, setIsDuplicable] = useState(standard?.isDuplicable ?? true); const [isActive, setIsActive] = useState(standard?.isActive ?? true); useEffect(() => { if (state.status === 'success') { showToast({ variant: 'success', message: isCreate ? '포인트 기준을 등록했습니다.' : '포인트 기준을 수정했습니다.', }); onClose(); } }, [state, showToast, onClose, isCreate]); const errors = state.status === 'error' ? (state.errors ?? {}) : {}; return ( formRef.current?.requestSubmit()} /> } >
submitFormAction(event, formAction)} className={styles.fields} >

* 는 필수 항목입니다.

{/* 수정에서는 화면이 읽기 전용이지만 백엔드 UPDATE가 EVENT_CD를 덮어써서 그대로 돌려보낸다. */}
{isCreate ? ( // 기획 ① 등록된 코드중에서 선택. ({ value: code.code, label: code.label, }))} placeholder="이벤트를 선택하세요." value={eventCode} onValueChange={setEventCode} error={Boolean(errors.eventCode)} hint={errors.eventCode} /> ) : ( // 기획 ① 이벤트행은 수정불가(Read Only). )}
포인트
포인트
{errors.point && }
제한포인트
'0' 일경우 일 누적 포인트에 대한 제한이 없습니다.
{errors.limitPoint && ( )}
중복 여부 setIsDuplicable(true)} /> setIsDuplicable(false)} />
사용여부 setIsActive(true)} /> setIsActive(false)} />
{state.status === 'error' && state.message && ( )}
); }