From bd185eac26ec073ca225bdf2852108d3f46967d4 Mon Sep 17 00:00:00 2001 From: Sireesha Kunchala Date: Fri, 29 May 2026 17:11:20 -0400 Subject: [PATCH 1/5] first draft --- .../Reports/Participation/ChartsSection.jsx | 146 ++++++++++++++++++ .../Participation/ChartsSection.module.css | 56 +++++++ .../Reports/Participation/Demographics.jsx | 24 +++ .../Participation/EventParticipation.jsx | 67 +++++++- .../Reports/Participation/MyCases.jsx | 89 ++++++++++- .../Reports/Participation/Personalization.jsx | 31 ++++ src/routes.jsx | 17 ++ 7 files changed, 416 insertions(+), 14 deletions(-) create mode 100644 src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx create mode 100644 src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css create mode 100644 src/components/CommunityPortal/Reports/Participation/Demographics.jsx create mode 100644 src/components/CommunityPortal/Reports/Participation/Personalization.jsx diff --git a/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx new file mode 100644 index 0000000000..d31ccebb3b --- /dev/null +++ b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx @@ -0,0 +1,146 @@ +import { useSelector } from 'react-redux'; +import { + BarChart, + Bar, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, + LineChart, + Line, + PieChart, + Pie, + Cell, + Legend, +} from 'recharts'; + +import mockEvents from './mockData'; +import styles from './ChartsSection.module.css'; + +function ChartsSection() { + const darkMode = useSelector(state => state.theme.darkMode); + + // Group data by event type + const eventTypeStats = []; + const groups = {}; + + mockEvents.forEach(evt => { + const key = evt.eventType; + + if (!groups[key]) { + groups[key] = { count: 0, noShowSum: 0, dropSum: 0 }; + } + + groups[key].count++; + groups[key].noShowSum += parseInt(evt.noShowRate, 10); + groups[key].dropSum += parseInt(evt.dropOffRate, 10); + }); + + for (const key in groups) { + eventTypeStats.push({ + eventType: key, + avgNoShow: Math.round(groups[key].noShowSum / groups[key].count), + avgDrop: Math.round(groups[key].dropSum / groups[key].count), + }); + } + + // Monthly trend + const monthlyTrend = {}; + + mockEvents.forEach(evt => { + const m = new Date(evt.eventDate).getMonth(); + + if (!monthlyTrend[m]) { + monthlyTrend[m] = { count: 0, noShowSum: 0 }; + } + + monthlyTrend[m].count++; + monthlyTrend[m].noShowSum += parseInt(evt.noShowRate, 10); + }); + + const trendData = Object.keys(monthlyTrend).map(m => ({ + month: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][m], + avgNoShow: Math.round(monthlyTrend[m].noShowSum / monthlyTrend[m].count), + })); + + // Location distribution + const locationGroups = {}; + + mockEvents.forEach(evt => { + const loc = evt.location; + if (!locationGroups[loc]) locationGroups[loc] = 0; + locationGroups[loc]++; + }); + + const locationData = Object.keys(locationGroups).map(loc => ({ + name: loc, + value: locationGroups[loc], + })); + + const pieColors = ['#007bff', '#00b894', '#e17055', '#6c5ce7', '#fdcb6e']; + + return ( +
+

Comparative Charts

+ + {/* Row 1 — Bar Charts */} +
+ {/* No-Show Chart */} +
+

No-show rate by event type

+ + + + + + + + +
+ + {/* Drop-Off Chart */} +
+

Drop-off rate by event type

+ + + + + + + + +
+
+ + {/* Row 2 — Line Chart */} +
+
Monthly no-show trend
+ + + + + + + + +
+ + {/* Row 3 — Pie Chart */} +
+
Participation by location
+ + + + {locationData.map((entry, index) => ( + + ))} + + + + +
+
+ ); +} + +export default ChartsSection; diff --git a/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css b/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css new file mode 100644 index 0000000000..f4bc55de80 --- /dev/null +++ b/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css @@ -0,0 +1,56 @@ +.chartsSection { + margin-top: 30px; + background: #fff; + padding: 25px; + border-radius: 10px; + box-shadow: 0 2px 8px rgb(0 0 0 / 8%); +} + +.chartsSectionDark { + background: #1c2541; + color: #fff; + border: 1px solid #333; +} + +.sectionTitle { + font-size: 1.3rem; + font-weight: 600; + margin-bottom: 20px; +} + +.row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; +} + +.chartBox { + background: #f8f9fa; + padding: 15px; + border-radius: 10px; + border: 1px solid #ddd; +} + +.chartsSectionDark .chartBox { + background: #3a506b; + border: 1px solid #555; +} + +.chartBox h4 { + margin-bottom: 10px; + font-size: 1rem; + font-weight: 600; +} + +.chartBoxFull { + margin-top: 20px; + background: #f8f9fa; + padding: 15px; + border-radius: 10px; + border: 1px solid #ddd; +} + +.chartsSectionDark .chartBoxFull { + background: #3a506b; + border: 1px solid #555; +} diff --git a/src/components/CommunityPortal/Reports/Participation/Demographics.jsx b/src/components/CommunityPortal/Reports/Participation/Demographics.jsx new file mode 100644 index 0000000000..84f1d2cb63 --- /dev/null +++ b/src/components/CommunityPortal/Reports/Participation/Demographics.jsx @@ -0,0 +1,24 @@ +import { useSelector } from 'react-redux'; +import styles from './Participation.module.css'; + +function Demographics() { + const darkMode = useSelector(state => state.theme.darkMode); + + return ( +
+

+ Demographics Overview +

+ +
+
+

Charts and breakdowns for age, gender, and location demographics will appear here.

+
+
+
+ ); +} + +export default Demographics; diff --git a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx index 7a7249309b..a4b91e8cde 100644 --- a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx +++ b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx @@ -1,20 +1,23 @@ /* eslint-disable testing-library/no-node-access */ import { useSelector } from 'react-redux'; import { useRef, useState, useCallback } from 'react'; +import { useHistory } from 'react-router-dom'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFilePdf } from '@fortawesome/free-solid-svg-icons'; import MyCases from './MyCases'; import DropOffTracking from './DropOffTracking'; import NoShowInsights from './NoShowInsights'; import styles from './Participation.module.css'; +import ChartsSection from './ChartsSection'; function EventParticipation() { const darkMode = useSelector(state => state.theme.darkMode); + const history = useHistory(); const exportRef = useRef(null); const [exporting, setExporting] = useState(false); const handleSaveAsPDF = useCallback(() => { - if (globalThis.window === undefined || globalThis.document === undefined) return; + if (!window === undefined || !document === undefined) return; if (exporting) return; setExporting(true); @@ -22,22 +25,22 @@ function EventParticipation() { // Expand "More" so all visible items are included const moreBtn = document.querySelector('.more-btn-global'); - const toggled = moreBtn?.textContent?.toLowerCase().includes('more') ?? false; - if (toggled) moreBtn.click(); + const shouldExpand = moreBtn?.textContent?.toLowerCase().includes('more'); + if (shouldExpand) moreBtn.click(); const prevTitle = document.title; document.title = 'event_participation'; setTimeout(() => { - globalThis.print(); + window.print(); setTimeout(() => { - if (toggled) moreBtn.click(); + if (shouldExpand) moreBtn.click(); delete document.documentElement.dataset.exporting; document.title = prevTitle; setExporting(false); - }, 100); + }, 120); }, 500); }, [exporting]); @@ -76,13 +79,63 @@ function EventParticipation() { +
+ + +
+
+ + + {/* ACTIONABLE INSIGHTS SECTION */} +
+

Actionable insights

- {/* Print-only footer note */} +
+
+

High no-show rate detected

+

+ Yoga Class events show an unusual increase in no-show percentage this month. +

+ ↑ 12% +
+ +
+

Weekend events perform better

+

+ Attendance is consistently higher on Saturdays compared to weekdays. +

+ ↑ 8% +
+ +
+ Generated from Event Participation +
+

Drop-off rate reduction opportunity

+

+ Average event drop-off decreases when host reminders are sent earlier. +

+ ↓ 5% +
+
+
+
); } diff --git a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx index f1d1e732b1..742b046778 100644 --- a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx +++ b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx @@ -1,18 +1,22 @@ -import { useState } from 'react'; +import { useState, useMemo } from 'react'; import { useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import styles from './MyCases.module.css'; import mockEvents from './mockData'; import CreateEventModal from './CreateEventModal'; import { filterEventsByDate } from './FilterByDate'; +import Calendar from 'react-calendar'; function MyCases() { const [view, setView] = useState('card'); const [filter, setFilter] = useState('all'); const [expanded, setExpanded] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); + const [calendarDate, setCalendarDate] = useState(new Date()); + const history = useHistory(); const isExporting = - typeof document !== 'undefined' && document.documentElement?.dataset?.exporting === 'true'; // Sonar: prefer . + typeof document !== 'undefined' && document.documentElement?.dataset?.exporting === 'true'; const darkMode = useSelector(state => state.theme.darkMode); @@ -110,11 +114,82 @@ function MyCases() { ); - const renderCalendarView = () => ( -
-

Calendar View is under construction...

-
- ); + const eventsByDate = useMemo(() => { + const map = {}; + filteredEvents.forEach(event => { + const baseDate = new Date(event.eventDate || event.eventTime); + const key = baseDate.toISOString().slice(0, 10); + if (!map[key]) map[key] = []; + map[key].push(event); + }); + return map; + }, [filteredEvents]); + + const renderCalendarTileContent = ({ date, view }) => { + if (view !== 'month') return null; + + const key = date.toISOString().slice(0, 10); + const dayEvents = eventsByDate[key]; + + if (!dayEvents || dayEvents.length === 0) return null; + + return
{dayEvents.length}
; + }; + + const renderCalendarView = () => { + const selectedKey = calendarDate.toISOString().slice(0, 10); + const selectedEvents = eventsByDate[selectedKey] || []; + + const formattedSelectedDate = calendarDate.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); + + return ( +
+
+ + {calendarDate.toLocaleString('en-US', { month: 'long', year: 'numeric' })} + +
+ + + +
+

Events on {formattedSelectedDate}

+ + {selectedEvents.length === 0 && ( +

No events scheduled for this day.

+ )} + + {selectedEvents.map(event => ( +
+
+ {event.eventName} + {event.eventType} +
+
+ {event.eventTime} + {event.location} + {`+${event.attendees} attendees`} +
+
+ ))} +
+
+ ); + }; return (
state.theme.darkMode); + + return ( +
+

+ Personalization Insights +

+ +
+
+

+ This section will show user engagement patterns, recommended event categories, and + personalized insights based on participation history. +

+
+
+
+ ); +} + +export default Personalization; diff --git a/src/routes.jsx b/src/routes.jsx index 95f99712ee..70912b34f8 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -95,6 +95,8 @@ import EventList from './components/CommunityPortal/Event/EventList/EventList'; import ResourcesUsage from './components/CommunityPortal/Activities/activityId/ResourcesUsage'; import EventParticipation from './components/CommunityPortal/Reports/Participation/EventParticipation'; import NoShowList from './components/CommunityPortal/Activities/NoShow/NoShowList'; +import Demographics from './components/CommunityPortal/Reports/Participation/Demographics'; +import Personalization from './components/CommunityPortal/Reports/Participation/Personalization'; import MaterialSummary from './components/MaterialSummary/MaterialSummary'; // Activity Feedback Modal @@ -1033,6 +1035,21 @@ export default ( render={() => } /> + + + {/* */} {/* Temporary route to redirect all subdirectories to login if unauthenticated */} {/* */} From 37290211b23edf6d5e72a5ebd9b4184e5745add5 Mon Sep 17 00:00:00 2001 From: Sireesha Kunchala Date: Sat, 30 May 2026 13:08:37 -0400 Subject: [PATCH 2/5] css fixes --- .../Participation/ChartsSection.module.css | 1 + .../Reports/Participation/MyCases.module.css | 126 ++++++++++++++---- .../Participation/Participation.module.css | 98 ++++++++++++-- 3 files changed, 189 insertions(+), 36 deletions(-) diff --git a/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css b/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css index f4bc55de80..56402d6839 100644 --- a/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css +++ b/src/components/CommunityPortal/Reports/Participation/ChartsSection.module.css @@ -16,6 +16,7 @@ font-size: 1.3rem; font-weight: 600; margin-bottom: 20px; + color: #333; } .row { diff --git a/src/components/CommunityPortal/Reports/Participation/MyCases.module.css b/src/components/CommunityPortal/Reports/Participation/MyCases.module.css index d16da33d57..97cfd6515b 100644 --- a/src/components/CommunityPortal/Reports/Participation/MyCases.module.css +++ b/src/components/CommunityPortal/Reports/Participation/MyCases.module.css @@ -65,12 +65,13 @@ } -@media (max-width: 1024px) { +@media (width <= 1024px) { .headerActions { flex-direction: column; align-items: stretch; gap: 10px; } + .myCasesPage .header { flex-direction: column; align-items: center; @@ -140,10 +141,22 @@ width:100%; } +/* Light Mode */ +.createNew { + font-weight: bold; + border: 1px solid #ccc; + border-radius: 6px; + background-color: #fff; + color: #333; + padding: 8px 16px; + cursor: pointer; + font-size: 14px; +} + .myCasesPageDark .viewSwitcher button, .myCasesPageDark .filterDropdown, .myCasesPageDark .createNew { - color: #ffffff !important; + color: #fff !important; border: 1px solid #555 !important; } @@ -187,22 +200,10 @@ /* Insight bar dark mode */ .myCasesPageDark .insight-bar-container { - background-color: rgba(255, 255, 255, 0.1); + background-color: rgb(255 255 255 / 10%); border-radius: 4px; } -/* Light Mode */ -.createNew { - font-weight: bold; - border: 1px solid #ccc; - border-radius: 6px; - background-color: #fff; - color: #333; - padding: 8px 16px; - cursor: pointer; - font-size: 14px; -} - /* Dark mode */ .createNewDarkMode { font-weight: bold; @@ -247,7 +248,7 @@ } .caseCard:hover { - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); + box-shadow: 0 4px 8px rgb(0 0 0 / 15%); } @@ -264,7 +265,7 @@ } .caseCardDark:hover { - box-shadow: 0 4px 8px rgba(255, 255, 255, 0.15); + box-shadow: 0 4px 8px rgb(255 255 255 / 15%); } .eventBadge { @@ -300,28 +301,28 @@ /* Dark Mode Badge Overrides - High Contrast for titles */ .myCasesPageDark .eventBadge { - border: 1px solid rgba(255, 255, 255, 0.1); + border: 1px solid rgb(255 255 255 / 10%); -webkit-print-color-adjust: exact; } .myCasesPageDark .eventBadge[data-type='Yoga Class'] { background-color: #1b4332 !important; - color: #ffffff !important; + color: #fff !important; } .myCasesPageDark .eventBadge[data-type='Cooking Workshop'] { background-color: #641212 !important; - color: #ffffff !important; + color: #fff !important; } .myCasesPageDark .eventBadge[data-type='Dance Class'] { background-color: #784a06 !important; - color: #ffffff !important; + color: #fff !important; } .myCasesPageDark .eventBadge[data-type='Fitness Bootcamp'] { background-color: #4a1d5a !important; - color: #ffffff !important; + color: #fff !important; } .eventTime { @@ -407,7 +408,7 @@ .myCasesPageDark .rateCard { background-color: #3A506B; - color: #ffffff; + color: #fff; border: 1px solid #555; } @@ -443,6 +444,7 @@ background-color: #3a506b; box-shadow: 0 2px 10px rgb(0 0 0 / 10%); } + .caseListItemDark:hover{ background-color: #2c3e50; } @@ -487,6 +489,82 @@ box-shadow: 0 2px 4px rgb(0 0 0 / 10%); } +.calendarHeader { + display: flex; + justify-content: center; + font-size: 20px; + font-weight: bold; + margin-bottom: 15px; + color: #333; +} + +.calendarHeaderDark { + color: #fff; +} + +.calendarGrid > div { + font-weight: 600; + text-align: center; + font-size: 16px; + box-shadow: 0 2px 4px rgb(0 0 0 / 10%); + padding: 4px 0; + color: #333 !important; +} + +.myCasesPageDark .calendarGrid > div { + color: #fff !important; +} + +.calendarCell { + border: 1px solid #ccc; + min-height: 90px; + padding: 6px; + border-radius: 8px; + background: #fff; + color: #333 !important; +} + +.myCasesPageDark .calendarCell { + background: #3a506b; + border: 1px solid #777; + color: #fff !important; +} + +/* ---------- Calendar Events inside Tiles ---------- */ +.calendarEvent { + font-size: 11px; + background: #e8f1ff; + padding: 2px 4px; + border-radius: 4px; + margin-bottom: 3px; + color: #003c8f; +} + +.calendarEventDark { + background: #244879; + color: #fff; +} + +.reactCalendar { + border: none; + width: 100%; +} + +.myCasesPageDark :global(.react-calendar__tile abbr) { + color: #333 !important; +} + +/* Fix text inside tiles (events & numbers) for light mode */ +.reactCalendar :global(.react-calendar__tile) { + color: #333 !important; +} + +/* Fix text inside tiles (events & numbers) for DARK mode */ +.myCasesPageDark .reactCalendar :global(.react-calendar__tile) { + color: #333 !important; +} + + /* ---------- More button ---------- */ .moreBtn { background-color: #007bff; @@ -591,4 +669,4 @@ background-color: #f5e6ff !important; color: #9b59b6 !important; } -} +} \ No newline at end of file diff --git a/src/components/CommunityPortal/Reports/Participation/Participation.module.css b/src/components/CommunityPortal/Reports/Participation/Participation.module.css index 869934e344..1bd40be000 100644 --- a/src/components/CommunityPortal/Reports/Participation/Participation.module.css +++ b/src/components/CommunityPortal/Reports/Participation/Participation.module.css @@ -178,7 +178,7 @@ box-sizing: border-box; } -@media (max-width: 1024px) { +@media (width <= 1024px) { .analyticsSection { flex-direction: column; gap: 30px; @@ -190,7 +190,7 @@ } } -@media (max-width: 768px) { +@media (width <= 768px) { .trackingContainer, .insights { width: 100%; @@ -214,7 +214,7 @@ } -@media (max-width: 1024px) { +@media (width <= 1024px) { .trackingHeader { flex-direction: column; align-items: center; @@ -400,17 +400,14 @@ margin-bottom: 15px; display: flex; justify-content: space-between; -} +} -.insightsHeaderDark { +.trackingTableDark td, +.trackingTableDark th { color: #fff; - font-weight: bold; - margin-bottom: 15px; - display: flex; - justify-content: space-between; } -@media (max-width: 1024px) { +@media (width <= 1024px) { .insightsHeader { flex-direction: column; align-items: center; @@ -952,7 +949,7 @@ .participationLandingPageDark .attendeesCountDark, .participationLandingPageDark .insightsLabelDark, .participationLandingPageDark .insightsPercentageDark { - color: #ffffff !important; + color: #fff !important; } .filterDropdown { @@ -964,7 +961,7 @@ .participationLandingPageDark .filterDropdown { background-color: #3A506B; - color: #ffffff; + color: #fff; border: 1px solid #555; color-scheme: dark; } @@ -1101,3 +1098,80 @@ color: #fff; border: 1px solid #3A506B; } + +/* ----- Actionable Insights ----- */ +.actionableSection { + margin-top: 30px; + background: #fff; + padding: 20px; + border-radius: 10px; + box-shadow: 0 2px 8px rgb(0 0 0 / 10%); +} + +.actionableSectionDark { + background: #1c2541; + border: 1px solid #333; + color: #fff; +} + +.actionableHeader { + font-size: 1.3rem; + font-weight: 600; + margin-bottom: 18px; + color: #333; +} + +.actionableSectionDark .actionableHeader { + color: #fff; +} + +.actionableGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 15px; +} + +.actionCard { + background: #f8f9fa; + border-radius: 10px; + padding: 15px; + border: 1px solid #ddd; +} + +.actionCard:hover { + background: #f1f1f1; +} + +.actionableSectionDark .actionCard { + background: #3a506b; + border: 1px solid #555; + color: #fff; +} + +.actionTitle { + font-size: 1rem; + font-weight: 600; + margin-bottom: 10px; +} + +.actionDescription { + font-size: 0.85rem; + color: #555; + margin-bottom: 10px; +} + +.actionableSectionDark .actionDescription { + color: #e0e0e0; +} + +.actionTrendUp { + font-size: 0.85rem; + font-weight: bold; + color: #28a745; +} + +.actionTrendDown { + font-size: 0.85rem; + font-weight: bold; + color: #e74c3c; +} \ No newline at end of file From 3f5ad9f58d716df2a98cf6e6c9b8e628a3ce8225 Mon Sep 17 00:00:00 2001 From: Sireesha Kunchala Date: Fri, 12 Jun 2026 15:46:43 -0400 Subject: [PATCH 3/5] dark mode css fixes --- .../Reports/Participation/MyCases.module.css | 89 +++++++++++-- .../Participation/Participation.module.css | 119 ++++++++++++++++-- 2 files changed, 190 insertions(+), 18 deletions(-) diff --git a/src/components/CommunityPortal/Reports/Participation/MyCases.module.css b/src/components/CommunityPortal/Reports/Participation/MyCases.module.css index 97cfd6515b..596074f1f9 100644 --- a/src/components/CommunityPortal/Reports/Participation/MyCases.module.css +++ b/src/components/CommunityPortal/Reports/Participation/MyCases.module.css @@ -550,18 +550,93 @@ width: 100%; } -.myCasesPageDark :global(.react-calendar__tile abbr) { - color: #333 !important; -} - /* Fix text inside tiles (events & numbers) for light mode */ .reactCalendar :global(.react-calendar__tile) { color: #333 !important; } -/* Fix text inside tiles (events & numbers) for DARK mode */ -.myCasesPageDark .reactCalendar :global(.react-calendar__tile) { - color: #333 !important; +/* ============================================================ + DARK MODE — react-calendar overrides + react-calendar ships its own stylesheet (background: white, + dark tile text). Without these overrides the whole widget + renders identically to light mode. + ============================================================ */ + +/* Calendar surface */ +.myCasesPageDark .reactCalendar, +.myCasesPageDark .reactCalendar :global(.react-calendar__viewContainer), +.myCasesPageDark .reactCalendar :global(.react-calendar__month-view) { + background-color: transparent !important; + color: #fff !important; +} + +/* Tiles (day cells) */ +.myCasesPageDark .reactCalendar :global(.react-calendar__tile), +.myCasesPageDark .reactCalendar :global(.react-calendar__tile abbr) { + color: #fff !important; + background-color: transparent !important; +} + +/* Neighbouring-month days — dimmed */ +.myCasesPageDark .reactCalendar :global(.react-calendar__month-view__days__day--neighboringMonth), +.myCasesPageDark + .reactCalendar + :global(.react-calendar__month-view__days__day--neighboringMonth abbr) { + color: #9aa7b8 !important; +} + +/* Tile hover / focus */ +.myCasesPageDark .reactCalendar :global(.react-calendar__tile:enabled:hover), +.myCasesPageDark .reactCalendar :global(.react-calendar__tile:enabled:focus) { + background-color: #2c3e50 !important; +} + +/* Today's tile */ +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--now) { + background-color: #5a6f8c !important; +} + +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--now:enabled:hover), +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--now:enabled:focus) { + background-color: #6b80a0 !important; +} + +/* Selected / active tile */ +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--active), +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--active:enabled:hover), +.myCasesPageDark .reactCalendar :global(.react-calendar__tile--active:enabled:focus) { + background-color: #1d6fa5 !important; +} + +/* Navigation bar (month/year + arrows) */ +.myCasesPageDark .reactCalendar :global(.react-calendar__navigation) { + background-color: transparent !important; +} + +.myCasesPageDark .reactCalendar :global(.react-calendar__navigation button) { + color: #fff !important; + background-color: transparent !important; +} + +.myCasesPageDark .reactCalendar :global(.react-calendar__navigation button:enabled:hover), +.myCasesPageDark .reactCalendar :global(.react-calendar__navigation button:enabled:focus) { + background-color: #2c3e50 !important; +} + +.myCasesPageDark .reactCalendar :global(.react-calendar__navigation button:disabled) { + background-color: transparent !important; + color: #b0b8c4 !important; +} + +/* Weekdays bar (Sun, Mon, ...) */ +.myCasesPageDark .reactCalendar :global(.react-calendar__month-view__weekdays), +.myCasesPageDark .reactCalendar :global(.react-calendar__month-view__weekdays__weekday) { + background-color: transparent !important; +} + +.myCasesPageDark .reactCalendar :global(.react-calendar__month-view__weekdays__weekday abbr) { + color: #fff !important; + text-decoration: none; } diff --git a/src/components/CommunityPortal/Reports/Participation/Participation.module.css b/src/components/CommunityPortal/Reports/Participation/Participation.module.css index 788f4f5ed7..84710fe1a1 100644 --- a/src/components/CommunityPortal/Reports/Participation/Participation.module.css +++ b/src/components/CommunityPortal/Reports/Participation/Participation.module.css @@ -528,7 +528,6 @@ .insightsDark .insightsTab { background-color: #3A506B; - color: #fff; border-right: 1px solid #555; } @@ -644,7 +643,6 @@ .exportOptionsButtons, .exportOptionsButtonsDark { - flex: 1; padding: 10px 12px; border-radius: 10px; @@ -795,7 +793,6 @@ :global(.case-card-global) { break-inside: avoid !important; - height: auto !important; } @@ -842,7 +839,6 @@ :global(.tracking-table-global-dark) thead th { background: #1C2541 !important; - color: #fff !important; } @@ -872,46 +868,39 @@ /* Dark mode styles for print */ .participationLandingPageDark { background: #1B2A41 !important; - color: #fff !important; } .participationLandingPageDark :global(.case-card-global) { background: #3A506B !important; - color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .trackingContainerDark { background: #1C2541 !important; - color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .insightsDark { background: #1C2541 !important; - color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .trackingListContainerDark { background: #3A506B !important; - color: #fff !important; } .participationLandingPageDark :global(.tracking-table-global-dark) thead th { background: #1C2541 !important; - color: #fff !important; } .participationLandingPageDark .trackingRateDark { background: #3A506B !important; - color: #fff !important; } @@ -1205,3 +1194,111 @@ font-weight: bold; color: #e74c3c; } + +/* ---------- Demographics Page ---------- */ +.demographicsPage { + padding: 20px; + background: #fff; + border-radius: 10px; + margin-top: 20px; +} + +.demographicsPageDark { + background: #1c2541; + color: #fff; +} + +.demographicsHeader { + font-size: 22px; + font-weight: bold; + color: #333; + margin-bottom: 20px; +} + +.demographicsHeaderDark { + color: #fff; +} + +.demographicsContent { + display: flex; + justify-content: center; +} + +.placeholderBox { + width: 100%; + padding: 20px; + border: 2px dashed #ccc; + border-radius: 10px; + text-align: center; + color: #555; +} + +.demographicsPageDark .placeholderBox { + border-color: #888; + color: #ddd; +} + +.subPageNav { + margin: 15px 0; + display: flex; + gap: 10px; +} + +.subPageBtn { + padding: 8px 16px; + border-radius: 6px; + border: 1px solid #ccc; + background: #f1f1f1; + cursor: pointer; + font-weight: 500; + color: #333; +} + +.subPageBtn:hover { + background: #e1e1e1; +} + +.subPageBtnDark { + background: #2b3a55; + border-color: #666; + color: #fff; +} + +.subPageBtnDark:hover { + background: #3a4b66; +} + +/* ---------- Personalization Page ---------- */ +.personalizationPage { + padding: 20px; + background: #fff; + border-radius: 10px; + margin-top: 20px; +} + +.personalizationPageDark { + background: #1c2541; + color: #fff; +} + +.personalizationHeader { + font-size: 22px; + font-weight: bold; + color: #333; + margin-bottom: 20px; +} + +.personalizationHeaderDark { + color: #fff; +} + +.personalizationContent { + display: flex; + justify-content: center; +} + +.personalizationPageDark .placeholderBox { + border-color: #888; + color: #ddd; +} + From 4b4b31ec1a1e195c7ac338f5e6d2a3dc42703e65 Mon Sep 17 00:00:00 2001 From: Sireesha Kunchala Date: Fri, 12 Jun 2026 17:12:25 -0400 Subject: [PATCH 4/5] fixed eslint errors --- .../Reports/Participation/ChartsSection.jsx | 10 +++--- .../Participation/EventParticipation.jsx | 2 +- .../Reports/Participation/MyCases.jsx | 10 +++--- src/routes.jsx | 36 ------------------- 4 files changed, 11 insertions(+), 47 deletions(-) diff --git a/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx index d31ccebb3b..a47fd6ea6e 100644 --- a/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx +++ b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx @@ -36,13 +36,13 @@ function ChartsSection() { groups[key].dropSum += parseInt(evt.dropOffRate, 10); }); - for (const key in groups) { + Object.entries(groups).forEach(([key, stats]) => { eventTypeStats.push({ eventType: key, - avgNoShow: Math.round(groups[key].noShowSum / groups[key].count), - avgDrop: Math.round(groups[key].dropSum / groups[key].count), + avgNoShow: Math.round(stats.noShowSum / stats.count), + avgDrop: Math.round(stats.dropSum / stats.count), }); - } + }); // Monthly trend const monthlyTrend = {}; @@ -132,7 +132,7 @@ function ChartsSection() { {locationData.map((entry, index) => ( - + ))} diff --git a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx index a4b91e8cde..548786d556 100644 --- a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx +++ b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx @@ -17,7 +17,7 @@ function EventParticipation() { const [exporting, setExporting] = useState(false); const handleSaveAsPDF = useCallback(() => { - if (!window === undefined || !document === undefined) return; + if (typeof window === 'undefined' || typeof document === 'undefined') return; if (exporting) return; setExporting(true); diff --git a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx index 742b046778..1c6065ae02 100644 --- a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx +++ b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx @@ -1,11 +1,11 @@ import { useState, useMemo } from 'react'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import Calendar from 'react-calendar'; import styles from './MyCases.module.css'; import mockEvents from './mockData'; import CreateEventModal from './CreateEventModal'; import { filterEventsByDate } from './FilterByDate'; -import Calendar from 'react-calendar'; function MyCases() { const [view, setView] = useState('card'); @@ -125,11 +125,11 @@ function MyCases() { return map; }, [filteredEvents]); - const renderCalendarTileContent = ({ date, view }) => { - if (view !== 'month') return null; + const renderCalendarTileContent = ({ date, view: tileView }) => { + if (tileView !== 'month') return null; - const key = date.toISOString().slice(0, 10); - const dayEvents = eventsByDate[key]; + const tileKey = date.toISOString().slice(0, 10); + const dayEvents = eventsByDate[tileKey]; if (!dayEvents || dayEvents.length === 0) return null; diff --git a/src/routes.jsx b/src/routes.jsx index 26c8fa1565..3c217640ba 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1100,21 +1100,6 @@ export default ( - - - - {/* */} - {/* Temporary route to redirect all subdirectories to login if unauthenticated */} - {/* */} - {/* ----- END BM Dashboard Routing ----- */} - {/* ----- Kitchen and Inventory Portal Routes ----- */} - - - - - - - - {/* ----- End of Kitchen and Inventory Portal Routes ----- */} From 45bffcb30563827761b4de0e351c13b6ee6fab09 Mon Sep 17 00:00:00 2001 From: Sireesha Kunchala Date: Sat, 13 Jun 2026 00:18:42 -0400 Subject: [PATCH 5/5] sonarcode fixes --- .../CommunityPortal/Reports/Participation/ChartsSection.jsx | 6 +++--- .../Reports/Participation/EventParticipation.jsx | 4 ++-- .../CommunityPortal/Reports/Participation/MyCases.jsx | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx index a47fd6ea6e..eaf44e0bea 100644 --- a/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx +++ b/src/components/CommunityPortal/Reports/Participation/ChartsSection.jsx @@ -32,8 +32,8 @@ function ChartsSection() { } groups[key].count++; - groups[key].noShowSum += parseInt(evt.noShowRate, 10); - groups[key].dropSum += parseInt(evt.dropOffRate, 10); + groups[key].noShowSum += Number.parseInt(evt.noShowRate, 10); + groups[key].dropSum += Number.parseInt(evt.dropOffRate, 10); }); Object.entries(groups).forEach(([key, stats]) => { @@ -55,7 +55,7 @@ function ChartsSection() { } monthlyTrend[m].count++; - monthlyTrend[m].noShowSum += parseInt(evt.noShowRate, 10); + monthlyTrend[m].noShowSum += Number.parseInt(evt.noShowRate, 10); }); const trendData = Object.keys(monthlyTrend).map(m => ({ diff --git a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx index 548786d556..94cae85c35 100644 --- a/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx +++ b/src/components/CommunityPortal/Reports/Participation/EventParticipation.jsx @@ -17,7 +17,7 @@ function EventParticipation() { const [exporting, setExporting] = useState(false); const handleSaveAsPDF = useCallback(() => { - if (typeof window === 'undefined' || typeof document === 'undefined') return; + if (typeof globalThis.window === 'undefined' || typeof document === 'undefined') return; if (exporting) return; setExporting(true); @@ -32,7 +32,7 @@ function EventParticipation() { document.title = 'event_participation'; setTimeout(() => { - window.print(); + globalThis.window.print(); setTimeout(() => { if (shouldExpand) moreBtn.click(); diff --git a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx index 1c6065ae02..a63c5d7d6f 100644 --- a/src/components/CommunityPortal/Reports/Participation/MyCases.jsx +++ b/src/components/CommunityPortal/Reports/Participation/MyCases.jsx @@ -1,6 +1,5 @@ import { useState, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { useHistory } from 'react-router-dom'; import Calendar from 'react-calendar'; import styles from './MyCases.module.css'; import mockEvents from './mockData'; @@ -13,7 +12,6 @@ function MyCases() { const [expanded, setExpanded] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [calendarDate, setCalendarDate] = useState(new Date()); - const history = useHistory(); const isExporting = typeof document !== 'undefined' && document.documentElement?.dataset?.exporting === 'true';