TorbatYar/frontend/modules/delivery/pages/shared.tsx
Mortezakoohjani 7978970783 feat(delivery): add Torbat Driver frontend module with real API wiring.
Ship the delivery platform UI under modules/delivery with thin app routes, BFF proxy, CRUD for phase 10.0-10.1 APIs, and capability-gated future screens.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 12:02:01 +03:30

55 lines
1.8 KiB
TypeScript

"use client";
import { LoadingState, ErrorState, EmptyState } from "@/components/ds";
import { DeliveryApiError } from "@/modules/delivery/services/delivery-api";
import { PermissionDeniedState } from "@/src/shared/ui";
export function DeliveryPageLoader({ label = "در حال بارگذاری…" }: { label?: string }) {
return <LoadingState label={label} />;
}
export function DeliveryPageError({
error,
onRetry,
}: {
error: unknown;
onRetry?: () => void;
}) {
if (error instanceof DeliveryApiError && error.status === 403) {
return (
<PermissionDeniedState
message={error.message || "مجوز لازم برای این عملیات وجود ندارد."}
/>
);
}
const message = error instanceof Error ? error.message : "خطا در دریافت داده‌ها";
return <ErrorState message={message} onRetry={onRetry} />;
}
export function DeliveryEmptyState({
title = "موردی یافت نشد",
description = "هنوز داده‌ای ثبت نشده است.",
action,
}: {
title?: string;
description?: string;
action?: React.ReactNode;
}) {
return <EmptyState title={title} description={description} action={action} />;
}
export function exportToCsv(title: string, rows: Record<string, unknown>[], columns: string[]) {
if (rows.length === 0) return;
const header = columns.join(",");
const body = rows
.map((r) => columns.map((c) => JSON.stringify(r[c] ?? "")).join(","))
.join("\n");
const blob = new Blob(["\uFEFF" + header + "\n" + body], { type: "text/csv;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `${title}-export.csv`;
a.click();
URL.revokeObjectURL(url);
}