From d4797c0024c5c893f3c95b87cf0e6b53fed6a0ee Mon Sep 17 00:00:00 2001 From: Karina Park-Okuna Date: Sat, 15 Nov 2025 10:11:47 -1000 Subject: [PATCH 1/2] Progress completion bar --- src/components/SampleData.ts | 1 + src/components/VendorProjectCard.tsx | 42 +++++++++++++- .../forms/ScheduleCompletionBar.tsx | 55 +++++++++++++++++++ src/pages/ProjectDetailPage.tsx | 2 - src/services/firebaseDataService.ts | 4 +- 5 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 src/components/forms/ScheduleCompletionBar.tsx diff --git a/src/components/SampleData.ts b/src/components/SampleData.ts index 2fd7295..939b6fa 100644 --- a/src/components/SampleData.ts +++ b/src/components/SampleData.ts @@ -95,6 +95,7 @@ export interface ProjectData { spent: number; vendor: string; vendorId?: string; + createdAt?: string | { seconds: number }; reports: ProjectReport[]; } diff --git a/src/components/VendorProjectCard.tsx b/src/components/VendorProjectCard.tsx index 14b82c1..0d4035e 100644 --- a/src/components/VendorProjectCard.tsx +++ b/src/components/VendorProjectCard.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Link } from "react-router-dom"; import { ProjectData } from "./SampleData"; +import ScheduleCompletionBar from "./forms/ScheduleCompletionBar"; interface VendorProjectCardProps { project: ProjectData; @@ -13,10 +14,10 @@ const VendorProjectCard: React.FC = ({ project }) => { name, status, statusColor, - metric1, metric2, description, reports, + createdAt, } = project; // Sort reports by date (most recent first) @@ -27,6 +28,9 @@ const VendorProjectCard: React.FC = ({ project }) => { // Get the two most recent reports const recentReports = sortedReports.slice(0, 2); + // Get the most recent report for schedule data + const latestReport = sortedReports[0]; + return (
@@ -53,14 +57,46 @@ const VendorProjectCard: React.FC = ({ project }) => {
- {metric1} + {/* Use ScheduleCompletion component */} + {latestReport?.scheduleData?.baseline?.expectedDate && + latestReport?.date && + createdAt ? ( + + ) : ( + + No schedule data available + + )}
- {metric2} +
Total Reports
+
+ + {reports.length} + +
diff --git a/src/components/forms/ScheduleCompletionBar.tsx b/src/components/forms/ScheduleCompletionBar.tsx new file mode 100644 index 0000000..caa58cd --- /dev/null +++ b/src/components/forms/ScheduleCompletionBar.tsx @@ -0,0 +1,55 @@ +// src/components/forms/ScheduleCompletionBar.tsx +import React from "react"; + +interface ScheduleCompletionBarProps { + projectCreatedAt: string; + expectedBaselineDate: string; + actualProjectedDate: string; + reportDate: string; +} + +const ScheduleCompletionBar: React.FC = ({ + projectCreatedAt, + expectedBaselineDate, + reportDate, +}) => { + // Parse dates + const createdDate = new Date(projectCreatedAt); + const baselineDate = new Date(expectedBaselineDate); + const currentDate = new Date(reportDate); + + // Calculate total project duration (from creation to baseline completion) + const totalDuration = baselineDate.getTime() - createdDate.getTime(); + + // Calculate elapsed time (from creation to report date) + const elapsedTime = currentDate.getTime() - createdDate.getTime(); + + // Calculate percentage complete + const percentageComplete = Math.min( + Math.max((elapsedTime / totalDuration) * 100, 0), + 100 + ); + + return ( +
+
Project Completion
+
+
+ {Math.round(percentageComplete)}% +
+
+
+ ); +}; + +export default ScheduleCompletionBar; diff --git a/src/pages/ProjectDetailPage.tsx b/src/pages/ProjectDetailPage.tsx index bd1645e..f415f63 100644 --- a/src/pages/ProjectDetailPage.tsx +++ b/src/pages/ProjectDetailPage.tsx @@ -26,7 +26,6 @@ const ProjectDetailPage: React.FC = () => { const loadProject = async () => { console.log("Looking for project with ID:", projectId); - // First, try to load from Firestore try { const projectRef = doc(db, "projects", projectId); const projectSnap = await getDoc(projectRef); @@ -54,7 +53,6 @@ const ProjectDetailPage: React.FC = () => { reports: [], } as ProjectData); - // Set up real-time listener for reports const reportsRef = collection(db, "projects", projectId, "reports"); const unsubscribe = onSnapshot(reportsRef, (snapshot) => { const reportsList = snapshot.docs.map( diff --git a/src/services/firebaseDataService.ts b/src/services/firebaseDataService.ts index f1a61c2..a3d4d87 100644 --- a/src/services/firebaseDataService.ts +++ b/src/services/firebaseDataService.ts @@ -255,7 +255,7 @@ export const fetchAllProjects = async (): Promise => { 100 ) : 0; - + // const project: ProjectData = { id: docSnapshot.id, name: data.name || "Untitled Project", @@ -271,6 +271,7 @@ export const fetchAllProjects = async (): Promise => { spent: data.spent || 0, vendor: data.vendor || data.vendorName || "No Vendor Assigned", vendorId: data.vendorId || undefined, + createdAt: data.createdAt || undefined, reports: reports, }; @@ -413,6 +414,7 @@ export const fetchProjectsByVendor = async ( spent: data.spent || 0, vendor: data.vendor || data.vendorName || "No Vendor Assigned", vendorId: data.vendorId || undefined, + createdAt: data.createdAt || undefined, reports: reports, }; From c0f364f785dffab2d5bff1f134cbb3bf759070ca Mon Sep 17 00:00:00 2001 From: Karina Park-Okuna Date: Sat, 15 Nov 2025 22:26:44 -1000 Subject: [PATCH 2/2] removed unused metric --- src/components/VendorProjectCard.tsx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/components/VendorProjectCard.tsx b/src/components/VendorProjectCard.tsx index 71073b4..261680b 100644 --- a/src/components/VendorProjectCard.tsx +++ b/src/components/VendorProjectCard.tsx @@ -9,16 +9,7 @@ interface VendorProjectCardProps { } const VendorProjectCard: React.FC = ({ project }) => { - const { - id, - name, - status, - statusColor, - metric2, - description, - reports, - createdAt, - } = project; + const { id, name, status, description, reports, createdAt } = project; // Sort reports by date (most recent first) const sortedReports = [...reports].sort(