From 4b88f8b5b4a1ac784188f387ed4a839fb1cdf7b6 Mon Sep 17 00:00:00 2001 From: pujitakalinadhabhotla <161961520+pujitakalinadhabhotla@users.noreply.github.com> Date: Wed, 26 Mar 2025 22:23:47 -0400 Subject: [PATCH 1/4] new changes --- .../frontend/src/components/map/MapLegend.tsx | 399 ++++-------------- apps/frontend/src/images/markers/circle.svg | 3 +- apps/frontend/src/images/markers/diamond.svg | 3 +- apps/frontend/src/images/markers/other.svg | 3 + apps/frontend/src/images/markers/other.tsx | 6 + apps/frontend/src/images/markers/pentagon.svg | 3 +- apps/frontend/src/images/markers/square.svg | 5 +- apps/frontend/src/images/markers/star.svg | 3 +- apps/frontend/src/images/markers/triangle.svg | 3 +- 9 files changed, 106 insertions(+), 322 deletions(-) create mode 100644 apps/frontend/src/images/markers/other.svg create mode 100644 apps/frontend/src/images/markers/other.tsx diff --git a/apps/frontend/src/components/map/MapLegend.tsx b/apps/frontend/src/components/map/MapLegend.tsx index 5e42bf69..5db2c8b6 100644 --- a/apps/frontend/src/components/map/MapLegend.tsx +++ b/apps/frontend/src/components/map/MapLegend.tsx @@ -16,184 +16,95 @@ import circleSVG from '../../images/markers/circle.svg'; import diamondSVG from '../../images/markers/diamond.svg'; import starSVG from '../../images/markers/star.svg'; import pentagonSVG from '../../images/markers/pentagon.svg'; +import otherSVG from '../../images/markers/other.svg'; import { CheckboxOptionType } from 'antd/es/checkbox/Group'; type CheckboxValueType = string | number | boolean; const Title = styled.h1` -font-size: 15px; -font-weight: bold; -font-family: Montserrat; -margin-top: 0px -margin-bottom: 0px; -color: #091F2F; -text-align: center; -`; - -const Heading = styled.h2` - color: rgba(88, 88, 91, 1); - text-align: center; - font-family: Lora; - font-size: 15px; - margin-top: 0px; - font-weight: 400; - line-height: 19px; - letter-spacing: 0em; - text-align: center; + font-size: 16px; /* Title remains 14px */ + font-weight: bold; + font-family: Montserrat; + margin-top: 10px; + margin-bottom: 5px; + color: #091F2F; + text-align: left; + padding-left: 5px; `; const MapLegendContainer = styled.div<{ isVisible: boolean }>` background: rgba(255, 253, 253, 1); - width: 247px; - gap: 20px; - padding-right: 0px; + width: 280px; position: relative; transition: height 0.3s ease; min-height: ${(props) => (props.isVisible ? '20px' : 'auto')}; - height: ${(props) => (props.isVisible ? '475px' : 'auto')}; - overflow: hidden; + max-height: ${(props) => (props.isVisible ? '600px' : 'auto')}; + overflow-y: auto; + padding-bottom: 30px; + padding: 25px 20px; `; const LegendItem = styled.div` - width: 100%; display: flex; - gap: 10px; - padding-left: 10px; align-items: center; - margin: 10px; + gap: 10px; + padding-left: 5px; + margin: 10px 0; `; const LegendImage = styled(Image)` - height: 20px; - width: 20px; - justify-content: center; + width: 18px; + height: 18px; display: inline-block; `; const LegendText = styled.div` - margin-left: 15px; + font-family: 'Lora', serif; + font-size: 16px; /* Increased text to 16px */ + color: #000; + line-height: 1.3; `; -const FeatureContainer = styled.div` - width: 90%; - height: 284px; - margin: 10px; - padding-top: 10px; - background: rgba(242, 242, 242, 1); +const BoxedGroup = styled.div` + background-color: #F2F2F2; + padding: 8px; + margin: 10px 6px; + border-radius: 4px; + width: calc(100% - 12px); `; const StatusCheckbox = styled(Checkbox.Group)` - height: 12px; - width: 200px; - color: #fff; - border: line; - padding: 10px 20px; - cursor: pointer; - display: flex; - .ant-checkbox-checked .ant-checkbox-inner { - background-color: #e74c3c; - border-color: #e74c3c; - } -`; - -const StatusContainer = styled.div` - width: 206px; - height: 79px; - margin: 10px; - background: rgba(242, 242, 242, 1); -`; - -const StyledButton = styled.button<{ isSelected: boolean }>` - background-color: ${(props) => (props.isSelected ? '#45789C' : '#fff')}; - height: 36px; - width: 187px; - border-style: solid; - border-color: black; - padding: 10px 20px; - cursor: pointer; - font-size: 14px; - letter-spacing: 0em; - text-align: left; - align-items: center; - color: ${(props) => (props.isSelected ? '#fff' : 'rgba(24, 112, 188, 1)')}; - display: flex; - &:hover { - background-color: ${(props) => (props.isSelected ? '#45789C' : '#45789C')}; - color: ${(props) => (props.isSelected ? '#fff' : '#fff')}; - } -`; - -const StatusButton = styled.button<{ isSelected: boolean }>` - // background-color: ${(props) => (props.isSelected ? '#e74c3c' : '#fff')}; - height: 28px; - width: 187px; - // color: #fff; - border: none; - padding: 10px 20px; - cursor: pointer; - font-size: 16px; - font-family: Montserrat; - font-size: 14px; - font-weight: 600; - line-height: 17px; - letter-spacing: 0em; - text-align: center; - align-items: center; - color: rgba(40, 139, 228, 1); display: flex; + flex-direction: column; + padding-left: 5px; + gap: 5px; `; const ToggleContainer = styled.div<{ isVisible: boolean }>` cursor: pointer; - font-size: 18px; + font-size: 16px; position: absolute; - width: 247px; + width: 280px; height: 20px; - z-index: 1; display: flex; justify-content: center; - background: #091f2f; + background: #0072C4; bottom: 0px; `; -const CaretDownStyled = styled(CaretDownOutlined)` - color: #ffffff; -`; - -const CaretUpStyled = styled(CaretUpOutlined)` - color: #ffffff; -`; - -const FullWidthSpace = styled(Space)` - width: 100%; -`; const statusSpan = (statusIcon: string, labelString: string): ReactNode => { + let color = '#000'; + if (labelString.toLowerCase().includes('adopted')) color = '#DFC22A'; + if (labelString.toLowerCase().includes('available')) color = '#2D6A4F'; + if (labelString.toLowerCase().includes('inactive')) color = '#58585B'; + return ( - - - - {labelString.replace(' Sites', '').toUpperCase()} + +
+ + {labelString} - + ); }; @@ -214,37 +125,26 @@ const MapLegend: React.FC = ({ }) => { const [isVisible, setIsVisible] = useState(true); - const options: CheckboxOptionType[] = SITE_STATUS_ROADMAP.map((option) => { - return { - label: statusSpan(option.image, option.label), - value: option.value, - }; - }); + const options: CheckboxOptionType[] = SITE_STATUS_ROADMAP.map((option) => ({ + label: statusSpan(option.image, option.label), + value: option.value, + })); const toggleShowLegend = () => { setIsVisible((prev) => !prev); }; - const [availableIcon, adoptedIcon] = - icons ?? SITE_STATUS_ROADMAP.map((option) => option.image); - - const handleFeatureClick = (icon: string) => { - // Check if the icon is already selected - const isAlreadySelected = selectedFeatures.includes(icon); - - if (isAlreadySelected) { - // Deselect the icon - setSelectedFeatures((prevSelectedFeatures: string[]) => - prevSelectedFeatures.filter((selected) => selected !== icon), - ); + const handleFeatureClick = (feature: string) => { + setSelectedFeatures((prevSelected: string[]) => { + if (prevSelected.includes(feature)) { + // Remove it + return prevSelected.filter((f) => f !== feature); } else { - // Select the icon - setSelectedFeatures((prevSelectedFeatures: string[]) => [ - ...prevSelectedFeatures, - icon, - ]); + // Add it + return [...prevSelected, feature]; } - }; + }); +}; const handleStatusClick = (values: CheckboxValueType[]) => { // set selected statuses @@ -254,193 +154,76 @@ const MapLegend: React.FC = ({ return ( - - -
-
- - FEATURE TYPE - - -
-
-
- Legend and Description + Feature Types - + {icons && ( - handleFeatureClick('Rain Garden')} - isSelected={selectedFeatures.includes('Rain Garden')} - > - - RAIN GARDEN - + handleFeatureClick('Bioretention')} /> )} + + Bioretention {icons && ( - handleFeatureClick('Bioswale')} - isSelected={selectedFeatures.includes('Bioswale')} - > - - BIOSWALE - + handleFeatureClick('Rain Garden')} /> )} + + Rain Garden {icons && ( - handleFeatureClick('Bioretention')} - isSelected={selectedFeatures.includes('Bioretention')} - > - - BIORETENTION - + handleFeatureClick('Bioswale')} /> )} + + Bioswale {icons && ( - handleFeatureClick('Porous Paving')} - isSelected={selectedFeatures.includes('Porous Paving')} - > - - POROUS PAVING - + handleFeatureClick('Porous Paving')} /> )} + + Porous Paving {icons && ( - handleFeatureClick('Tree Trench/Pit')} - isSelected={selectedFeatures.includes('Tree Trench/Pit')} - > - - TREE TRENCH/PIT - + handleFeatureClick('Tree Trench/Pit')} /> )} + + Tree Trench / Planter {icons && ( - handleFeatureClick('Green Roof/Planter')} - isSelected={selectedFeatures.includes('Green Roof/Planter')} - > - - GREEN ROOF/PLANTER - + handleFeatureClick('Green Roof/Planter')} /> )} + + Green Roof / Planter - - {icons && ( - - handleStatusClick(values as CheckboxValueType[]) - } - value={selectedStatuses} - options={options} - /> + handleFeatureClick('Other')}/> )} + + Other - + + + + Status + + + handleStatusClick(values as CheckboxValueType[])} value={selectedStatuses} options={options} /> +
+ - {isVisible ? ( - - ) : ( - - )} + {isVisible ? : }
); diff --git a/apps/frontend/src/images/markers/circle.svg b/apps/frontend/src/images/markers/circle.svg index e32bc76f..2eaeab55 100644 --- a/apps/frontend/src/images/markers/circle.svg +++ b/apps/frontend/src/images/markers/circle.svg @@ -1,4 +1,3 @@ - - + diff --git a/apps/frontend/src/images/markers/diamond.svg b/apps/frontend/src/images/markers/diamond.svg index 36976ed8..f900dfc8 100644 --- a/apps/frontend/src/images/markers/diamond.svg +++ b/apps/frontend/src/images/markers/diamond.svg @@ -1,4 +1,3 @@ - - + diff --git a/apps/frontend/src/images/markers/other.svg b/apps/frontend/src/images/markers/other.svg new file mode 100644 index 00000000..9d071f65 --- /dev/null +++ b/apps/frontend/src/images/markers/other.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/frontend/src/images/markers/other.tsx b/apps/frontend/src/images/markers/other.tsx new file mode 100644 index 00000000..6e104f92 --- /dev/null +++ b/apps/frontend/src/images/markers/other.tsx @@ -0,0 +1,6 @@ +export default function generateOtherSVG(color: string) { + return ` + + `; + } + \ No newline at end of file diff --git a/apps/frontend/src/images/markers/pentagon.svg b/apps/frontend/src/images/markers/pentagon.svg index f382372a..f05f5339 100644 --- a/apps/frontend/src/images/markers/pentagon.svg +++ b/apps/frontend/src/images/markers/pentagon.svg @@ -1,4 +1,3 @@ - - + diff --git a/apps/frontend/src/images/markers/square.svg b/apps/frontend/src/images/markers/square.svg index 44bf4fe9..1089c9ea 100644 --- a/apps/frontend/src/images/markers/square.svg +++ b/apps/frontend/src/images/markers/square.svg @@ -1,6 +1,3 @@ - - + - - diff --git a/apps/frontend/src/images/markers/star.svg b/apps/frontend/src/images/markers/star.svg index 73cf2307..d4a05521 100644 --- a/apps/frontend/src/images/markers/star.svg +++ b/apps/frontend/src/images/markers/star.svg @@ -1,4 +1,3 @@ - - + diff --git a/apps/frontend/src/images/markers/triangle.svg b/apps/frontend/src/images/markers/triangle.svg index ca69290f..00d35499 100644 --- a/apps/frontend/src/images/markers/triangle.svg +++ b/apps/frontend/src/images/markers/triangle.svg @@ -1,4 +1,3 @@ - - + From 2ff4e506e981dfa0553be31f8babdc9e19814328 Mon Sep 17 00:00:00 2001 From: pujitakalinadhabhotla <161961520+pujitakalinadhabhotla@users.noreply.github.com> Date: Thu, 3 Apr 2025 10:58:07 -0400 Subject: [PATCH 2/4] Update MapLegend.tsx --- .../frontend/src/components/map/MapLegend.tsx | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/apps/frontend/src/components/map/MapLegend.tsx b/apps/frontend/src/components/map/MapLegend.tsx index 5db2c8b6..a299f4d9 100644 --- a/apps/frontend/src/components/map/MapLegend.tsx +++ b/apps/frontend/src/components/map/MapLegend.tsx @@ -125,6 +125,29 @@ const MapLegend: React.FC = ({ }) => { const [isVisible, setIsVisible] = useState(true); + const allFeatureTypes = [ + 'Bioretention', + 'Rain Garden', + 'Bioswale', + 'Porous Paving', + 'Tree Trench/Pit', + 'Green Roof/Planter', + 'Other', + ]; + + useState(() => { + setSelectedFeatures(allFeatureTypes); + + const defaultStatus = SITE_STATUS_ROADMAP.find((s) => + s.label.toLowerCase().includes('available') + ); + if (defaultStatus) { + setSelectedStatuses([defaultStatus.value]); + } + + return; + }); + const options: CheckboxOptionType[] = SITE_STATUS_ROADMAP.map((option) => ({ label: statusSpan(option.image, option.label), value: option.value, @@ -135,19 +158,16 @@ const MapLegend: React.FC = ({ }; const handleFeatureClick = (feature: string) => { - setSelectedFeatures((prevSelected: string[]) => { - if (prevSelected.includes(feature)) { - // Remove it - return prevSelected.filter((f) => f !== feature); - } else { - // Add it - return [...prevSelected, feature]; - } - }); -}; + setSelectedFeatures((prevSelected: string[]) => { + if (prevSelected.includes(feature)) { + return prevSelected.filter((f) => f !== feature); + } else { + return [...prevSelected, feature]; + } + }); + }; const handleStatusClick = (values: CheckboxValueType[]) => { - // set selected statuses setSelectedStatuses(values); }; From 5d6ca4660d3b1eb09e6973fb22a65070b504bf84 Mon Sep 17 00:00:00 2001 From: pujitakalinadhabhotla <161961520+pujitakalinadhabhotla@users.noreply.github.com> Date: Tue, 8 Apr 2025 20:00:52 -0400 Subject: [PATCH 3/4] Update MapLegend.tsx --- apps/frontend/src/components/map/MapLegend.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/components/map/MapLegend.tsx b/apps/frontend/src/components/map/MapLegend.tsx index a299f4d9..4d5bcb77 100644 --- a/apps/frontend/src/components/map/MapLegend.tsx +++ b/apps/frontend/src/components/map/MapLegend.tsx @@ -85,8 +85,9 @@ const ToggleContainer = styled.div<{ isVisible: boolean }>` font-size: 16px; position: absolute; width: 280px; - height: 20px; + height: 30px; display: flex; + align-items: center; justify-content: center; background: #0072C4; bottom: 0px; From 08fd960f61a181bbf332ea0068ba4f4138dac5db Mon Sep 17 00:00:00 2001 From: pujitakalinadhabhotla <161961520+pujitakalinadhabhotla@users.noreply.github.com> Date: Thu, 10 Apr 2025 01:23:28 -0400 Subject: [PATCH 4/4] new changes --- apps/frontend/src/components/map/Map.tsx | 18 ++++++++---- .../frontend/src/components/map/MapLegend.tsx | 28 ++++++++++++++++--- apps/frontend/src/images/markers/other.svg | 4 +-- apps/frontend/src/images/markers/other.tsx | 13 +++++---- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/apps/frontend/src/components/map/Map.tsx b/apps/frontend/src/components/map/Map.tsx index 5a9c7025..6f60ada6 100644 --- a/apps/frontend/src/components/map/Map.tsx +++ b/apps/frontend/src/components/map/Map.tsx @@ -7,6 +7,7 @@ import generateDiamondSVG from '../../images/markers/diamond'; import generateTriangleSVG from '../../images/markers/triangle'; import generateStarSVG from '../../images/markers/star'; import generatePentagonSVG from '../../images/markers/pentagon'; +import generateOtherSVG from '../../images/markers/other'; import PopupBox from '../mapIcon/PopupBox'; import { createRoot } from 'react-dom/client'; import { createPortal } from 'react-dom'; @@ -31,7 +32,7 @@ const iconGenerators = { 'Porous Paving': generateDiamondSVG, 'Tree Trench/Pit': generateStarSVG, 'Green Roof/Planter': generatePentagonSVG, - 'Other': generatePentagonSVG // Placeholder, will remove + 'Other': generateOtherSVG // Placeholder, will remove } as const; type SymbolType = keyof typeof iconGenerators; @@ -50,7 +51,7 @@ function filterMarkers( if (selectedFeatures.length === 0) { markers.forEach((marker: google.maps.Marker) => { marker.setMap(map); - }); + }); tempMarkers = markers; } else { markers.forEach((marker: google.maps.Marker) => marker.setMap(null)); @@ -130,9 +131,16 @@ const Map: React.FC = ({ console.warn(`Unknown symbol type: ${symbolType}`); return; } - - const typeColor = - markerInfo.siteStatus === 'Available' ? '#2D6A4F' : '#FB4D42'; + + + let typeColor = '#58585B'; + if (markerInfo.siteStatus === 'Available') { + typeColor = '#2D6A4F'; // Green + } else if (markerInfo.siteStatus === 'Adopted') { + typeColor = '#DFC22A'; // Yellow (match legend) + } else if (markerInfo.siteStatus === 'Inactive') { + typeColor = '#58585B'; // Gray + } const generateIcon = iconGenerators[symbolType]; const tempIcon = generateIcon(typeColor); diff --git a/apps/frontend/src/components/map/MapLegend.tsx b/apps/frontend/src/components/map/MapLegend.tsx index 4d5bcb77..c8d52f46 100644 --- a/apps/frontend/src/components/map/MapLegend.tsx +++ b/apps/frontend/src/components/map/MapLegend.tsx @@ -18,6 +18,8 @@ import starSVG from '../../images/markers/star.svg'; import pentagonSVG from '../../images/markers/pentagon.svg'; import otherSVG from '../../images/markers/other.svg'; import { CheckboxOptionType } from 'antd/es/checkbox/Group'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; + type CheckboxValueType = string | number | boolean; @@ -53,11 +55,12 @@ const LegendItem = styled.div` `; const LegendImage = styled(Image)` - width: 18px; - height: 18px; + width: 21px; + height: 20px; display: inline-block; `; + const LegendText = styled.div` font-family: 'Lora', serif; font-size: 16px; /* Increased text to 16px */ @@ -168,6 +171,14 @@ const MapLegend: React.FC = ({ }); }; + const CenteredIconWrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; +`; + const handleStatusClick = (values: CheckboxValueType[]) => { setSelectedStatuses(values); }; @@ -244,8 +255,17 @@ const MapLegend: React.FC = ({ - {isVisible ? : } - + + + + + ); }; diff --git a/apps/frontend/src/images/markers/other.svg b/apps/frontend/src/images/markers/other.svg index 9d071f65..73cf37ce 100644 --- a/apps/frontend/src/images/markers/other.svg +++ b/apps/frontend/src/images/markers/other.svg @@ -1,3 +1,3 @@ - - + + diff --git a/apps/frontend/src/images/markers/other.tsx b/apps/frontend/src/images/markers/other.tsx index 6e104f92..238fbd2e 100644 --- a/apps/frontend/src/images/markers/other.tsx +++ b/apps/frontend/src/images/markers/other.tsx @@ -1,6 +1,9 @@ export default function generateOtherSVG(color: string) { - return ` - - `; - } - \ No newline at end of file + return ` + + + + + `; +} +