Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ Thumbs.db
*.env
*.env.*
!.env.example

vite.config.*.timestamp*
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
/coverage
/.nx/cache
/.nx/workspace-data
6 changes: 3 additions & 3 deletions apps/backend/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/backend/src",
"projectType": "application",
"tags": [],
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
Expand Down Expand Up @@ -39,7 +40,7 @@
}
},
"lint": {
"executor": "@nx/linter:eslint",
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/backend/**/*.ts"]
Expand Down Expand Up @@ -67,6 +68,5 @@
"forwardAllArgs": false
}
}
},
"tags": []
}
}
6 changes: 5 additions & 1 deletion apps/frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"ignorePatterns": [
"!**/*",
"**/vite.config.*.timestamp*",
"**/vitest.config.*.timestamp*"
],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
Expand Down
8 changes: 4 additions & 4 deletions apps/frontend/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/frontend/src",
"projectType": "application",
"tags": [],
"targets": {
"build": {
"executor": "@nx/vite:build",
Expand Down Expand Up @@ -54,15 +55,15 @@
}
},
"test": {
"executor": "@nx/vite:test",
"executor": "@nx/vitest:test",
"outputs": ["{options.reportsDirectory}"],
"options": {
"passWithNoTests": true,
"reportsDirectory": "../../coverage/apps/frontend"
}
},
"lint": {
"executor": "@nx/linter:eslint",
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/frontend/**/*.{ts,tsx,js,jsx}"]
Expand All @@ -82,6 +83,5 @@
"forwardAllArgs": false
}
}
},
"tags": []
}
}
4 changes: 2 additions & 2 deletions apps/frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PantryPastOrders from '@containers/pantryPastOrders';
import Pantries from '@containers/pantries';
import Orders from '@containers/orders';
import PantryDashboard from '@containers/pantryDashboard';
import { submitFoodRequestFormModal } from '@components/forms/requestFormModal';
import submitFoodRequestFormModal from '@components/forms/requestFormModal';
import { submitDeliveryConfirmationFormModal } from '@components/forms/deliveryConfirmationModal';
import FormRequests from '@containers/FormRequests';
import PantryApplication from '@containers/pantryApplication';
Expand Down Expand Up @@ -164,7 +164,7 @@ const router = createBrowserRouter([
loader: pantryIdLoader,
},
{
path: '/donation-mangement',
path: '/donation-management',
element: (
<ProtectedRoute>
<DonationManagement />
Expand Down
107 changes: 32 additions & 75 deletions apps/frontend/src/components/forms/requestFormModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,29 @@ import {
Field,
CloseButton,
} from '@chakra-ui/react';
import { Form, ActionFunction, ActionFunctionArgs } from 'react-router-dom';
import { FoodRequest, FoodTypes, RequestSize } from '../../types/types';
import {
CreateFoodRequestBody,
FoodRequest,
FoodTypes,
RequestSize,
} from '../../types/types';
import { ChevronDownIcon } from 'lucide-react';
import apiClient from '@api/apiClient';

interface FoodRequestFormModalProps {
previousRequest?: FoodRequest;
isOpen: boolean;
onClose: () => void;
pantryId: number;
onSuccess: () => void;
}

const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
previousRequest,
isOpen,
onClose,
pantryId,
onSuccess,
}) => {
const [selectedItems, setSelectedItems] = useState<string[]>([]);
const [requestedSize, setRequestedSize] = useState<string>('');
Expand All @@ -45,6 +52,26 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
}
}, [isOpen, previousRequest]);

const handleSubmit = async () => {
const foodRequestData: CreateFoodRequestBody = {
pantryId,
requestedSize: requestedSize as RequestSize,
requestedItems: selectedItems,
additionalInformation: additionalNotes || '',
dateReceived: null,
feedback: null,
photos: [],
};

try {
await apiClient.createFoodRequest(foodRequestData);
onClose();
onSuccess();
} catch (error) {
alert('Failed to submit request. Please try again.');
}
};

return (
<Dialog.Root
open={isOpen}
Expand Down Expand Up @@ -75,28 +102,13 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
: `Please keep in mind that we may not be able to accommodate specific
food requests at all times, but we will do our best to match your preferences.`}
</Text>
<Form
method="post"
action="/food-request"
onSubmit={(e) => {
if (selectedItems.length === 0) {
e.preventDefault();
alert('Please select at least one food type');
}
if (requestedSize === '') {
e.preventDefault();
alert('Please select a requested size.');
}
}}
>
<input type="hidden" name="pantryId" value={pantryId} />
<Box>
<Field.Root required mb={4}>
<Field.Label>
<Text textStyle="p2" fontWeight={600} color="neutral.800">
Size of Shipment
</Text>
</Field.Label>
<input type="hidden" name="size" value={requestedSize} />
<Menu.Root>
<Menu.Trigger asChild>
<Button
Expand Down Expand Up @@ -147,15 +159,6 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
</Text>
</Field.Label>

{selectedItems.map((item) => (
<input
key={item}
type="hidden"
name="restrictions"
value={item}
/>
))}

<Menu.Root closeOnSelect={false}>
<Menu.Trigger asChild>
<Button
Expand Down Expand Up @@ -261,7 +264,6 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
</Field.Label>
<Textarea
pl={2.5}
name="notes"
placeholder="Anything else we should know about"
_placeholder={{
color: 'neutral.300',
Expand Down Expand Up @@ -300,15 +302,15 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
</Button>

<Button
type="submit"
onClick={handleSubmit}
bg={isFormValid ? '#213C4A' : 'neutral.400'}
color={'white'}
disabled={!isFormValid}
>
Continue
</Button>
</Flex>
</Form>
</Box>
</Dialog.Body>
<Dialog.CloseTrigger asChild>
<CloseButton size="lg" />
Expand All @@ -319,49 +321,4 @@ const FoodRequestFormModal: React.FC<FoodRequestFormModalProps> = ({
);
};

export const submitFoodRequestFormModal: ActionFunction = async ({
request,
}: ActionFunctionArgs) => {
const form = await request.formData();

const foodRequestData = new Map();

const pantryId = form.get('pantryId');
foodRequestData.set('requestedSize', form.get('size'));
form.delete('size');
foodRequestData.set('additionalInformation', form.get('notes'));
form.delete('notes');
foodRequestData.set('requestedItems', form.getAll('restrictions'));
form.delete('restrictions');
foodRequestData.set('pantryId', form.get('pantryId'));

const data = Object.fromEntries(foodRequestData);
console.log(data);

try {
const response = await fetch('/api/requests/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});

if (response.ok) {
console.log('Food request submitted successfully');

window.location.href = `/request-form/${pantryId}`;
return null;
} else {
console.error('Failed to submit food request', await response.text());
window.location.href = `/request-form/${pantryId}`;
return null;
}
} catch (error) {
console.error('Error submitting food request', error);
window.location.href = `/request-form/${pantryId}`;
return null;
}
};

export default FoodRequestFormModal;
36 changes: 19 additions & 17 deletions apps/frontend/src/containers/FormRequests.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import {
Box,
Expand Down Expand Up @@ -39,27 +39,27 @@ const FormRequests: React.FC = () => {

const pageSize = 10;

useEffect(() => {
const fetchRequests = async () => {
if (pantryId) {
try {
const data = await ApiClient.getPantryRequests(pantryId);
const sortedData = data
.slice()
.sort((a, b) => b.requestId - a.requestId);
setRequests(sortedData);
const fetchRequests = useCallback(async () => {
if (pantryId) {
try {
const data = await ApiClient.getPantryRequests(pantryId);
const sortedData = data
.slice()
.sort((a, b) => b.requestId - a.requestId);
setRequests(sortedData);

if (sortedData.length > 0) {
setPreviousRequest(sortedData[0]);
}
} catch (error) {
console.log(error);
if (sortedData.length > 0) {
setPreviousRequest(sortedData[0]);
}
} catch (error) {
console.log(error);
}
};
}
}, [pantryId]);

useEffect(() => {
fetchRequests();
}, [pantryId]);
}, [pantryId, fetchRequests]);

const paginatedRequests = requests.slice(
(currentPage - 1) * pageSize,
Expand Down Expand Up @@ -88,6 +88,7 @@ const FormRequests: React.FC = () => {
isOpen={newRequestDisclosure.open}
onClose={newRequestDisclosure.onClose}
pantryId={pantryId}
onSuccess={fetchRequests}
/>
{previousRequest && (
<>
Expand All @@ -108,6 +109,7 @@ const FormRequests: React.FC = () => {
isOpen={previousRequestDisclosure.open}
onClose={previousRequestDisclosure.onClose}
pantryId={pantryId}
onSuccess={fetchRequests}
/>
</>
)}
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,6 @@ export interface CreateFoodRequestBody {
requestedSize: string;
requestedItems: string[];
additionalInformation: string | null | undefined;
status: string;
fulfilledBy: number | null | undefined;
dateReceived: string | null | undefined;
feedback: string | null | undefined;
photos: string[] | null | undefined;
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/tsconfig.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"]
},
"include": [
"vite.config.ts",
"vite.config.mts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
Expand Down
Loading