diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 7d33ae3e..59fd9597 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -11,6 +11,7 @@ import { Pantry, PantryApplicationDto, CreateMultipleDonationItemsBody, + ManufacturerApplicationDto, OrderSummary, UserDto, OrderDetails, @@ -175,6 +176,12 @@ export class ApiClient { .then((response) => response.data); } + public async postManufacturer( + data: ManufacturerApplicationDto, + ): Promise> { + return this.axiosInstance.post(`/api/manufacturers/application`, data); + } + public async getAllOrders(): Promise { return this.axiosInstance .get('/api/orders/') diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index e31dc284..c61305f3 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -14,7 +14,7 @@ import { submitFoodRequestFormModal } from '@components/forms/requestFormModal'; import { submitDeliveryConfirmationFormModal } from '@components/forms/deliveryConfirmationModal'; import FormRequests from '@containers/FormRequests'; import PantryApplication from '@containers/pantryApplication'; -import PantryApplicationSubmitted from '@containers/pantryApplicationSubmitted'; +import ApplicationSubmitted from '@containers/applicationSubmitted'; import { submitPantryApplicationForm } from '@components/forms/pantryApplicationForm'; import ApprovePantries from '@containers/approvePantries'; import VolunteerManagement from '@containers/volunteerManagement'; @@ -29,6 +29,8 @@ import { Authenticator } from '@aws-amplify/ui-react'; import { Amplify } from 'aws-amplify'; import CognitoAuthConfig from './aws-exports'; import { Button } from '@chakra-ui/react'; +import FoodManufacturerApplication from '@containers/foodManufacturerApplication'; +import { submitManufacturerApplicationForm } from '@components/forms/manufacturerApplicationForm'; Amplify.configure(CognitoAuthConfig); @@ -83,8 +85,8 @@ const router = createBrowserRouter([ action: submitPantryApplicationForm, }, { - path: '/pantry-application/submitted', - element: , + path: '/application/submitted', + element: , }, // Private routes (protected by auth) { @@ -128,6 +130,11 @@ const router = createBrowserRouter([ ), }, + { + path: '/food-manufacturer-application', + element: , + action: submitManufacturerApplicationForm, + }, { path: '/orders', element: ( diff --git a/apps/frontend/src/components/forms/manufacturerApplicationForm.tsx b/apps/frontend/src/components/forms/manufacturerApplicationForm.tsx new file mode 100644 index 00000000..ae787944 --- /dev/null +++ b/apps/frontend/src/components/forms/manufacturerApplicationForm.tsx @@ -0,0 +1,771 @@ +import { + Box, + Button, + Heading, + Input, + RadioGroup, + Stack, + Text, + Field, + Textarea, + SimpleGrid, + NativeSelect, + NativeSelectIndicator, + Tag, + Separator, + Checkbox, + Menu, + Flex, +} from '@chakra-ui/react'; +import { + ActionFunction, + ActionFunctionArgs, + Form, + redirect, +} from 'react-router-dom'; +import React, { useState } from 'react'; +import { USPhoneInput } from '@components/forms/usPhoneInput'; +import { ManufacturerApplicationDto } from '../../types/types'; +import ApiClient from '@api/apiClient'; +import axios from 'axios'; +import { ChevronDownIcon } from 'lucide-react'; + +const allergenOptions = [ + 'Milk', + 'Egg', + 'Peanut', + 'Tree nuts', + 'Wheat', + 'Soy', + 'Fish', + 'Shellfish', + 'Sesame', + 'Gluten', +]; + +const ManufacturerApplicationForm: React.FC = () => { + const [contactPhone, setContactPhone] = useState(''); + const [secondaryContactPhone, setSecondaryContactPhone] = + useState(''); + const [unlistedProductAllergens, setUnlistedProductAllergens] = useState([]); + const [facilityFreeAllergens, setFacilityFreeAllergens] = useState([]); + + const sectionTitleStyles = { + fontFamily: 'inter', + fontWeight: '600', + fontSize: 'md', + color: 'gray.dark', + mb: '1.75em', + }; + + const sectionSubtitleStyles = { + fontFamily: 'inter', + fontWeight: '400', + color: 'gray.light', + mb: '2.25em', + fontSize: 'sm', + }; + + const fieldHeaderStyles = { + color: 'neutral.800', + fontFamily: 'inter', + fontSize: 'sm', + fontWeight: '600', + }; + + return ( + + + + Partner Manufacturer Application + + + Thank you for your interest in partnering with Securing Safe Food + (SSF) to help serve clients with food allergies and other adverse + reactions to foods. + + + +
+ + Food Manufacturer Application Form + + + + This form helps us learn about your company’s allergen-friendly products, + facility standards, and sustainability practices so we can connect you + with the right partner pantries. + + + Please answer as accurately as possible. If you have any questions + or need help, don’t hesitate to contact the SSF team. + + + + + Company Information + + + + Company Name + + + + + + + Company Website + + + + + + + + + Primary Contact Information + + + + First Name + + + + + + + Last Name + + + + + + + Phone Number + + + + + + + Email Address + + + + + + + + + Secondary Contact Information + + + First Name + + + + Last Name + + + + Phone Number + + + + Email Address + + + + + + + Product Details + + + What allergen(s) are not listed in your products' ingredients? + + + + {unlistedProductAllergens.map((value) => ( + + ))} + + + + + + + + + {allergenOptions.map((value) => { + const isChecked = unlistedProductAllergens.includes(value); + return ( + { + setUnlistedProductAllergens((prev) => + checked + ? [...prev, value] + : prev.filter((i) => i !== value), + ); + }} + display="flex" + alignItems="center" + > + + + + {value} + + + ); + })} + + + + + {unlistedProductAllergens.length > 0 && ( + + {unlistedProductAllergens.map((value) => ( + + {value} + + + setUnlistedProductAllergens((prev) => + prev.filter((item) => item !== value), + ) + } + style={{ cursor: 'pointer' }} + /> + + + ))} + + )} + + + + + What allergen(s) is your facility free from? + + + + {facilityFreeAllergens.map((value) => ( + + ))} + + + + + + + + + {allergenOptions.map((value) => { + const isChecked = facilityFreeAllergens.includes(value); + return ( + { + setFacilityFreeAllergens((prev) => + checked + ? [...prev, value] + : prev.filter((i) => i !== value), + ); + }} + display="flex" + alignItems="center" + > + + + + {value} + + + ); + })} + + + + + {facilityFreeAllergens.length > 0 && ( + + {facilityFreeAllergens.map((value) => ( + + {value} + + + setFacilityFreeAllergens((prev) => + prev.filter((item) => item !== value), + ) + } + style={{ cursor: 'pointer' }} + /> + + + ))} + + )} + + + + + Are your products certified gluten-free? + + + + + {['Yes, always', 'No'].map((value) => ( + + + + + + + {value} + + + ))} + + + + + + + Do your products contain sulfites? + + + + + {['Yes', 'No'].map((value) => ( + + + + + + + {value} + + + ))} + + + + + + + Additional Details + + We focus on partnering with eco-friendly businesses and appreciate your support in responding to the next question: + + + + Are your products sustainable or environmentally conscious? Please describe. + + +