From b8b9df3293a011293fd9cb2a3b2ebe1f0bdb1cd9 Mon Sep 17 00:00:00 2001 From: mehanana Date: Tue, 12 May 2026 09:41:15 -0400 Subject: [PATCH 1/5] active project card created + tested --- .../src/app/components/ActiveProjectCard.tsx | 44 +++++++++++++++++++ .../components/ActiveProjectCard.test.tsx | 34 ++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 apps/frontend/src/app/components/ActiveProjectCard.tsx create mode 100644 apps/frontend/test/components/ActiveProjectCard.test.tsx diff --git a/apps/frontend/src/app/components/ActiveProjectCard.tsx b/apps/frontend/src/app/components/ActiveProjectCard.tsx new file mode 100644 index 0000000..f81d2a0 --- /dev/null +++ b/apps/frontend/src/app/components/ActiveProjectCard.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { LuDollarSign } from "react-icons/lu"; +import { RxPeople } from "react-icons/rx"; + +interface ProjectCardProps { + name: string; + total_budget: number; + budget_used: number; + members: number; +} + +export default function ActiveProjectCard({ name, total_budget, budget_used, members }: ProjectCardProps) { + const percentage = Math.round((budget_used / total_budget) * 100); + + return ( +
+
+

{name}

+
+
+
+ +
Budget
+
+

${budget_used.toLocaleString()}/${total_budget.toLocaleString()}

+
+
+
+ +
Staff
+
+

{members.toLocaleString()} members

+
+
+
+
+
+
+

30%

+
+
+
+ ); +} \ No newline at end of file diff --git a/apps/frontend/test/components/ActiveProjectCard.test.tsx b/apps/frontend/test/components/ActiveProjectCard.test.tsx new file mode 100644 index 0000000..d362199 --- /dev/null +++ b/apps/frontend/test/components/ActiveProjectCard.test.tsx @@ -0,0 +1,34 @@ +import { render, screen } from '../utils'; +import ProjectCard from '@/app/components/ActiveProjectCard'; + +const mockProps = { + name: 'Clinician Communication Study', + total_budget: 500000, + budget_used: 150000, + members: 3, +}; + +describe('ProjectCard', () => { + it('renders the project name', () => { + render(); + expect(screen.getByText('Clinician Communication Study')).toBeInTheDocument(); + }); + + it('renders the budget label and values', () => { + render(); + expect(screen.getByText('Budget')).toBeInTheDocument(); + expect(screen.getByText((content) => content.includes('150,000') && content.includes('500,000'))).toBeInTheDocument(); + }); + + it('renders the staff label and member count', () => { + render(); + expect(screen.getByText('Staff')).toBeInTheDocument(); + expect(screen.getByText('3 members')).toBeInTheDocument(); + }); + + it('renders the correct percentage', () => { + render(); + const percentage = Math.round((mockProps.budget_used / mockProps.total_budget) * 100); + expect(screen.getByText(`${percentage}%`)).toBeInTheDocument(); + }); +}); \ No newline at end of file From 23e46e0ac7b911ee4931a673bc815bc789d8fafe Mon Sep 17 00:00:00 2001 From: mehanana Date: Tue, 12 May 2026 09:41:30 -0400 Subject: [PATCH 2/5] archive project card + tests created --- .../src/app/components/ArchiveProjectCard.tsx | 49 +++++++++++++++++++ .../components/ArchiveProjectCard.test.tsx | 41 ++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 apps/frontend/src/app/components/ArchiveProjectCard.tsx create mode 100644 apps/frontend/test/components/ArchiveProjectCard.test.tsx diff --git a/apps/frontend/src/app/components/ArchiveProjectCard.tsx b/apps/frontend/src/app/components/ArchiveProjectCard.tsx new file mode 100644 index 0000000..31cd9cf --- /dev/null +++ b/apps/frontend/src/app/components/ArchiveProjectCard.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { LuDollarSign } from "react-icons/lu"; +import { RxPeople } from "react-icons/rx"; +import { FaArrowRight } from "react-icons/fa6"; + +interface ArchiveCardProps { + name: string; + total_budget: number; + members: number; + start_date: string; + end_date: string; +} + +export default function ArchiveProjectCard({ name, total_budget, members, start_date, end_date }: ArchiveCardProps) { + return ( +
+
+

{name}

+
+
+
+ +
Budget
+
+

${total_budget.toLocaleString()}

+
+
+
+ +
Staff
+
+

{members} members

+
+
+
+
+
Start Date
+

{start_date}

+
+ +
+
End Date
+

{end_date}

+
+
+
+
+ ); +} \ No newline at end of file diff --git a/apps/frontend/test/components/ArchiveProjectCard.test.tsx b/apps/frontend/test/components/ArchiveProjectCard.test.tsx new file mode 100644 index 0000000..7a2df7b --- /dev/null +++ b/apps/frontend/test/components/ArchiveProjectCard.test.tsx @@ -0,0 +1,41 @@ +import { render, screen } from '../utils'; +import ArchiveProjectCard from '@/app/components/ArchiveProjectCard'; + +const mockProps = { + name: 'Health Education Initiative', + total_budget: 300000, + members: 2, + start_date: 'Jan 1, 2025', + end_date: 'Mar 1, 2026', +}; + +describe('ArchiveProjectCard', () => { + it('renders the project name', () => { + render(); + expect(screen.getByText('Health Education Initiative')).toBeInTheDocument(); + }); + + it('renders the budget label and total', () => { + render(); + expect(screen.getByText('Budget')).toBeInTheDocument(); + expect(screen.getByText('$300,000')).toBeInTheDocument(); + }); + + it('renders the staff label and member count', () => { + render(); + expect(screen.getByText('Staff')).toBeInTheDocument(); + expect(screen.getByText('2 members')).toBeInTheDocument(); + }); + + it('renders the start and end date labels', () => { + render(); + expect(screen.getByText('Start Date')).toBeInTheDocument(); + expect(screen.getByText('End Date')).toBeInTheDocument(); + }); + + it('renders the correct start and end date values', () => { + render(); + expect(screen.getByText('Jan 1, 2025')).toBeInTheDocument(); + expect(screen.getByText('Mar 1, 2026')).toBeInTheDocument(); + }); +}); \ No newline at end of file From 705493920d104735dcf6e27dfdbf6b64bf0d22f8 Mon Sep 17 00:00:00 2001 From: mehanana Date: Sun, 17 May 2026 17:35:35 -0400 Subject: [PATCH 3/5] used 1 ProjectCard type with a prop to declare if it's an active or archive card + rewrote tests to match this --- .../backend/lambdas/reports/package-lock.json | 32 ++++---- apps/frontend/package-lock.json | 4 +- apps/frontend/package.json | 3 + .../src/app/components/ActiveProjectCard.tsx | 44 ----------- .../src/app/components/ArchiveProjectCard.tsx | 2 +- .../src/app/components/ProjectCard.tsx | 76 +++++++++++++++++++ apps/frontend/src/app/page.tsx | 3 + .../components/ActiveProjectCard.test.tsx | 34 --------- .../components/ArchiveProjectCard.test.tsx | 41 ---------- .../test/components/ProjectCard.test.tsx | 75 ++++++++++++++++++ 10 files changed, 176 insertions(+), 138 deletions(-) delete mode 100644 apps/frontend/src/app/components/ActiveProjectCard.tsx create mode 100644 apps/frontend/src/app/components/ProjectCard.tsx delete mode 100644 apps/frontend/test/components/ActiveProjectCard.test.tsx delete mode 100644 apps/frontend/test/components/ArchiveProjectCard.test.tsx create mode 100644 apps/frontend/test/components/ProjectCard.test.tsx diff --git a/apps/backend/lambdas/reports/package-lock.json b/apps/backend/lambdas/reports/package-lock.json index 5ef4442..e3e50aa 100644 --- a/apps/backend/lambdas/reports/package-lock.json +++ b/apps/backend/lambdas/reports/package-lock.json @@ -1347,7 +1347,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -1360,7 +1360,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2706,28 +2706,28 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { @@ -3146,7 +3146,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3159,7 +3159,7 @@ "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -3227,7 +3227,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -3875,7 +3875,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { @@ -3978,7 +3978,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -5702,7 +5702,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -6966,7 +6966,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -7037,7 +7037,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -7187,7 +7187,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -7535,7 +7535,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/apps/frontend/package-lock.json b/apps/frontend/package-lock.json index 4e772a6..5c6de45 100644 --- a/apps/frontend/package-lock.json +++ b/apps/frontend/package-lock.json @@ -9,7 +9,6 @@ "version": "0.1.0", "dependencies": { "@chakra-ui/react": "^3.33.0", - "@emotion/react": "^11.14.0", "next": "15.5.4", "react": "19.1.0", "react-dom": "19.1.0", @@ -974,7 +973,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@emotion/unitless": { "version": "0.10.0", diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 0c8d0fb..af35674 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -13,6 +13,9 @@ "dependencies": { "@emotion/react": "^11.14.0", "@chakra-ui/react": "^3.33.0", + "@emotion/cache": "^11.14.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", "next": "15.5.4", "react": "19.1.0", "react-dom": "19.1.0", diff --git a/apps/frontend/src/app/components/ActiveProjectCard.tsx b/apps/frontend/src/app/components/ActiveProjectCard.tsx deleted file mode 100644 index f81d2a0..0000000 --- a/apps/frontend/src/app/components/ActiveProjectCard.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import { LuDollarSign } from "react-icons/lu"; -import { RxPeople } from "react-icons/rx"; - -interface ProjectCardProps { - name: string; - total_budget: number; - budget_used: number; - members: number; -} - -export default function ActiveProjectCard({ name, total_budget, budget_used, members }: ProjectCardProps) { - const percentage = Math.round((budget_used / total_budget) * 100); - - return ( -
-
-

{name}

-
-
-
- -
Budget
-
-

${budget_used.toLocaleString()}/${total_budget.toLocaleString()}

-
-
-
- -
Staff
-
-

{members.toLocaleString()} members

-
-
-
-
-
-
-

30%

-
-
-
- ); -} \ No newline at end of file diff --git a/apps/frontend/src/app/components/ArchiveProjectCard.tsx b/apps/frontend/src/app/components/ArchiveProjectCard.tsx index 31cd9cf..3b1de70 100644 --- a/apps/frontend/src/app/components/ArchiveProjectCard.tsx +++ b/apps/frontend/src/app/components/ArchiveProjectCard.tsx @@ -29,7 +29,7 @@ export default function ArchiveProjectCard({ name, total_budget, members, start_
Staff
-

{members} members

+

{members.toLocaleString()} members

diff --git a/apps/frontend/src/app/components/ProjectCard.tsx b/apps/frontend/src/app/components/ProjectCard.tsx new file mode 100644 index 0000000..84a514f --- /dev/null +++ b/apps/frontend/src/app/components/ProjectCard.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { LuDollarSign } from "react-icons/lu"; +import { RxPeople } from "react-icons/rx"; +import { FaArrowRight } from "react-icons/fa6"; + +type ActiveProps = { + variant: 'active'; + name: string; + total_budget: number; + budget_used: number; + members: number; +}; + +type ArchiveProps = { + variant: 'archive'; + name: string; + total_budget: number; + members: number; + start_date: string; + end_date: string; +}; + +type ProjectCardProps = ActiveProps | ArchiveProps; + +export default function ProjectCard(props: ProjectCardProps) { + return ( +
+
+

{props.name}

+
+
+
+ +
Budget
+
+

+ {props.variant === 'active' + ? `$${props.budget_used.toLocaleString()}/$${props.total_budget.toLocaleString()}` + : `$${props.total_budget.toLocaleString()}`} +

+
+
+
+ +
Staff
+
+

{props.members.toLocaleString()} members

+
+
+ {props.variant === 'active' ? ( +
+
+
+
+

{Math.round((props.budget_used / props.total_budget) * 100)}%

+
+ ) : ( +
+
+
Start Date
+

{props.start_date}

+
+ +
+
End Date
+

{props.end_date}

+
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/apps/frontend/src/app/page.tsx b/apps/frontend/src/app/page.tsx index edfb214..d9e2db2 100644 --- a/apps/frontend/src/app/page.tsx +++ b/apps/frontend/src/app/page.tsx @@ -1,4 +1,5 @@ "use client"; +import ProjectCard from "./components/ProjectCard"; import NavBar from "./components/Navbar"; export default function Home() { @@ -6,6 +7,8 @@ export default function Home() {
+ +
); diff --git a/apps/frontend/test/components/ActiveProjectCard.test.tsx b/apps/frontend/test/components/ActiveProjectCard.test.tsx deleted file mode 100644 index d362199..0000000 --- a/apps/frontend/test/components/ActiveProjectCard.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { render, screen } from '../utils'; -import ProjectCard from '@/app/components/ActiveProjectCard'; - -const mockProps = { - name: 'Clinician Communication Study', - total_budget: 500000, - budget_used: 150000, - members: 3, -}; - -describe('ProjectCard', () => { - it('renders the project name', () => { - render(); - expect(screen.getByText('Clinician Communication Study')).toBeInTheDocument(); - }); - - it('renders the budget label and values', () => { - render(); - expect(screen.getByText('Budget')).toBeInTheDocument(); - expect(screen.getByText((content) => content.includes('150,000') && content.includes('500,000'))).toBeInTheDocument(); - }); - - it('renders the staff label and member count', () => { - render(); - expect(screen.getByText('Staff')).toBeInTheDocument(); - expect(screen.getByText('3 members')).toBeInTheDocument(); - }); - - it('renders the correct percentage', () => { - render(); - const percentage = Math.round((mockProps.budget_used / mockProps.total_budget) * 100); - expect(screen.getByText(`${percentage}%`)).toBeInTheDocument(); - }); -}); \ No newline at end of file diff --git a/apps/frontend/test/components/ArchiveProjectCard.test.tsx b/apps/frontend/test/components/ArchiveProjectCard.test.tsx deleted file mode 100644 index 7a2df7b..0000000 --- a/apps/frontend/test/components/ArchiveProjectCard.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { render, screen } from '../utils'; -import ArchiveProjectCard from '@/app/components/ArchiveProjectCard'; - -const mockProps = { - name: 'Health Education Initiative', - total_budget: 300000, - members: 2, - start_date: 'Jan 1, 2025', - end_date: 'Mar 1, 2026', -}; - -describe('ArchiveProjectCard', () => { - it('renders the project name', () => { - render(); - expect(screen.getByText('Health Education Initiative')).toBeInTheDocument(); - }); - - it('renders the budget label and total', () => { - render(); - expect(screen.getByText('Budget')).toBeInTheDocument(); - expect(screen.getByText('$300,000')).toBeInTheDocument(); - }); - - it('renders the staff label and member count', () => { - render(); - expect(screen.getByText('Staff')).toBeInTheDocument(); - expect(screen.getByText('2 members')).toBeInTheDocument(); - }); - - it('renders the start and end date labels', () => { - render(); - expect(screen.getByText('Start Date')).toBeInTheDocument(); - expect(screen.getByText('End Date')).toBeInTheDocument(); - }); - - it('renders the correct start and end date values', () => { - render(); - expect(screen.getByText('Jan 1, 2025')).toBeInTheDocument(); - expect(screen.getByText('Mar 1, 2026')).toBeInTheDocument(); - }); -}); \ No newline at end of file diff --git a/apps/frontend/test/components/ProjectCard.test.tsx b/apps/frontend/test/components/ProjectCard.test.tsx new file mode 100644 index 0000000..2a95cbe --- /dev/null +++ b/apps/frontend/test/components/ProjectCard.test.tsx @@ -0,0 +1,75 @@ +import { render, screen } from '../utils'; +import ProjectCard from '@/app/components/ProjectCard'; + +const activeMockProps = { + variant: 'active' as const, + name: 'Clinician Communication Study', + total_budget: 500000, + budget_used: 150000, + members: 3, +}; + +const archiveMockProps = { + variant: 'archive' as const, + name: 'Health Education Initiative', + total_budget: 300000, + members: 2, + start_date: 'Jan 1, 2025', + end_date: 'Mar 1, 2026', +}; + +describe('ProjectCard (active)', () => { + it('renders the project name', () => { + render(); + expect(screen.getByText('Clinician Communication Study')).toBeInTheDocument(); + }); + + it('renders the budget label and values', () => { + render(); + expect(screen.getByText('Budget')).toBeInTheDocument(); + expect(screen.getByText((content) => content.includes('150,000') && content.includes('500,000'))).toBeInTheDocument(); + }); + + it('renders the staff label and member count', () => { + render(); + expect(screen.getByText('Staff')).toBeInTheDocument(); + expect(screen.getByText('3 members')).toBeInTheDocument(); + }); + + it('renders the correct percentage', () => { + render(); + const percentage = Math.round((activeMockProps.budget_used / activeMockProps.total_budget) * 100); + expect(screen.getByText(`${percentage}%`)).toBeInTheDocument(); + }); +}); + +describe('ProjectCard (archive)', () => { + it('renders the project name', () => { + render(); + expect(screen.getByText('Health Education Initiative')).toBeInTheDocument(); + }); + + it('renders the budget label and total', () => { + render(); + expect(screen.getByText('Budget')).toBeInTheDocument(); + expect(screen.getByText('$300,000')).toBeInTheDocument(); + }); + + it('renders the staff label and member count', () => { + render(); + expect(screen.getByText('Staff')).toBeInTheDocument(); + expect(screen.getByText('2 members')).toBeInTheDocument(); + }); + + it('renders the start and end date labels', () => { + render(); + expect(screen.getByText('Start Date')).toBeInTheDocument(); + expect(screen.getByText('End Date')).toBeInTheDocument(); + }); + + it('renders the correct start and end date values', () => { + render(); + expect(screen.getByText('Jan 1, 2025')).toBeInTheDocument(); + expect(screen.getByText('Mar 1, 2026')).toBeInTheDocument(); + }); +}); \ No newline at end of file From 6703a027efa7f48afd273f383fa79b5fc61f67dc Mon Sep 17 00:00:00 2001 From: mehanana Date: Tue, 19 May 2026 13:39:47 -0400 Subject: [PATCH 4/5] update package-lock.json --- apps/frontend/package-lock.json | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/frontend/package-lock.json b/apps/frontend/package-lock.json index 5c6de45..94f7fae 100644 --- a/apps/frontend/package-lock.json +++ b/apps/frontend/package-lock.json @@ -9,6 +9,9 @@ "version": "0.1.0", "dependencies": { "@chakra-ui/react": "^3.33.0", + "@emotion/cache": "^11.14.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", "next": "15.5.4", "react": "19.1.0", "react-dom": "19.1.0", @@ -973,8 +976,30 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", "license": "MIT", - "peer": true + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } }, "node_modules/@emotion/unitless": { "version": "0.10.0", From 74c29dca5af61f86f6d40f74fa7aff97dfa9c4d9 Mon Sep 17 00:00:00 2001 From: mehanana Date: Wed, 3 Jun 2026 22:14:16 -0400 Subject: [PATCH 5/5] removed ProjectCard from page.tsx and minor css fixes --- apps/frontend/src/app/components/ProjectCard.tsx | 14 +++++++------- apps/frontend/src/app/page.tsx | 2 -- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/frontend/src/app/components/ProjectCard.tsx b/apps/frontend/src/app/components/ProjectCard.tsx index 84a514f..c27adbb 100644 --- a/apps/frontend/src/app/components/ProjectCard.tsx +++ b/apps/frontend/src/app/components/ProjectCard.tsx @@ -25,11 +25,11 @@ type ProjectCardProps = ActiveProps | ArchiveProps; export default function ProjectCard(props: ProjectCardProps) { return (
-
-

{props.name}

-
+
+

{props.name}

+
-
+
Budget
@@ -39,7 +39,7 @@ export default function ProjectCard(props: ProjectCardProps) { : `$${props.total_budget.toLocaleString()}`}

-
+
Staff
@@ -58,12 +58,12 @@ export default function ProjectCard(props: ProjectCardProps) {

{Math.round((props.budget_used / props.total_budget) * 100)}%

) : ( -
+
Start Date

{props.start_date}

- +
End Date

{props.end_date}

diff --git a/apps/frontend/src/app/page.tsx b/apps/frontend/src/app/page.tsx index d9e2db2..101bfb7 100644 --- a/apps/frontend/src/app/page.tsx +++ b/apps/frontend/src/app/page.tsx @@ -7,8 +7,6 @@ export default function Home() {
- -
);