diff --git a/src/components/cards/CallCard.tsx b/src/components/cards/CallCard.tsx index a19224d..3b1bb41 100644 --- a/src/components/cards/CallCard.tsx +++ b/src/components/cards/CallCard.tsx @@ -1,58 +1,12 @@ -import { Store, MapPin, TrendingUp, Calendar, Clock, Info } from 'lucide-react'; +import { Store, MapPin, TrendingUp, Calendar, Clock, Info, Truck } from 'lucide-react'; import { formatValue } from '../../lib/format'; -import { BASE_URL, APP_ID } from '../../api/config'; import './card.css'; -// { -// "42b7f47d-96f0-4289-a6d9-38f455ad57dd__user_id": { -// "email": "surya.c@getzino.com", -// "job_title": "", -// "name": "Surya C", -// "user_id": 29113 -// }, -// "current_state_id": "33d7ab1f-ddf4-4549-ac99-7d23172c4ca5", -// "current_state_name": "Productive Call", -// "date_of_visit": "2026-07-15", -// "instance_id": 6592, -// "is_productive_call": "yes", -// "select_store": { -// "area": "Dummy Area", -// "business_name": "Business Name 777", -// "complete_address": "Dummy notes for Complete Address", -// "distributor_email": "test@example.com", -// "distributor_name": "Banashree Multi Millet Flour", -// "distributor_owner_name": "Dummy Distributor Owner Name", -// "distributor_phone_number": { -// "dial_code": "+91", -// "phone": "9876543210", -// "phone_with_dial_code": "+919876543210" -// }, -// "email": "test@example.com", -// "instance_id": 6118, -// "notes": "Dummy notes for Notes", -// "owner_name": "Dummy Owner Name", -// "phone_number": { -// "dial_code": "+91", -// "phone": "9876543210", -// "phone_with_dial_code": "+919876543210" -// }, -// "pin_code": "100000", -// "potential": "[{\"row_kgs\": 0, \"quantity\": 20, \"product_category\": \"MAIDA SUPER VALUE\"}, {\"row_kgs\": 0, \"quantity\": 30, \"product_category\": \"SUJI\"}, {\"row_kgs\": 0, \"quantity\": 10, \"product_category\": \"FORTIFIED MAIDA\"}, {\"row_kgs\": 0, \"quantity\": 300, \"product_category\": \"ATTA REGULAR\"}]", -// "route_code": "k", -// "route_name": "Krishna", -// "store_code": "STR-00024", -// "store_image": "[{\"uuid\": \"a449f6cb-0dce-4e21-9599-ab4d3e47042b\", \"blob_path\": \"434/a449f6cb-0dce-4e21-9599-ab4d3e47042b.png\", \"mime_type\": \"image/png\", \"size_bytes\": 32174, \"original_name\": \"profile.png\"}]", -// "store_location": "{\"latitude\":12.9716,\"longitude\":77.5946}", -// "sub_route": "A" -// }, -// "time_of_visit": "13:02:00", -// "upload_image": null -// } - export function CallCard({ row, isDetailView = false }: { row: Record; isDetailView?: boolean }) { // Status Mapping const stateName = row.current_state_name; const lowerState = stateName.toLowerCase(); + const showOrderDetails = lowerState.includes('ordered') || lowerState.includes('order closed') || lowerState.includes('close order'); let statusClass = 'z-card-status--neutral'; if (lowerState.includes('productive call')) { @@ -72,26 +26,37 @@ export function CallCard({ row, isDetailView = false }: { row: Record k.includes('user_id')); const userObj = userKey ? row[userKey] : null; - // Image - let imageObj = null; - let imgData = row.upload_image || storeObj?.store_image || row.store_image || row.image; - if (typeof imgData === 'string' && imgData.startsWith('[')) { - try { imgData = JSON.parse(imgData); } catch (e) { } - } - if (Array.isArray(imgData) && imgData.length > 0) { - imageObj = imgData[0]; - } else if (imgData && typeof imgData === 'object' && imgData.blob_path) { - imageObj = imgData; - } - // Store Details const storeName = formatValue(storeObj?.business_name || storeObj?.distributor_name || row.store_name || row.customer_name || (typeof row.store === 'string' ? row.store : 'Unknown Store')); const storeCode = formatValue(storeObj?.store_code || row.store_code || '—'); - // Grid Details (Calculate from potential if missing) - let totalWeightVal = Number(row.total_kgs || row.total_weight || row.weight || 0); - let totalQuantityVal = Number(row.total_bags || row.total_quantity || row.quantity || 0); - let totalOrdersVal = Number(row.order_count || row.total_orders || 0); + // Phone and Email + const storeEmail = formatValue(storeObj?.email || row.email || row.store_email || '—'); + const storePhoneRaw = storeObj?.phone_number || row.phone_number || row.phone || row.store_phone; + let storePhone = '—'; + if (typeof storePhoneRaw === 'object' && storePhoneRaw !== null) { + storePhone = formatValue(storePhoneRaw.phone_with_dial_code || storePhoneRaw.phone || '—'); + } else if (typeof storePhoneRaw === 'string') { + storePhone = formatValue(storePhoneRaw); + } + + // Distributor Details + const distName = formatValue(storeObj?.distributor_name || '—'); + const distOwner = formatValue(storeObj?.distributor_owner_name || '—'); + const distEmail = formatValue(storeObj?.distributor_email || '—'); + const distPhoneRaw = storeObj?.distributor_phone_number; + let distPhone = '—'; + if (typeof distPhoneRaw === 'object' && distPhoneRaw !== null) { + distPhone = formatValue(distPhoneRaw.phone_with_dial_code || distPhoneRaw.phone || '—'); + } else if (typeof distPhoneRaw === 'string') { + distPhone = formatValue(distPhoneRaw); + } + const hasDistributor = distName !== '—' || distOwner !== '—' || distEmail !== '—' || distPhone !== '—'; + + // Grid Details (Calculate from potential or orders if missing) + let totalWeightVal = Number(row.total_kgs_3 || row.total_kgs || row.total_weight || row.weight || 0); + let totalQuantityVal = Number(row.total_bags_3 || row.total_bags || row.total_quantity || row.quantity || 0); + let totalOrdersVal = Number(row.order_count || row.total_orders || (row.order_details_3 ? row.order_details_3.length : 0)); if (totalWeightVal === 0 && totalQuantityVal === 0 && storeObj?.potential) { try { @@ -209,47 +174,18 @@ export function CallCard({ row, isDetailView = false }: { row: Record - - {storeCode !== '—' && ( + {storePhone !== '—' && (

- Code: {storeCode} + Phone: {storePhone} +

+ )} + {storeEmail !== '—' && ( +

+ Email: {storeEmail}

)} - {imageObj && imageObj.uuid && ( -
- Store { - (e.target as HTMLImageElement).style.display = 'none'; - }} - /> -
- )} - {/* Logistics Grid */} -
-
-

Total Weight

-

- {totalWeight} Kgs -

-
-
-

Total Quantity

-

- {totalQuantity} Bags -

-
-
- Total Orders - - {totalOrders} {Number(totalOrders) === 1 ? 'Order' : 'Orders'} - -
-
{/* Route & Assignment */}
@@ -277,6 +213,89 @@ export function CallCard({ row, isDetailView = false }: { row: Record
+ {/* Call Meta Chips */} +
+ {row.order_received_channel && ( + + Channel: {String(row.order_received_channel).replace(/_/g, ' ').toUpperCase()} + + )} + {row.remarks && ( +
+ Remarks: + {row.remarks} +
+ )} +
+ + {/* Product Cards (Order Details) */} + {showOrderDetails && row.order_details_3 && Array.isArray(row.order_details_3) && row.order_details_3.length > 0 && ( +
+
+

Order Products

+ + {totalOrders} {Number(totalOrders) === 1 ? 'Item' : 'Items'} + +
+
+ {row.order_details_3.map((prod: any, idx: number) => { + const productName = formatValue(prod.product_name_3 || prod.product_category_3 || 'Unknown Product'); + const bags = formatValue(prod.bags_3 || 0); + return ( +
+ {productName} + {bags} Bags +
+ ); + })} +
+
+ )} + + {/* Logistics Totals at the bottom */} + {showOrderDetails && (Number(totalWeightVal) > 0 || Number(totalQuantityVal) > 0) && ( +
+
+ Total Weight + {totalWeight} Kgs +
+
+ Total Quantity + {totalQuantity} Bags +
+
+ )} + + {/* Distributor Details */} + {hasDistributor && ( +
+

Distributor Details

+ + {distName !== '—' && ( +
+ +

{distName}

+
+ )} + + {distOwner !== '—' && ( +

+ Owner: {distOwner} +

+ )} + {distPhone !== '—' && ( +

+ Phone: {distPhone} +

+ )} + {distEmail !== '—' && ( +

+ Email: {distEmail} +

+ )} +
+ )} + )} diff --git a/src/components/cards/card.css b/src/components/cards/card.css index 48d2a46..b18c804 100644 --- a/src/components/cards/card.css +++ b/src/components/cards/card.css @@ -164,10 +164,15 @@ .z-card-meta { font-size: 13px; - color: var(--z-text-neutral-500); + color: var(--z-text-neutral-600); margin-top: 2px; } +.z-card-meta-val { + font-weight: 700; + color: var(--z-text-neutral-900); +} + .z-card-meta-code { font-family: var(--font-mono); font-weight: 500; diff --git a/src/components/dv/CallDetail.tsx b/src/components/dv/CallDetail.tsx index 13270f6..babfbe5 100644 --- a/src/components/dv/CallDetail.tsx +++ b/src/components/dv/CallDetail.tsx @@ -1,16 +1,21 @@ import { orderBookingClient } from '../../api/clients'; import { ORDER_BOOKING } from '../../api/config'; -import { DetailView } from './DetailView'; import type { WiredDetailViewProps } from './OrderDetail'; +import { useDetailViewData } from './useDetailViewData'; +import { Spinner } from '../reusable/Spinner'; +import { EmptyState } from '../reusable/EmptyState'; +import { CallCard } from '../cards/CallCard'; + +export function CallDetail({ instanceId }: WiredDetailViewProps) { + const { data, loading, error } = useDetailViewData(orderBookingClient, ORDER_BOOKING.detailViews.CALLS, instanceId); + + if (error) return ; + if (loading) return
; + if (!data) return ; -export function CallDetail({ instanceId, columns = 2 }: WiredDetailViewProps) { return ( - +
+ +
); }