'use client'; import { useActionState, useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Field } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; import { Modal } from '@/components/ui/modal'; import { Select } from '@/components/ui/select'; import { useFeedback } from '@/app/_hooks/use-feedback'; import { ADMIN_LOCK_STATUS_OPTIONS, type AdminMember, } from '@/lib/domain/admin-member'; import { ADMIN_PASSWORD_HELP_TEXT, INITIAL_ADMIN_MEMBER_FORM_STATE, } from '@/lib/domain/admin-member-form'; import { updateAdminMemberAction } from '../_actions'; import { AdminMemberFormFields, FieldError, } from './admin-member-form-fields'; interface AdminMemberEditModalProps { member: AdminMember; onClose: () => void; } const FORM_ID = 'admin-member-edit-form'; /** * 관리자 수정 팝업(시안 ADM_ADM_103_p). * * 이름·ID는 읽기 전용이다(시안 ①). 다만 화면의 readOnly는 표시일 뿐이라 Server Action은 두 값을 * 아예 반영하지 않는다 — 직접 POST로 다른 값을 보내도 바뀌지 않는다. * * **비밀번호는 [비밀번호 변경]을 눌러야 입력할 수 있다**(시안 ②). 다만 비워 둔 채로는 수정이 * 저장되지 않는다 — 백엔드 UPDATE가 비밀번호를 조건 없이 덮어써서 빈 값을 보내면 그 계정이 로그인 * 불가가 되기 때문이다(`ADMIN_PASSWORD_REQUIRED_ON_UPDATE_TEXT` 주석). 비활성 input은 FormData에 * 실리지 않으므로 버튼을 누르지 않고 제출하면 그 안내가 그대로 뜬다. * * 휴대전화번호·이메일은 항상 빈 칸으로 시작한다 — 백엔드가 두 값을 되돌려주지 않아 기존 값을 * 채울 수단이 없다(Repository 주석). 입력한 값으로 덮어쓰는 동작이다. * * "잠김여부"는 활성/비활성으로 표기되지만 백엔드 필드는 `acctLockYn`(잠김 여부)이라 의미가 * 뒤집혀 있다. 그 변환은 도메인(`ADMIN_LOCK_STATUS_OPTIONS`)이 한 곳에서 책임진다. */ export function AdminMemberEditModal({ member, onClose, }: AdminMemberEditModalProps) { const { showToast } = useFeedback(); const [state, formAction, isPending] = useActionState( updateAdminMemberAction, INITIAL_ADMIN_MEMBER_FORM_STATE ); const [isPasswordEditable, setIsPasswordEditable] = useState(false); useEffect(() => { if (state.status === 'success') { showToast({ variant: 'success', message: '관리자 정보를 수정했습니다.' }); onClose(); } }, [state, showToast, onClose]); const errors = state.status === 'error' ? (state.errors ?? {}) : {}; return ( } >
{/* 수정 대상을 가리키는 유일한 입력. 이름·ID는 읽기 전용이라 아예 제출하지 않는다 — Server Action도 그 둘을 읽지 않으므로 위조해 보내도 반영되지 않는다. */}

* 는 필수 항목입니다.

{isPasswordEditable && (

{ADMIN_PASSWORD_HELP_TEXT}

)} {state.status === 'error' && state.message && (

{state.message}

)}
); }