임동욱 임동욱 08-21
merge: 관리자 메뉴 선택 제거
@06f7918ee8ddc73bfcd7edaedb683695140150c8
app/(protected)/(basic)/admins/_actions.ts
--- app/(protected)/(basic)/admins/_actions.ts
+++ app/(protected)/(basic)/admins/_actions.ts
@@ -9,7 +9,6 @@
   isAdminLoginIdTaken,
   updateAdminMember,
 } from '@/lib/data/repositories/admin-member-repository';
-import { ADMIN_MENU_OPTIONS } from '@/lib/domain/admin-member';
 import {
   formatPhoneNumber,
   validateAdminLoginId,
@@ -31,15 +30,6 @@
   return typeof value === 'string' ? value : '';
 }
 
-function readMenuCodes(formData: FormData): string[] {
-  return formData
-    .getAll('menuCodes')
-    .filter((value): value is string => typeof value === 'string')
-    .filter((value) =>
-      ADMIN_MENU_OPTIONS.some((option) => option.value === value)
-    );
-}
-
 function readEditableValues(formData: FormData): AdminMemberEditableValues {
   const phoneNumber = formatPhoneNumber(readString(formData, 'phoneNumber'));
 
@@ -48,7 +38,6 @@
     phoneNumber: phoneNumber ?? '',
     email: readString(formData, 'email'),
     roleCode: readString(formData, 'roleCode'),
-    menuCodes: readMenuCodes(formData),
   };
 }
 
app/(protected)/(basic)/admins/_components/admin-member-create-modal.tsx
--- app/(protected)/(basic)/admins/_components/admin-member-create-modal.tsx
+++ app/(protected)/(basic)/admins/_components/admin-member-create-modal.tsx
@@ -72,7 +72,6 @@
   const [emailValue, setEmailValue] = useState(`@${EMAIL_DOMAIN_OPTIONS[0]}`);
   const [isEmailTouched, setIsEmailTouched] = useState(false);
   const [roleCode, setRoleCode] = useState<string>(DEFAULT_ADMIN_ROLE_CODE);
-  const [menuCodes, setMenuCodes] = useState<string[]>([]);
 
   useEffect(() => {
     if (state.status === 'success') {
@@ -196,8 +195,6 @@
           onPhoneNumberChange={setPhoneNumber}
           roleCode={roleCode}
           onRoleCodeChange={setRoleCode}
-          menuCodes={menuCodes}
-          onMenuCodesChange={setMenuCodes}
           errors={errors}
           emailField={
             <>
app/(protected)/(basic)/admins/_components/admin-member-edit-modal.tsx
--- app/(protected)/(basic)/admins/_components/admin-member-edit-modal.tsx
+++ app/(protected)/(basic)/admins/_components/admin-member-edit-modal.tsx
@@ -49,7 +49,6 @@
   const [roleCode, setRoleCode] = useState(
     member.roleCode || DEFAULT_ADMIN_ROLE_CODE
   );
-  const [menuCodes, setMenuCodes] = useState<string[]>(member.menuCodes);
   const [isActive, setIsActive] = useState(!(member.isLocked ?? false));
 
   useEffect(() => {
@@ -135,8 +134,6 @@
           onPhoneNumberChange={setPhoneNumber}
           roleCode={roleCode}
           onRoleCodeChange={setRoleCode}
-          menuCodes={menuCodes}
-          onMenuCodesChange={setMenuCodes}
           errors={errors}
           emailField={
             <FoxInput
app/(protected)/(basic)/admins/_components/admin-member-form-fields.tsx
--- app/(protected)/(basic)/admins/_components/admin-member-form-fields.tsx
+++ app/(protected)/(basic)/admins/_components/admin-member-form-fields.tsx
@@ -1,15 +1,10 @@
 'use client';
 
 import { useId, type ReactNode } from 'react';
-import { FoxChip } from '@fox/core/components/fox-chip';
-import { FoxChipArea } from '@fox/core/components/fox-chip-area';
 import { FoxFormLabel } from '@fox/core/components/fox-form-label';
 import { FoxPhoneNumber } from '@fox/core/components/fox-phone-number';
 import { FoxSelect } from '@fox/core/components/fox-select';
-import {
-  ADMIN_MENU_OPTIONS,
-  ADMIN_ROLE_OPTIONS,
-} from '@/lib/domain/admin-member';
+import { ADMIN_ROLE_OPTIONS } from '@/lib/domain/admin-member';
 import type { AdminMemberFormErrors } from '@/lib/domain/admin-member-form';
 import { MOBILE_PHONE_PREFIXES } from '@/lib/domain/phone-number';
 import styles from './admin-member-modal.module.scss';
@@ -19,8 +14,6 @@
   onPhoneNumberChange: (phoneNumber: string) => void;
   roleCode: string;
   onRoleCodeChange: (roleCode: string) => void;
-  menuCodes: string[];
-  onMenuCodesChange: (menuCodes: string[]) => void;
   emailField: ReactNode;
   errors: AdminMemberFormErrors;
 }
@@ -30,24 +23,10 @@
   onPhoneNumberChange,
   roleCode,
   onRoleCodeChange,
-  menuCodes,
-  onMenuCodesChange,
   emailField,
   errors,
 }: AdminMemberFormFieldsProps) {
   const phoneLabelId = useId();
-  const menuLabelId = useId();
-
-  const allMenuValues = ADMIN_MENU_OPTIONS.map((option) => option.value);
-  const isAllSelected = menuCodes.length === allMenuValues.length;
-
-  function toggleMenu(value: string) {
-    onMenuCodesChange(
-      menuCodes.includes(value)
-        ? menuCodes.filter((code) => code !== value)
-        : [...menuCodes, value]
-    );
-  }
 
   return (
     <>
@@ -81,34 +60,6 @@
         hint={errors.roleCode}
       />
       <input type="hidden" name="roleCode" value={roleCode} />
-
-      <div className={styles.field} role="group" aria-labelledby={menuLabelId}>
-        <FoxFormLabel as="span" id={menuLabelId} requirement="required">
-          메뉴 선택
-        </FoxFormLabel>
-        <FoxChipArea size="md" wrap labelledBy={menuLabelId}>
-          <FoxChip
-            type="check"
-            label="전체"
-            checked={isAllSelected}
-            onCheckedChange={(checked) =>
-              onMenuCodesChange(checked ? allMenuValues : [])
-            }
-          />
-          {ADMIN_MENU_OPTIONS.map((option) => (
-            <FoxChip
-              key={option.value}
-              type="check"
-              label={option.label}
-              checked={menuCodes.includes(option.value)}
-              onCheckedChange={() => toggleMenu(option.value)}
-            />
-          ))}
-        </FoxChipArea>
-      </div>
-      {menuCodes.map((code) => (
-        <input key={code} type="hidden" name="menuCodes" value={code} />
-      ))}
     </>
   );
 }
lib/data/repositories/admin-member-repository.ts
--- lib/data/repositories/admin-member-repository.ts
+++ lib/data/repositories/admin-member-repository.ts
@@ -57,8 +57,6 @@
     phoneNumber: readOptionalString(raw, 'admTelNo'),
     email: readOptionalString(raw, 'admEmlAddr'),
     roleCode: readOptionalString(raw, 'admRoleCd') ?? '',
-    // 이슈: 백엔드에 관리자별 메뉴 권한이 없어 저장도 조회도 되지 않는다.
-    menuCodes: [],
     createdAt: readOptionalString(raw, 'frstRegDtStr'),
     isLocked: parseYesNo(raw.acctLockYn),
     isActive: parseYesNo(raw.useYn),
lib/domain/admin-member-form.ts
--- lib/domain/admin-member-form.ts
+++ lib/domain/admin-member-form.ts
@@ -6,7 +6,6 @@
   type FoxValidator,
 } from '@fox/core/validation';
 import {
-  ADMIN_MENU_OPTIONS,
   ADMIN_ROLE_OPTIONS,
   type AdminRoleCode,
 } from '@/lib/domain/admin-member';
@@ -66,7 +65,6 @@
   phoneNumber: string;
   email: string;
   roleCode: AdminRoleCode;
-  menuCodes: string[];
 };
 
 export type AdminMemberCreateValues = AdminMemberEditableValues & {
@@ -146,11 +144,7 @@
     errors.roleCode = '역할을 선택해 주세요.';
   }
 
-  const menuCodes = values.menuCodes.filter((code) =>
-    ADMIN_MENU_OPTIONS.some((option) => option.value === code)
-  );
-
-  return { password, phoneNumber, email, roleCode: values.roleCode, menuCodes };
+  return { password, phoneNumber, email, roleCode: values.roleCode };
 }
 
 export function validateAdminMemberCreate(
lib/domain/admin-member.ts
--- lib/domain/admin-member.ts
+++ lib/domain/admin-member.ts
@@ -29,11 +29,6 @@
   email: string | null;
   /** 백엔드 `admRoleCd`. 표기용 이름은 `formatAdminRoleLabel`이 만든다. */
   roleCode: AdminRoleCode;
-  /**
-   * 접근 가능 메뉴 코드 목록(시안 ADM_ADM_102_p ③ "메뉴 선택", 다중 선택).
-   * 백엔드 목록 응답에 없어 mock으로 등록/수정한 행에만 값이 있다 — 빈 배열은 "미지정"이다.
-   */
-  menuCodes: string[];
   /** ISO 형식(YYYY-MM-DD) 문자열. 백엔드 목록 응답에 없다(정렬에만 쓰이고 select되지 않는다). */
   createdAt: string | null;
   /** 백엔드 `acctLockYn` — 계정 잠김 여부. 시안의 "잠김여부"는 이 값의 반대(활성/비활성)다. */
@@ -107,35 +102,3 @@
   return isLocked ? '비활성' : '활성';
 }
 
-/**
- * 접근 가능 메뉴 목록(시안 ADM_ADM_102_p ③ "메뉴 선택").
- *
- * **백엔드에 관리자 메뉴 API가 없어 mock 카탈로그다.** 값은 시안 사이드바의 대메뉴 구성을 그대로
- * 옮겼다 — 실제 메뉴 API가 생기면 이 상수를 지우고 그 응답으로 대체한다.
- */
-export const ADMIN_MENU_OPTIONS: ReadonlyArray<{
-  value: string;
-  label: string;
-}> = [
-  { value: 'MEMBER', label: '회원정보관리' },
-  { value: 'ADMIN', label: '관리자정보관리' },
-  { value: 'DECO_ITEM', label: '꾸미기아이템관리' },
-  { value: 'BOARD', label: '게시판관리(고객센터)' },
-  { value: 'POINT', label: '포인트관리' },
-  { value: 'CONTENTS', label: '콘텐츠관리' },
-  { value: 'SYSTEM', label: '시스템관리' },
-];
-
-/** 선택된 메뉴 코드를 화면 표기로 바꾼다. 하나도 없으면 `-`. */
-export function formatAdminMenuLabels(menuCodes: string[]): string {
-  if (menuCodes.length === 0) {
-    return EMPTY_FIELD_PLACEHOLDER;
-  }
-
-  return menuCodes
-    .map(
-      (code) =>
-        ADMIN_MENU_OPTIONS.find((option) => option.value === code)?.label ?? code
-    )
-    .join(', ');
-}
Add a comment
List