49ed21a768
useActionState 사용하는 폼에서 서버 에러 반환 시 입력값이 초기화되는 문제 수정. 서버 액션이 에러 시 submitted values를 함께 반환하고, 폼 input에 defaultValue 바인딩. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
'use server';
|
|
|
|
import { revalidatePath } from 'next/cache';
|
|
import { createPrismaClient } from '@startover/database';
|
|
import { auth } from '@/lib/auth';
|
|
import { applyVendorCertificationService } from '@/services/vendor-certification-service';
|
|
import type { VendorType } from '@startover/domain';
|
|
|
|
const prisma = createPrismaClient();
|
|
|
|
const VALID_VENDOR_TYPES = new Set<string>(['DEMOLITION', 'INTERIOR', 'ACQUISITION']);
|
|
|
|
export type VendorActionState = {
|
|
success: boolean;
|
|
message: string;
|
|
values?: {
|
|
businessName: string;
|
|
vendorType: string;
|
|
contactName: string;
|
|
businessRegistrationNumber: string;
|
|
coverageRegionCodes: string[];
|
|
};
|
|
} | null;
|
|
|
|
export async function applyVendorCertificationAction(
|
|
_prev: VendorActionState,
|
|
formData: FormData,
|
|
): Promise<VendorActionState> {
|
|
const session = await auth();
|
|
if (!session?.user?.dbId) {
|
|
return { success: false, message: '로그인이 필요합니다.' };
|
|
}
|
|
|
|
const vendorType = formData.get('vendorType') as string;
|
|
const businessName = formData.get('businessName') as string;
|
|
const contactName = formData.get('contactName') as string;
|
|
const businessRegistrationNumber = formData.get('businessRegistrationNumber') as string | null;
|
|
const coverageRegionCodes = formData.getAll('coverageRegions') as string[];
|
|
|
|
const submittedValues = {
|
|
businessName: businessName || '',
|
|
vendorType: vendorType || '',
|
|
contactName: contactName || '',
|
|
businessRegistrationNumber: businessRegistrationNumber || '',
|
|
coverageRegionCodes,
|
|
};
|
|
|
|
if (!vendorType || !VALID_VENDOR_TYPES.has(vendorType)) {
|
|
return { success: false, message: '업체 유형을 선택해주세요.', values: submittedValues };
|
|
}
|
|
if (!businessName?.trim()) {
|
|
return { success: false, message: '업체명을 입력해주세요.', values: submittedValues };
|
|
}
|
|
if (!contactName?.trim()) {
|
|
return { success: false, message: '담당자명을 입력해주세요.', values: submittedValues };
|
|
}
|
|
if (coverageRegionCodes.length === 0) {
|
|
return { success: false, message: '서비스 가능 지역을 하나 이상 선택해주세요.', values: submittedValues };
|
|
}
|
|
|
|
const result = await applyVendorCertificationService(prisma, {
|
|
ownerUserId: session.user.dbId,
|
|
vendorType: vendorType as VendorType,
|
|
businessName: businessName.trim(),
|
|
contactName: contactName.trim(),
|
|
businessRegistrationNumber: businessRegistrationNumber?.trim() || undefined,
|
|
coverageRegionCodes,
|
|
});
|
|
|
|
if (!result.ok) {
|
|
return { success: false, message: result.error.message ?? '인증 신청에 실패했습니다.', values: submittedValues };
|
|
}
|
|
|
|
revalidatePath('/vendors');
|
|
return { success: true, message: '인증 신청이 완료되었습니다. 심사 후 결과를 안내드립니다.' };
|
|
}
|