From ec4a6d35fae3859cdebb5f9f47241e1c98118e93 Mon Sep 17 00:00:00 2001 From: Tarun-Nagesh Date: Sun, 25 Jan 2026 13:53:28 -0500 Subject: [PATCH 1/3] Added applications details page --- apps/frontend/src/app.tsx | 9 + .../src/containers/applicationDetails.tsx | 361 ++++++++++++++++++ .../src/containers/approvePantries.tsx | 13 +- 3 files changed, 373 insertions(+), 10 deletions(-) create mode 100644 apps/frontend/src/containers/applicationDetails.tsx diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index e31dc284..89872b41 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -17,6 +17,7 @@ import PantryApplication from '@containers/pantryApplication'; import PantryApplicationSubmitted from '@containers/pantryApplicationSubmitted'; import { submitPantryApplicationForm } from '@components/forms/pantryApplicationForm'; import ApprovePantries from '@containers/approvePantries'; +import ApplicationDetails from '@containers/applicationDetails'; import VolunteerManagement from '@containers/volunteerManagement'; import FoodManufacturerOrderDashboard from '@containers/foodManufacturerOrderDashboard'; import DonationManagement from '@containers/donationManagement'; @@ -161,6 +162,14 @@ const router = createBrowserRouter([ ), }, + { + path: '/application-details/:applicationId', + element: ( + + + + ), + }, { path: '/admin-donation', element: ( diff --git a/apps/frontend/src/containers/applicationDetails.tsx b/apps/frontend/src/containers/applicationDetails.tsx new file mode 100644 index 00000000..10cab566 --- /dev/null +++ b/apps/frontend/src/containers/applicationDetails.tsx @@ -0,0 +1,361 @@ +import React, { useEffect, useState } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { + Center, + Box, + Grid, + GridItem, + Text, + Button, + Heading, + VStack, + HStack, + Spinner, + Badge, + Flex, +} from '@chakra-ui/react'; +import ApiClient from '@api/apiClient'; +import { Pantry } from 'types/types'; + +const ApplicationDetails: React.FC = () => { + const { applicationId } = useParams<{ applicationId: string }>(); + const navigate = useNavigate(); + const [application, setApplication] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + const formatPhone = (phone?: string | null) => { + if (!phone) return null; + const digits = phone.replace(/\D/g, ''); + if (digits.length === 10) { + return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`; + } + return phone; + }; + + const fetchApplicationDetails = async () => { + try { + setLoading(true); + setError(null); + if (!applicationId) { + setError('Application ID not provided'); + return; + } + const data = await ApiClient.getPantry(parseInt(applicationId, 10)); + setApplication(data); + } catch (err) { + setError('Error loading application details: ' + (err instanceof Error ? err.message : String(err))); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchApplicationDetails(); + }, [applicationId]); + + const handleApprove = async () => { + if (application) { + try { + await ApiClient.updatePantry(application.pantryId, 'approve'); + navigate('/approve-pantries'); + } catch (err) { + alert('Error approving application: ' + err); + } + } + }; + + const handleDeny = async () => { + if (application) { + try { + await ApiClient.updatePantry(application.pantryId, 'deny'); + navigate('/approve-pantries'); + } catch (err) { + alert('Error denying application: ' + err); + } + } + }; + + if (loading) { + return ( +
+ + Loading application details... +
+ ); + } + + if (error) { + return ( +
+ + {error} + + +
+ ); + } + + if (!application) { + return ( +
+ + Application not found + + +
+ ); + } + + const pantryUser = application.pantryUser; + + return ( + + + {/* Page Title */} + + Application Details + + + {/* Main Content Card */} + + + {/* Application Header */} + + + Application #{application.pantryId} + + + {application.pantryName} + + + Applied {new Date(application.dateApplied).toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' })} + + + + {/* Point of Contact and Shipping Address */} + + + + Point of Contact Information + + + + {pantryUser + ? `${pantryUser.firstName} ${pantryUser.lastName}` + : application.secondaryContactFirstName && application.secondaryContactLastName + ? `${application.secondaryContactFirstName} ${application.secondaryContactLastName}` + : 'N/A'} + + + {formatPhone(pantryUser?.phone ?? application.secondaryContactPhone) ?? 'N/A'} + + + {pantryUser?.email ?? application.secondaryContactEmail ?? 'N/A'} + + + + + + Shipping Address + + + {(application as any).shipmentAddressLine1}, + + {(application as any).shipmentAddressCity}, {(application as any).shipmentAddressState} {(application as any).shipmentAddressZip} + + {(application as any).shipmentAddressCountry === 'US' ? 'United States of America' : (application as any).shipmentAddressCountry} + + + + + {/* Pantry Details */} + + + Pantry Details + + + + + Name + + {application.pantryName} + + + + Approximate # of Clients + + {application.allergenClients} + + + + + {/* Food Allergies and Restrictions */} + + + Food Allergies and Restrictions + + + {application.restrictions && application.restrictions.length > 0 ? ( + application.restrictions.map((restriction, index) => ( + + {restriction} + + )) + ) : ( + None + )} + + + + + + Accepts Refrigerated Donations? + + {application.refrigeratedDonation} + + + + Willing to Reserve Donations for Allergen-Avoidant Individuals + + {application.reserveFoodForAllergic} + + + + {application.reservationExplanation && ( + + + Justification + + {application.reservationExplanation} + + )} + + + + + Dedicated section for allergy-friendly items? + + {application.dedicatedAllergyFriendly ? 'Yes, we have a dedicated shelf or box' : 'No'} + + + + How Often Allergen-Avoidant Clients Visit + + {application.clientVisitFrequency ?? 'Not specified'} + + + + + + + Confident in Identifying the Top 9 Allergens + + {application.identifyAllergensConfidence ?? 'Not specified'} + + + + Serves Allergen-Avoidant Children + + {application.serveAllergicChildren ?? 'Not specified'} + + + + + {/* Open to SSF Activities */} + + + Open to SSF Activities + + + {application.activities && application.activities.length > 0 ? ( + application.activities.map((activity, index) => ( + + {activity} + + )) + ) : ( + None + )} + + + + {/* Comments/Concerns */} + + + Comments/Concerns + + {application.activitiesComments || '-'} + + + {/* Allergen-free Items in Stock */} + + + Allergen-free Items in Stock + + {application.itemsInStock} + + + {/* Client Requests */} + + + Client Requests + + {application.needMoreOptions} + + + {/* Subscribed to Newsletter */} + + + Subscribed to Newsletter + + {application.newsletterSubscription ? 'Yes' : 'No'} + + + {/* Action Buttons */} + + + + + + + + + ); +}; + +export default ApplicationDetails; diff --git a/apps/frontend/src/containers/approvePantries.tsx b/apps/frontend/src/containers/approvePantries.tsx index bbe3882a..61f94b51 100644 --- a/apps/frontend/src/containers/approvePantries.tsx +++ b/apps/frontend/src/containers/approvePantries.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { Center, Table, @@ -7,16 +8,15 @@ import { NativeSelect, NativeSelectIndicator, } from '@chakra-ui/react'; -import PantryApplicationModal from '@components/forms/pantryApplicationModal'; import ApiClient from '@api/apiClient'; import { Pantry } from 'types/types'; import { formatDate } from '@utils/utils'; const ApprovePantries: React.FC = () => { + const navigate = useNavigate(); const [pendingPantries, setPendingPantries] = useState([]); const [sortedPantries, setSortedPantries] = useState([]); const [sort, setSort] = useState(''); - const [openPantry, setOpenPantry] = useState(null); const fetchPantries = async () => { try { @@ -91,7 +91,7 @@ const ApprovePantries: React.FC = () => { bg="transparent" color="cyan" fontWeight="600" - onClick={() => setOpenPantry(pantry)} + onClick={() => navigate(`/application-details/${pantry.pantryId}`)} > {pantry.pantryName} @@ -117,13 +117,6 @@ const ApprovePantries: React.FC = () => { ))} - {openPantry && ( - setOpenPantry(null)} - /> - )} From d9558eed0f93589abbf4f63970be674fcae1315a Mon Sep 17 00:00:00 2001 From: Tarun-Nagesh Date: Sun, 25 Jan 2026 14:00:13 -0500 Subject: [PATCH 2/3] Linting issues --- .../src/containers/applicationDetails.tsx | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/apps/frontend/src/containers/applicationDetails.tsx b/apps/frontend/src/containers/applicationDetails.tsx index 10cab566..c7541ab2 100644 --- a/apps/frontend/src/containers/applicationDetails.tsx +++ b/apps/frontend/src/containers/applicationDetails.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Center, @@ -17,10 +17,21 @@ import { import ApiClient from '@api/apiClient'; import { Pantry } from 'types/types'; +type PantryWithShipment = Pantry & { + shipmentAddressLine1?: string | null; + shipmentAddressLine2?: string | null; + shipmentAddressCity?: string | null; + shipmentAddressState?: string | null; + shipmentAddressZip?: string | null; + shipmentAddressCountry?: string | null; +}; + const ApplicationDetails: React.FC = () => { const { applicationId } = useParams<{ applicationId: string }>(); const navigate = useNavigate(); - const [application, setApplication] = useState(null); + const [application, setApplication] = useState( + null, + ); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -33,7 +44,7 @@ const ApplicationDetails: React.FC = () => { return phone; }; - const fetchApplicationDetails = async () => { + const fetchApplicationDetails = useCallback(async () => { try { setLoading(true); setError(null); @@ -42,17 +53,20 @@ const ApplicationDetails: React.FC = () => { return; } const data = await ApiClient.getPantry(parseInt(applicationId, 10)); - setApplication(data); + setApplication(data as PantryWithShipment); } catch (err) { - setError('Error loading application details: ' + (err instanceof Error ? err.message : String(err))); + setError( + 'Error loading application details: ' + + (err instanceof Error ? err.message : String(err)), + ); } finally { setLoading(false); } - }; + }, [applicationId]); useEffect(() => { fetchApplicationDetails(); - }, [applicationId]); + }, [fetchApplicationDetails]); const handleApprove = async () => { if (application) { @@ -141,17 +155,22 @@ const ApplicationDetails: React.FC = () => { - {pantryUser - ? `${pantryUser.firstName} ${pantryUser.lastName}` - : application.secondaryContactFirstName && application.secondaryContactLastName + {pantryUser + ? `${pantryUser.firstName} ${pantryUser.lastName}` + : application.secondaryContactFirstName && + application.secondaryContactLastName ? `${application.secondaryContactFirstName} ${application.secondaryContactLastName}` : 'N/A'} - {formatPhone(pantryUser?.phone ?? application.secondaryContactPhone) ?? 'N/A'} + {formatPhone( + pantryUser?.phone ?? application.secondaryContactPhone, + ) ?? 'N/A'} - {pantryUser?.email ?? application.secondaryContactEmail ?? 'N/A'} + {pantryUser?.email ?? + application.secondaryContactEmail ?? + 'N/A'} @@ -160,11 +179,19 @@ const ApplicationDetails: React.FC = () => { Shipping Address - {(application as any).shipmentAddressLine1}, - {(application as any).shipmentAddressCity}, {(application as any).shipmentAddressState} {(application as any).shipmentAddressZip} + {application.shipmentAddressLine1 ?? 'N/A'}, + + + {application.shipmentAddressCity ?? 'N/A'},{' '} + {application.shipmentAddressState ?? 'N/A'}{' '} + {application.shipmentAddressZip ?? ''} + + + {application.shipmentAddressCountry === 'US' + ? 'United States of America' + : application.shipmentAddressCountry ?? 'N/A'} - {(application as any).shipmentAddressCountry === 'US' ? 'United States of America' : (application as any).shipmentAddressCountry} From 2bba55ba92f339aaa65934aaf0a2a8f2560e31bc Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Wed, 25 Feb 2026 23:15:12 -0500 Subject: [PATCH 3/3] review comments --- apps/frontend/src/app.tsx | 4 +- .../forms/pantryApplicationModal.tsx | 12 +- .../src/containers/applicationDetails.tsx | 393 +++++++++--------- .../src/containers/approvePantries.tsx | 4 +- apps/frontend/src/theme.ts | 7 + apps/frontend/src/types/types.ts | 26 +- apps/frontend/src/utils/utils.ts | 9 + 7 files changed, 229 insertions(+), 226 deletions(-) diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index 53d167ca..a49dde7b 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -178,9 +178,9 @@ const router = createBrowserRouter([ { path: '/application-details/:applicationId', element: ( - + - + ), }, { diff --git a/apps/frontend/src/components/forms/pantryApplicationModal.tsx b/apps/frontend/src/components/forms/pantryApplicationModal.tsx index 4c973fd6..ede50a2e 100644 --- a/apps/frontend/src/components/forms/pantryApplicationModal.tsx +++ b/apps/frontend/src/components/forms/pantryApplicationModal.tsx @@ -66,32 +66,32 @@ const PantryApplicationModal: React.FC = ({ Shipping Address Line 1 - {pantry.shippingAddressLine1} + {pantry.shipmentAddressLine1} Shipping Address Line 2 - {pantry.shippingAddressLine2 ?? ''} + {pantry.shipmentAddressLine2 ?? ''} Shipping Address City - {pantry.shippingAddressCity} + {pantry.shipmentAddressCity} Shipping Address State - {pantry.shippingAddressState} + {pantry.shipmentAddressState} Shipping Address Zip - {pantry.shippingAddressZip} + {pantry.shipmentAddressZip} Shipping Address Country - {pantry.shippingAddressCountry ?? ''} + {pantry.shipmentAddressCountry ?? ''} Allergen Clients diff --git a/apps/frontend/src/containers/applicationDetails.tsx b/apps/frontend/src/containers/applicationDetails.tsx index c7541ab2..ebc61c6d 100644 --- a/apps/frontend/src/containers/applicationDetails.tsx +++ b/apps/frontend/src/containers/applicationDetails.tsx @@ -11,37 +11,39 @@ import { VStack, HStack, Spinner, - Badge, - Flex, } from '@chakra-ui/react'; import ApiClient from '@api/apiClient'; import { Pantry } from 'types/types'; - -type PantryWithShipment = Pantry & { - shipmentAddressLine1?: string | null; - shipmentAddressLine2?: string | null; - shipmentAddressCity?: string | null; - shipmentAddressState?: string | null; - shipmentAddressZip?: string | null; - shipmentAddressCountry?: string | null; -}; +import { formatDate, formatPhone } from '@utils/utils'; +import { TagGroup } from '@components/forms/tagGroup'; const ApplicationDetails: React.FC = () => { const { applicationId } = useParams<{ applicationId: string }>(); const navigate = useNavigate(); - const [application, setApplication] = useState( - null, - ); + const [application, setApplication] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - const formatPhone = (phone?: string | null) => { - if (!phone) return null; - const digits = phone.replace(/\D/g, ''); - if (digits.length === 10) { - return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`; - } - return phone; + const fieldContentStyles = { + textStyle: 'p2', + color: 'gray.light', + lineHeight: '1.2', + }; + + const headerStyles = { + textStyle: 'p2', + color: 'neutral.800', + }; + + const sectionHeaderStyles = { + ...headerStyles, + fontWeight: 600, + }; + + const fieldHeaderStyles = { + ...headerStyles, + fontWeight: 500, + mb: 1, }; const fetchApplicationDetails = useCallback(async () => { @@ -53,7 +55,7 @@ const ApplicationDetails: React.FC = () => { return; } const data = await ApiClient.getPantry(parseInt(applicationId, 10)); - setApplication(data as PantryWithShipment); + setApplication(data); } catch (err) { setError( 'Error loading application details: ' + @@ -105,7 +107,9 @@ const ApplicationDetails: React.FC = () => { {error} - + ); } @@ -116,7 +120,9 @@ const ApplicationDetails: React.FC = () => { Application not found - + ); } @@ -124,256 +130,235 @@ const ApplicationDetails: React.FC = () => { const pantryUser = application.pantryUser; return ( - + - {/* Page Title */} - + Application Details - {/* Main Content Card */} - + - {/* Application Header */} - + Application #{application.pantryId} - + {application.pantryName} - - Applied {new Date(application.dateApplied).toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' })} + + Applied {formatDate(application.dateApplied)} - {/* Point of Contact and Shipping Address */} - + Point of Contact Information - - - {pantryUser - ? `${pantryUser.firstName} ${pantryUser.lastName}` - : application.secondaryContactFirstName && - application.secondaryContactLastName - ? `${application.secondaryContactFirstName} ${application.secondaryContactLastName}` - : 'N/A'} - - - {formatPhone( - pantryUser?.phone ?? application.secondaryContactPhone, - ) ?? 'N/A'} - - - {pantryUser?.email ?? - application.secondaryContactEmail ?? - 'N/A'} - - + + {pantryUser + ? `${pantryUser.firstName} ${pantryUser.lastName}` + : application.secondaryContactFirstName && + application.secondaryContactLastName + ? `${application.secondaryContactFirstName} ${application.secondaryContactLastName}` + : 'N/A'} + + + {formatPhone( + pantryUser?.phone ?? application.secondaryContactPhone, + ) ?? 'N/A'} + + + {pantryUser?.email ?? + application.secondaryContactEmail ?? + 'N/A'} + - - Shipping Address + + Shipment Address - - - {application.shipmentAddressLine1 ?? 'N/A'}, - - - {application.shipmentAddressCity ?? 'N/A'},{' '} - {application.shipmentAddressState ?? 'N/A'}{' '} - {application.shipmentAddressZip ?? ''} - - - {application.shipmentAddressCountry === 'US' - ? 'United States of America' - : application.shipmentAddressCountry ?? 'N/A'} - - + + {application.shipmentAddressLine1 ?? 'N/A'}, + + + {application.shipmentAddressCity ?? 'N/A'},{' '} + {application.shipmentAddressState ?? 'N/A'}{' '} + {application.shipmentAddressZip ?? ''} + + + {application.shipmentAddressCountry === 'US' + ? 'United States of America' + : application.shipmentAddressCountry ?? 'N/A'} + - {/* Pantry Details */} - + Pantry Details - - Name - - {application.pantryName} + Name + {application.pantryName} - - Approximate # of Clients + Approximate # of Clients + + {application.allergenClients} - {application.allergenClients} - {/* Food Allergies and Restrictions */} - + Food Allergies and Restrictions - - {application.restrictions && application.restrictions.length > 0 ? ( - application.restrictions.map((restriction, index) => ( - - {restriction} - - )) - ) : ( - None - )} - + {application.restrictions && + application.restrictions.length > 0 ? ( + + ) : ( + None + )} + - - - - Accepts Refrigerated Donations? - - {application.refrigeratedDonation} - - - - Willing to Reserve Donations for Allergen-Avoidant Individuals - - {application.reserveFoodForAllergic} - - + + + + Accepts Refrigerated Donations? + + + {application.refrigeratedDonation} + + + + + Willing to Reserve Donations for Allergen-Avoidant Individuals + + + {application.reserveFoodForAllergic} + + + - {application.reservationExplanation && ( - - - Justification - - {application.reservationExplanation} - - )} + {application.reservationExplanation && ( + + Justification + + {application.reservationExplanation} + + + )} - - - - Dedicated section for allergy-friendly items? - - {application.dedicatedAllergyFriendly ? 'Yes, we have a dedicated shelf or box' : 'No'} - - - - How Often Allergen-Avoidant Clients Visit - - {application.clientVisitFrequency ?? 'Not specified'} - - + + + + Dedicated section for allergy-friendly items? + + + {application.dedicatedAllergyFriendly + ? 'Yes, we have a dedicated shelf or box' + : 'No'} + + + + + How Often Allergen-Avoidant Clients Visit + + + {application.clientVisitFrequency ?? 'Not specified'} + + + - - - - Confident in Identifying the Top 9 Allergens - - {application.identifyAllergensConfidence ?? 'Not specified'} - - - - Serves Allergen-Avoidant Children - - {application.serveAllergicChildren ?? 'Not specified'} - - - + + + + Confidence in Identifying the Top 9 Allergens + + + {application.identifyAllergensConfidence ?? 'Not specified'} + + + + + Serves Allergen-Avoidant Children + + + {application.serveAllergicChildren ?? 'Not specified'} + + + - {/* Open to SSF Activities */} - - Open to SSF Activities - - - {application.activities && application.activities.length > 0 ? ( - application.activities.map((activity, index) => ( - - {activity} - - )) - ) : ( - None - )} - + Open to SSF Activities + {application.activities && application.activities.length > 0 ? ( + + ) : ( + None + )} - {/* Comments/Concerns */} - - Comments/Concerns - - {application.activitiesComments || '-'} + Comments/Concerns + + {application.activitiesComments || '-'} + - {/* Allergen-free Items in Stock */} - + Allergen-free Items in Stock - {application.itemsInStock} + {application.itemsInStock} - {/* Client Requests */} - - Client Requests - - {application.needMoreOptions} + Client Requests + {application.needMoreOptions} - {/* Subscribed to Newsletter */} - - Subscribed to Newsletter - - {application.newsletterSubscription ? 'Yes' : 'No'} + Subscribed to Newsletter + + {application.newsletterSubscription ? 'Yes' : 'No'} + - {/* Action Buttons */} - + diff --git a/apps/frontend/src/containers/approvePantries.tsx b/apps/frontend/src/containers/approvePantries.tsx index 44d439f9..b47fac2d 100644 --- a/apps/frontend/src/containers/approvePantries.tsx +++ b/apps/frontend/src/containers/approvePantries.tsx @@ -91,7 +91,9 @@ const ApprovePantries: React.FC = () => { bg="transparent" color="cyan" fontWeight="600" - onClick={() => navigate(`/application-details/${pantry.pantryId}`)} + onClick={() => + navigate(`/application-details/${pantry.pantryId}`) + } > {pantry.pantryName} diff --git a/apps/frontend/src/theme.ts b/apps/frontend/src/theme.ts index abf16ad8..0b320004 100644 --- a/apps/frontend/src/theme.ts +++ b/apps/frontend/src/theme.ts @@ -53,6 +53,13 @@ const textStyles = defineTextStyles({ fontWeight: '400', }, }, + p3: { + value: { + fontFamily: 'inter', + fontSize: '12px', + fontWeight: '400', + }, + }, }); const customConfig = defineConfig({ diff --git a/apps/frontend/src/types/types.ts b/apps/frontend/src/types/types.ts index ce85f3b4..eed45507 100644 --- a/apps/frontend/src/types/types.ts +++ b/apps/frontend/src/types/types.ts @@ -19,12 +19,12 @@ import { export interface Pantry { pantryId: number; pantryName: string; - shippingAddressLine1: string; - shippingAddressLine2?: string; - shippingAddressCity: string; - shippingAddressState: string; - shippingAddressZip: string; - shippingAddressCountry?: string; + shipmentAddressLine1: string; + shipmentAddressLine2?: string; + shipmentAddressCity: string; + shipmentAddressState: string; + shipmentAddressZip: string; + shipmentAddressCountry?: string; mailingAddressLine1: string; mailingAddressLine2?: string; mailingAddressCity: string; @@ -71,12 +71,12 @@ export interface PantryApplicationDto { secondaryContactEmail?: string; secondaryContactPhone?: string; pantryName: string; - shippingAddressLine1: string; - shippingAddressLine2?: string; - shippingAddressCity: string; - shippingAddressState: string; - shippingAddressZip: string; - shippingAddressCountry?: string; + shipmentAddressLine1: string; + shipmentAddressLine2?: string; + shipmentAddressCity: string; + shipmentAddressState: string; + shipmentAddressZip: string; + shipmentAddressCountry?: string; mailingAddressLine1: string; mailingAddressLine2?: string; mailingAddressCity: string; @@ -218,7 +218,7 @@ export interface Order { deliveredAt?: Date; allocations: Allocation[]; trackingLink?: string; - shippingCost?: number; + shipmentCost?: number; } export interface OrderItemDetails { diff --git a/apps/frontend/src/utils/utils.ts b/apps/frontend/src/utils/utils.ts index 2b7faa21..4e704f80 100644 --- a/apps/frontend/src/utils/utils.ts +++ b/apps/frontend/src/utils/utils.ts @@ -1,5 +1,14 @@ import { DayOfWeek, RecurrenceEnum, RepeatOnState } from '../types/types'; +export const formatPhone = (phone?: string | null) => { + if (!phone) return null; + const digits = phone.replace(/\D/g, ''); + if (digits.length === 10) { + return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`; + } + return phone; +}; + export const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString('en-US');