diff --git a/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx b/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx index 60a0e84ec9..99b230b0db 100644 --- a/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx +++ b/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { useSelector } from 'react-redux'; import styles from './Participation.module.css'; +import { ArrowUpDown, ArrowUp, ArrowDown, SquareArrowOutUpRight } from 'lucide-react'; import mockEvents from './mockData'; function DropOffTracking() { @@ -10,6 +11,8 @@ function DropOffTracking() { const [isModalOpen, setIsModalOpen] = useState(false); const [activeEvent, setActiveEvent] = useState(null); const [selectedUsers, setSelectedUsers] = useState([]); + const [sortColumn, setSortColumn] = useState(null); + const [sortDirection, setSortDirection] = useState('asc'); const darkMode = useSelector(state => state.theme.darkMode); @@ -62,6 +65,38 @@ function DropOffTracking() { setSelectedUsers([]); }; + const handleSort = column => { + if (sortColumn === column) { + setSortDirection(prev => (prev === 'asc' ? 'desc' : 'asc')); + } else { + setSortColumn(column); + setSortDirection('asc'); + } + }; + + const parseRate = val => parseFloat(val); + + const sortedEvents = [...filteredEvents].sort((a, b) => { + if (!sortColumn) return 0; + let aVal = a[sortColumn]; + let bVal = b[sortColumn]; + if (sortColumn === 'noShowRate' || sortColumn === 'dropOffRate') { + aVal = parseRate(aVal); + bVal = parseRate(bVal); + } else { + aVal = aVal?.toLowerCase() ?? ''; + bVal = bVal?.toLowerCase() ?? ''; + } + if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1; + if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1; + return 0; + }); + + const sortIndicator = column => { + if (sortColumn !== column) return ; + return sortDirection === 'asc' ? : ; + }; + return (
- Event name - No-show rate - Drop-off rate + handleSort('eventName')} className={styles.sortableHeader}> + + Event name {sortIndicator('eventName')} + + + handleSort('noShowRate')} className={styles.sortableHeader}> + + No-show rate {sortIndicator('noShowRate')} + + + handleSort('dropOffRate')} className={styles.sortableHeader}> + + Drop-off rate {sortIndicator('dropOffRate')} + + Get list - {filteredEvents.map(event => ( + {sortedEvents.map(event => ( {event.eventName} {event.noShowRate} @@ -201,7 +248,6 @@ function DropOffTracking() { className={styles.sendEmailBtn} disabled={selectedUsers.length === 0} onClick={() => { - console.log('Send email to:', selectedUsers); handleCloseModal(); }} > diff --git a/src/components/CommunityPortal/Reports/Participation/Participation.module.css b/src/components/CommunityPortal/Reports/Participation/Participation.module.css index 77f6c0857d..cc7d6166d1 100644 --- a/src/components/CommunityPortal/Reports/Participation/Participation.module.css +++ b/src/components/CommunityPortal/Reports/Participation/Participation.module.css @@ -1,6 +1,6 @@ /* ---------- General Styling ---------- */ .body { - font-family: 'Arial', sans-serif; + font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f5f5f5; @@ -9,13 +9,14 @@ .participationLandingPage { max-width: 90%; margin: 0 auto; + background: white; } .participationLandingPageDark { max-width: 90%; margin: 0 auto; background-color: #1b2a41; - color: #ffffff; + color: #fff; } /* ---------- Page Header ---------- */ @@ -38,7 +39,7 @@ .landingPageHeaderDark { font-size: 2.2rem; font-weight: 700; - color: #ffffff !important; + color: #fff !important; letter-spacing: 0.5px; } @@ -75,7 +76,7 @@ transform: translateY(-1px); } -@media (max-width: 768px) { +@media (width <= 768px) { .landingPageHeaderContainer { flex-direction: column; align-items: center; @@ -138,7 +139,7 @@ background: white; border: 1px solid #ddd; border-radius: 5px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 4px rgb(0 0 0 / 10%); } /* ---------- Analytics Section ---------- */ @@ -155,9 +156,9 @@ .insights { flex: 1; min-width: 48%; - background-color: #ffffff; + background-color: #fff; border-radius: 10px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 8px rgb(0 0 0 / 10%); padding: 20px; box-sizing: border-box; } @@ -167,15 +168,15 @@ flex: 1; min-width: 48%; background-color: #1c2541; - color: #ffffff; + color: #fff; border-radius: 10px; border: 1px solid #ddd; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 8px rgb(0 0 0 / 10%); padding: 20px; box-sizing: border-box; } -@media (max-width: 768px) { +@media (width <= 768px) { .analyticsSection { flex-wrap: wrap; } @@ -199,7 +200,7 @@ justify-content: space-between; align-items: center; margin-bottom: 20px; - color: #ffffff; + color: #fff; } .trackingHeader h3 { @@ -209,7 +210,7 @@ } .trackingHeaderDark h3 { - color: #ffffff; + color: #fff; font-size: 1.3rem; margin: 0; } @@ -272,12 +273,12 @@ border-radius: 10px; width: 48%; padding: 10px; - color: #ffffff; + color: #fff; } .trackingRateDark .trackingRateSubheading span, .trackingRateDark .trackingRateValue span { - color: #ffffff; + color: #fff; } .trackingRateValue { @@ -295,6 +296,7 @@ padding: 10px; background: #fff; } + .trackingListContainerDark { max-height: 600px; overflow-y: auto; @@ -302,14 +304,14 @@ border-radius: 10px; padding: 10px; background: #3a506b; - color: #ffffff; + color: #fff; } .trackingTable { width: 100%; border-collapse: collapse; table-layout: fixed; - word-wrap: break-word; + overflow-wrap: break-word; } .trackingTable thead th { @@ -318,9 +320,29 @@ background: #f4f4f4; } +.sortableHeader { + cursor: pointer; + user-select: none; + white-space: nowrap; +} + +.sortableHeaderContent { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.sortableHeader:hover { + background: #e8e8e8; +} + +.trackingTableDark .sortableHeader:hover { + background: #253055; +} + .trackingTableDark thead th { background: #1c2541; - color: #ffffff; + color: #fff; } .trackingTable tbody td { @@ -345,8 +367,9 @@ display: flex; justify-content: space-between; } + .insightsHeaderDark { - color: #ffffff; + color: #fff; font-weight: bold; margin-bottom: 15px; display: flex; @@ -358,8 +381,9 @@ color: #333; margin: 0; } + .insightsHeaderDark h3 { - color: #ffffff; + color: #fff; font-size: 1.3rem; margin: 0; } @@ -455,7 +479,7 @@ .insightsDark .insightsTab { background-color: #3A506B; - color: #ffffff; + color: #fff; border-right: 1px solid #555; } @@ -487,12 +511,14 @@ color: #555; margin-right: 10px; } + .insightLabelDark { - color: #ffffff; + color: #fff; font-size: 0.9rem; flex: 1; margin-right: 10px; } + .insightBar { flex: 2; height: 8px; @@ -518,7 +544,7 @@ } .insightsPercentageDark { - color: #ffffff; + color: #fff; } .tooltipWrapper { @@ -549,10 +575,11 @@ } /* ---------- Export PDF modal ---------- */ -.modalOverlay { + +/* .modalOverlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.45); + background: rgb(0 0 0 / 45%); display: flex; justify-content: center; align-items: center; @@ -609,7 +636,7 @@ .modalActions { display: flex; gap: 10px; -} +} */ .exportOptionsButtons, .exportOptionsButtonsDark { @@ -645,12 +672,10 @@ cursor: not-allowed; } - - /* ---------- PDF/Print helpers ---------- */ -.pageBreakBefore { break-before: page; page-break-before: always; } -.pageBreakAfter { break-after: page; page-break-after: always; } -.avoidBreak { break-inside: avoid; page-break-inside: avoid; } +.pageBreakBefore { break-before: always; } +.pageBreakAfter { break-after: always; } +.avoidBreak { break-inside: avoid; } :global(html[data-exporting="true"]) .caseCards:global(.expanded), :global(html[data-exporting="true"]) .caseList:global(.expanded), @@ -665,6 +690,7 @@ border: 1px solid #555; background-color: #1e293b; /* Dark background */ } + /* Dark mode tab */ .insightsTabDarkMode { color: #ddd; @@ -680,6 +706,16 @@ display: none; } +/* .participationLandingPage, +.participationLandingPage * { + -webkit-print-color-adjust: exact !important; + print-color-adjust: exact !important; +} + +.participationLandingPage { + background: white !important; +} */ + @media print { /* Hide everything except the participation component */ :global(body > *:not(#root)) { @@ -728,22 +764,20 @@ display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 12px !important; - page-break-inside: auto !important; + break-inside: auto !important; } :global(.case-card-global) { - break-inside: avoid-page !important; - page-break-inside: avoid !important; + break-inside: avoid !important; height: auto !important; } :global(.case-list-global) { - page-break-inside: auto !important; + break-inside: auto !important; } :global(.case-list-item-global) { - break-inside: avoid-page !important; - page-break-inside: avoid !important; + break-inside: avoid !important; } .trackingListContainer, @@ -755,12 +789,10 @@ :global(.tracking-table-global) tr { break-inside: avoid; - page-break-inside: avoid; } .insightItem { break-inside: avoid; - page-break-inside: avoid; } :global(.view-switcher-global), @@ -782,22 +814,12 @@ :global(.tracking-table-global-dark) thead th { background: #1C2541 !important; - color: #ffffff !important; + color: #fff !important; } .printOnly { display: block !important; } - - .participationLandingPage, - .participationLandingPage * { - -webkit-print-color-adjust: exact !important; - print-color-adjust: exact !important; - } - - .participationLandingPage { - background: white !important; - } :global(#root) .case-card-global { background: white !important; @@ -820,40 +842,40 @@ /* Dark mode styles for print */ .participationLandingPageDark { background: #1B2A41 !important; - color: #ffffff !important; + color: #fff !important; } .participationLandingPageDark :global(.case-card-global) { background: #3A506B !important; - color: #ffffff !important; + color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .trackingContainerDark { background: #1C2541 !important; - color: #ffffff !important; + color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .insightsDark { background: #1C2541 !important; - color: #ffffff !important; + color: #fff !important; border: 1px solid #555 !important; } .participationLandingPageDark .trackingListContainerDark { background: #3A506B !important; - color: #ffffff !important; + color: #fff !important; } .participationLandingPageDark :global(.tracking-table-global-dark) thead th { background: #1C2541 !important; - color: #ffffff !important; + color: #fff !important; } .participationLandingPageDark .trackingRateDark { background: #3A506B !important; - color: #ffffff !important; + color: #fff !important; } /* Event badge colors for print */ @@ -900,9 +922,10 @@ .participationLandingPageDark .attendeesCountDark, .participationLandingPageDark .insightsLabelDark, .participationLandingPageDark .insightsPercentageDark { - color: #ffffff !important; + color: #fff !important; } } + /* Active tab dark mode */ .activeTabDarkMode { background-color: #3b82f6; @@ -927,7 +950,7 @@ .modalOverlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.45); + background: rgb(0 0 0 / 45%); display: flex; align-items: center; justify-content: center; @@ -935,7 +958,7 @@ } .modalContent { - background: #ffffff; + background: #fff; width: 420px; max-height: 80vh; border-radius: 10px; @@ -946,7 +969,7 @@ .modalContentDark { background: #1C2541; - color: #ffffff; + color: #fff; } .modalHeader { @@ -1023,41 +1046,41 @@ /* ===== Dark mode fixes ===== */ .participationLandingPageDark :global(button) { - color: #ffffff !important; + color: #fff !important; } .participationLandingPageDark :global(.btn), .participationLandingPageDark :global(.btn-light), .participationLandingPageDark :global(.btn-outline-secondary) { - color: #ffffff !important; + color: #fff !important; background-color: #3a506b !important; border-color: #3a506b !important; } .participationLandingPageDark :global(.btn-primary), .participationLandingPageDark :global(.active) { - color: #ffffff !important; + color: #fff !important; } .trackingContainerDark .trackingFilters select { background-color: #3A506B; - color: #ffffff; + color: #fff; border: 1px solid #3A506B; } -.insightsDark .insightsFilters select { +/* .insightsDark .insightsFilters select { background-color: #3A506B; - color: #ffffff; + color: #fff; border: 1px solid #3A506B; } .insightsDark .insightsTab { background-color: #3A506B; - color: #ffffff; + color: #fff; border-right: 1px solid #555; } .insightsDark .insightsTab.activeTab { background-color: #007bff; - color: #ffffff; -} \ No newline at end of file + color: #fff; +} */ \ No newline at end of file