From 476b1c0b9be1617967b62200c17fc5594bbc7946 Mon Sep 17 00:00:00 2001 From: SaiKiran0407 Date: Wed, 16 Oct 2024 14:40:13 -0500 Subject: [PATCH 1/4] #43 developed donatedItemDetails page --- client-app/src/App.js | 2 + .../src/Components/DonatedItemDetails.tsx | 104 ++++++++++++++++++ server/src/routes/donatedItemRoutes.ts | 44 ++++++-- server/src/services/donatedItemService.ts | 30 +++++ 4 files changed, 169 insertions(+), 11 deletions(-) create mode 100644 client-app/src/Components/DonatedItemDetails.tsx create mode 100644 server/src/services/donatedItemService.ts diff --git a/client-app/src/App.js b/client-app/src/App.js index b3fc88b5..41509a84 100644 --- a/client-app/src/App.js +++ b/client-app/src/App.js @@ -13,6 +13,7 @@ import StatusDisplayPage from './Components/StatusDisplayPage'; import Programs from './Components/Programs'; import AddProgramPage from './Components/AddProgramPage'; // Import AddProgramPage correctly import NewItemForm from './Components/NewItemForm.tsx'; +import DonatedItemDetails from './Components/DonatedItemDetails'; import AddDonor from './Components/AddDonor'; // Why is this here? function App() { @@ -45,6 +46,7 @@ function App() { path="/addprogram" element={} /> + } /> ); diff --git a/client-app/src/Components/DonatedItemDetails.tsx b/client-app/src/Components/DonatedItemDetails.tsx new file mode 100644 index 00000000..95b15a0f --- /dev/null +++ b/client-app/src/Components/DonatedItemDetails.tsx @@ -0,0 +1,104 @@ +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { useParams } from 'react-router-dom'; + +interface Donor { + id: number; + firstName: string; + lastName: string; + contact: string; + email: string; + addressLine1: string; + addressLine2?: string; + state: string; + city: string; + zipcode: string; + emailOptIn: boolean; +} + +interface Program { + id: number; + name: string; + description: string; + startDate: Date; + aimAndCause: string; +} + +interface StatusLog { + id: number; + type: string; + dateModified: Date; +} + +interface DonatedItem { + id: number; + itemType: string; + currentStatus: string; + dateDonated: Date; + lastUpdated: Date; + donor: Donor; + program: Program; + statuses: StatusLog[]; +} + +const DonatedItemDetails: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const [donatedItem, setDonatedItem] = useState(null); + const [error, setError] = useState(''); + + useEffect(() => { + const fetchDonatedItemDetails = async () => { + try { + const API_BASE_URL = process.env.REACT_APP_BACKEND_API_BASE_URL; + const response = await axios.get(`${API_BASE_URL}donatedItem/${id}`); + setDonatedItem(response.data); + } catch (err) { + setError('Failed to fetch donated item details'); + console.error('Error fetching donated item:', err); + } + }; + + fetchDonatedItemDetails(); + }, [id]); + + if (error) { + return
{error}
; + } + + if (!donatedItem) { + return
Loading...
; + } + + return ( +
+

Donated Item Details

+

Item Details

+

Type: {donatedItem.itemType}

+

Status: {donatedItem.currentStatus}

+

Donated On: {donatedItem.dateDonated.toDateString()}

+

Last Updated: {donatedItem.lastUpdated.toDateString()}

+ +

Donor Details

+

Name: {donatedItem.donor.firstName} {donatedItem.donor.lastName}

+

Email: {donatedItem.donor.email}

+

Contact: {donatedItem.donor.contact}

+

Address: {donatedItem.donor.addressLine1}, {donatedItem.donor.addressLine2 ?? ''}

+

City/State: {donatedItem.donor.city}, {donatedItem.donor.state} {donatedItem.donor.zipcode}

+ +

Program Details

+

Name: {donatedItem.program.name}

+

Description: {donatedItem.program.description}

+

Start Date: {donatedItem.program.startDate.toDateString()}

+

Aim and Cause: {donatedItem.program.aimAndCause}

+ +

Status Logs

+ {donatedItem.statuses.map(status => ( +
+

Status: {status.type} - Modified on {status.dateModified.toDateString()}

+
+ ))} +
+ ); +}; + +export default DonatedItemDetails; diff --git a/server/src/routes/donatedItemRoutes.ts b/server/src/routes/donatedItemRoutes.ts index 97a944ff..43e14132 100644 --- a/server/src/routes/donatedItemRoutes.ts +++ b/server/src/routes/donatedItemRoutes.ts @@ -3,6 +3,8 @@ import prisma from '../prismaClient'; // Import Prisma client import { donatedItemValidator } from '../validators/donatedItemValidator'; // Import the validator import { validateDonor } from '../services/donorService'; import { validateProgram } from '../services/programService'; +import { validateDonatedItem } from '../services/donatedItemService'; + import { date } from 'joi'; const router = Router(); @@ -44,8 +46,7 @@ router.post('/', donatedItemValidator, async (req: Request, res: Response) => { donatedItem: newItem, donatedItemStatus: newStatus, }); - - + } catch (error) { console.error('Error creating donated item:', error); res.status(500).json({ message: 'Error creating donated item' }); @@ -53,19 +54,40 @@ router.post('/', donatedItemValidator, async (req: Request, res: Response) => { }); // GET /donatedItem - Fetch all donated items -router.get('/', async (req: Request, res: Response) => { +router.get('/:id', async (req: Request, res: Response) => { try { - const items = await prisma.donatedItem.findMany({ + const donatedItemId = parseInt(req.params.id); + if (isNaN(donatedItemId)) { + return res.status(400).json({ error: "Donated item ID must be an integer." }); + } + + const donatedItem = await prisma.donatedItem.findUnique({ + where: { id: donatedItemId }, include: { - statuses: true, // Include related status updates - program:true, - donor:true, - }, + donor: true, // Include all donor details + program: true, // Include all program details + statuses: { + orderBy: { + dateModified: 'asc' // Ensure they are ordered chronologically + } + } + } }); - res.json(items); + + if (!donatedItem) { + return res.status(404).json({ error: `Donated item with ID ${donatedItemId} not found` }); + } + + res.json(donatedItem); } catch (error) { - console.error(error); - res.status(500).json({ message: 'Error fetching donated items' }); + if (error instanceof Error) { + console.error('Error fetching donated item:', error.message); + res.status(error.message.includes('must be an integer') ? 400 : 404).json({ error: error.message }); + } else { + console.error('Error fetching donated item:', 'Unknown error'); + res.status(500).json({ error: 'Unknown error' }); + } + } }); diff --git a/server/src/services/donatedItemService.ts b/server/src/services/donatedItemService.ts new file mode 100644 index 00000000..39fb65c9 --- /dev/null +++ b/server/src/services/donatedItemService.ts @@ -0,0 +1,30 @@ +import prisma from '../prismaClient'; + +// export async function validateDonatedItem(donatedItemId: number) { +// // Check if donatedItemId is a valid number (integer) +// if (isNaN(donatedItemId) || !Number.isInteger(donatedItemId)) { +// throw new Error("Donated item ID must be an integer"); +// } +// const donatedItem = await prisma.donatedItem.findUnique({ +// where: { id: donatedItemId }, +// include: { +// donor: true, +// program: true, +// } +// }); + +// if (!donatedItem) { +// throw new Error(`Donated item with ID ${donatedItemId} not found`); +// } +// return donatedItem; +// } + +export function validateDonatedItem(donatedItemId: number) { + // Check if donatedItemId is a valid number (integer) + if (isNaN(donatedItemId)) { + return false; + } else { + return true; + } + +} From 7c9ebe25e9eb5aa070212cd0753ff316e605f9e7 Mon Sep 17 00:00:00 2001 From: SaiKiran0407 Date: Sat, 26 Oct 2024 23:05:25 -0500 Subject: [PATCH 2/4] #43 Developed detailed view page for a donated item --- client-app/src/App.js | 2 +- .../src/Components/DonatedItemDetails.tsx | 112 ++++++++++++------ client-app/src/css/DonatedItemDetails.css | 100 ++++++++++++++++ server/src/routes/donatedItemRoutes.ts | 32 ++++- 4 files changed, 208 insertions(+), 38 deletions(-) create mode 100644 client-app/src/css/DonatedItemDetails.css diff --git a/client-app/src/App.js b/client-app/src/App.js index 41509a84..5e045537 100644 --- a/client-app/src/App.js +++ b/client-app/src/App.js @@ -46,7 +46,7 @@ function App() { path="/addprogram" element={} /> - } /> + } /> ); diff --git a/client-app/src/Components/DonatedItemDetails.tsx b/client-app/src/Components/DonatedItemDetails.tsx index 95b15a0f..92ab85af 100644 --- a/client-app/src/Components/DonatedItemDetails.tsx +++ b/client-app/src/Components/DonatedItemDetails.tsx @@ -1,6 +1,11 @@ import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { useParams } from 'react-router-dom'; +import PersonIcon from '@mui/icons-material/Person'; +import CategoryIcon from '@mui/icons-material/Category'; +import EventNoteIcon from '@mui/icons-material/EventNote'; +import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn'; +import '../css/DonatedItemDetails.css'; // Import the new CSS file interface Donor { id: number; @@ -20,22 +25,22 @@ interface Program { id: number; name: string; description: string; - startDate: Date; + startDate: string; aimAndCause: string; } interface StatusLog { id: number; type: string; - dateModified: Date; + dateModified: string; } interface DonatedItem { id: number; itemType: string; currentStatus: string; - dateDonated: Date; - lastUpdated: Date; + dateDonated: string; + lastUpdated: string; donor: Donor; program: Program; statuses: StatusLog[]; @@ -44,59 +49,98 @@ interface DonatedItem { const DonatedItemDetails: React.FC = () => { const { id } = useParams<{ id: string }>(); const [donatedItem, setDonatedItem] = useState(null); + const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { const fetchDonatedItemDetails = async () => { try { - const API_BASE_URL = process.env.REACT_APP_BACKEND_API_BASE_URL; + + const API_BASE_URL = process.env.REACT_APP_BACKEND_API_BASE_URL || ''; + console.log(API_BASE_URL); + console.log(id); const response = await axios.get(`${API_BASE_URL}donatedItem/${id}`); + + console.log(response); setDonatedItem(response.data); } catch (err) { - setError('Failed to fetch donated item details'); + if (axios.isAxiosError(err)) { + setError(`Failed to fetch donated item details: ${err.response?.statusText || 'Server error'}`); + } else { + setError('An unexpected error occurred'); + } console.error('Error fetching donated item:', err); + } finally { + setLoading(false); } }; fetchDonatedItemDetails(); }, [id]); - if (error) { - return
{error}
; - } + const formatDate = (dateString: string) => { + const date = new Date(dateString); + return isNaN(date.getTime()) ? 'Invalid date' : date.toDateString(); + }; - if (!donatedItem) { - return
Loading...
; - } + if (loading) return
Loading...
; + if (error) return
Error: {error}
; + if (!donatedItem) return
No data available.
; return ( -
+

Donated Item Details

-

Item Details

-

Type: {donatedItem.itemType}

-

Status: {donatedItem.currentStatus}

-

Donated On: {donatedItem.dateDonated.toDateString()}

-

Last Updated: {donatedItem.lastUpdated.toDateString()}

+
+ {/* Left Column */} +
+
+
+ +

Item Details

+
+

Type: {donatedItem.itemType}

+

Status: {donatedItem.currentStatus}

+

Donated On: {formatDate(donatedItem.dateDonated)}

+

Last Updated: {formatDate(donatedItem.lastUpdated)}

+
-

Donor Details

-

Name: {donatedItem.donor.firstName} {donatedItem.donor.lastName}

-

Email: {donatedItem.donor.email}

-

Contact: {donatedItem.donor.contact}

-

Address: {donatedItem.donor.addressLine1}, {donatedItem.donor.addressLine2 ?? ''}

-

City/State: {donatedItem.donor.city}, {donatedItem.donor.state} {donatedItem.donor.zipcode}

+
+
+ +

Status Logs

+
+ {donatedItem.statuses.map(status => ( +

Status: {status.type} - Modified on: {formatDate(status.dateModified)}

+ ))} +
+
-

Program Details

-

Name: {donatedItem.program.name}

-

Description: {donatedItem.program.description}

-

Start Date: {donatedItem.program.startDate.toDateString()}

-

Aim and Cause: {donatedItem.program.aimAndCause}

+ {/* Right Column */} +
+
+
+ +

Donor Details

+
+

Name: {donatedItem.donor.firstName} {donatedItem.donor.lastName}

+

Email: {donatedItem.donor.email}

+

Contact: {donatedItem.donor.contact}

+

Address: {donatedItem.donor.addressLine1}, {donatedItem.donor.addressLine2 ?? ''}

+

City/State: {donatedItem.donor.city}, {donatedItem.donor.state} {donatedItem.donor.zipcode}

+
-

Status Logs

- {donatedItem.statuses.map(status => ( -
-

Status: {status.type} - Modified on {status.dateModified.toDateString()}

+
+
+ +

Program Details

+
+

Name: {donatedItem.program.name}

+

Description: {donatedItem.program.description}

+

Start Date: {formatDate(donatedItem.program.startDate)}

+

Aim and Cause: {donatedItem.program.aimAndCause}

+
- ))} +
); }; diff --git a/client-app/src/css/DonatedItemDetails.css b/client-app/src/css/DonatedItemDetails.css new file mode 100644 index 00000000..366c84b2 --- /dev/null +++ b/client-app/src/css/DonatedItemDetails.css @@ -0,0 +1,100 @@ +.donated-item-details-container { + max-width: 1200px; + margin: auto; + padding: 20px; + background-color: #f3f6f9; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +/* Two-column layout for the main details */ +.details-grid { + display: grid; + grid-template-columns: 7fr 3fr; /* 70% for left column, 30% for right column */ + gap: 20px; +} + +/* Section styling */ +.section-header { + display: flex; + align-items: center; + padding: 8px; + border-radius: 5px; + color: #fff; +} + +.section-header h2 { + font-size: 20px; + margin: 0; +} + +.section-header .icon { + font-size: 28px; + margin-right: 8px; +} + +/* Left Column Styling (70% width) */ +.left-column .item-details-section, +.left-column .status-logs-section { + padding: 15px; + border-radius: 8px; + margin-bottom: 20px; +} + +.left-column .item-details-section { + background-color: #f7e7b9; +} + +.left-column .item-details-section .section-header { + background-color: #d9b867; +} + + +.left-column .status-logs-section { + background-color: #badaf6; +} + +.left-column .status-logs-section .section-header { + background-color: #7ca3c7; +} + +/* Right Column Styling (30% width) */ +.right-column .donor-details-section, +.right-column .program-details-section { + padding: 15px; + border-radius: 8px; + margin-bottom: 20px; +} + +.right-column .donor-details-section { + background-color: #c8e0c9; +} + +.right-column .donor-details-section .section-header { + background-color: #8aa88b; +} + +.right-column .program-details-section { + background-color: #d5e5f3; +} + +.right-column .program-details-section .section-header { + background-color: #7ca3c7; +} + +/* Paragraph and text styling */ +p { + margin: 8px 0; + font-size: 16px; +} + +strong { + color: #555; +} + +/* Responsive design for smaller screens */ +@media (max-width: 768px) { + .details-grid { + grid-template-columns: 1fr; /* Stacks sections vertically on small screens */ + } +} diff --git a/server/src/routes/donatedItemRoutes.ts b/server/src/routes/donatedItemRoutes.ts index 43e14132..1c7b3aa9 100644 --- a/server/src/routes/donatedItemRoutes.ts +++ b/server/src/routes/donatedItemRoutes.ts @@ -54,13 +54,40 @@ router.post('/', donatedItemValidator, async (req: Request, res: Response) => { }); // GET /donatedItem - Fetch all donated items -router.get('/:id', async (req: Request, res: Response) => { +router.get('/', async (req: Request, res: Response) => { try { + const donatedItem = await prisma.donatedItem.findMany({ + include: { + donor: true, // Include all donor details + program: true, // Include all program details + statuses: { + orderBy: { + dateModified: 'asc' // Ensure they are ordered chronologically + } + } + } + }); + res.json(donatedItem); +} catch (error) { + if (error instanceof Error) { + console.error('Error fetching donated item:', error.message); + res.status(error.message.includes('must be an integer') ? 400 : 404).json({ error: error.message }); + } else { + console.error('Error fetching donated item:', 'Unknown error'); + res.status(500).json({ error: 'Unknown error' }); + } + +} +}); + + +// GET /donatedItem - Fetch donated item by ID +router.get('/:id', async (req: Request, res: Response) => { const donatedItemId = parseInt(req.params.id); if (isNaN(donatedItemId)) { return res.status(400).json({ error: "Donated item ID must be an integer." }); } - + try { const donatedItem = await prisma.donatedItem.findUnique({ where: { id: donatedItemId }, include: { @@ -77,7 +104,6 @@ router.get('/:id', async (req: Request, res: Response) => { if (!donatedItem) { return res.status(404).json({ error: `Donated item with ID ${donatedItemId} not found` }); } - res.json(donatedItem); } catch (error) { if (error instanceof Error) { From e646aee1bc9910e1668a1740b8a729d78a0f2487 Mon Sep 17 00:00:00 2001 From: SaiKiran0407 Date: Mon, 4 Nov 2024 10:24:38 -0600 Subject: [PATCH 3/4] #43 Refactor code based on code review feedback and PR suggestions --- client-app/package.json | 4 ++ .../src/Components/DonatedItemDetails.tsx | 47 +++---------------- client-app/src/Modals/DonatedItemModal.ts | 14 ++++++ client-app/src/Modals/DonatedItemStatus.ts | 5 ++ client-app/src/Modals/DonorModal.ts | 13 +++++ client-app/src/Modals/ProgramModal.ts | 7 +++ client-app/src/css/DonatedItemDetails.css | 4 +- server/README.md | 2 +- server/src/routes/donatedItemRoutes.ts | 12 ++--- 9 files changed, 57 insertions(+), 51 deletions(-) create mode 100644 client-app/src/Modals/DonatedItemModal.ts create mode 100644 client-app/src/Modals/DonatedItemStatus.ts create mode 100644 client-app/src/Modals/DonorModal.ts create mode 100644 client-app/src/Modals/ProgramModal.ts diff --git a/client-app/package.json b/client-app/package.json index 7c23d719..c16abcfe 100644 --- a/client-app/package.json +++ b/client-app/package.json @@ -3,7 +3,11 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", "@fortawesome/fontawesome-free": "^6.5.1", + "@mui/icons-material": "^6.1.6", + "@mui/material": "^6.1.6", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/client-app/src/Components/DonatedItemDetails.tsx b/client-app/src/Components/DonatedItemDetails.tsx index 92ab85af..92b2dbed 100644 --- a/client-app/src/Components/DonatedItemDetails.tsx +++ b/client-app/src/Components/DonatedItemDetails.tsx @@ -6,45 +6,10 @@ import CategoryIcon from '@mui/icons-material/Category'; import EventNoteIcon from '@mui/icons-material/EventNote'; import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn'; import '../css/DonatedItemDetails.css'; // Import the new CSS file - -interface Donor { - id: number; - firstName: string; - lastName: string; - contact: string; - email: string; - addressLine1: string; - addressLine2?: string; - state: string; - city: string; - zipcode: string; - emailOptIn: boolean; -} - -interface Program { - id: number; - name: string; - description: string; - startDate: string; - aimAndCause: string; -} - -interface StatusLog { - id: number; - type: string; - dateModified: string; -} - -interface DonatedItem { - id: number; - itemType: string; - currentStatus: string; - dateDonated: string; - lastUpdated: string; - donor: Donor; - program: Program; - statuses: StatusLog[]; -} +import { Donor } from '../Modals/DonorModal'; +import { Program } from '../Modals/ProgramModal'; +import { DonatedItemStatus } from '../Modals/DonatedItemStatus'; +import { DonatedItem } from '../Modals/DonatedItemModal'; const DonatedItemDetails: React.FC = () => { const { id } = useParams<{ id: string }>(); @@ -104,10 +69,10 @@ const DonatedItemDetails: React.FC = () => {

Last Updated: {formatDate(donatedItem.lastUpdated)}

-
+
-

Status Logs

+

Donated Item Status

{donatedItem.statuses.map(status => (

Status: {status.type} - Modified on: {formatDate(status.dateModified)}

diff --git a/client-app/src/Modals/DonatedItemModal.ts b/client-app/src/Modals/DonatedItemModal.ts new file mode 100644 index 00000000..b829d962 --- /dev/null +++ b/client-app/src/Modals/DonatedItemModal.ts @@ -0,0 +1,14 @@ +import { Donor } from '../Modals/DonorModal'; +import { Program } from '../Modals/ProgramModal'; +import { DonatedItemStatus } from '../Modals/DonatedItemStatus'; + +export interface DonatedItem { + id: number; + itemType: string; + currentStatus: string; + dateDonated: string; + lastUpdated: string; + donor: Donor; + program: Program; + statuses: DonatedItemStatus[]; +} diff --git a/client-app/src/Modals/DonatedItemStatus.ts b/client-app/src/Modals/DonatedItemStatus.ts new file mode 100644 index 00000000..cd5f1b8c --- /dev/null +++ b/client-app/src/Modals/DonatedItemStatus.ts @@ -0,0 +1,5 @@ +export interface DonatedItemStatus { + id: number; + type: string; + dateModified: string; +} diff --git a/client-app/src/Modals/DonorModal.ts b/client-app/src/Modals/DonorModal.ts new file mode 100644 index 00000000..3f3c6a01 --- /dev/null +++ b/client-app/src/Modals/DonorModal.ts @@ -0,0 +1,13 @@ +export interface Donor { + id: number; + firstName: string; + lastName: string; + contact: string; + email: string; + addressLine1: string; + addressLine2?: string; + state: string; + city: string; + zipcode: string; + emailOptIn: boolean; +} diff --git a/client-app/src/Modals/ProgramModal.ts b/client-app/src/Modals/ProgramModal.ts new file mode 100644 index 00000000..b52b5c78 --- /dev/null +++ b/client-app/src/Modals/ProgramModal.ts @@ -0,0 +1,7 @@ +export interface Program { + id: number; + name: string; + description: string; + startDate: string; + aimAndCause: string; +} diff --git a/client-app/src/css/DonatedItemDetails.css b/client-app/src/css/DonatedItemDetails.css index 366c84b2..1fd36398 100644 --- a/client-app/src/css/DonatedItemDetails.css +++ b/client-app/src/css/DonatedItemDetails.css @@ -50,11 +50,11 @@ } -.left-column .status-logs-section { +.left-column .donated-item-status-section { background-color: #badaf6; } -.left-column .status-logs-section .section-header { +.left-column .donated-item-status-section .section-header { background-color: #7ca3c7; } diff --git a/server/README.md b/server/README.md index ac10d633..428ec16b 100644 --- a/server/README.md +++ b/server/README.md @@ -46,7 +46,7 @@ Create a `.env` file and define the necessary environment variables: DATABASE_URL="postgresql://username:password@localhost:5432/dbname" PORT=5000 AZURE_STORAGE_ACCOUNT_NAME="mdmaproject" -AZURE_STORAGE_ACCESS_KEY=""> +AZURE_STORAGE_ACCESS_KEY="" ``` Replace `username`, `password`, and `dbname` with your PostgreSQL username, password, and the name of the database you created. diff --git a/server/src/routes/donatedItemRoutes.ts b/server/src/routes/donatedItemRoutes.ts index 833409e6..146ad3cc 100644 --- a/server/src/routes/donatedItemRoutes.ts +++ b/server/src/routes/donatedItemRoutes.ts @@ -5,7 +5,7 @@ import { donatedItemValidator } from '../validators/donatedItemValidator'; // Im import { validateDonor } from '../services/donorService'; import { validateProgram } from '../services/programService'; import { validateDonatedItem } from '../services/donatedItemService'; - +import { uploadToStorage, getFileExtension } from '../services/donatedItemService'; import { date } from 'joi'; const router = Router(); @@ -70,7 +70,7 @@ router.post('/', [upload.array('imageFiles'), donatedItemValidator], async (req: // GET /donatedItem - Fetch all donated items router.get('/', async (req: Request, res: Response) => { try { - const donatedItem = await prisma.donatedItem.findMany({ + const donatedItems = await prisma.donatedItem.findMany({ include: { donor: true, // Include all donor details program: true, // Include all program details @@ -81,7 +81,7 @@ router.get('/', async (req: Request, res: Response) => { } } }); - res.json(donatedItem); + res.json(donatedItems); } catch (error) { if (error instanceof Error) { console.error('Error fetching donated item:', error.message); @@ -97,11 +97,9 @@ router.get('/', async (req: Request, res: Response) => { // GET /donatedItem - Fetch donated item by ID router.get('/:id', async (req: Request, res: Response) => { - const donatedItemId = parseInt(req.params.id); - if (isNaN(donatedItemId)) { - return res.status(400).json({ error: "Donated item ID must be an integer." }); - } try { + const donatedItemId = parseInt(req.params.id); + await validateDonatedItem(donatedItemId); const donatedItem = await prisma.donatedItem.findUnique({ where: { id: donatedItemId }, include: { From 671d43c4b2e3b39b0cfb871d57c4f7d51a994909 Mon Sep 17 00:00:00 2001 From: SaiKiran0407 Date: Mon, 4 Nov 2024 11:59:26 -0600 Subject: [PATCH 4/4] #43 Implement code refactoring as per PR review comments and suggestions --- .../src/Components/DonatedItemDetails.tsx | 2 +- client-app/src/Modals/DonatedItemModal.ts | 2 +- ...temStatus.ts => DonatedItemStatusModal.ts} | 0 server/src/services/donatedItemService.ts | 19 ------------------- 4 files changed, 2 insertions(+), 21 deletions(-) rename client-app/src/Modals/{DonatedItemStatus.ts => DonatedItemStatusModal.ts} (100%) diff --git a/client-app/src/Components/DonatedItemDetails.tsx b/client-app/src/Components/DonatedItemDetails.tsx index 92b2dbed..d54a9b33 100644 --- a/client-app/src/Components/DonatedItemDetails.tsx +++ b/client-app/src/Components/DonatedItemDetails.tsx @@ -8,7 +8,7 @@ import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn'; import '../css/DonatedItemDetails.css'; // Import the new CSS file import { Donor } from '../Modals/DonorModal'; import { Program } from '../Modals/ProgramModal'; -import { DonatedItemStatus } from '../Modals/DonatedItemStatus'; +import { DonatedItemStatus } from '../Modals/DonatedItemStatusModal'; import { DonatedItem } from '../Modals/DonatedItemModal'; const DonatedItemDetails: React.FC = () => { diff --git a/client-app/src/Modals/DonatedItemModal.ts b/client-app/src/Modals/DonatedItemModal.ts index b829d962..6a954a6f 100644 --- a/client-app/src/Modals/DonatedItemModal.ts +++ b/client-app/src/Modals/DonatedItemModal.ts @@ -1,6 +1,6 @@ import { Donor } from '../Modals/DonorModal'; import { Program } from '../Modals/ProgramModal'; -import { DonatedItemStatus } from '../Modals/DonatedItemStatus'; +import { DonatedItemStatus } from './DonatedItemStatusModal'; export interface DonatedItem { id: number; diff --git a/client-app/src/Modals/DonatedItemStatus.ts b/client-app/src/Modals/DonatedItemStatusModal.ts similarity index 100% rename from client-app/src/Modals/DonatedItemStatus.ts rename to client-app/src/Modals/DonatedItemStatusModal.ts diff --git a/server/src/services/donatedItemService.ts b/server/src/services/donatedItemService.ts index 81f1982f..cd21014a 100644 --- a/server/src/services/donatedItemService.ts +++ b/server/src/services/donatedItemService.ts @@ -24,25 +24,6 @@ export function getFileExtension(mimeType: string) { } } -// export async function validateDonatedItem(donatedItemId: number) { -// // Check if donatedItemId is a valid number (integer) -// if (isNaN(donatedItemId) || !Number.isInteger(donatedItemId)) { -// throw new Error("Donated item ID must be an integer"); -// } -// const donatedItem = await prisma.donatedItem.findUnique({ -// where: { id: donatedItemId }, -// include: { -// donor: true, -// program: true, -// } -// }); - -// if (!donatedItem) { -// throw new Error(`Donated item with ID ${donatedItemId} not found`); -// } -// return donatedItem; -// } - export function validateDonatedItem(donatedItemId: number) { // Check if donatedItemId is a valid number (integer) if (isNaN(donatedItemId)) {