diff --git a/backend-node/src/routes/mailAccountFileRoutes.ts b/backend-node/src/routes/mailAccountFileRoutes.ts index cc022cb8..35772d39 100644 --- a/backend-node/src/routes/mailAccountFileRoutes.ts +++ b/backend-node/src/routes/mailAccountFileRoutes.ts @@ -1,8 +1,12 @@ import { Router } from 'express'; import { mailAccountFileController } from '../controllers/mailAccountFileController'; +import { authenticateToken } from '../middleware/authMiddleware'; const router = Router(); +// 모든 메일 계정 라우트에 인증 미들웨어 적용 +router.use(authenticateToken); + router.get('/', (req, res) => mailAccountFileController.getAllAccounts(req, res)); router.get('/:id', (req, res) => mailAccountFileController.getAccountById(req, res)); router.post('/', (req, res) => mailAccountFileController.createAccount(req, res)); diff --git a/backend-node/src/routes/mailReceiveBasicRoutes.ts b/backend-node/src/routes/mailReceiveBasicRoutes.ts index f8d0d670..d21df689 100644 --- a/backend-node/src/routes/mailReceiveBasicRoutes.ts +++ b/backend-node/src/routes/mailReceiveBasicRoutes.ts @@ -4,8 +4,12 @@ import express from 'express'; import { MailReceiveBasicController } from '../controllers/mailReceiveBasicController'; +import { authenticateToken } from '../middleware/authMiddleware'; const router = express.Router(); + +// 모든 메일 수신 라우트에 인증 미들웨어 적용 +router.use(authenticateToken); const controller = new MailReceiveBasicController(); // 메일 목록 조회 diff --git a/backend-node/src/routes/mailSendSimpleRoutes.ts b/backend-node/src/routes/mailSendSimpleRoutes.ts index db56b66d..726a220c 100644 --- a/backend-node/src/routes/mailSendSimpleRoutes.ts +++ b/backend-node/src/routes/mailSendSimpleRoutes.ts @@ -1,8 +1,12 @@ import { Router } from 'express'; import { mailSendSimpleController } from '../controllers/mailSendSimpleController'; +import { authenticateToken } from '../middleware/authMiddleware'; const router = Router(); +// 모든 메일 발송 라우트에 인증 미들웨어 적용 +router.use(authenticateToken); + // POST /api/mail/send/simple - 메일 발송 router.post('/simple', (req, res) => mailSendSimpleController.sendMail(req, res)); diff --git a/backend-node/src/routes/mailTemplateFileRoutes.ts b/backend-node/src/routes/mailTemplateFileRoutes.ts index eb79ed34..a4f81b1b 100644 --- a/backend-node/src/routes/mailTemplateFileRoutes.ts +++ b/backend-node/src/routes/mailTemplateFileRoutes.ts @@ -1,8 +1,12 @@ import { Router } from 'express'; import { mailTemplateFileController } from '../controllers/mailTemplateFileController'; +import { authenticateToken } from '../middleware/authMiddleware'; const router = Router(); +// 모든 메일 템플릿 라우트에 인증 미들웨어 적용 +router.use(authenticateToken); + // 템플릿 CRUD router.get('/', (req, res) => mailTemplateFileController.getAllTemplates(req, res)); router.get('/:id', (req, res) => mailTemplateFileController.getTemplateById(req, res)); diff --git a/frontend/app/(main)/admin/mail/dashboard/page.tsx b/frontend/app/(main)/admin/mail/dashboard/page.tsx index 1fa6a728..f2e737bc 100644 --- a/frontend/app/(main)/admin/mail/dashboard/page.tsx +++ b/frontend/app/(main)/admin/mail/dashboard/page.tsx @@ -14,6 +14,7 @@ import { Calendar, Clock } from "lucide-react"; +import { getMailAccounts, getMailTemplates } from "@/lib/api/mail"; interface DashboardStats { totalAccounts: number; @@ -38,17 +39,15 @@ export default function MailDashboardPage() { const loadStats = async () => { setLoading(true); try { - // 계정 수 - const accountsRes = await fetch('/api/mail/accounts'); - const accountsData = await accountsRes.json(); + // 계정 수 (apiClient를 통해 토큰 포함) + const accounts = await getMailAccounts(); - // 템플릿 수 - const templatesRes = await fetch('/api/mail/templates-file'); - const templatesData = await templatesRes.json(); + // 템플릿 수 (apiClient를 통해 토큰 포함) + const templates = await getMailTemplates(); setStats({ - totalAccounts: accountsData.success ? accountsData.data.length : 0, - totalTemplates: templatesData.success ? templatesData.data.length : 0, + totalAccounts: accounts.length, + totalTemplates: templates.length, sentToday: 0, // TODO: 실제 발송 통계 API 연동 receivedToday: 0, sentThisMonth: 0, diff --git a/frontend/app/(main)/admin/screenMng/page.tsx b/frontend/app/(main)/admin/screenMng/page.tsx index 88dff27f..54da701b 100644 --- a/frontend/app/(main)/admin/screenMng/page.tsx +++ b/frontend/app/(main)/admin/screenMng/page.tsx @@ -83,7 +83,7 @@ export default function ScreenManagementPage() {
{category.category_code}
+{category.category_code}
{category.description &&{category.description}
}{createForm.formState.errors.categoryCode.message}
+{createForm.formState.errors.categoryCode.message}
)} {!createForm.formState.errors.categoryCode && (카테고리 코드는 수정할 수 없습니다.
{updateForm.formState.errors.categoryName.message}
+{updateForm.formState.errors.categoryName.message}
) : createForm.formState.errors.categoryName && ( -{createForm.formState.errors.categoryName.message}
+{createForm.formState.errors.categoryName.message}
)} {!(isEditing ? updateForm.formState.errors.categoryName : createForm.formState.errors.categoryName) && ({updateForm.formState.errors.categoryNameEng.message}
+{updateForm.formState.errors.categoryNameEng.message}
) : createForm.formState.errors.categoryNameEng && ( -{createForm.formState.errors.categoryNameEng.message}
+{createForm.formState.errors.categoryNameEng.message}
)} {!(isEditing ? updateForm.formState.errors.categoryNameEng @@ -289,20 +289,20 @@ export function CodeCategoryFormModal({ className={ isEditing ? updateForm.formState.errors.description - ? "border-red-500" + ? "border-destructive" : "" : createForm.formState.errors.description - ? "border-red-500" + ? "border-destructive" : "" } onBlur={() => handleFieldBlur("description")} /> {isEditing ? updateForm.formState.errors.description && ( -{updateForm.formState.errors.description.message}
+{updateForm.formState.errors.description.message}
) : createForm.formState.errors.description && ( -{createForm.formState.errors.description.message}
+{createForm.formState.errors.description.message}
)}{updateForm.formState.errors.sortOrder.message}
+{updateForm.formState.errors.sortOrder.message}
) : createForm.formState.errors.sortOrder && ( -{createForm.formState.errors.sortOrder.message}
+{createForm.formState.errors.sortOrder.message}
)}카테고리를 불러오는 중 오류가 발생했습니다.
+카테고리를 불러오는 중 오류가 발생했습니다.
코드를 불러오는 중 오류가 발생했습니다.
+코드를 불러오는 중 오류가 발생했습니다.
+
{activeCode.codeValue || activeCode.code_value}
{activeCode.description && ( diff --git a/frontend/components/admin/CodeFormModal.tsx b/frontend/components/admin/CodeFormModal.tsx index 6e915904..26b617a4 100644 --- a/frontend/components/admin/CodeFormModal.tsx +++ b/frontend/components/admin/CodeFormModal.tsx @@ -168,7 +168,7 @@ export function CodeFormModal({ isOpen, onClose, categoryCode, editingCode, code {...form.register("codeValue")} disabled={isLoading || isEditing} // 수정 시에는 비활성화 placeholder="코드값을 입력하세요" - className={(form.formState.errors as any)?.codeValue ? "border-red-500" : ""} + className={(form.formState.errors as any)?.codeValue ? "border-destructive" : ""} onBlur={(e) => { const value = e.target.value.trim(); if (value && !isEditing) { @@ -180,7 +180,7 @@ export function CodeFormModal({ isOpen, onClose, categoryCode, editingCode, code }} /> {(form.formState.errors as any)?.codeValue && ( -{getErrorMessage((form.formState.errors as any)?.codeValue)}
+{getErrorMessage((form.formState.errors as any)?.codeValue)}
)} {!isEditing && !(form.formState.errors as any)?.codeValue && ({getErrorMessage(form.formState.errors.codeName)}
+{getErrorMessage(form.formState.errors.codeName)}
)} {!form.formState.errors.codeName && ({getErrorMessage(form.formState.errors.codeNameEng)}
+{getErrorMessage(form.formState.errors.codeNameEng)}
)} {!form.formState.errors.codeNameEng && ({getErrorMessage(form.formState.errors.description)}
+{getErrorMessage(form.formState.errors.description)}
)}{getErrorMessage(form.formState.errors.sortOrder)}
+{getErrorMessage(form.formState.errors.sortOrder)}
)}{tableNameError}
} + {tableNameError &&{tableNameError}
}영문자로 시작, 영문자/숫자/언더스코어만 사용 가능
+
{getUITextSync("menu.management.admin.description")}
+
{getUITextSync("menu.management.user.description")}
현재 실행 중인 작업
@@ -193,7 +193,7 @@ export default function MonitoringDashboard() {주의가 필요한 작업
@@ -269,7 +269,7 @@ export default function MonitoringDashboard() {+
URL: {selectedMenu.menu_url || selectedMenu.MENU_URL || (selectedMenu as any).menu_url || "없음"}
-+
설명:{" "} {selectedMenu.menu_desc || selectedMenu.MENU_DESC || (selectedMenu as any).menu_desc || "없음"}
@@ -294,7 +294,7 @@ export const ScreenAssignmentTab: React.FC+
테이블: {screen.tableName} | 생성일: {screen.createdDate.toLocaleDateString()}
{screen.description &&{screen.description}
} @@ -306,7 +306,7 @@ export const ScreenAssignmentTab: React.FC테이블: {screen.tableName}
+테이블: {screen.tableName}
{code.codeValue || code.code_value}
+{code.codeValue || code.code_value}
{code.description &&{code.description}
}{message}
+{message}
비밀번호가 일치하지 않습니다.
} + {showMismatchError &&비밀번호가 일치하지 않습니다.
} {isPasswordMatch &&비밀번호가 일치합니다.
}+
데이터 소스와 차트 설정을 구성하세요