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 @@
-