diff --git a/Frontend/erp-system/app/dashboard/hrm/attendance/[id]/page.tsx b/Frontend/erp-system/app/dashboard/hrm/attendance/[id]/page.tsx index 9df1019..8ff207e 100644 --- a/Frontend/erp-system/app/dashboard/hrm/attendance/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/attendance/[id]/page.tsx @@ -112,7 +112,7 @@ export default function AttendanceBatchDetailPage() { return (
-
+

{batch.docNo}

{new Date(batch.periodStart).toLocaleDateString()} – {new Date(batch.periodEnd).toLocaleDateString()} · {batch.rowCountTotal} rows

@@ -132,9 +132,9 @@ export default function AttendanceBatchDetailPage() { Reason setUnlockReason(e.target.value)} /> -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/attendance/page.tsx b/Frontend/erp-system/app/dashboard/hrm/attendance/page.tsx index f0feb61..97d18c9 100644 --- a/Frontend/erp-system/app/dashboard/hrm/attendance/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/attendance/page.tsx @@ -69,7 +69,7 @@ export default function AttendanceBatchesPage() { return (
-
+

Attendance

Upload → Preview → Confirm. Once Confirmed, a batch becomes payroll's source of truth.

@@ -86,7 +86,7 @@ export default function AttendanceBatchesPage() { Columns: Employee Code, Date, Check In, Check Out. -
+
Period start setPeriodStart(e.target.value)} /> Period end setPeriodEnd(e.target.value)} />
@@ -95,9 +95,9 @@ export default function AttendanceBatchesPage() { setFile(e.target.files?.[0] ?? null)} /> -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/employees/[id]/page.tsx b/Frontend/erp-system/app/dashboard/hrm/employees/[id]/page.tsx index 9f33dee..d1e79a6 100644 --- a/Frontend/erp-system/app/dashboard/hrm/employees/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/employees/[id]/page.tsx @@ -208,7 +208,7 @@ export default function EmployeeDetailPage() { return (
-
+

{employee.fullName}

@@ -237,7 +237,7 @@ export default function EmployeeDetailPage() { {tab === "Overview" && ( -

+
Full name setEmployee({ ...employee, fullName: e.target.value })} /> Email setEmployee({ ...employee, email: e.target.value })} /> NIC setEmployee({ ...employee, nic: e.target.value })} /> @@ -363,7 +363,7 @@ export default function EmployeeDetailPage() { Supersedes the current open-ended structure from this date. -
+
Effective from setStructureEffectiveFrom(e.target.value)} /> Basic salary setStructureBasic(Number(e.target.value))} />
@@ -383,9 +383,9 @@ export default function EmployeeDetailPage() {
-
- - +
+ +
@@ -433,7 +433,7 @@ export default function EmployeeDetailPage() { LoanAdvance -
+
Principal setLoanPrincipal(Number(e.target.value))} /> Installment amount setLoanInstallmentAmount(Number(e.target.value))} /> # installments setLoanCount(Number(e.target.value))} /> @@ -445,9 +445,9 @@ export default function EmployeeDetailPage() {
-
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/employees/page.tsx b/Frontend/erp-system/app/dashboard/hrm/employees/page.tsx index 51651f0..f38ce2e 100644 --- a/Frontend/erp-system/app/dashboard/hrm/employees/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/employees/page.tsx @@ -121,7 +121,7 @@ export default function EmployeesPage() { return (
-
+

Employees

Staff records — separate from system login accounts (see the link chip below).

@@ -134,7 +134,7 @@ export default function EmployeesPage() { Not every employee needs a login — a system user account is optional and separate. -
+
Employee code setForm((f) => ({ ...f, employeeCode: e.target.value }))} aria-invalid={!!errors.employeeCode} /> @@ -170,7 +170,7 @@ export default function EmployeesPage() {
)} -
+
Department -
+
Start date setStartDate(e.target.value)} /> End date setEndDate(e.target.value)} />
Reason (optional) setReason(e.target.value)} /> -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/lines/[lineId]/page.tsx b/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/lines/[lineId]/page.tsx index b5eb4f2..0f3c797 100644 --- a/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/lines/[lineId]/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/lines/[lineId]/page.tsx @@ -64,7 +64,7 @@ export default function PayrollLineDetailPage() {
-
+
Present days: {line.presentDays}
Absent days: {line.absentDays}
Leave days: {line.leaveDays}
diff --git a/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/page.tsx b/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/page.tsx index 2186cd4..c7d3005 100644 --- a/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/payroll/[id]/page.tsx @@ -88,12 +88,12 @@ export default function PayrollRunDetailPage() { return (
-
+

{run.docNo}

{run.periodMonth.toString().padStart(2, "0")}/{run.periodYear} · {run.employeeCount} employees

-
+
{run.status} {run.status === "Draft" && } {run.status === "Approved" && } @@ -110,9 +110,9 @@ export default function PayrollRunDetailPage() { Reason setUnlockReason(e.target.value)} /> -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/payroll/page.tsx b/Frontend/erp-system/app/dashboard/hrm/payroll/page.tsx index e09f753..f4d7f20 100644 --- a/Frontend/erp-system/app/dashboard/hrm/payroll/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/payroll/page.tsx @@ -63,7 +63,7 @@ export default function PayrollRunsPage() { return (
-
+

Payroll

Generate → Review → Approve → Lock → Payslips.

@@ -76,14 +76,14 @@ export default function PayrollRunsPage() { Blocked if attendance for this period isn't fully Confirmed yet. -
+
Year setPeriodYear(Number(e.target.value))} /> Month setPeriodMonth(Number(e.target.value))} />
-
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/departments/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/departments/page.tsx index ade8dc2..6e7cea4 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/departments/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/departments/page.tsx @@ -92,7 +92,7 @@ export default function DepartmentsPage() { return (
-
+

Departments

Org structure — unlimited nesting, optionally scoped to a branch.

@@ -140,9 +140,9 @@ export default function DepartmentsPage() { -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/document-types/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/document-types/page.tsx index 42663db..63d0c9c 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/document-types/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/document-types/page.tsx @@ -79,7 +79,7 @@ export default function DocumentTypesPage() { return (
-
+

Document Types

The staff document catalog — NIC, contracts, certificates, etc.

@@ -120,9 +120,9 @@ export default function DocumentTypesPage() { Track expiry date (e.g. passport, visa) -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/leave-types/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/leave-types/page.tsx index 633791c..7b81dd0 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/leave-types/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/leave-types/page.tsx @@ -81,7 +81,7 @@ export default function LeaveTypesPage() { return (
-
+

Leave Types

Annual, Casual, Medical, Unpaid, etc. — drives Attendance's OnLeave classification and Payroll's No-Pay calc.

@@ -121,9 +121,9 @@ export default function LeaveTypesPage() { Carry-forward allowed -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/salary-components/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/salary-components/page.tsx index 126307f..df555ad 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/salary-components/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/salary-components/page.tsx @@ -78,7 +78,7 @@ export default function SalaryComponentsPage() { return (
-
+

Salary Components

Allowances and ad hoc other deductions — OT/Late/No-Pay/Loan/EPF/ETF/Tax are computed automatically, not components.

@@ -120,9 +120,9 @@ export default function SalaryComponentsPage() { EPF/ETF applicable -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/statutory/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/statutory/page.tsx index 737fd7a..5cda7d8 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/statutory/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/statutory/page.tsx @@ -85,7 +85,7 @@ export default function StatutorySettingsPage() { {error &&
{error}
}
-
+

EPF / ETF Rates

New Setting} /> @@ -101,9 +101,9 @@ export default function StatutorySettingsPage() { ETF employer rate (0-1) setEtfEmployerRate(Number(e.target.value))} /> Default OT multiplier setOtMultiplierDefault(Number(e.target.value))} /> -
- - +
+ +
@@ -133,7 +133,7 @@ export default function StatutorySettingsPage() {
-
+

Tax Slabs

New Slab} /> @@ -148,9 +148,9 @@ export default function StatutorySettingsPage() { Upper bound (optional) setUpperBound(e.target.value)} placeholder="And above" /> Rate (0-1) setRate(Number(e.target.value))} /> -
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/hrm/settings/work-shifts/page.tsx b/Frontend/erp-system/app/dashboard/hrm/settings/work-shifts/page.tsx index 1c1c7f0..28523cd 100644 --- a/Frontend/erp-system/app/dashboard/hrm/settings/work-shifts/page.tsx +++ b/Frontend/erp-system/app/dashboard/hrm/settings/work-shifts/page.tsx @@ -99,7 +99,7 @@ export default function WorkShiftsPage() { return (
-
+

Work Shifts

The baseline Attendance computes Late/Early/OT against.

@@ -122,7 +122,7 @@ export default function WorkShiftsPage() { setName(e.target.value)} aria-invalid={!!errors.name} /> -
+
Start time setStartTime(e.target.value)} /> @@ -136,7 +136,7 @@ export default function WorkShiftsPage() { setIsOvernight(v === true)} /> Overnight shift (end time rolls past midnight) -
+
Grace (minutes) setGraceMinutes(Number(e.target.value))} /> @@ -166,9 +166,9 @@ export default function WorkShiftsPage() {
-
- - +
+ +
diff --git a/Frontend/erp-system/app/dashboard/layout.tsx b/Frontend/erp-system/app/dashboard/layout.tsx index 17b3edc..4ac5d87 100644 --- a/Frontend/erp-system/app/dashboard/layout.tsx +++ b/Frontend/erp-system/app/dashboard/layout.tsx @@ -13,10 +13,10 @@ export default function DashboardLayout({
-
+
-
-
+
+
diff --git a/Frontend/erp-system/app/dashboard/procurement/purchase-orders/[id]/page.tsx b/Frontend/erp-system/app/dashboard/procurement/purchase-orders/[id]/page.tsx index cf3db2a..65c6a6b 100644 --- a/Frontend/erp-system/app/dashboard/procurement/purchase-orders/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/procurement/purchase-orders/[id]/page.tsx @@ -267,7 +267,7 @@ export default function PurchaseOrderDetailPage() { return (
-
+
@@ -283,7 +283,7 @@ export default function PurchaseOrderDetailPage() {
-
+
{po.status === "Draft" && ( <> -
diff --git a/Frontend/erp-system/app/dashboard/products/categories/[id]/page.tsx b/Frontend/erp-system/app/dashboard/products/categories/[id]/page.tsx index c41f9a9..0541ec0 100644 --- a/Frontend/erp-system/app/dashboard/products/categories/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/products/categories/[id]/page.tsx @@ -111,7 +111,7 @@ export default function CategorySubCategoriesPage() { return (
-
+
@@ -138,11 +138,11 @@ export default function CategorySubCategoriesPage() { -
- -
diff --git a/Frontend/erp-system/app/dashboard/products/categories/page.tsx b/Frontend/erp-system/app/dashboard/products/categories/page.tsx index d11549e..566f376 100644 --- a/Frontend/erp-system/app/dashboard/products/categories/page.tsx +++ b/Frontend/erp-system/app/dashboard/products/categories/page.tsx @@ -154,7 +154,7 @@ export default function CategoriesPage() { return (
-
+
@@ -179,11 +179,11 @@ export default function CategoriesPage() { -
- -
diff --git a/Frontend/erp-system/app/dashboard/products/item-types/page.tsx b/Frontend/erp-system/app/dashboard/products/item-types/page.tsx index 71d6d22..1381bcc 100644 --- a/Frontend/erp-system/app/dashboard/products/item-types/page.tsx +++ b/Frontend/erp-system/app/dashboard/products/item-types/page.tsx @@ -108,7 +108,7 @@ export default function ItemTypesPage() { return (
-
+
@@ -141,11 +141,11 @@ export default function ItemTypesPage() { -
- -
diff --git a/Frontend/erp-system/app/dashboard/products/page.tsx b/Frontend/erp-system/app/dashboard/products/page.tsx index e5b4e9e..3e09fce 100644 --- a/Frontend/erp-system/app/dashboard/products/page.tsx +++ b/Frontend/erp-system/app/dashboard/products/page.tsx @@ -100,7 +100,7 @@ export default function ItemsPage() { return (
-
+

Items

Item master — SKU, tracking mode, category, default vendor (FR-MD-01).

diff --git a/Frontend/erp-system/app/dashboard/products/uoms/page.tsx b/Frontend/erp-system/app/dashboard/products/uoms/page.tsx index 70a3ebd..960cb72 100644 --- a/Frontend/erp-system/app/dashboard/products/uoms/page.tsx +++ b/Frontend/erp-system/app/dashboard/products/uoms/page.tsx @@ -57,7 +57,7 @@ export default function UomsPage() { return (
-
+
@@ -82,11 +82,11 @@ export default function UomsPage() { -
- -
diff --git a/Frontend/erp-system/app/dashboard/receiving/grn/[id]/page.tsx b/Frontend/erp-system/app/dashboard/receiving/grn/[id]/page.tsx index cab3278..26d1b7d 100644 --- a/Frontend/erp-system/app/dashboard/receiving/grn/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/receiving/grn/[id]/page.tsx @@ -116,7 +116,7 @@ export default function GrnDetailPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/receiving/grn/new/page.tsx b/Frontend/erp-system/app/dashboard/receiving/grn/new/page.tsx index d16dadf..292283b 100644 --- a/Frontend/erp-system/app/dashboard/receiving/grn/new/page.tsx +++ b/Frontend/erp-system/app/dashboard/receiving/grn/new/page.tsx @@ -400,20 +400,7 @@ export default function NewGrnPage() { )}
-
-
-

Lines

- {mode === "po" && ( -

- Lines default from the PO's open quantities — add a row for anything received that wasn't ordered. -

- )} -
- -
+

Lines

{mode === "po" && ( @@ -422,7 +409,7 @@ export default function NewGrnPage() {

)}
-
+
{/* Off-PO items are allowed on a PO-based GRN — the server treats a line with no poLineId as a direct receipt (docs/10 FR-GRN-01, revised). */} -
diff --git a/Frontend/erp-system/app/dashboard/settings/users/page.tsx b/Frontend/erp-system/app/dashboard/settings/users/page.tsx index 715a8c4..08cbdaa 100644 --- a/Frontend/erp-system/app/dashboard/settings/users/page.tsx +++ b/Frontend/erp-system/app/dashboard/settings/users/page.tsx @@ -147,7 +147,7 @@ export default function UsersPage() { return (
-
+

Users

@@ -242,11 +242,11 @@ export default function UsersPage() { -

- -
diff --git a/Frontend/erp-system/app/dashboard/stock/adjustments/page.tsx b/Frontend/erp-system/app/dashboard/stock/adjustments/page.tsx index b0520c2..84d7439 100644 --- a/Frontend/erp-system/app/dashboard/stock/adjustments/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/adjustments/page.tsx @@ -37,7 +37,7 @@ export default function AdjustmentsListPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/stock/counts/[id]/page.tsx b/Frontend/erp-system/app/dashboard/stock/counts/[id]/page.tsx index 3e78c47..0a61115 100644 --- a/Frontend/erp-system/app/dashboard/stock/counts/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/counts/[id]/page.tsx @@ -89,7 +89,7 @@ export default function CountDetailPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/stock/counts/page.tsx b/Frontend/erp-system/app/dashboard/stock/counts/page.tsx index 1d1dd05..6269438 100644 --- a/Frontend/erp-system/app/dashboard/stock/counts/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/counts/page.tsx @@ -34,7 +34,7 @@ export default function CountsListPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/stock/transfers/[id]/page.tsx b/Frontend/erp-system/app/dashboard/stock/transfers/[id]/page.tsx index b90ae6b..32574bd 100644 --- a/Frontend/erp-system/app/dashboard/stock/transfers/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/transfers/[id]/page.tsx @@ -83,7 +83,7 @@ export default function TransferDetailPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/stock/transfers/page.tsx b/Frontend/erp-system/app/dashboard/stock/transfers/page.tsx index 273ebe9..9282fab 100644 --- a/Frontend/erp-system/app/dashboard/stock/transfers/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/transfers/page.tsx @@ -34,7 +34,7 @@ export default function TransfersListPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/stock/wastage/page.tsx b/Frontend/erp-system/app/dashboard/stock/wastage/page.tsx index 578331f..b63d6cf 100644 --- a/Frontend/erp-system/app/dashboard/stock/wastage/page.tsx +++ b/Frontend/erp-system/app/dashboard/stock/wastage/page.tsx @@ -66,7 +66,7 @@ export default function WastagePage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/vendors/[id]/page.tsx b/Frontend/erp-system/app/dashboard/vendors/[id]/page.tsx index b04f997..85730ed 100644 --- a/Frontend/erp-system/app/dashboard/vendors/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/vendors/[id]/page.tsx @@ -130,7 +130,7 @@ export default function VendorDetailPage() { return (
-
+
diff --git a/Frontend/erp-system/app/dashboard/vendors/page.tsx b/Frontend/erp-system/app/dashboard/vendors/page.tsx index 38ee91e..c3afcbf 100644 --- a/Frontend/erp-system/app/dashboard/vendors/page.tsx +++ b/Frontend/erp-system/app/dashboard/vendors/page.tsx @@ -127,7 +127,7 @@ export default function VendorsPage() { return (
-
+

Vendors

Supplier master data — code, terms, tax registration, currency (FR-MD-06).

@@ -172,11 +172,11 @@ export default function VendorsPage() { -
- -
@@ -303,7 +303,7 @@ export default function VendorsPage() {
- }>Close + }>Close
diff --git a/Frontend/erp-system/app/dashboard/warehouse/[id]/page.tsx b/Frontend/erp-system/app/dashboard/warehouse/[id]/page.tsx index 44705a8..d8b6826 100644 --- a/Frontend/erp-system/app/dashboard/warehouse/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/warehouse/[id]/page.tsx @@ -88,7 +88,7 @@ export default function WarehouseDetailPage() { return (
-
+
@@ -124,11 +124,11 @@ export default function WarehouseDetailPage() { setBinType(e.target.value)} placeholder="Shelf, Pallet, …" /> -
- -
diff --git a/Frontend/erp-system/app/dashboard/warehouse/page.tsx b/Frontend/erp-system/app/dashboard/warehouse/page.tsx index 8a2aad4..af4d534 100644 --- a/Frontend/erp-system/app/dashboard/warehouse/page.tsx +++ b/Frontend/erp-system/app/dashboard/warehouse/page.tsx @@ -98,7 +98,7 @@ export default function WarehousesPage() { return (
-
+
@@ -134,11 +134,11 @@ export default function WarehousesPage() { -
- -
diff --git a/Frontend/erp-system/app/globals.css b/Frontend/erp-system/app/globals.css index 24bab46..a0ee55b 100644 --- a/Frontend/erp-system/app/globals.css +++ b/Frontend/erp-system/app/globals.css @@ -2,7 +2,7 @@ @import "tw-animate-css"; @import "shadcn/tailwind.css"; -@custom-variant dark (&:is(.dark *)); +@custom-variant dark (&:is(.dark *, .vibrant *)); @theme inline { --color-background: var(--background); @@ -129,6 +129,69 @@ --sidebar-ring: oklch(0.68 0.186 265.215); } +/* Vibrant — the "System" toggle option. Light content area (background, + cards, header, table panels) paired with a dark sidebar — the same split + Linear/Vercel/Notion use in their light themes. One violet accent drives + every interactive state; the sidebar keeps its own dark token family + (applied via .sidebar-surface below) so it stays dark regardless. */ +.vibrant { + --background: oklch(0.97 0.004 265); + --foreground: oklch(0.2 0.02 265); + --card: oklch(0.995 0.002 265); + --card-foreground: oklch(0.2 0.02 265); + --popover: oklch(0.995 0.002 265); + --popover-foreground: oklch(0.2 0.02 265); + --primary: oklch(0.55 0.2 275); + --primary-foreground: oklch(0.98 0 0); + --secondary: oklch(0.93 0.02 275); + --secondary-foreground: oklch(0.32 0.15 275); + --muted: oklch(0.94 0.006 265); + --muted-foreground: oklch(0.48 0.02 265); + --accent: oklch(0.55 0.14 210); + --accent-foreground: oklch(0.98 0 0); + --destructive: oklch(0.58 0.22 25); + --border: oklch(0.88 0.012 265); + --input: oklch(0.92 0.01 265); + --ring: oklch(0.55 0.2 275); + --success: oklch(0.55 0.15 150); + --warning: oklch(0.72 0.15 80); + --error: oklch(0.58 0.22 25); + --info: oklch(0.55 0.14 210); + --chart-1: oklch(0.55 0.2 275); + --chart-2: oklch(0.55 0.14 210); + --chart-3: oklch(0.55 0.15 150); + --chart-4: oklch(0.72 0.15 80); + --chart-5: oklch(0.58 0.22 25); + --sidebar: oklch(0.18 0.02 265); + --sidebar-foreground: oklch(0.96 0.005 265); + --sidebar-primary: oklch(0.64 0.19 275); + --sidebar-primary-foreground: oklch(0.98 0 0); + --sidebar-accent: oklch(0.28 0.03 265); + --sidebar-accent-foreground: oklch(0.96 0.005 265); + --sidebar-border: oklch(0.26 0.025 265); + --sidebar-ring: oklch(0.64 0.19 275); +} + +/* Re-points the shared tokens (--card, --foreground, --muted*, --primary...) + at the sidebar's own dark family for anything inside this scope, so + AppSidebar's existing bg-card/text-foreground/text-muted-foreground + classes render dark without AppSidebar.tsx needing sidebar-specific + classes. CSS custom properties resolve against the cascade at point of + use, so this indirection (the same trick .dark/.vibrant use at the root) + works scoped to just this subtree. */ +.vibrant .sidebar-surface { + --card: var(--sidebar); + --card-foreground: var(--sidebar-foreground); + --popover: var(--sidebar); + --popover-foreground: var(--sidebar-foreground); + --foreground: var(--sidebar-foreground); + --muted: var(--sidebar-accent); + --muted-foreground: oklch(0.72 0.015 265); + --primary: var(--sidebar-primary); + --primary-foreground: var(--sidebar-primary-foreground); + --border: var(--sidebar-border); +} + @layer base { * { @apply border-border outline-ring/50; @@ -154,4 +217,5 @@ h4 { @apply text-lg; } -} \ No newline at end of file +} + diff --git a/Frontend/erp-system/app/layout.tsx b/Frontend/erp-system/app/layout.tsx index b596f10..b1c1f57 100644 --- a/Frontend/erp-system/app/layout.tsx +++ b/Frontend/erp-system/app/layout.tsx @@ -31,7 +31,12 @@ export default function RootLayout({ suppressHydrationWarning > - + {children} diff --git a/Frontend/erp-system/app/login/forgot/otp/page.tsx b/Frontend/erp-system/app/login/forgot/otp/page.tsx index 05c8cde..0d22975 100644 --- a/Frontend/erp-system/app/login/forgot/otp/page.tsx +++ b/Frontend/erp-system/app/login/forgot/otp/page.tsx @@ -25,10 +25,10 @@ export default function ForgotOtpPage() { return (
-
+
-
- +
+

Verify your email

@@ -46,7 +46,7 @@ export default function ForgotOtpPage() { e.preventDefault() handleResend() }} - className="text-sm font-medium text-black hover:text-black/80 transition-colors" + className="text-sm font-medium text-foreground hover:text-foreground/80 transition-colors" > Didn't receive the code? Resend @@ -57,10 +57,10 @@ export default function ForgotOtpPage() {
- + - +
diff --git a/Frontend/erp-system/app/login/forgot/page.tsx b/Frontend/erp-system/app/login/forgot/page.tsx index 1b02ea7..e78493b 100644 --- a/Frontend/erp-system/app/login/forgot/page.tsx +++ b/Frontend/erp-system/app/login/forgot/page.tsx @@ -19,7 +19,7 @@ export default function ForgotEmailPage() { return (
-
+

Reset your password

Enter the email address associated with your account and we'll send you a one-time code to verify your identity.

@@ -40,19 +40,28 @@ export default function ForgotEmailPage() { {emailError !== "" &&

{emailError}

}
- +
+ + +
diff --git a/Frontend/erp-system/app/login/forgot/reset/page.tsx b/Frontend/erp-system/app/login/forgot/reset/page.tsx index d784d27..856958a 100644 --- a/Frontend/erp-system/app/login/forgot/reset/page.tsx +++ b/Frontend/erp-system/app/login/forgot/reset/page.tsx @@ -39,7 +39,7 @@ export default function ForgotResetPage() { return (
-
+

Create a new password

Choose a strong password to secure your account.

@@ -103,15 +103,15 @@ export default function ForgotResetPage() {
@@ -131,7 +131,7 @@ export default function ForgotResetPage() {
- diff --git a/Frontend/erp-system/app/login/page.tsx b/Frontend/erp-system/app/login/page.tsx index 8ae1730..612976d 100644 --- a/Frontend/erp-system/app/login/page.tsx +++ b/Frontend/erp-system/app/login/page.tsx @@ -17,29 +17,6 @@ import { Checkbox } from "@/components/ui/checkbox" import { Field, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field" import { Input } from "@/components/ui/input" -function GoogleIcon() { - return ( - - - - - - - ) -} - export default function LoginPage() { return ( @@ -77,19 +54,28 @@ function LoginForm() { return (
- {/* Full-page background photo — right side only */} -
+ {/* Full-page background photo — right side only. Dark mode swaps to the backdrop-free + cutout (whithoutbackground.png) so there's no white scene box floating on the + dark panel. */} +
ERP Illustration + ERP Illustration
{/* Login panel — overlays left side, no hard border with the photo */} -
+
Hexa ERP @@ -153,7 +139,7 @@ function LoginForm() {
- + Forgot password?
@@ -168,7 +154,7 @@ function LoginForm() {
-
-
- Or continue with -
-
- - -

- Don't have an account? Create an account + Don't have an account? Create an account

diff --git a/Frontend/erp-system/components/Layouts/AppSidebar.tsx b/Frontend/erp-system/components/Layouts/AppSidebar.tsx index fa0fce9..cd7f25a 100644 --- a/Frontend/erp-system/components/Layouts/AppSidebar.tsx +++ b/Frontend/erp-system/components/Layouts/AppSidebar.tsx @@ -47,6 +47,9 @@ const navItems: { /** Where clicking the row actually navigates, if different from `href`. `href` itself * stays the section prefix used to decide whether this row is "active". */ landingHref?: string + /** This item's own href has no page of its own (no landingHref either) — clicking the + * row should only expand/collapse its children, never navigate. */ + expandOnly?: boolean icon: LucideIcon chevron?: boolean children?: { title: string; code: string; href: string; icon: LucideIcon }[] @@ -106,6 +109,7 @@ const navItems: { title: "Settings", code: "settings", href: "/dashboard/settings", + expandOnly: true, icon: Settings, chevron: true, children: [ @@ -139,9 +143,13 @@ function SidebarContent({ const [expanded, setExpanded] = useState>({}) useEffect(() => { - const parent = items.find((i) => - i.children?.some((c) => pathname === c.href || pathname.startsWith(`${c.href}/`)) - ) + const parent = items.find((i) => { + if (!i.children?.length) return false + if (i.children.some((c) => pathname === c.href || pathname.startsWith(`${c.href}/`))) return true + // Landing on the parent's own hub page (e.g. /dashboard/settings itself, + // not one of its children) should also reveal its sub-items. + return pathname === i.href || pathname.startsWith(`${i.href}/`) + }) if (parent) { setExpanded((prev) => (prev[parent.code] ? prev : { ...prev, [parent.code]: true })) } @@ -153,7 +161,7 @@ function SidebarContent({ return (