Files
startover/apps/web/src/app/vendors/actions.ts
T
Johngreen 49ed21a768 fix: 폼 에러 시 사용자 입력값 유지 (회원가입, 업체 인증 신청)
useActionState 사용하는 폼에서 서버 에러 반환 시 입력값이 초기화되는 문제 수정.
서버 액션이 에러 시 submitted values를 함께 반환하고, 폼 input에 defaultValue 바인딩.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:50:23 +09:00

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: '인증 신청이 완료되었습니다. 심사 후 결과를 안내드립니다.' };
}