File name
Commit message
Commit date
File name
Commit message
Commit date
09-16
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
'use server';
import { revalidatePath } from 'next/cache';
import { verifySession } from '@/lib/auth/dal';
import {
createAdminMenu,
deleteAdminMenu,
fetchAdminMenus,
updateAdminMenu,
} from '@/lib/data/repositories/admin-menu-repository';
import { ADMIN_MENU_ROOT_PATH } from '@/lib/domain/admin-menu';
import {
validateAdminMenu,
type AdminMenuFormState,
type AdminMenuValues,
} from '@/lib/domain/admin-menu-form';
import { BackendRequestError } from '@/lib/http/backend-fetch';
const INVALID_REQUEST_MESSAGE = '요청이 올바르지 않습니다.';
const SAVE_FAILED_MESSAGE = '저장하지 못했습니다. 잠시 후 다시 시도해 주세요.';
const DELETE_FAILED_MESSAGE = '삭제하지 못했습니다. 잠시 후 다시 시도해 주세요.';
function readString(formData: FormData, key: string): string {
const value = formData.get(key);
return typeof value === 'string' ? value : '';
}
function readNumber(formData: FormData, key: string): number {
const trimmed = readString(formData, key).trim();
return trimmed === '' ? NaN : Number(trimmed);
}
function readValues(formData: FormData): AdminMenuValues {
return {
name: readString(formData, 'name'),
sortOrder: readNumber(formData, 'sortOrder'),
roleId: readString(formData, 'roleId'),
isTopActive: readString(formData, 'isTopActive') === 'true',
url: readString(formData, 'url'),
opensNewWindow: readString(formData, 'opensNewWindow') === 'true',
description: readString(formData, 'description'),
isActive: readString(formData, 'isActive') === 'true',
};
}
async function allowedRoleIds(): Promise<string[]> {
const menus = await fetchAdminMenus();
return [...new Set(menus.map((menu) => menu.roleId).filter(Boolean))];
}
function describeFailure(error: unknown, fallback: string): string {
return error instanceof BackendRequestError ? error.message : fallback;
}
export async function createAdminMenuAction(
_prevState: AdminMenuFormState,
formData: FormData
): Promise<AdminMenuFormState> {
await verifySession();
const parentId = readString(formData, 'parentId').trim();
if (!parentId) {
return { status: 'error', message: INVALID_REQUEST_MESSAGE };
}
const validation = validateAdminMenu(
readValues(formData),
await allowedRoleIds()
);
if (!validation.ok) {
return { status: 'error', errors: validation.errors };
}
try {
await createAdminMenu(parentId, validation.values);
} catch (error) {
return { status: 'error', message: describeFailure(error, SAVE_FAILED_MESSAGE) };
}
revalidatePath(ADMIN_MENU_ROOT_PATH);
return { status: 'success' };
}
export async function updateAdminMenuAction(
_prevState: AdminMenuFormState,
formData: FormData
): Promise<AdminMenuFormState> {
await verifySession();
const menuId = readString(formData, 'menuId').trim();
if (!menuId) {
return { status: 'error', message: INVALID_REQUEST_MESSAGE };
}
const validation = validateAdminMenu(
readValues(formData),
await allowedRoleIds()
);
if (!validation.ok) {
return { status: 'error', errors: validation.errors };
}
try {
await updateAdminMenu(menuId, validation.values);
} catch (error) {
return { status: 'error', message: describeFailure(error, SAVE_FAILED_MESSAGE) };
}
revalidatePath(ADMIN_MENU_ROOT_PATH);
return { status: 'success' };
}
export async function deleteAdminMenuAction(
menuId: string
): Promise<AdminMenuFormState> {
await verifySession();
if (!menuId) {
return { status: 'error', message: INVALID_REQUEST_MESSAGE };
}
try {
await deleteAdminMenu(menuId);
} catch (error) {
return { status: 'error', message: describeFailure(error, DELETE_FAILED_MESSAGE) };
}
revalidatePath(ADMIN_MENU_ROOT_PATH);
return { status: 'success' };
}