From 1cabafd50cd1d287b5dde2d5d9f353dda4d1a06f Mon Sep 17 00:00:00 2001 From: Mehana Nagarur Date: Wed, 25 Mar 2026 17:39:58 -0400 Subject: [PATCH 1/3] created donors page --- apps/frontend/package-lock.json | 12 +- apps/frontend/package.json | 3 +- apps/frontend/src/app/Donors.tsx | 293 +++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 apps/frontend/src/app/Donors.tsx diff --git a/apps/frontend/package-lock.json b/apps/frontend/package-lock.json index 3761ddf..16f1e66 100644 --- a/apps/frontend/package-lock.json +++ b/apps/frontend/package-lock.json @@ -11,7 +11,8 @@ "@chakra-ui/react": "^3.33.0", "next": "15.5.4", "react": "19.1.0", - "react-dom": "19.1.0" + "react-dom": "19.1.0", + "react-icons": "^5.6.0" }, "devDependencies": { "@eslint/eslintrc": "^3", @@ -10328,6 +10329,15 @@ "react": "^19.1.0" } }, + "node_modules/react-icons": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz", + "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/apps/frontend/package.json b/apps/frontend/package.json index fa067a0..e32d5e8 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -14,7 +14,8 @@ "@chakra-ui/react": "^3.33.0", "next": "15.5.4", "react": "19.1.0", - "react-dom": "19.1.0" + "react-dom": "19.1.0", + "react-icons": "^5.6.0" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/apps/frontend/src/app/Donors.tsx b/apps/frontend/src/app/Donors.tsx new file mode 100644 index 0000000..27c4d82 --- /dev/null +++ b/apps/frontend/src/app/Donors.tsx @@ -0,0 +1,293 @@ +'use client' +import React, { useState } from 'react'; +import { HStack, Input, Button, Table, Heading, Dialog, Portal, CloseButton, Stack } from "@chakra-ui/react"; +import TextInputField from './components/TextInputField'; +import { CiFilter } from "react-icons/ci"; +import { LuArrowDownUp } from "react-icons/lu"; +import { FaPlus, FaAngleLeft, FaAngleRight } from "react-icons/fa"; +import DropdownSelector from './components/DropdownSelector'; +type Donor = { + donor_id: number; + organization: string; + contact_name: string | null; + contact_email: string | null; + num_projects: number; + last_donation: string | null; +}; + +const mockDonors: Donor[] = [ + { donor_id: 1, organization: 'Green Future Foundation', contact_name: 'Alice Chen', contact_email: 'alice@greenfuture.org', num_projects: 4, last_donation: '03/12/2024' }, + { donor_id: 2, organization: 'Horizon Trust', contact_name: 'James Patel', contact_email: 'james@horizontrust.org', num_projects: 2, last_donation: '01/05/2024' }, + { donor_id: 3, organization: 'Bright Path Nonprofit', contact_name: null, contact_email: null, num_projects: 7, last_donation: '02/28/2024' }, + { donor_id: 4, organization: 'Unity Giving Circle', contact_name: 'Maria Lopez', contact_email: 'maria@unitygiving.org', num_projects: 1, last_donation: '03/30/2024' }, + { donor_id: 5, organization: 'Sunrise Community Fund', contact_name: 'David Kim', contact_email: 'david@sunrisefund.org', num_projects: 3, last_donation: '04/01/2024' }, + { donor_id: 6, organization: 'Blue Ridge Giving', contact_name: 'Sarah Thompson', contact_email: 'sarah@blueridge.org', num_projects: 5, last_donation: '02/14/2024' }, + { donor_id: 7, organization: 'Maple Leaf Charitable Trust', contact_name: null, contact_email: null, num_projects: 2, last_donation: '01/20/2024' }, + { donor_id: 8, organization: 'Evergreen Partners', contact_name: 'Rachel Singh', contact_email: 'rachel@evergreenpartners.org', num_projects: 6, last_donation: '03/05/2024' }, + { donor_id: 9, organization: 'New Horizons Society', contact_name: 'Tom Bradley', contact_email: 'tom@newhorizons.org', num_projects: 9, last_donation: '04/10/2024' }, + { donor_id: 10, organization: 'Coastal Care Foundation', contact_name: 'Nina Rossi', contact_email: 'nina@coastalcare.org', num_projects: 3, last_donation: '03/22/2024' }, + { donor_id: 11, organization: 'Valley Hope Fund', contact_name: 'Carlos Rivera', contact_email: 'carlos@valleyhope.org', num_projects: 2, last_donation: '02/08/2024' }, + { donor_id: 12, organization: 'Summit Philanthropy Group', contact_name: null, contact_email: null, num_projects: 4, last_donation: '01/30/2024' }, + { donor_id: 13, organization: 'Harbor Light Charity', contact_name: 'Emily Nguyen', contact_email: 'emily@harborlight.org', num_projects: 8, last_donation: '03/17/2024' }, + { donor_id: 14, organization: 'Prairie Roots Foundation', contact_name: 'Michael Scott', contact_email: 'michael@praireroots.org', num_projects: 1, last_donation: '04/05/2024' }, + { donor_id: 15, organization: 'Starlight Endowment', contact_name: 'Laura White', contact_email: 'laura@starlightend.org', num_projects: 5, last_donation: '02/25/2024' }, + { donor_id: 16, organization: 'Redwood Community Trust', contact_name: 'Kevin Park', contact_email: 'kevin@redwoodtrust.org', num_projects: 3, last_donation: '03/09/2024' }, + { donor_id: 17, organization: 'Silver Lining Fund', contact_name: null, contact_email: null, num_projects: 6, last_donation: '01/15/2024' }, + { donor_id: 18, organization: 'Lakeside Giving Circle', contact_name: 'Amanda Foster', contact_email: 'amanda@lakesidegiving.org', num_projects: 2, last_donation: '04/02/2024' }, + { donor_id: 19, organization: 'Northstar Charitable Fund', contact_name: 'Brian Walsh', contact_email: 'brian@northstarfund.org', num_projects: 7, last_donation: '03/28/2024' }, + { donor_id: 20, organization: 'Desert Bloom Foundation', contact_name: 'Priya Mehta', contact_email: 'priya@desertbloom.org', num_projects: 4, last_donation: '02/19/2024' }, + { donor_id: 21, organization: 'Willow Creek Society', contact_name: 'Jason Turner', contact_email: 'jason@willowcreek.org', num_projects: 3, last_donation: '03/14/2024' }, + { donor_id: 22, organization: 'Ironwood Philanthropy', contact_name: null, contact_email: null, num_projects: 5, last_donation: '01/25/2024' }, + { donor_id: 23, organization: 'Clearwater Endowment', contact_name: 'Sophia Adams', contact_email: 'sophia@clearwaterend.org', num_projects: 2, last_donation: '04/07/2024' }, + { donor_id: 24, organization: 'Goldfinch Foundation', contact_name: 'Daniel Lee', contact_email: 'daniel@goldfinchfdn.org', num_projects: 9, last_donation: '03/01/2024' }, + { donor_id: 25, organization: 'Meadowbrook Trust', contact_name: 'Hannah Clark', contact_email: 'hannah@meadowbrook.org', num_projects: 1, last_donation: '02/11/2024' }, + { donor_id: 26, organization: 'Tidewater Giving Fund', contact_name: 'Marcus Hill', contact_email: 'marcus@tidewaterfund.org', num_projects: 4, last_donation: '03/20/2024' }, + { donor_id: 27, organization: 'Pinecrest Charitable Trust', contact_name: null, contact_email: null, num_projects: 6, last_donation: '01/10/2024' }, + { donor_id: 28, organization: 'Foxglove Foundation', contact_name: 'Olivia Martin', contact_email: 'olivia@foxglovefdn.org', num_projects: 3, last_donation: '04/14/2024' }, + { donor_id: 29, organization: 'Stonegate Philanthropy', contact_name: 'Ethan Brooks', contact_email: 'ethan@stonegatephil.org', num_projects: 7, last_donation: '02/03/2024' }, + { donor_id: 30, organization: 'Riverview Society', contact_name: 'Isabella Young', contact_email: 'isabella@riverviewsoc.org', num_projects: 2, last_donation: '03/25/2024' }, + { donor_id: 31, organization: 'Thunderbird Fund', contact_name: 'Noah Perez', contact_email: 'noah@thunderbirdfund.org', num_projects: 5, last_donation: '01/28/2024' }, + { donor_id: 32, organization: 'Aspen Grove Foundation', contact_name: null, contact_email: null, num_projects: 8, last_donation: '04/09/2024' }, + { donor_id: 33, organization: 'Brightwater Giving', contact_name: 'Chloe Evans', contact_email: 'chloe@brightwatergiving.org', num_projects: 1, last_donation: '03/06/2024' }, + { donor_id: 34, organization: 'Cedarwood Endowment', contact_name: 'Liam Robinson', contact_email: 'liam@cedarwoodend.org', num_projects: 4, last_donation: '02/22/2024' }, + { donor_id: 35, organization: 'Moonstone Charitable Trust', contact_name: 'Ava Mitchell', contact_email: 'ava@moonstonetrust.org', num_projects: 3, last_donation: '03/31/2024' }, + { donor_id: 36, organization: 'Harborview Partners', contact_name: 'Mason Carter', contact_email: 'mason@harborviewpartners.org', num_projects: 6, last_donation: '01/18/2024' }, + { donor_id: 37, organization: 'Cloverfield Foundation', contact_name: null, contact_email: null, num_projects: 2, last_donation: '04/03/2024' }, + { donor_id: 38, organization: 'Sycamore Hill Trust', contact_name: 'Emma Phillips', contact_email: 'emma@sycamorehill.org', num_projects: 7, last_donation: '02/16/2024' }, + { donor_id: 39, organization: 'Falcon Ridge Fund', contact_name: 'William Turner', contact_email: 'william@falconridge.org', num_projects: 4, last_donation: '03/13/2024' }, + { donor_id: 40, organization: 'Whitestone Giving Circle', contact_name: 'Mia Campbell', contact_email: 'mia@whitestonegiving.org', num_projects: 5, last_donation: '01/07/2024' }, + { donor_id: 41, organization: 'Birchwood Society', contact_name: 'James Nelson', contact_email: 'james@birchwoodsoc.org', num_projects: 3, last_donation: '04/11/2024' }, + { donor_id: 42, organization: 'Ember Light Foundation', contact_name: null, contact_email: null, num_projects: 9, last_donation: '02/27/2024' }, + { donor_id: 43, organization: 'Saltgrass Endowment', contact_name: 'Charlotte Baker', contact_email: 'charlotte@saltgrassend.org', num_projects: 2, last_donation: '03/04/2024' }, + { donor_id: 44, organization: 'Ironstone Philanthropy', contact_name: 'Henry Gonzalez', contact_email: 'henry@ironstonephil.org', num_projects: 6, last_donation: '01/23/2024' }, + { donor_id: 45, organization: 'Dawnwood Trust', contact_name: 'Amelia Scott', contact_email: 'amelia@dawnwoodtrust.org', num_projects: 1, last_donation: '04/08/2024' }, + { donor_id: 46, organization: 'Copperleaf Fund', contact_name: 'Benjamin Harris', contact_email: 'benjamin@copperleaffund.org', num_projects: 4, last_donation: '03/19/2024' }, + { donor_id: 47, organization: 'Snowcap Foundation', contact_name: null, contact_email: null, num_projects: 3, last_donation: '02/06/2024' }, + { donor_id: 48, organization: 'Thornberry Giving', contact_name: 'Ella Walker', contact_email: 'ella@thornberrygiving.org', num_projects: 7, last_donation: '03/26/2024' }, + { donor_id: 49, organization: 'Granite Peak Society', contact_name: 'Alexander Hall', contact_email: 'alexander@granitepeak.org', num_projects: 5, last_donation: '01/31/2024' }, + { donor_id: 50, organization: 'Wren Valley Foundation', contact_name: 'Sofia Allen', contact_email: 'sofia@wrenvalley.org', num_projects: 2, last_donation: '04/15/2024' }, +]; + +export default function Donors() { + + const [currentPage, setCurrentPage] = useState(1); + const rowsPerPage = 10; + + const totalPages = Math.ceil(mockDonors.length / rowsPerPage); + const currentDonors = mockDonors.slice( + (currentPage - 1) * rowsPerPage, + currentPage * rowsPerPage + ); + + const getPageNumbers = () => { + if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1); + + if (currentPage <= 3) return [1, 2, 3, '...', totalPages]; + if (currentPage >= totalPages - 2) return [1, '...', totalPages - 2, totalPages - 1, totalPages]; + return [1, '...', currentPage - 1, currentPage, currentPage + 1, '...', totalPages]; + }; + + const [showFilter, setShowFilter] = useState(false); + const [selectedDonor, setSelectedDonor] = useState(''); + const donorNames = mockDonors.map(d => d.organization); + + const [showSort, setShowSort] = useState(false); + const[selectedSort, setSelectedSort] = useState(''); + const sortOptions = ['# of Projects', 'Last Donated'] + + const [showNewDonor, setShowNewDonor] = useState(false); + const [newOrganization, setNewOrganization] = useState(''); + const [newContactName, setNewContactName] = useState(''); + const [newContactEmail, setNewContactEmail] = useState(''); + const [orgError, setOrgError] = useState(false); + const [nameError, setNameError] = useState(false); + const [emailError, setEmailError] = useState(false); + const handleSave = () => { + const hasOrgError = !newOrganization.trim(); + const hasNameError = !newContactName.trim(); + const hasEmailError = !newContactEmail.trim(); + + setOrgError(hasOrgError); + setNameError(hasNameError); + setEmailError(hasEmailError); + + if (hasOrgError || hasNameError || hasEmailError) return; + + // need to implement the save logic later (like saving it to the db) + + setShowNewDonor(false); + }; + + return ( +
+ Donors + + + + + +
+ + {showFilter && ( +
+ setSelectedDonor(val as string)} + /> +
+ )} +
+
+ + {showSort && ( +
+ setSelectedSort(val as string)} + /> +
+ )} +
+ +
+
+ + setShowNewDonor(e.open)}> + + + + + + Add New Donor + setShowNewDonor(false)} /> + + + + { setNewOrganization(val); setOrgError(false); }} + isError={orgError} + errorMessage="Enter valid name" + /> + { setNewContactName(val); setNameError(false); }} + isError={nameError} + errorMessage="Enter valid name" + /> + { setNewContactEmail(val); setEmailError(false); }} + isError={emailError} + errorMessage="Enter valid email" + /> + + + + + + + + + + + + + + + + + + + + + + Donor ID + Donor Name + # of Projects + Last Donation + + + + + {currentDonors.map((donor) => ( + + #{String(donor.donor_id).padStart(6, '0')} + {donor.organization} + {donor.num_projects} + {donor.last_donation ?? '—'} + + ))} + + + + +
+ + setCurrentPage(p => Math.max(p - 1, 1))} + style={{ cursor: currentPage === 1 ? 'not-allowed' : 'pointer', opacity: currentPage === 1 ? 0.3 : 1, color: 'var(--color-core-green)' }} + /> + {getPageNumbers().map((page, index) => ( + page === '...' + ? + : + ))} + setCurrentPage(p => Math.min(p + 1, totalPages))} + style={{ cursor: currentPage === totalPages ? 'not-allowed' : 'pointer', opacity: currentPage === totalPages ? 0.3 : 1, color: 'var(--color-core-green)' }} + /> + +
+
+ ) +} \ No newline at end of file From 42639330d4093c514a873612d998f60268c4ffd4 Mon Sep 17 00:00:00 2001 From: Mehana Nagarur Date: Wed, 25 Mar 2026 22:08:35 -0400 Subject: [PATCH 2/3] tests for donors page --- apps/frontend/src/app/Donors.tsx | 44 +------------ apps/frontend/test/components/Donors.test.tsx | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 apps/frontend/test/components/Donors.test.tsx diff --git a/apps/frontend/src/app/Donors.tsx b/apps/frontend/src/app/Donors.tsx index 27c4d82..7141fdb 100644 --- a/apps/frontend/src/app/Donors.tsx +++ b/apps/frontend/src/app/Donors.tsx @@ -1,6 +1,6 @@ 'use client' import React, { useState } from 'react'; -import { HStack, Input, Button, Table, Heading, Dialog, Portal, CloseButton, Stack } from "@chakra-ui/react"; +import { HStack, Input, Button, Table, Dialog, Portal, CloseButton, Stack } from "@chakra-ui/react"; import TextInputField from './components/TextInputField'; import { CiFilter } from "react-icons/ci"; import { LuArrowDownUp } from "react-icons/lu"; @@ -26,46 +26,6 @@ const mockDonors: Donor[] = [ { donor_id: 8, organization: 'Evergreen Partners', contact_name: 'Rachel Singh', contact_email: 'rachel@evergreenpartners.org', num_projects: 6, last_donation: '03/05/2024' }, { donor_id: 9, organization: 'New Horizons Society', contact_name: 'Tom Bradley', contact_email: 'tom@newhorizons.org', num_projects: 9, last_donation: '04/10/2024' }, { donor_id: 10, organization: 'Coastal Care Foundation', contact_name: 'Nina Rossi', contact_email: 'nina@coastalcare.org', num_projects: 3, last_donation: '03/22/2024' }, - { donor_id: 11, organization: 'Valley Hope Fund', contact_name: 'Carlos Rivera', contact_email: 'carlos@valleyhope.org', num_projects: 2, last_donation: '02/08/2024' }, - { donor_id: 12, organization: 'Summit Philanthropy Group', contact_name: null, contact_email: null, num_projects: 4, last_donation: '01/30/2024' }, - { donor_id: 13, organization: 'Harbor Light Charity', contact_name: 'Emily Nguyen', contact_email: 'emily@harborlight.org', num_projects: 8, last_donation: '03/17/2024' }, - { donor_id: 14, organization: 'Prairie Roots Foundation', contact_name: 'Michael Scott', contact_email: 'michael@praireroots.org', num_projects: 1, last_donation: '04/05/2024' }, - { donor_id: 15, organization: 'Starlight Endowment', contact_name: 'Laura White', contact_email: 'laura@starlightend.org', num_projects: 5, last_donation: '02/25/2024' }, - { donor_id: 16, organization: 'Redwood Community Trust', contact_name: 'Kevin Park', contact_email: 'kevin@redwoodtrust.org', num_projects: 3, last_donation: '03/09/2024' }, - { donor_id: 17, organization: 'Silver Lining Fund', contact_name: null, contact_email: null, num_projects: 6, last_donation: '01/15/2024' }, - { donor_id: 18, organization: 'Lakeside Giving Circle', contact_name: 'Amanda Foster', contact_email: 'amanda@lakesidegiving.org', num_projects: 2, last_donation: '04/02/2024' }, - { donor_id: 19, organization: 'Northstar Charitable Fund', contact_name: 'Brian Walsh', contact_email: 'brian@northstarfund.org', num_projects: 7, last_donation: '03/28/2024' }, - { donor_id: 20, organization: 'Desert Bloom Foundation', contact_name: 'Priya Mehta', contact_email: 'priya@desertbloom.org', num_projects: 4, last_donation: '02/19/2024' }, - { donor_id: 21, organization: 'Willow Creek Society', contact_name: 'Jason Turner', contact_email: 'jason@willowcreek.org', num_projects: 3, last_donation: '03/14/2024' }, - { donor_id: 22, organization: 'Ironwood Philanthropy', contact_name: null, contact_email: null, num_projects: 5, last_donation: '01/25/2024' }, - { donor_id: 23, organization: 'Clearwater Endowment', contact_name: 'Sophia Adams', contact_email: 'sophia@clearwaterend.org', num_projects: 2, last_donation: '04/07/2024' }, - { donor_id: 24, organization: 'Goldfinch Foundation', contact_name: 'Daniel Lee', contact_email: 'daniel@goldfinchfdn.org', num_projects: 9, last_donation: '03/01/2024' }, - { donor_id: 25, organization: 'Meadowbrook Trust', contact_name: 'Hannah Clark', contact_email: 'hannah@meadowbrook.org', num_projects: 1, last_donation: '02/11/2024' }, - { donor_id: 26, organization: 'Tidewater Giving Fund', contact_name: 'Marcus Hill', contact_email: 'marcus@tidewaterfund.org', num_projects: 4, last_donation: '03/20/2024' }, - { donor_id: 27, organization: 'Pinecrest Charitable Trust', contact_name: null, contact_email: null, num_projects: 6, last_donation: '01/10/2024' }, - { donor_id: 28, organization: 'Foxglove Foundation', contact_name: 'Olivia Martin', contact_email: 'olivia@foxglovefdn.org', num_projects: 3, last_donation: '04/14/2024' }, - { donor_id: 29, organization: 'Stonegate Philanthropy', contact_name: 'Ethan Brooks', contact_email: 'ethan@stonegatephil.org', num_projects: 7, last_donation: '02/03/2024' }, - { donor_id: 30, organization: 'Riverview Society', contact_name: 'Isabella Young', contact_email: 'isabella@riverviewsoc.org', num_projects: 2, last_donation: '03/25/2024' }, - { donor_id: 31, organization: 'Thunderbird Fund', contact_name: 'Noah Perez', contact_email: 'noah@thunderbirdfund.org', num_projects: 5, last_donation: '01/28/2024' }, - { donor_id: 32, organization: 'Aspen Grove Foundation', contact_name: null, contact_email: null, num_projects: 8, last_donation: '04/09/2024' }, - { donor_id: 33, organization: 'Brightwater Giving', contact_name: 'Chloe Evans', contact_email: 'chloe@brightwatergiving.org', num_projects: 1, last_donation: '03/06/2024' }, - { donor_id: 34, organization: 'Cedarwood Endowment', contact_name: 'Liam Robinson', contact_email: 'liam@cedarwoodend.org', num_projects: 4, last_donation: '02/22/2024' }, - { donor_id: 35, organization: 'Moonstone Charitable Trust', contact_name: 'Ava Mitchell', contact_email: 'ava@moonstonetrust.org', num_projects: 3, last_donation: '03/31/2024' }, - { donor_id: 36, organization: 'Harborview Partners', contact_name: 'Mason Carter', contact_email: 'mason@harborviewpartners.org', num_projects: 6, last_donation: '01/18/2024' }, - { donor_id: 37, organization: 'Cloverfield Foundation', contact_name: null, contact_email: null, num_projects: 2, last_donation: '04/03/2024' }, - { donor_id: 38, organization: 'Sycamore Hill Trust', contact_name: 'Emma Phillips', contact_email: 'emma@sycamorehill.org', num_projects: 7, last_donation: '02/16/2024' }, - { donor_id: 39, organization: 'Falcon Ridge Fund', contact_name: 'William Turner', contact_email: 'william@falconridge.org', num_projects: 4, last_donation: '03/13/2024' }, - { donor_id: 40, organization: 'Whitestone Giving Circle', contact_name: 'Mia Campbell', contact_email: 'mia@whitestonegiving.org', num_projects: 5, last_donation: '01/07/2024' }, - { donor_id: 41, organization: 'Birchwood Society', contact_name: 'James Nelson', contact_email: 'james@birchwoodsoc.org', num_projects: 3, last_donation: '04/11/2024' }, - { donor_id: 42, organization: 'Ember Light Foundation', contact_name: null, contact_email: null, num_projects: 9, last_donation: '02/27/2024' }, - { donor_id: 43, organization: 'Saltgrass Endowment', contact_name: 'Charlotte Baker', contact_email: 'charlotte@saltgrassend.org', num_projects: 2, last_donation: '03/04/2024' }, - { donor_id: 44, organization: 'Ironstone Philanthropy', contact_name: 'Henry Gonzalez', contact_email: 'henry@ironstonephil.org', num_projects: 6, last_donation: '01/23/2024' }, - { donor_id: 45, organization: 'Dawnwood Trust', contact_name: 'Amelia Scott', contact_email: 'amelia@dawnwoodtrust.org', num_projects: 1, last_donation: '04/08/2024' }, - { donor_id: 46, organization: 'Copperleaf Fund', contact_name: 'Benjamin Harris', contact_email: 'benjamin@copperleaffund.org', num_projects: 4, last_donation: '03/19/2024' }, - { donor_id: 47, organization: 'Snowcap Foundation', contact_name: null, contact_email: null, num_projects: 3, last_donation: '02/06/2024' }, - { donor_id: 48, organization: 'Thornberry Giving', contact_name: 'Ella Walker', contact_email: 'ella@thornberrygiving.org', num_projects: 7, last_donation: '03/26/2024' }, - { donor_id: 49, organization: 'Granite Peak Society', contact_name: 'Alexander Hall', contact_email: 'alexander@granitepeak.org', num_projects: 5, last_donation: '01/31/2024' }, - { donor_id: 50, organization: 'Wren Valley Foundation', contact_name: 'Sofia Allen', contact_email: 'sofia@wrenvalley.org', num_projects: 2, last_donation: '04/15/2024' }, ]; export default function Donors() { @@ -120,7 +80,7 @@ export default function Donors() { return (
- Donors +

Donors

diff --git a/apps/frontend/test/components/Donors.test.tsx b/apps/frontend/test/components/Donors.test.tsx new file mode 100644 index 0000000..06881b8 --- /dev/null +++ b/apps/frontend/test/components/Donors.test.tsx @@ -0,0 +1,61 @@ +import { render, screen, fireEvent, waitFor } from '../utils'; +import Donors from '@/app/Donors'; + +describe('Login Page Component', () => { + it('renders the login heading', () => { + render(); + expect(screen.getByText('Donors', { selector: 'h1' })).toBeInTheDocument(); + }); + + it('renders the search input', () => { + render(); + expect(screen.getByPlaceholderText('🔍︎ Search...')).toBeInTheDocument(); + }); + + it('renders Filter By, Sort By, and New Donor buttons', () => { + render(); + expect(screen.getByText('Filter By')).toBeInTheDocument(); + expect(screen.getByText('Sort By')).toBeInTheDocument(); + expect(screen.getByText('New Donor')).toBeInTheDocument(); + }); + + it('renders the table with correct headers', () => { + render(); + expect(screen.getByText('Donor ID')).toBeInTheDocument(); + expect(screen.getByText('Donor Name')).toBeInTheDocument(); + expect(screen.getByText('# of Projects')).toBeInTheDocument(); + expect(screen.getByText('Last Donation')).toBeInTheDocument(); + }); + + it('renders left and right pagination arrows', () => { + render(); + expect(document.querySelector('svg')).toBeInTheDocument(); + }); + + it('renders left and right pagination arrows', () => { + render(); + const buttons = screen.getAllByRole('button'); + // arrows are icon elements, check left/right chevron icons are in the document + expect(document.querySelector('svg')).toBeInTheDocument(); + }); + + it('shows filter dropdown when Filter By is clicked', () => { + render(); + fireEvent.click(screen.getByText('Filter By')); + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + it('shows sort dropdown when Sort By is clicked', () => { + render(); + fireEvent.click(screen.getByText('Sort By')); + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + it('shows new donor modal when New Donor is clicked', async () => { + render(); + fireEvent.click(screen.getByText('New Donor')); + await waitFor(() => { + expect(screen.getByText('Add New Donor')).toBeInTheDocument(); + }); + }); +}) \ No newline at end of file From e2b36c9c07fa800dd8e4284926d389e11be4045f Mon Sep 17 00:00:00 2001 From: Mehana Nagarur Date: Wed, 25 Mar 2026 22:09:12 -0400 Subject: [PATCH 3/3] fixed small test error --- apps/frontend/test/components/Donors.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/frontend/test/components/Donors.test.tsx b/apps/frontend/test/components/Donors.test.tsx index 06881b8..e8d46e9 100644 --- a/apps/frontend/test/components/Donors.test.tsx +++ b/apps/frontend/test/components/Donors.test.tsx @@ -34,8 +34,6 @@ describe('Login Page Component', () => { it('renders left and right pagination arrows', () => { render(); - const buttons = screen.getAllByRole('button'); - // arrows are icon elements, check left/right chevron icons are in the document expect(document.querySelector('svg')).toBeInTheDocument(); });