diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index b5cc80a..7f90862 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -95,6 +95,32 @@ ] } }, + { + "files": ["app/delivery/**/*", "modules/delivery/**/*"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "group": [ + "@/components/accounting/**", + "@/components/beauty/**", + "@/components/healthcare/**", + "@/modules/beauty/**", + "@/modules/accounting/**", + "@/modules/hospitality/**", + "@/modules/crm/**", + "@/src/modules/healthcare/**", + "@/src/modules/accounting/**" + ], + "message": "Delivery must not import other business modules." + } + ] + } + ] + } + }, { "files": [ "components/ds/**/*", @@ -120,6 +146,7 @@ "@/modules/beauty/**", "@/modules/healthcare/**", "@/modules/hospitality/**", + "@/modules/delivery/**", "@/src/modules/healthcare/**", "@/src/modules/accounting/**", "@/modules/accounting/**", diff --git a/frontend/app/api/delivery/[...path]/route.ts b/frontend/app/api/delivery/[...path]/route.ts new file mode 100644 index 0000000..b1027f7 --- /dev/null +++ b/frontend/app/api/delivery/[...path]/route.ts @@ -0,0 +1,53 @@ +import { NextRequest, NextResponse } from "next/server"; + +const UPSTREAM = + process.env.DELIVERY_SERVICE_URL || + process.env.NEXT_PUBLIC_DELIVERY_API_URL || + "http://localhost:8007"; + +async function proxy(req: NextRequest, pathSegments: string[]) { + const p = pathSegments.join("/"); + const url = new URL(req.url); + const target = `${UPSTREAM.replace(/\/$/, "")}/${p}${url.search}`; + const headers = new Headers(); + for (const h of ["authorization", "content-type", "x-tenant-id", "accept"]) { + const v = req.headers.get(h); + if (v) headers.set(h, v); + } + let body: ArrayBuffer | undefined; + if (req.method !== "GET" && req.method !== "HEAD") body = await req.arrayBuffer(); + try { + const res = await fetch(target, { method: req.method, headers, body, cache: "no-store" }); + const out = new Headers(); + const ct = res.headers.get("content-type"); + if (ct) out.set("content-type", ct); + return new NextResponse(await res.arrayBuffer(), { status: res.status, headers: out }); + } catch (err) { + const detail = err instanceof Error ? err.message : "upstream_unreachable"; + return NextResponse.json( + { error: { code: "delivery_proxy_error", message: `پروکسی تربت درایور — ${detail}` } }, + { status: 502 } + ); + } +} + +export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + const { path: p } = await ctx.params; + return proxy(req, p); +} +export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + const { path: p } = await ctx.params; + return proxy(req, p); +} +export async function PATCH(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + const { path: p } = await ctx.params; + return proxy(req, p); +} +export async function PUT(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + const { path: p } = await ctx.params; + return proxy(req, p); +} +export async function DELETE(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + const { path: p } = await ctx.params; + return proxy(req, p); +} diff --git a/frontend/app/delivery/ai/recommendations/error.tsx b/frontend/app/delivery/ai/recommendations/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/ai/recommendations/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/ai/recommendations/loading.tsx b/frontend/app/delivery/ai/recommendations/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/ai/recommendations/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/ai/recommendations/page.tsx b/frontend/app/delivery/ai/recommendations/page.tsx new file mode 100644 index 0000000..1c2965f --- /dev/null +++ b/frontend/app/delivery/ai/recommendations/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { AiRecommendationsPage as default } from "@/modules/delivery/features/aiRecommendations"; diff --git a/frontend/app/delivery/analytics/error.tsx b/frontend/app/delivery/analytics/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/analytics/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/analytics/heatmaps/error.tsx b/frontend/app/delivery/analytics/heatmaps/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/analytics/heatmaps/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/analytics/heatmaps/loading.tsx b/frontend/app/delivery/analytics/heatmaps/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/analytics/heatmaps/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/analytics/heatmaps/page.tsx b/frontend/app/delivery/analytics/heatmaps/page.tsx new file mode 100644 index 0000000..a9fc2cc --- /dev/null +++ b/frontend/app/delivery/analytics/heatmaps/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { HeatMapsPage as default } from "@/modules/delivery/features/heatmaps"; diff --git a/frontend/app/delivery/analytics/kpis/error.tsx b/frontend/app/delivery/analytics/kpis/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/analytics/kpis/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/analytics/kpis/loading.tsx b/frontend/app/delivery/analytics/kpis/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/analytics/kpis/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/analytics/kpis/page.tsx b/frontend/app/delivery/analytics/kpis/page.tsx new file mode 100644 index 0000000..0145405 --- /dev/null +++ b/frontend/app/delivery/analytics/kpis/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { PerformanceKpisPage as default } from "@/modules/delivery/features/kpis"; diff --git a/frontend/app/delivery/analytics/loading.tsx b/frontend/app/delivery/analytics/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/analytics/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/analytics/page.tsx b/frontend/app/delivery/analytics/page.tsx new file mode 100644 index 0000000..a8dbe48 --- /dev/null +++ b/frontend/app/delivery/analytics/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { AnalyticsPage as default } from "@/modules/delivery/features/analytics"; diff --git a/frontend/app/delivery/api-keys/error.tsx b/frontend/app/delivery/api-keys/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/api-keys/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/api-keys/loading.tsx b/frontend/app/delivery/api-keys/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/api-keys/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/api-keys/page.tsx b/frontend/app/delivery/api-keys/page.tsx new file mode 100644 index 0000000..22d9eda --- /dev/null +++ b/frontend/app/delivery/api-keys/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ApiKeysPage as default } from "@/modules/delivery/features/apiKeys"; diff --git a/frontend/app/delivery/audit/error.tsx b/frontend/app/delivery/audit/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/audit/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/audit/loading.tsx b/frontend/app/delivery/audit/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/audit/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/audit/page.tsx b/frontend/app/delivery/audit/page.tsx new file mode 100644 index 0000000..2e6e0c0 --- /dev/null +++ b/frontend/app/delivery/audit/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { AuditLogsPage as default } from "@/modules/delivery/features/audit"; diff --git a/frontend/app/delivery/automation/error.tsx b/frontend/app/delivery/automation/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/automation/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/automation/loading.tsx b/frontend/app/delivery/automation/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/automation/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/automation/page.tsx b/frontend/app/delivery/automation/page.tsx new file mode 100644 index 0000000..48fb50d --- /dev/null +++ b/frontend/app/delivery/automation/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { AutomationPage as default } from "@/modules/delivery/features/automation"; diff --git a/frontend/app/delivery/branches/error.tsx b/frontend/app/delivery/branches/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/branches/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/branches/loading.tsx b/frontend/app/delivery/branches/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/branches/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/branches/page.tsx b/frontend/app/delivery/branches/page.tsx new file mode 100644 index 0000000..64b8bba --- /dev/null +++ b/frontend/app/delivery/branches/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { BranchesPage as default } from "@/modules/delivery/features/branches"; diff --git a/frontend/app/delivery/capabilities/error.tsx b/frontend/app/delivery/capabilities/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/capabilities/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/capabilities/loading.tsx b/frontend/app/delivery/capabilities/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/capabilities/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/capabilities/page.tsx b/frontend/app/delivery/capabilities/page.tsx new file mode 100644 index 0000000..d3f7cb0 --- /dev/null +++ b/frontend/app/delivery/capabilities/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { CapabilitiesPage as default } from "@/modules/delivery/features/capabilities"; diff --git a/frontend/app/delivery/cod/error.tsx b/frontend/app/delivery/cod/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/cod/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/cod/loading.tsx b/frontend/app/delivery/cod/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/cod/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/cod/page.tsx b/frontend/app/delivery/cod/page.tsx new file mode 100644 index 0000000..9b50ac0 --- /dev/null +++ b/frontend/app/delivery/cod/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { CodManagementPage as default } from "@/modules/delivery/features/cod"; diff --git a/frontend/app/delivery/commissions/error.tsx b/frontend/app/delivery/commissions/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/commissions/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/commissions/loading.tsx b/frontend/app/delivery/commissions/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/commissions/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/commissions/page.tsx b/frontend/app/delivery/commissions/page.tsx new file mode 100644 index 0000000..bf2220a --- /dev/null +++ b/frontend/app/delivery/commissions/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { CommissionsPage as default } from "@/modules/delivery/features/commissions"; diff --git a/frontend/app/delivery/configurations/error.tsx b/frontend/app/delivery/configurations/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/configurations/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/configurations/loading.tsx b/frontend/app/delivery/configurations/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/configurations/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/configurations/page.tsx b/frontend/app/delivery/configurations/page.tsx new file mode 100644 index 0000000..9410dec --- /dev/null +++ b/frontend/app/delivery/configurations/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ConfigurationsPage as default } from "@/modules/delivery/features/configurations"; diff --git a/frontend/app/delivery/deliveries/error.tsx b/frontend/app/delivery/deliveries/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/deliveries/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/deliveries/loading.tsx b/frontend/app/delivery/deliveries/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/deliveries/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/deliveries/page.tsx b/frontend/app/delivery/deliveries/page.tsx new file mode 100644 index 0000000..d39897e --- /dev/null +++ b/frontend/app/delivery/deliveries/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DeliveriesPage as default } from "@/modules/delivery/features/deliveries"; diff --git a/frontend/app/delivery/dispatch/assignment/error.tsx b/frontend/app/delivery/dispatch/assignment/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/dispatch/assignment/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/dispatch/assignment/loading.tsx b/frontend/app/delivery/dispatch/assignment/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/dispatch/assignment/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/dispatch/assignment/page.tsx b/frontend/app/delivery/dispatch/assignment/page.tsx new file mode 100644 index 0000000..3fcaa56 --- /dev/null +++ b/frontend/app/delivery/dispatch/assignment/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { AssignmentCenterPage as default } from "@/modules/delivery/features/assignment"; diff --git a/frontend/app/delivery/dispatch/queue/error.tsx b/frontend/app/delivery/dispatch/queue/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/dispatch/queue/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/dispatch/queue/loading.tsx b/frontend/app/delivery/dispatch/queue/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/dispatch/queue/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/dispatch/queue/page.tsx b/frontend/app/delivery/dispatch/queue/page.tsx new file mode 100644 index 0000000..22b9005 --- /dev/null +++ b/frontend/app/delivery/dispatch/queue/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DispatchQueuePage as default } from "@/modules/delivery/features/dispatchQueue"; diff --git a/frontend/app/delivery/dispatcher/error.tsx b/frontend/app/delivery/dispatcher/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/dispatcher/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/dispatcher/loading.tsx b/frontend/app/delivery/dispatcher/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/dispatcher/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/dispatcher/page.tsx b/frontend/app/delivery/dispatcher/page.tsx new file mode 100644 index 0000000..9a3641b --- /dev/null +++ b/frontend/app/delivery/dispatcher/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DispatcherDashboard as default } from "@/modules/delivery/features/dispatcher"; diff --git a/frontend/app/delivery/drivers/[id]/error.tsx b/frontend/app/delivery/drivers/[id]/error.tsx new file mode 100644 index 0000000..cf81b54 --- /dev/null +++ b/frontend/app/delivery/drivers/[id]/error.tsx @@ -0,0 +1,3 @@ +"use client"; +import { ErrorState } from "@/components/ds"; +export default function Error({ error, reset }: { error: Error; reset: () => void }) { return ; } diff --git a/frontend/app/delivery/drivers/[id]/loading.tsx b/frontend/app/delivery/drivers/[id]/loading.tsx new file mode 100644 index 0000000..0c1a2f2 --- /dev/null +++ b/frontend/app/delivery/drivers/[id]/loading.tsx @@ -0,0 +1,2 @@ +import { LoadingState } from "@/components/ds"; +export default function Loading() { return ; } diff --git a/frontend/app/delivery/drivers/[id]/page.tsx b/frontend/app/delivery/drivers/[id]/page.tsx new file mode 100644 index 0000000..3e85cdc --- /dev/null +++ b/frontend/app/delivery/drivers/[id]/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DriverDetailPage as default } from "@/modules/delivery/features/driverDetail"; diff --git a/frontend/app/delivery/drivers/availability/error.tsx b/frontend/app/delivery/drivers/availability/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/drivers/availability/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/drivers/availability/loading.tsx b/frontend/app/delivery/drivers/availability/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/drivers/availability/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/drivers/availability/page.tsx b/frontend/app/delivery/drivers/availability/page.tsx new file mode 100644 index 0000000..8cd62b7 --- /dev/null +++ b/frontend/app/delivery/drivers/availability/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DriverAvailabilityPage as default } from "@/modules/delivery/features/driverAvailability"; diff --git a/frontend/app/delivery/drivers/error.tsx b/frontend/app/delivery/drivers/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/drivers/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/drivers/loading.tsx b/frontend/app/delivery/drivers/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/drivers/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/drivers/page.tsx b/frontend/app/delivery/drivers/page.tsx new file mode 100644 index 0000000..b6eef34 --- /dev/null +++ b/frontend/app/delivery/drivers/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DriversPage as default } from "@/modules/delivery/features/drivers"; diff --git a/frontend/app/delivery/drivers/performance/error.tsx b/frontend/app/delivery/drivers/performance/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/drivers/performance/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/drivers/performance/loading.tsx b/frontend/app/delivery/drivers/performance/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/drivers/performance/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/drivers/performance/page.tsx b/frontend/app/delivery/drivers/performance/page.tsx new file mode 100644 index 0000000..c6e3094 --- /dev/null +++ b/frontend/app/delivery/drivers/performance/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DriverPerformancePage as default } from "@/modules/delivery/features/driverPerformance"; diff --git a/frontend/app/delivery/error.tsx b/frontend/app/delivery/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/failed/error.tsx b/frontend/app/delivery/failed/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/failed/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/failed/loading.tsx b/frontend/app/delivery/failed/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/failed/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/failed/page.tsx b/frontend/app/delivery/failed/page.tsx new file mode 100644 index 0000000..568d4e3 --- /dev/null +++ b/frontend/app/delivery/failed/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { FailedDeliveriesPage as default } from "@/modules/delivery/features/failed"; diff --git a/frontend/app/delivery/fleet-dashboard/error.tsx b/frontend/app/delivery/fleet-dashboard/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/fleet-dashboard/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/fleet-dashboard/loading.tsx b/frontend/app/delivery/fleet-dashboard/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/fleet-dashboard/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/fleet-dashboard/page.tsx b/frontend/app/delivery/fleet-dashboard/page.tsx new file mode 100644 index 0000000..04040f1 --- /dev/null +++ b/frontend/app/delivery/fleet-dashboard/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { FleetDashboard as default } from "@/modules/delivery/features/fleetDashboard"; diff --git a/frontend/app/delivery/fleet/maintenance/error.tsx b/frontend/app/delivery/fleet/maintenance/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/fleet/maintenance/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/fleet/maintenance/loading.tsx b/frontend/app/delivery/fleet/maintenance/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/fleet/maintenance/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/fleet/maintenance/page.tsx b/frontend/app/delivery/fleet/maintenance/page.tsx new file mode 100644 index 0000000..223e97b --- /dev/null +++ b/frontend/app/delivery/fleet/maintenance/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { FleetMaintenancePage as default } from "@/modules/delivery/features/maintenance"; diff --git a/frontend/app/delivery/health/error.tsx b/frontend/app/delivery/health/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/health/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/health/loading.tsx b/frontend/app/delivery/health/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/health/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/health/page.tsx b/frontend/app/delivery/health/page.tsx new file mode 100644 index 0000000..0ce919a --- /dev/null +++ b/frontend/app/delivery/health/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { HealthPage as default } from "@/modules/delivery/features/health"; diff --git a/frontend/app/delivery/hub/error.tsx b/frontend/app/delivery/hub/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/hub/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/hub/loading.tsx b/frontend/app/delivery/hub/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/hub/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/hub/page.tsx b/frontend/app/delivery/hub/page.tsx new file mode 100644 index 0000000..179532e --- /dev/null +++ b/frontend/app/delivery/hub/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DeliveryHub as default } from "@/modules/delivery/features/hub"; diff --git a/frontend/app/delivery/incidents/error.tsx b/frontend/app/delivery/incidents/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/incidents/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/incidents/loading.tsx b/frontend/app/delivery/incidents/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/incidents/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/incidents/page.tsx b/frontend/app/delivery/incidents/page.tsx new file mode 100644 index 0000000..08e1297 --- /dev/null +++ b/frontend/app/delivery/incidents/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { IncidentsPage as default } from "@/modules/delivery/features/incidents"; diff --git a/frontend/app/delivery/integrations/providers/error.tsx b/frontend/app/delivery/integrations/providers/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/integrations/providers/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/integrations/providers/loading.tsx b/frontend/app/delivery/integrations/providers/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/integrations/providers/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/integrations/providers/page.tsx b/frontend/app/delivery/integrations/providers/page.tsx new file mode 100644 index 0000000..549cbc4 --- /dev/null +++ b/frontend/app/delivery/integrations/providers/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ExternalProvidersPage as default } from "@/modules/delivery/features/externalProviders"; diff --git a/frontend/app/delivery/integrations/routing/error.tsx b/frontend/app/delivery/integrations/routing/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/integrations/routing/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/integrations/routing/loading.tsx b/frontend/app/delivery/integrations/routing/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/integrations/routing/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/integrations/routing/page.tsx b/frontend/app/delivery/integrations/routing/page.tsx new file mode 100644 index 0000000..9f75e15 --- /dev/null +++ b/frontend/app/delivery/integrations/routing/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { RoutingEnginesPage as default } from "@/modules/delivery/features/routingEngines"; diff --git a/frontend/app/delivery/layout.tsx b/frontend/app/delivery/layout.tsx new file mode 100644 index 0000000..874de78 --- /dev/null +++ b/frontend/app/delivery/layout.tsx @@ -0,0 +1,5 @@ +"use client"; + +import { DeliveryRootLayout } from "@/modules/delivery/components/createPortalLayout"; + +export default DeliveryRootLayout; diff --git a/frontend/app/delivery/loading.tsx b/frontend/app/delivery/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/geofence/error.tsx b/frontend/app/delivery/maps/geofence/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/maps/geofence/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/maps/geofence/loading.tsx b/frontend/app/delivery/maps/geofence/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/maps/geofence/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/geofence/page.tsx b/frontend/app/delivery/maps/geofence/page.tsx new file mode 100644 index 0000000..3fb62e9 --- /dev/null +++ b/frontend/app/delivery/maps/geofence/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { GeofencePage as default } from "@/modules/delivery/features/geofence"; diff --git a/frontend/app/delivery/maps/routes/optimization/error.tsx b/frontend/app/delivery/maps/routes/optimization/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/maps/routes/optimization/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/maps/routes/optimization/loading.tsx b/frontend/app/delivery/maps/routes/optimization/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/maps/routes/optimization/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/routes/optimization/page.tsx b/frontend/app/delivery/maps/routes/optimization/page.tsx new file mode 100644 index 0000000..0d0f83c --- /dev/null +++ b/frontend/app/delivery/maps/routes/optimization/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { RouteOptimizationPage as default } from "@/modules/delivery/features/routeOptimization"; diff --git a/frontend/app/delivery/maps/routes/planner/error.tsx b/frontend/app/delivery/maps/routes/planner/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/maps/routes/planner/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/maps/routes/planner/loading.tsx b/frontend/app/delivery/maps/routes/planner/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/maps/routes/planner/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/routes/planner/page.tsx b/frontend/app/delivery/maps/routes/planner/page.tsx new file mode 100644 index 0000000..16fab43 --- /dev/null +++ b/frontend/app/delivery/maps/routes/planner/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { RoutePlannerPage as default } from "@/modules/delivery/features/routePlanner"; diff --git a/frontend/app/delivery/maps/view/error.tsx b/frontend/app/delivery/maps/view/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/maps/view/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/maps/view/loading.tsx b/frontend/app/delivery/maps/view/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/maps/view/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/view/page.tsx b/frontend/app/delivery/maps/view/page.tsx new file mode 100644 index 0000000..94bde01 --- /dev/null +++ b/frontend/app/delivery/maps/view/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { MapViewPage as default } from "@/modules/delivery/features/mapView"; diff --git a/frontend/app/delivery/maps/zones/error.tsx b/frontend/app/delivery/maps/zones/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/maps/zones/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/maps/zones/loading.tsx b/frontend/app/delivery/maps/zones/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/maps/zones/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/maps/zones/page.tsx b/frontend/app/delivery/maps/zones/page.tsx new file mode 100644 index 0000000..df011d9 --- /dev/null +++ b/frontend/app/delivery/maps/zones/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DeliveryZonesPage as default } from "@/modules/delivery/features/deliveryZones"; diff --git a/frontend/app/delivery/not-found.tsx b/frontend/app/delivery/not-found.tsx new file mode 100644 index 0000000..df2a67a --- /dev/null +++ b/frontend/app/delivery/not-found.tsx @@ -0,0 +1,10 @@ +import Link from "next/link"; +import { Button, EmptyState } from "@/components/ds"; + +export default function DeliveryNotFound() { + return ( +
+ } /> +
+ ); +} diff --git a/frontend/app/delivery/notifications/error.tsx b/frontend/app/delivery/notifications/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/notifications/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/notifications/loading.tsx b/frontend/app/delivery/notifications/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/notifications/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/notifications/page.tsx b/frontend/app/delivery/notifications/page.tsx new file mode 100644 index 0000000..2a95646 --- /dev/null +++ b/frontend/app/delivery/notifications/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { NotificationsPage as default } from "@/modules/delivery/features/notifications"; diff --git a/frontend/app/delivery/operations/error.tsx b/frontend/app/delivery/operations/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/operations/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/operations/loading.tsx b/frontend/app/delivery/operations/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/operations/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/operations/page.tsx b/frontend/app/delivery/operations/page.tsx new file mode 100644 index 0000000..485cc7e --- /dev/null +++ b/frontend/app/delivery/operations/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { LiveOperationsDashboard as default } from "@/modules/delivery/features/operations"; diff --git a/frontend/app/delivery/orders/error.tsx b/frontend/app/delivery/orders/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/orders/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/orders/loading.tsx b/frontend/app/delivery/orders/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/orders/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/orders/page.tsx b/frontend/app/delivery/orders/page.tsx new file mode 100644 index 0000000..e633021 --- /dev/null +++ b/frontend/app/delivery/orders/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { OrdersPage as default } from "@/modules/delivery/features/orders"; diff --git a/frontend/app/delivery/organizations/error.tsx b/frontend/app/delivery/organizations/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/organizations/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/organizations/loading.tsx b/frontend/app/delivery/organizations/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/organizations/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/organizations/page.tsx b/frontend/app/delivery/organizations/page.tsx new file mode 100644 index 0000000..7f99ad6 --- /dev/null +++ b/frontend/app/delivery/organizations/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { OrganizationsPage as default } from "@/modules/delivery/features/organizations"; diff --git a/frontend/app/delivery/page.tsx b/frontend/app/delivery/page.tsx new file mode 100644 index 0000000..6b875d5 --- /dev/null +++ b/frontend/app/delivery/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ExecutiveDashboard as default } from "@/modules/delivery/features/dashboard"; diff --git a/frontend/app/delivery/payments/error.tsx b/frontend/app/delivery/payments/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/payments/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/payments/loading.tsx b/frontend/app/delivery/payments/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/payments/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/payments/page.tsx b/frontend/app/delivery/payments/page.tsx new file mode 100644 index 0000000..27e36ca --- /dev/null +++ b/frontend/app/delivery/payments/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { PaymentsPage as default } from "@/modules/delivery/features/payments"; diff --git a/frontend/app/delivery/permissions/error.tsx b/frontend/app/delivery/permissions/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/permissions/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/permissions/loading.tsx b/frontend/app/delivery/permissions/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/permissions/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/permissions/page.tsx b/frontend/app/delivery/permissions/page.tsx new file mode 100644 index 0000000..e7d57cc --- /dev/null +++ b/frontend/app/delivery/permissions/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { PermissionsPage as default } from "@/modules/delivery/features/permissions"; diff --git a/frontend/app/delivery/pickups/error.tsx b/frontend/app/delivery/pickups/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/pickups/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/pickups/loading.tsx b/frontend/app/delivery/pickups/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/pickups/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/pickups/page.tsx b/frontend/app/delivery/pickups/page.tsx new file mode 100644 index 0000000..9e80379 --- /dev/null +++ b/frontend/app/delivery/pickups/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { PickupsPage as default } from "@/modules/delivery/features/pickups"; diff --git a/frontend/app/delivery/reports/error.tsx b/frontend/app/delivery/reports/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/reports/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/reports/loading.tsx b/frontend/app/delivery/reports/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/reports/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/reports/page.tsx b/frontend/app/delivery/reports/page.tsx new file mode 100644 index 0000000..8556817 --- /dev/null +++ b/frontend/app/delivery/reports/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ReportsPage as default } from "@/modules/delivery/features/reports"; diff --git a/frontend/app/delivery/returns/error.tsx b/frontend/app/delivery/returns/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/returns/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/returns/loading.tsx b/frontend/app/delivery/returns/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/returns/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/returns/page.tsx b/frontend/app/delivery/returns/page.tsx new file mode 100644 index 0000000..d510939 --- /dev/null +++ b/frontend/app/delivery/returns/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ReturnsPage as default } from "@/modules/delivery/features/returns"; diff --git a/frontend/app/delivery/roles/error.tsx b/frontend/app/delivery/roles/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/roles/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/roles/loading.tsx b/frontend/app/delivery/roles/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/roles/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/roles/page.tsx b/frontend/app/delivery/roles/page.tsx new file mode 100644 index 0000000..792c4a9 --- /dev/null +++ b/frontend/app/delivery/roles/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { RolesPage as default } from "@/modules/delivery/features/roles"; diff --git a/frontend/app/delivery/schedules/error.tsx b/frontend/app/delivery/schedules/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/schedules/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/schedules/loading.tsx b/frontend/app/delivery/schedules/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/schedules/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/schedules/page.tsx b/frontend/app/delivery/schedules/page.tsx new file mode 100644 index 0000000..61fb779 --- /dev/null +++ b/frontend/app/delivery/schedules/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { SchedulesPage as default } from "@/modules/delivery/features/schedules"; diff --git a/frontend/app/delivery/settings/error.tsx b/frontend/app/delivery/settings/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/settings/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/settings/loading.tsx b/frontend/app/delivery/settings/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/settings/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/settings/page.tsx b/frontend/app/delivery/settings/page.tsx new file mode 100644 index 0000000..4d72e29 --- /dev/null +++ b/frontend/app/delivery/settings/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { SettingsPage as default } from "@/modules/delivery/features/settings"; diff --git a/frontend/app/delivery/settlements/error.tsx b/frontend/app/delivery/settlements/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/settlements/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/settlements/loading.tsx b/frontend/app/delivery/settlements/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/settlements/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/settlements/page.tsx b/frontend/app/delivery/settlements/page.tsx new file mode 100644 index 0000000..98f7ab2 --- /dev/null +++ b/frontend/app/delivery/settlements/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { SettlementsPage as default } from "@/modules/delivery/features/settlements"; diff --git a/frontend/app/delivery/shifts/error.tsx b/frontend/app/delivery/shifts/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/shifts/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/shifts/loading.tsx b/frontend/app/delivery/shifts/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/shifts/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/shifts/page.tsx b/frontend/app/delivery/shifts/page.tsx new file mode 100644 index 0000000..736dfee --- /dev/null +++ b/frontend/app/delivery/shifts/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { ShiftsPage as default } from "@/modules/delivery/features/shifts"; diff --git a/frontend/app/delivery/support/error.tsx b/frontend/app/delivery/support/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/support/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/support/loading.tsx b/frontend/app/delivery/support/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/support/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/support/page.tsx b/frontend/app/delivery/support/page.tsx new file mode 100644 index 0000000..c2b6f84 --- /dev/null +++ b/frontend/app/delivery/support/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { SupportTicketsPage as default } from "@/modules/delivery/features/support"; diff --git a/frontend/app/delivery/tasks/error.tsx b/frontend/app/delivery/tasks/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/tasks/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/tasks/loading.tsx b/frontend/app/delivery/tasks/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/tasks/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/tasks/page.tsx b/frontend/app/delivery/tasks/page.tsx new file mode 100644 index 0000000..c6fca83 --- /dev/null +++ b/frontend/app/delivery/tasks/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { TasksPage as default } from "@/modules/delivery/features/tasks"; diff --git a/frontend/app/delivery/tracking/customer/error.tsx b/frontend/app/delivery/tracking/customer/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/tracking/customer/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/tracking/customer/loading.tsx b/frontend/app/delivery/tracking/customer/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/tracking/customer/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/tracking/customer/page.tsx b/frontend/app/delivery/tracking/customer/page.tsx new file mode 100644 index 0000000..cf62ba3 --- /dev/null +++ b/frontend/app/delivery/tracking/customer/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { CustomerTrackingPage as default } from "@/modules/delivery/features/customerTracking"; diff --git a/frontend/app/delivery/tracking/live/error.tsx b/frontend/app/delivery/tracking/live/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/tracking/live/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/tracking/live/loading.tsx b/frontend/app/delivery/tracking/live/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/tracking/live/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/tracking/live/page.tsx b/frontend/app/delivery/tracking/live/page.tsx new file mode 100644 index 0000000..b871941 --- /dev/null +++ b/frontend/app/delivery/tracking/live/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { LiveTrackingPage as default } from "@/modules/delivery/features/liveTracking"; diff --git a/frontend/app/delivery/vehicle-types/error.tsx b/frontend/app/delivery/vehicle-types/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/vehicle-types/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/vehicle-types/loading.tsx b/frontend/app/delivery/vehicle-types/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/vehicle-types/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/vehicle-types/page.tsx b/frontend/app/delivery/vehicle-types/page.tsx new file mode 100644 index 0000000..6fc79c6 --- /dev/null +++ b/frontend/app/delivery/vehicle-types/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { VehicleTypesPage as default } from "@/modules/delivery/features/vehicleTypes"; diff --git a/frontend/app/delivery/vehicles/error.tsx b/frontend/app/delivery/vehicles/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/vehicles/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/vehicles/loading.tsx b/frontend/app/delivery/vehicles/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/vehicles/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/vehicles/page.tsx b/frontend/app/delivery/vehicles/page.tsx new file mode 100644 index 0000000..817c3b5 --- /dev/null +++ b/frontend/app/delivery/vehicles/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { VehiclesPage as default } from "@/modules/delivery/features/vehicles"; diff --git a/frontend/app/delivery/vendor-portal/error.tsx b/frontend/app/delivery/vendor-portal/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/vendor-portal/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/vendor-portal/loading.tsx b/frontend/app/delivery/vendor-portal/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/vendor-portal/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/vendor-portal/page.tsx b/frontend/app/delivery/vendor-portal/page.tsx new file mode 100644 index 0000000..6a35e40 --- /dev/null +++ b/frontend/app/delivery/vendor-portal/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { VendorPortalPage as default } from "@/modules/delivery/features/vendorPortal"; diff --git a/frontend/app/delivery/wallet/error.tsx b/frontend/app/delivery/wallet/error.tsx new file mode 100644 index 0000000..b8dfa5e --- /dev/null +++ b/frontend/app/delivery/wallet/error.tsx @@ -0,0 +1,7 @@ +"use client"; + +import { ErrorState } from "@/components/ds"; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ; +} diff --git a/frontend/app/delivery/wallet/loading.tsx b/frontend/app/delivery/wallet/loading.tsx new file mode 100644 index 0000000..61eb1c6 --- /dev/null +++ b/frontend/app/delivery/wallet/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingState } from "@/components/ds"; + +export default function Loading() { + return ; +} diff --git a/frontend/app/delivery/wallet/page.tsx b/frontend/app/delivery/wallet/page.tsx new file mode 100644 index 0000000..76b7e4c --- /dev/null +++ b/frontend/app/delivery/wallet/page.tsx @@ -0,0 +1,3 @@ +"use client"; + +export { DriverWalletPage as default } from "@/modules/delivery/features/wallet"; diff --git a/frontend/docs/delivery-component-map.md b/frontend/docs/delivery-component-map.md new file mode 100644 index 0000000..4710a92 --- /dev/null +++ b/frontend/docs/delivery-component-map.md @@ -0,0 +1,61 @@ +# Delivery Component Map + +## Shared (reused, not duplicated) + +| Component | Source | Usage in Delivery | +|-----------|--------|-------------------| +| Button, Input, Dialog, Drawer | `@/components/ds` | All forms and actions | +| PageHeader, StatCard, DataTable | `@/components/ds` | List pages, dashboards | +| LoadingState, ErrorState, EmptyState | `@/components/ds` | All page states | +| PermissionDeniedState | `@/src/shared/ui` | 403 / missing permission | +| AuthGuard | `@/components/AuthGuard` | Portal gate | +| Tabs, Pagination, Breadcrumbs | `@/components/ds` | Tables, driver detail | + +## Delivery module components + +| Component | Path | Purpose | +|-----------|------|---------| +| DeliveryPortalShell | `components/DeliveryPortalShell.tsx` | Sidebar nav, mobile drawer, dark mode | +| createPortalLayout | `components/createPortalLayout.tsx` | Auth + tenant gate | +| DeliveryListCrudPage | `components/DeliveryListCrudPage.tsx` | CRUD factory for foundation entities | +| DeliveryPhaseGate | `components/DeliveryPhaseGate.tsx` | Capability-gated future screens | +| DeliveryMapPlaceholder | `components/DeliveryMapPlaceholder.tsx` | Map-first skeleton when routing enabled | +| DeliveryBreadcrumbs | `components/DeliveryBreadcrumbs.tsx` | RTL breadcrumbs | + +## Design system + +| Component | Path | +|-----------|------| +| deliveryTokens | `design-system/tokens.ts` | +| DeliveryStatusChip | `design-system/DeliveryStatusChip.tsx` | +| DeliveryTablePage | `design-system/DeliveryTablePage.tsx` | +| DeliveryStatGrid | `design-system/DeliveryStatGrid.tsx` | + +## Feature pages (by domain) + +| Domain | Feature files | +|--------|---------------| +| Dashboards | `dashboard.tsx`, `dispatcher.tsx`, `operations.tsx`, `fleetDashboard.tsx` | +| Drivers | `drivers.tsx`, `driverDetail.tsx`, `driverAvailability.tsx`, `driverPerformance.tsx` | +| Foundation | `organizations.tsx`, `branches.tsx`, `configurations.tsx`, `settings.tsx` | +| Integrations | `externalProviders.tsx`, `routingEngines.tsx` | +| Maps | `mapView.tsx`, `routePlanner.tsx`, `routeOptimization.tsx`, `geofence.tsx`, `deliveryZones.tsx` | +| Operations (phase) | `orders.tsx`, `dispatchQueue.tsx`, `assignment.tsx`, `pickups.tsx`, … | +| Finance (phase) | `cod.tsx`, `settlements.tsx`, `payments.tsx`, `wallet.tsx`, `commissions.tsx` | +| Admin | `permissions.tsx`, `audit.tsx`, `health.tsx`, `capabilities.tsx` | + +## Hooks + +| Hook | File | +|------|------| +| useDeliveryCapabilities | `hooks/useDeliveryCapabilities.ts` | +| useDeliveryPermissions | `hooks/useDeliveryPermissions.ts` | +| useDeliveryLookups | `hooks/useDeliveryCapabilities.ts` (organizations + hubs) | +| useDeliveryMetrics | `hooks/useDeliveryCapabilities.ts` | + +## API + +| Client | Path | +|--------|------| +| deliveryApi | `services/delivery-api.ts` | +| BFF proxy | `app/api/delivery/[...path]/route.ts` | diff --git a/frontend/docs/delivery-design-system.md b/frontend/docs/delivery-design-system.md new file mode 100644 index 0000000..686a9e3 --- /dev/null +++ b/frontend/docs/delivery-design-system.md @@ -0,0 +1,59 @@ +# Delivery Design System + +Delivery uses the **shared platform design system** (`@/components/ds`) with module-specific tokens only — no duplicated Button/Input/Dialog implementations. + +## CSS tokens + +Defined in `frontend/styles/globals.css`: + +```css +--delivery-accent: #0891b2; /* light — logistics cyan */ +--delivery-accent-soft: rgba(8, 145, 178, 0.12); +--delivery-map: #0e7490; +--delivery-success / warning / danger +``` + +Dark mode: `--delivery-accent: #22d3ee` + +**Rule:** Reference `var(--delivery-accent)` in module components; never hardcode hex. + +## Module design-system (`modules/delivery/design-system/`) + +| Export | Purpose | +|--------|---------| +| `deliveryTokens` | Accent variable references | +| `DeliveryStatusChip` | Driver + lifecycle status badges | +| `DeliveryTablePage` | Search, sort, pagination wrapper | +| `DeliveryStatGrid` | Dashboard stat cards row | +| `lifecycleStatusLabels` | Persian labels for statuses | +| `driverStatusLabels` | Driver-specific statuses | + +## Layout patterns + +- **Portal shell:** Fixed RTL sidebar (desktop), drawer (mobile), sticky mobile header +- **Page header:** Title + description + action slot +- **CRUD list:** Table + create dialog + edit drawer + delete confirm +- **Phase gate:** Centered card with phase badge — used instead of placeholder/mock data +- **Map placeholder:** 16:9 aspect map canvas with marker/route badges + +## Typography & spacing + +Inherited from platform DS and Tailwind utilities. Consistent `space-y-6` page rhythm, `rounded-2xl` cards, `p-4 lg:p-6` main padding. + +## Icons + +Lucide React — consistent with other TorbatYar modules. + +## Accessibility + +- `aria-label` on mobile menu and close buttons +- Keyboard: Escape closes dialogs/drawers (DS default) +- RTL-first breadcrumb and table alignment + +## Dark mode + +Supported via `ColorModeProvider` toggle in portal shell; all surfaces use CSS variables. + +## Future: shared/maps + +When `frontend/shared/maps/` is populated, Delivery map pages should import shared map components rather than extending `DeliveryMapPlaceholder`. diff --git a/frontend/docs/delivery-frontend-architecture.md b/frontend/docs/delivery-frontend-architecture.md new file mode 100644 index 0000000..04239ac --- /dev/null +++ b/frontend/docs/delivery-frontend-architecture.md @@ -0,0 +1,73 @@ +# Delivery Frontend Architecture + +**Module:** Torbat Driver (Delivery Platform) +**Date:** 2026-07-26 +**Backend phase:** 10.1 (Driver Management) + +## Overview + +The Delivery frontend is the enterprise reference implementation for logistics and courier operations inside TorbatYar SuperApp. Business code lives under `frontend/modules/delivery/`; App Router routes under `app/delivery/` are thin re-exports only. + +## Layer diagram + +``` +app/delivery/ → Routes (page, layout, loading, error, not-found) + ↓ +modules/delivery/ → Business UI, hooks, API client, constants + ↓ +components/ds/ → Shared design system primitives + ↓ +/api/delivery/* BFF → delivery-service :8007 +``` + +## Directory structure + +``` +modules/delivery/ +├── components/ Portal shell, CRUD factory, phase gates, map placeholder +├── constants/ portals.ts, permissions.ts, phaseRegistry.ts +├── design-system/ tokens, status chips, table page +├── features/ One file per screen (56+ routes) +├── hooks/ capabilities, permissions, lookups +├── pages/shared.tsx PageLoader, PageError, CSV export +├── services/delivery-api.ts +└── types/index.ts +``` + +## Backend integration (Phase 10.0–10.1) + +| Domain | API prefix | CRUD status | +|--------|------------|-------------| +| Organizations | `/api/v1/organizations` | ✅ Full | +| Hubs (Branches) | `/api/v1/hubs` | ✅ Full | +| External providers | `/api/v1/external-providers` | ✅ Full | +| Routing engines | `/api/v1/routing-engines` | ✅ Full | +| Configurations | `/api/v1/configurations` | ✅ Full | +| Settings | `/api/v1/settings` | ✅ Upsert + list | +| Audit | `/api/v1/audit` | ✅ Query by entity | +| Drivers | `/api/v1/drivers` | ✅ Full + lifecycle | +| Permissions catalog | `/api/v1/permissions/catalog` | ✅ Read | +| Health / Capabilities / Metrics | `/health`, `/capabilities`, `/metrics` | ✅ Read | + +## Future phases (capability-gated UI) + +Screens for fleet, dispatch, orders, tracking, maps (live), settlement, AI, etc. render **phase gate pages** that read `/capabilities` — no mock data, no fake CRUD. When backend enables a feature flag, the UI unlocks automatically. + +## Real-time + +WebSocket/SSE for driver locations, dispatch queue, and tracking is planned for Phase 10.7. The map placeholder documents the integration point. + +## Commands + +```bash +node scripts/scaffold-delivery-module.mjs # Regenerate routes + feature stubs +npm run validate:delivery # Route + architecture validation +``` + +## Related docs + +- [delivery-component-map.md](./delivery-component-map.md) +- [delivery-routing-map.md](./delivery-routing-map.md) +- [delivery-design-system.md](./delivery-design-system.md) +- [delivery-validation-report.md](./delivery-validation-report.md) +- [delivery-ui-checklist.md](./delivery-ui-checklist.md) diff --git a/frontend/docs/delivery-routing-map.md b/frontend/docs/delivery-routing-map.md new file mode 100644 index 0000000..e7cc79b --- /dev/null +++ b/frontend/docs/delivery-routing-map.md @@ -0,0 +1,119 @@ +# Delivery Routing Map + +All routes under `/delivery`. App files are thin re-exports; implementation in `modules/delivery/features/`. + +## Portal + +| Route | Feature | Backend | +|-------|---------|---------| +| `/delivery/hub` | hub | — | +| `/delivery` | dashboard | Real counts (orgs, hubs, drivers) | + +## Dashboards + +| Route | Feature | Status | +|-------|---------|--------| +| `/delivery/dispatcher` | dispatcher | Phase gate (10.5) | +| `/delivery/operations` | operations | Phase gate (10.7) | +| `/delivery/fleet-dashboard` | fleetDashboard | Phase gate (10.2) | + +## Drivers + +| Route | Feature | Status | +|-------|---------|--------| +| `/delivery/drivers` | drivers | ✅ Real API | +| `/delivery/drivers/[id]` | driverDetail | ✅ Real API + lifecycle | +| `/delivery/drivers/availability` | driverAvailability | Phase gate (10.3) | +| `/delivery/drivers/performance` | driverPerformance | Phase gate (10.10) | + +## Orders & dispatch + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/orders` | orders | 10.5 | +| `/delivery/dispatch/queue` | dispatchQueue | 10.5 | +| `/delivery/dispatch/assignment` | assignment | 10.5 | +| `/delivery/pickups` | pickups | 10.5 | +| `/delivery/deliveries` | deliveries | 10.5 | +| `/delivery/returns` | returns | 10.5 | +| `/delivery/failed` | failed | 10.5 | + +## Tracking + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/tracking/live` | liveTracking | 10.7 | +| `/delivery/tracking/customer` | customerTracking | 10.7 | + +## Maps + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/maps/view` | mapView | 10.6 (map skeleton when enabled) | +| `/delivery/maps/routes/planner` | routePlanner | 10.6 | +| `/delivery/maps/routes/optimization` | routeOptimization | 10.6 | +| `/delivery/maps/geofence` | geofence | 10.6 | +| `/delivery/maps/zones` | deliveryZones | 10.3 | + +## Fleet + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/vehicles` | vehicles | 10.2 | +| `/delivery/vehicle-types` | vehicleTypes | 10.2 | +| `/delivery/fleet/maintenance` | maintenance | 10.2 | +| `/delivery/schedules` | schedules | 10.3 | +| `/delivery/shifts` | shifts | 10.3 | +| `/delivery/tasks` | tasks | 10.5 | + +## Foundation (live) + +| Route | Feature | API | +|-------|---------|-----| +| `/delivery/organizations` | organizations | organizations | +| `/delivery/branches` | branches | hubs | +| `/delivery/configurations` | configurations | configurations | +| `/delivery/settings` | settings | settings | +| `/delivery/integrations/providers` | externalProviders | external-providers | +| `/delivery/integrations/routing` | routingEngines | routing-engines | + +## Finance (phase) + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/cod` | cod | 10.8 | +| `/delivery/settlements` | settlements | 10.8 | +| `/delivery/payments` | payments | 10.8 | +| `/delivery/wallet` | wallet | 10.8 | +| `/delivery/commissions` | commissions | 10.8 | + +## Insights & AI (phase) + +| Route | Feature | Phase | +|-------|---------|-------| +| `/delivery/reports` | reports | 10.10 | +| `/delivery/analytics` | analytics | 10.10 | +| `/delivery/analytics/heatmaps` | heatmaps | 10.10 | +| `/delivery/analytics/kpis` | kpis | 10.10 | +| `/delivery/ai/recommendations` | aiRecommendations | 10.10 | +| `/delivery/automation` | automation | 10.10 | + +## Admin + +| Route | Feature | Status | +|-------|---------|--------| +| `/delivery/permissions` | permissions | ✅ Catalog API | +| `/delivery/roles` | roles | Phase gate | +| `/delivery/audit` | audit | ✅ Audit API | +| `/delivery/api-keys` | apiKeys | Phase gate | +| `/delivery/health` | health | ✅ Health API | +| `/delivery/capabilities` | capabilities | ✅ Capabilities API | +| `/delivery/notifications` | notifications | Phase 10.9 | +| `/delivery/incidents` | incidents | Phase 10.5 | +| `/delivery/support` | support | Phase 10.9 | +| `/delivery/vendor-portal` | vendorPortal | Phase 10.9 | + +## Segment files (every route) + +Each route directory includes: `page.tsx`, `loading.tsx`, `error.tsx` +Root: `layout.tsx`, `not-found.tsx` diff --git a/frontend/docs/delivery-ui-checklist.md b/frontend/docs/delivery-ui-checklist.md new file mode 100644 index 0000000..8b8ebda --- /dev/null +++ b/frontend/docs/delivery-ui-checklist.md @@ -0,0 +1,76 @@ +# Delivery UI Checklist + +Per-screen requirements for Torbat Driver frontend. + +## Global (every screen) + +- [x] Loading state (`loading.tsx` + in-page loader) +- [x] Error state (`error.tsx` + `DeliveryPageError`) +- [x] Empty state (`DeliveryEmptyState` / DS `EmptyState`) +- [x] Permission state (`PermissionDeniedState`) +- [x] Responsive layout (mobile drawer + desktop sidebar) +- [x] Breadcrumb (where applicable) +- [x] RTL layout +- [x] Dark mode tokens + +## Live CRUD screens + +### Organizations `/delivery/organizations` +- [x] List, create, edit, delete +- [x] Search, pagination, CSV export +- [x] Status badges +- [x] Permission check + +### Branches `/delivery/branches` +- [x] Organization selector on create +- [x] Full CRUD +- [x] API: hubs + +### Drivers `/delivery/drivers` +- [x] Paginated list +- [x] Link to detail +- [x] Create with org/hub +- [x] Edit, delete + +### Driver detail `/delivery/drivers/[id]` +- [x] Profile tab +- [x] Lifecycle tab + actions (activate, suspend, …) +- [x] Credentials tab (read) +- [x] Documents tab (read) +- [x] Timeline from lifecycle API + +### Integrations +- [x] External providers CRUD +- [x] Routing engines CRUD + +### Admin +- [x] Settings upsert +- [x] Audit search +- [x] Permissions catalog +- [x] Health status +- [x] Capabilities grid + +## Phase-gated screens (checklist when backend enables) + +When `features.` becomes `true` in `/capabilities`: + +- [ ] Replace phase gate with real implementation +- [ ] Connect WebSocket for tracking/dispatch +- [ ] Integrate shared map component +- [ ] Add realtime polling fallback + +## Dashboard checklist + +- [x] Executive: real org/hub/driver counts +- [ ] Dispatcher: dispatch queue metrics (10.5) +- [ ] Live ops: tracking sessions (10.7) +- [ ] Fleet: vehicle counts (10.2) + +## Validation loop + +```bash +npm run validate:delivery +npm run build +``` + +Review [delivery-validation-report.md](./delivery-validation-report.md) after each backend phase upgrade. diff --git a/frontend/docs/delivery-validation-report.md b/frontend/docs/delivery-validation-report.md new file mode 100644 index 0000000..a84e3c7 --- /dev/null +++ b/frontend/docs/delivery-validation-report.md @@ -0,0 +1,76 @@ +# Delivery Frontend Validation Report + +**Date:** 2026-07-26 +**Module version:** Phase 10.1 UI +**Backend:** delivery-service v0.10.1.0 @ :8007 + +## Automated checks + +| Check | Command | Result | +|-------|---------|--------| +| Route thinness | `npm run validate:delivery-routes` | ✅ PASS (56 routes) | +| Architecture boundaries | `npm run validate:architecture` | ✅ PASS (delivery marker registered) | +| TypeScript compile | `next build` (compile phase) | ✅ Compiled successfully | +| ESLint (delivery) | No delivery-specific errors | ✅ PASS | + +## API connectivity + +| Screen | Mock/placeholder? | Backend endpoint | +|--------|-------------------|------------------| +| Executive dashboard | No | organizations, hubs, drivers list | +| Organizations | No | CRUD `/api/v1/organizations` | +| Branches (hubs) | No | CRUD `/api/v1/hubs` | +| Drivers list | No | CRUD `/api/v1/drivers` | +| Driver detail | No | get, lifecycle, credentials, documents | +| External providers | No | CRUD | +| Routing engines | No | CRUD | +| Configurations | No | CRUD | +| Settings | No | GET + PUT | +| Audit | No | GET with entity_type/id | +| Permissions | No | catalog | +| Health / Capabilities | No | public endpoints | +| Dispatch, orders, fleet, maps (live), settlement, AI | **Phase gate** (not mock) | Awaits backend phase | + +## Intentional phase-gated screens + +34 screens map to `PHASE_REGISTRY` entries. They display: +- Current roadmap phase number +- Feature flag name from `/capabilities` +- Links to capabilities page and dashboard + +This is **production-honest** behavior — no fake tables or dummy CRUD for APIs that do not exist. + +## BFF + +| Path | Upstream | +|------|----------| +| `/api/delivery/*` | `DELIVERY_SERVICE_URL` → `http://localhost:8007` | + +Headers forwarded: `Authorization`, `X-Tenant-ID`, `Content-Type`, `Accept` + +## Known limitations + +1. **Realtime:** No WebSocket client until Phase 10.7 backend support +2. **Map tiles:** Placeholder canvas until shared map provider integrated +3. **Roles / API keys:** Identity platform concern; phase-gated until dedicated APIs +4. **Build:** Full `next build` may require clean `.next` on Windows if manifest race occurs (compile succeeds) + +## Regression commands + +```bash +cd frontend +npm run validate:delivery +npm run build +node scripts/scaffold-delivery-module.mjs # idempotent regen +``` + +## Sign-off criteria met + +- [x] Module under `frontend/modules/delivery/` +- [x] Thin routes under `app/delivery/` +- [x] BFF proxy configured +- [x] All Phase 10.0–10.1 APIs wired +- [x] Future screens capability-gated (no mocks) +- [x] Loading / error / empty / permission states +- [x] ESLint + architecture validation +- [x] Documentation generated diff --git a/frontend/modules/delivery/README.md b/frontend/modules/delivery/README.md new file mode 100644 index 0000000..cd5d4fa --- /dev/null +++ b/frontend/modules/delivery/README.md @@ -0,0 +1,16 @@ +# Torbat Driver — Delivery Module + +Business UI for `/delivery/*`. Routes are thin re-exports in `app/delivery/`. + +## Structure + +- `features/` — page implementations +- `components/` — portal shell, CRUD factory, phase gates +- `services/delivery-api.ts` — real backend client (BFF `/api/delivery`) +- `constants/` — nav, permissions, phase registry + +## Scaffold + +```bash +node scripts/scaffold-delivery-module.mjs +``` diff --git a/frontend/modules/delivery/components/DeliveryBreadcrumbs.tsx b/frontend/modules/delivery/components/DeliveryBreadcrumbs.tsx new file mode 100644 index 0000000..0e44ba5 --- /dev/null +++ b/frontend/modules/delivery/components/DeliveryBreadcrumbs.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { Breadcrumbs } from "@/components/ds"; + +export function DeliveryBreadcrumbs({ current }: { current: string }) { + return ( + + ); +} + +export function DeliveryDetailBreadcrumbs({ + section, + current, + sectionHref, +}: { + section: string; + current: string; + sectionHref: string; +}) { + return ( + + ); +} diff --git a/frontend/modules/delivery/components/DeliveryListCrudPage.tsx b/frontend/modules/delivery/components/DeliveryListCrudPage.tsx new file mode 100644 index 0000000..344e49e --- /dev/null +++ b/frontend/modules/delivery/components/DeliveryListCrudPage.tsx @@ -0,0 +1,429 @@ +"use client"; + +import { useCallback, useState } from "react"; +import { useForm, type FieldValues, type DefaultValues } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { toast } from "sonner"; +import { Plus, Pencil, Trash2, Download, RefreshCw, Eye } from "lucide-react"; +import Link from "next/link"; +import { z } from "zod"; +import { + Button, + Dialog, + Drawer, + Input, + ConfirmDialog, + Select, + Textarea, + FormField, +} from "@/components/ds"; +import { DeliveryTablePage, DeliveryStatGrid } from "@/modules/delivery/design-system"; +import { + DeliveryPageLoader, + DeliveryPageError, + exportToCsv, +} from "@/modules/delivery/pages/shared"; +import { useTenantId } from "@/hooks/useTenantId"; +import { useDeliveryLookups } from "@/modules/delivery/hooks/useDeliveryCapabilities"; +import { useDeliveryPermissions } from "@/modules/delivery/hooks/useDeliveryPermissions"; +import { DeliveryStatusChip } from "@/modules/delivery/design-system"; +import { PermissionDeniedState } from "@/src/shared/ui"; + +export type DeliveryFieldConfig = { + name: string; + label: string; + type?: "text" | "number" | "email" | "tel" | "textarea" | "select" | "organization" | "hub"; + options?: { value: string; label: string }[]; + required?: boolean; + createOnly?: boolean; + editOnly?: boolean; + placeholder?: string; +}; + +export type DeliveryColumnConfig = { + key: string; + header: string; + type?: "status" | "datetime" | "text" | "link"; + linkPrefix?: string; + render?: (row: Record) => React.ReactNode; +}; + +type ApiResource = { + list: ( + tenantId: string, + params?: Record + ) => Promise[] | { items: Record[]; total: number }>; + get?: (tenantId: string, id: string) => Promise>; + create?: (tenantId: string, body: Record) => Promise; + update?: (tenantId: string, id: string, body: Record) => Promise; + remove?: (tenantId: string, id: string) => Promise; +}; + +export type DeliveryListConfig = { + title: string; + description?: string; + breadcrumb?: string; + resourceKey: string; + permission?: string; + api: ApiResource; + columns: DeliveryColumnConfig[]; + createFields?: DeliveryFieldConfig[]; + editFields?: DeliveryFieldConfig[]; + readOnly?: boolean; + detailHref?: (row: Record) => string | null; + rowActions?: { + label: string; + onClick: (tenantId: string, row: Record) => Promise; + variant?: "default" | "outline" | "danger"; + }[]; +}; + +function buildSchema(fields: DeliveryFieldConfig[]) { + const shape: Record = {}; + for (const f of fields) { + shape[f.name] = f.required + ? z.string().min(1, `${f.label} الزامی است`) + : z.string().optional(); + } + return z.object(shape); +} + +function normalizeList( + data: Record[] | { items: Record[]; total: number } +): Record[] { + if (Array.isArray(data)) return data; + return data.items ?? []; +} + +function renderCell(col: DeliveryColumnConfig, row: Record) { + if (col.render) return col.render(row); + const val = row[col.key]; + if (col.type === "status" && val) return ; + if (col.type === "datetime" && val) { + try { + return new Date(String(val)).toLocaleString("fa-IR"); + } catch { + return String(val); + } + } + if (col.type === "link" && col.linkPrefix && row.id) { + return ( + + {val != null ? String(val) : "—"} + + ); + } + return val != null ? String(val) : "—"; +} + +function renderField( + field: DeliveryFieldConfig, + register: ReturnType["register"], + mode: "create" | "edit", + lookups: { organizations: Record[]; hubs: Record[] } +) { + if (mode === "create" && field.editOnly) return null; + if (mode === "edit" && field.createOnly) return null; + + if (field.type === "textarea") { + return ( + +