| @@ -44,9 +44,9 @@ | ||
| 44 | 44 | TableHead, |
| 45 | 45 | TableHeader, |
| 46 | 46 | TableRow, |
| 47 | 47 | } from "../components/ui/table"; |
| 48 | -import { getCurrencySymbol, getCurrency } from "../data/currencies"; | |
| 48 | +import { formatYatraMoney } from "../lib/currency-display"; | |
| 49 | 49 | import { formatDate as formatDateUtil } from "../lib/dateFormat"; |
| 50 | 50 | |
| 51 | 51 | interface Customer { |
| 52 | 52 | id: number; |
| @@ -163,9 +163,9 @@ | ||
| 163 | 163 | }); |
| 164 | 164 | |
| 165 | 165 | return await apiService.getCustomers(paramsObj); |
| 166 | 166 | }, |
| 167 | - enabled: can("yatra_view_bookings"), | |
| 167 | + enabled: can("yatra_view_customers"), | |
| 168 | 168 | }); |
| 169 | 169 | |
| 170 | 170 | // Fetch customer stats (counts) |
| 171 | 171 | const { data: statsRaw } = useQuery({ |
| @@ -172,9 +172,9 @@ | ||
| 172 | 172 | queryKey: ["customers-stats"], |
| 173 | 173 | queryFn: async () => { |
| 174 | 174 | return await apiService.getCustomerStats(); |
| 175 | 175 | }, |
| 176 | - enabled: can("yatra_view_bookings"), | |
| 176 | + enabled: can("yatra_view_customers"), | |
| 177 | 177 | }); |
| 178 | 178 | const statsData: any = statsRaw ?? {}; |
| 179 | 179 | |
| 180 | 180 | // Delete mutation |
| @@ -201,19 +201,13 @@ | ||
| 201 | 201 | const formatDate = (dateString: string | null | undefined) => { |
| 202 | 202 | return formatDateUtil(dateString); |
| 203 | 203 | }; |
| 204 | 204 | |
| 205 | - const formatPrice = (price: number, currencyCode: string = "USD") => { | |
| 206 | - const symbol = getCurrencySymbol(currencyCode); | |
| 207 | - const currencyData = getCurrency(currencyCode); | |
| 208 | - const decimals = currencyData?.decimalDigits ?? 2; | |
| 205 | + const formatPrice = (price: number, currencyCode: string = "USD") => | |
| 206 | + formatYatraMoney(Number(price) || 0, currencyCode, { | |
| 207 | + zeroAsUnknown: false, | |
| 208 | + }); | |
| 209 | 209 | |
| 210 | - return `${symbol}${new Intl.NumberFormat(undefined, { | |
| 211 | - minimumFractionDigits: decimals, | |
| 212 | - maximumFractionDigits: decimals, | |
| 213 | - }).format(price)}`; | |
| 214 | - }; | |
| 215 | - | |
| 216 | 210 | const getStatusBadge = (status: string) => { |
| 217 | 211 | const statusMap: Record<string, { className: string; label: string }> = { |
| 218 | 212 | active: { |
| 219 | 213 | className: |
| @@ -597,9 +591,9 @@ | ||
| 597 | 591 | key: "edit", |
| 598 | 592 | label: __("Edit"), |
| 599 | 593 | icon: <Edit className="w-4 h-4" />, |
| 600 | 594 | onClick: (customer: Customer) => handleEdit(customer), |
| 601 | - condition: () => can("yatra_edit_bookings"), | |
| 595 | + condition: () => can("yatra_edit_customers"), | |
| 602 | 596 | }, |
| 603 | 597 | { |
| 604 | 598 | key: "mark_active", |
| 605 | 599 | label: __("Mark as Active"), |
| @@ -608,9 +602,9 @@ | ||
| 608 | 602 | await updateStatusForIds([customer.id], "active"); |
| 609 | 603 | queryClient.invalidateQueries({ queryKey: ["customers"] }); |
| 610 | 604 | }, |
| 611 | 605 | condition: (customer: Customer) => |
| 612 | - can("yatra_edit_bookings") && customer.status !== "active", | |
| 606 | + can("yatra_edit_customers") && customer.status !== "active", | |
| 613 | 607 | }, |
| 614 | 608 | { |
| 615 | 609 | key: "mark_inactive", |
| 616 | 610 | label: __("Mark as Inactive"), |
| @@ -619,9 +613,9 @@ | ||
| 619 | 613 | await updateStatusForIds([customer.id], "inactive"); |
| 620 | 614 | queryClient.invalidateQueries({ queryKey: ["customers"] }); |
| 621 | 615 | }, |
| 622 | 616 | condition: (customer: Customer) => |
| 623 | - can("yatra_edit_bookings") && customer.status !== "inactive", | |
| 617 | + can("yatra_edit_customers") && customer.status !== "inactive", | |
| 624 | 618 | }, |
| 625 | 619 | { |
| 626 | 620 | key: "mark_blocked", |
| 627 | 621 | label: __("Mark as Blocked"), |
| @@ -630,9 +624,9 @@ | ||
| 630 | 624 | await updateStatusForIds([customer.id], "blocked"); |
| 631 | 625 | queryClient.invalidateQueries({ queryKey: ["customers"] }); |
| 632 | 626 | }, |
| 633 | 627 | condition: (customer: Customer) => |
| 634 | - can("yatra_edit_bookings") && customer.status !== "blocked", | |
| 628 | + can("yatra_edit_customers") && customer.status !== "blocked", | |
| 635 | 629 | }, |
| 636 | 630 | { |
| 637 | 631 | key: "delete", |
| 638 | 632 | label: __("Delete"), |
| @@ -638,9 +632,9 @@ | ||
| 638 | 632 | label: __("Delete"), |
| 639 | 633 | icon: <Trash2 className="w-4 h-4" />, |
| 640 | 634 | onClick: (customer: Customer) => handleDelete(customer), |
| 641 | 635 | variant: "destructive" as const, |
| 642 | - condition: () => can("yatra_delete_bookings"), | |
| 636 | + condition: () => can("yatra_delete_customers"), | |
| 643 | 637 | }, |
| 644 | 638 | ]; |
| 645 | 639 | |
| 646 | 640 | // Skeleton loader |
| @@ -708,9 +702,9 @@ | ||
| 708 | 702 | <div className="space-y-3"> |
| 709 | 703 | <PageHeader |
| 710 | 704 | title={__("Customers")} |
| 711 | 705 | description={__("Manage your customer database")} |
| 712 | - actionCapability="yatra_edit_bookings" | |
| 706 | + actionCapability="yatra_edit_customers" | |
| 713 | 707 | actions={ |
| 714 | 708 | <Button |
| 715 | 709 | onClick={handleCreateCustomer} |
| 716 | 710 | className="flex items-center gap-2" |
| @@ -722,9 +716,9 @@ | ||
| 722 | 716 | /> |
| 723 | 717 | |
| 724 | 718 | <div className="space-y-3"> |
| 725 | 719 | {/* Search and Filters Card */} |
| 726 | - <ConditionalRender capability="yatra_view_bookings"> | |
| 720 | + <ConditionalRender capability="yatra_view_customers"> | |
| 727 | 721 | <Card> |
| 728 | 722 | <CardContent className="p-4"> |
| 729 | 723 | <div className="grid grid-cols-1 lg:grid-cols-12 gap-4 items-center"> |
| 730 | 724 | {/* Search & status/sort (handled by toolbar) */} |
| @@ -779,9 +773,9 @@ | ||
| 779 | 773 | </Card> |
| 780 | 774 | </ConditionalRender> |
| 781 | 775 | |
| 782 | 776 | {/* Bulk Actions Toolbar */} |
| 783 | - <ConditionalRender capability="yatra_view_bookings"> | |
| 777 | + <ConditionalRender capability="yatra_view_customers"> | |
| 784 | 778 | <BulkActionToolbar |
| 785 | 779 | selectedIds={selectedIds} |
| 786 | 780 | bulkAction={bulkAction} |
| 787 | 781 | setBulkAction={setBulkAction} |
| @@ -820,9 +814,9 @@ | ||
| 820 | 814 | /> |
| 821 | 815 | </ConditionalRender> |
| 822 | 816 | |
| 823 | 817 | {/* Customers Table Card */} |
| 824 | - <ConditionalRender capability="yatra_view_bookings"> | |
| 818 | + <ConditionalRender capability="yatra_view_customers"> | |
| 825 | 819 | <Card> |
| 826 | 820 | <CardContent className="p-0"> |
| 827 | 821 | {isLoading ? ( |
| 828 | 822 | renderSkeleton() |
| @@ -848,9 +842,9 @@ | ||
| 848 | 842 | ? __("Try adjusting your filters to see more results.") |
| 849 | 843 | : __("Customers will appear here when bookings are made") |
| 850 | 844 | } |
| 851 | 845 | onCreateClick={ |
| 852 | - can("yatra_edit_bookings") | |
| 846 | + can("yatra_edit_customers") | |
| 853 | 847 | ? handleCreateCustomer |
| 854 | 848 | : undefined |
| 855 | 849 | } |
| 856 | 850 | onSort={handleSort} |
| @@ -860,9 +854,9 @@ | ||
| 860 | 854 | onSelectAll={handleSelectAll} |
| 861 | 855 | isAllSelected={isAllSelected} |
| 862 | 856 | getItemId={(customer: Customer) => customer.id} |
| 863 | 857 | skeletonRows={5} |
| 864 | - capability="yatra_view_bookings" | |
| 858 | + capability="yatra_view_customers" | |
| 865 | 859 | /> |
| 866 | 860 | )} |
| 867 | 861 | </CardContent> |
| 868 | 862 | </Card> |