All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m41s
- 3 shared component PageHeader/KpiCard/WidgetCard ×2 app SHA256-identical; tái dùng token Hồ sơ NS (.app-gradient-brand/.card-accent/.icon-chip/.stat-value/.label-eyebrow + accent palette teal/violet/amberx/greenx); gotcha #66 text-white! trên gradient header. - OfficeDashboardPage 2-cột widget kiểu PURO HomePage: Đề xuất/Đơn từ/Ticket/Phòng họp hôm nay + "Công việc của tôi" + Thao tác nhanh. Reuse query endpoint sẵn có (shared TanStack cache, KHÔNG BE/API mới), đếm client-side, loading/error/empty mỗi widget. - Sync fe-admin/src/index.css ← fe-user (đóng drift S66-S68: heading 600→700, ink #0f172a→#0b1220, label-eyebrow slate→brand-600 + rule gotcha #66). Nay 2 app đồng bộ. - Menu key Off_Dashboard (MenuKeys.cs const + All[] + DbInitializer seed Order 0 dưới Off) — no migration, idempotent. GIỮ ẨN non-Admin (RevokeTemporarilyHiddenModules StartsWith Off). Chưa golive. - Wire 4-place ×2 app: App.tsx route /office/dashboard + menuKeys.ts + Layout staticMap. - Fix KpiCard activeBorder -300 → -500 (accent palette chỉ 50/100/500/600/700 — chống "vỡ màu im lặng" Tailwind v4: border-teal-300 rơi default Tailwind, border-amberx-300 drop hẳn). - Build PASS x2 (fe-user index-DrxDysO7 / fe-admin index-TbkadgKd) + dotnet slnx 0/0. reviewer PASS 0 blocker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
124 lines
7.4 KiB
TypeScript
124 lines
7.4 KiB
TypeScript
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
|
|
import { Toaster } from 'sonner'
|
|
import { AuthProvider } from '@/contexts/AuthContext'
|
|
import { ProtectedRoute } from '@/components/ProtectedRoute'
|
|
import { Layout } from '@/components/Layout'
|
|
import { LoginPage } from '@/pages/LoginPage'
|
|
import { DashboardPage } from '@/pages/DashboardPage'
|
|
import { SuppliersPage } from '@/pages/master/SuppliersPage'
|
|
import { ProjectsPage } from '@/pages/master/ProjectsPage'
|
|
import { DepartmentsPage } from '@/pages/master/DepartmentsPage'
|
|
import { CatalogsPage } from '@/pages/master/CatalogsPage'
|
|
import { PermissionsPage } from '@/pages/system/PermissionsPage'
|
|
import { MenuVisibilityPage } from '@/pages/system/MenuVisibilityPage'
|
|
import { RolesPage } from '@/pages/system/RolesPage'
|
|
import { WorkflowsPage } from '@/pages/system/WorkflowsPage'
|
|
import { PeWorkflowsPage } from '@/pages/system/PeWorkflowsPage'
|
|
import { ApprovalWorkflowsV2Page } from '@/pages/system/ApprovalWorkflowsV2Page'
|
|
import { FormsPage } from '@/pages/forms/FormsPage'
|
|
import { ContractsListPage } from '@/pages/contracts/ContractsListPage'
|
|
import { ContractDetailPage } from '@/pages/contracts/ContractDetailPage'
|
|
import { ContractCreatePage } from '@/pages/contracts/ContractCreatePage'
|
|
import { ReportsPage } from '@/pages/ReportsPage'
|
|
import { UsersPage } from '@/pages/system/UsersPage'
|
|
import { PurchaseEvaluationsListPage, PurchaseEvaluationDetailPage } from '@/pages/pe/PurchaseEvaluationsListPage'
|
|
import { PurchaseEvaluationCreatePage } from '@/pages/pe/PurchaseEvaluationCreatePage'
|
|
import { PurchaseEvaluationWorkspacePage } from '@/pages/pe/PurchaseEvaluationWorkspacePage'
|
|
import { EmployeesListPage } from '@/pages/hrm/EmployeesListPage'
|
|
import { EmployeeCreatePage } from '@/pages/hrm/EmployeeCreatePage'
|
|
import { HrmConfigsPage } from '@/pages/hrm/HrmConfigsPage'
|
|
import { InternalDirectoryPage } from '@/pages/office/InternalDirectoryPage'
|
|
import { MeetingCalendarPage } from '@/pages/office/MeetingCalendarPage'
|
|
import { MeetingRoomsPage } from '@/pages/office/MeetingRoomsPage'
|
|
import { ProposalCreatePage } from '@/pages/office/ProposalCreatePage'
|
|
import { ProposalDetailPage } from '@/pages/office/ProposalDetailPage'
|
|
import { ProposalsListPage } from '@/pages/office/ProposalsListPage'
|
|
import { WorkflowAppsListPage } from '@/pages/office/WorkflowAppsListPage'
|
|
import { WorkflowAppDetailPage } from '@/pages/office/WorkflowAppDetailPage'
|
|
import { ItTicketsPage } from '@/pages/office/ItTicketsPage'
|
|
import { MyAttendancePage } from '@/pages/office/MyAttendancePage'
|
|
import { AttendanceReportPage } from '@/pages/office/AttendanceReportPage'
|
|
import { OfficeDashboardPage } from '@/pages/office/OfficeDashboardPage'
|
|
import { HrmDashboardPage } from '@/pages/hrm/HrmDashboardPage'
|
|
|
|
function App() {
|
|
return (
|
|
<BrowserRouter>
|
|
<AuthProvider>
|
|
<Routes>
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route
|
|
element={
|
|
<ProtectedRoute>
|
|
<Layout />
|
|
</ProtectedRoute>
|
|
}
|
|
>
|
|
<Route path="/dashboard" element={<DashboardPage />} />
|
|
<Route path="/master/suppliers" element={<SuppliersPage />} />
|
|
<Route path="/master/projects" element={<ProjectsPage />} />
|
|
<Route path="/master/departments" element={<DepartmentsPage />} />
|
|
<Route path="/master/catalogs" element={<Navigate to="/master/catalogs/units" replace />} />
|
|
<Route path="/master/catalogs/:kind" element={<CatalogsPage />} />
|
|
<Route path="/system/users" element={<UsersPage />} />
|
|
<Route path="/system/roles" element={<RolesPage />} />
|
|
<Route path="/system/permissions" element={<PermissionsPage />} />
|
|
<Route path="/system/menu-visibility" element={<MenuVisibilityPage />} />
|
|
<Route path="/system/workflows" element={<WorkflowsPage />} />
|
|
<Route path="/system/workflows/:typeCode" element={<WorkflowsPage />} />
|
|
<Route path="/system/pe-workflows" element={<PeWorkflowsPage />} />
|
|
<Route path="/system/pe-workflows/:typeCode" element={<PeWorkflowsPage />} />
|
|
{/* Quy trình duyệt MỚI (Mig 22 — UAT) */}
|
|
<Route path="/system/approval-workflows-v2" element={<ApprovalWorkflowsV2Page />} />
|
|
<Route path="/system/approval-workflows-v2/:typeCode" element={<ApprovalWorkflowsV2Page />} />
|
|
<Route path="/forms" element={<FormsPage />} />
|
|
<Route path="/contracts" element={<ContractsListPage />} />
|
|
<Route path="/contracts/new" element={<ContractCreatePage />} />
|
|
<Route path="/contracts/:id" element={<ContractDetailPage />} />
|
|
<Route path="/purchase-evaluations" element={<PurchaseEvaluationsListPage />} />
|
|
<Route path="/purchase-evaluations/workspace" element={<PurchaseEvaluationWorkspacePage />} />
|
|
<Route path="/purchase-evaluations/new" element={<PurchaseEvaluationCreatePage />} />
|
|
<Route path="/purchase-evaluations/:id" element={<PurchaseEvaluationDetailPage />} />
|
|
{/* Hồ sơ Nhân sự (Phase 10.1 G-H1 — Mig 34) */}
|
|
<Route path="/employees" element={<EmployeesListPage />} />
|
|
<Route path="/employees/new" element={<EmployeeCreatePage />} />
|
|
{/* Cấu hình HRM (Phase 10.2 G-H2 — Mig 35) */}
|
|
<Route path="/hrm/configs" element={<Navigate to="/hrm/configs/leave-types" replace />} />
|
|
<Route path="/hrm/configs/:kind" element={<HrmConfigsPage />} />
|
|
{/* Văn phòng số — Bảng điều khiển (landing dashboard, Off_Dashboard) */}
|
|
<Route path="/office/dashboard" element={<OfficeDashboardPage />} />
|
|
{/* Văn phòng số — Danh bạ nội bộ (Phase 10.2 G-O1) */}
|
|
<Route path="/directory" element={<InternalDirectoryPage />} />
|
|
{/* Văn phòng số — Phòng họp Booking + Catalog (Phase 10.2 G-O2 — Mig 36 S36) */}
|
|
<Route path="/meeting-calendar" element={<MeetingCalendarPage />} />
|
|
<Route path="/meeting-rooms" element={<MeetingRoomsPage />} />
|
|
<Route path="/proposals" element={<ProposalsListPage />} />
|
|
<Route path="/proposals/new" element={<ProposalCreatePage />} />
|
|
<Route path="/proposals/:id" element={<ProposalDetailPage />} />
|
|
<Route path="/workflow-apps/:kind" element={<WorkflowAppsListPage />} />
|
|
<Route path="/workflow-apps/:kind/:id" element={<WorkflowAppDetailPage />} />
|
|
<Route path="/it-tickets" element={<ItTicketsPage />} />
|
|
<Route path="/attendance" element={<MyAttendancePage />} />
|
|
{/* Báo cáo chấm công (P11-E) — admin-only, reachable qua button trên trang Chấm công */}
|
|
<Route path="/attendance/report" element={<AttendanceReportPage />} />
|
|
<Route path="/hr/dashboard" element={<HrmDashboardPage />} />
|
|
<Route path="/reports" element={<ReportsPage />} />
|
|
<Route path="/" element={<Navigate to="/dashboard" replace />} />
|
|
<Route
|
|
path="*"
|
|
element={
|
|
<div className="p-8 text-slate-500">
|
|
Trang này chưa được build — sẽ có ở Phase tiếp theo.
|
|
</div>
|
|
}
|
|
/>
|
|
</Route>
|
|
</Routes>
|
|
<Toaster richColors position="top-right" />
|
|
</AuthProvider>
|
|
</BrowserRouter>
|
|
)
|
|
}
|
|
|
|
export default App
|