Skip to content
This repository was archived by the owner on Jan 12, 2026. It is now read-only.

Commit a6a1a7e

Browse files
Merge pull request #77 from Code-4-Community/pk-73-store-siteID
Pk 73 store site
2 parents 6350ced + 67723ba commit a6a1a7e

File tree

4 files changed

+92
-108
lines changed

4 files changed

+92
-108
lines changed

apps/frontend/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
VITE_GOOGLE_MAPS_API_KEY=INSERT_API_KEY_HERE
2+

apps/frontend/src/components/map/Map.tsx

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useRef, useState } from 'react';
2-
import { loader, BOSTON_BOUNDS, BOSTON_PLACE_ID } from '../../constants';
2+
import { loader, BOSTON_BOUNDS } from '../../constants';
33
import styled from 'styled-components';
44
import generateCircleSVG from '../../images/markers/circle';
55
import generateSquareSVG from '../../images/markers/square';
@@ -17,7 +17,7 @@ const MapDiv = styled.div`
1717
`;
1818

1919
async function fetchAllSites() {
20-
const response = await fetch('http://localhost:3000/sites');
20+
const response = await fetch('http://localhost:3000/sites');
2121
if (!response.ok) {
2222
throw new Error('Failed to fetch site data');
2323
}
@@ -31,7 +31,7 @@ const iconGenerators = {
3131
'Porous Paving': generateDiamondSVG,
3232
'Tree Trench/Pit': generateStarSVG,
3333
'Green Roof/Planter': generatePentagonSVG,
34-
'Other': generatePentagonSVG // Placeholder, will remove
34+
'Other': generatePentagonSVG,
3535
} as const;
3636

3737
type SymbolType = keyof typeof iconGenerators;
@@ -84,14 +84,12 @@ interface MapProps {
8484
selectedStatuses: string[];
8585
}
8686

87-
const Map: React.FC<MapProps> = ({
88-
zoom,
89-
selectedFeatures,
90-
selectedStatuses,
91-
}) => {
87+
const Map: React.FC<MapProps> = ({ zoom, selectedFeatures, selectedStatuses }) => {
9288
const mapRef = useRef<HTMLDivElement | null>(null);
9389
const [showSignUp, setShowSignUp] = useState(false);
9490
const [markers, setMarkers] = useState<google.maps.Marker[]>([]);
91+
// CHANGED: State to store the selected site's ID.
92+
const [selectedSiteId, setSelectedSiteId] = useState<string | null>(null);
9593

9694
let map: google.maps.Map;
9795

@@ -100,7 +98,7 @@ const Map: React.FC<MapProps> = ({
10098
loader.load().then(async () => {
10199
map = new google.maps.Map(mapRef.current as HTMLElement, {
102100
center: { lat: 42.36, lng: -71.06 },
103-
zoom: 8,
101+
zoom: zoom,
104102
mapId: '3aa9b524d13192b',
105103
mapTypeControl: false,
106104
fullscreenControl: true,
@@ -131,9 +129,7 @@ const Map: React.FC<MapProps> = ({
131129
return;
132130
}
133131

134-
const typeColor =
135-
markerInfo.siteStatus === 'Available' ? '#2D6A4F' : '#FB4D42';
136-
132+
const typeColor = markerInfo.siteStatus === 'Available' ? '#2D6A4F' : '#FB4D42';
137133
const generateIcon = iconGenerators[symbolType];
138134
const tempIcon = generateIcon(typeColor);
139135
const typeIcon = `data:image/svg+xml;utf8,${encodeURIComponent(tempIcon)}`;
@@ -169,7 +165,7 @@ const Map: React.FC<MapProps> = ({
169165
anchor: new google.maps.Point(10, 10),
170166
};
171167

172-
const marker: google.maps.Marker = new google.maps.Marker({
168+
const marker = new google.maps.Marker({
173169
position: {
174170
lat: Number(markerInfo.siteLatitude),
175171
lng: Number(markerInfo.siteLongitude),
@@ -187,6 +183,10 @@ const Map: React.FC<MapProps> = ({
187183
}
188184
infoWindow.open(map, marker);
189185
currentInfoWindow = infoWindow;
186+
187+
// CHANGED: Store the selected site's ID in state for later use in the sign-up form.
188+
setSelectedSiteId(markerInfo.siteID);
189+
console.log("Selected Site ID set to:", markerInfo.siteID);
190190
});
191191

192192
markersArray.push(marker);
@@ -203,12 +203,9 @@ const Map: React.FC<MapProps> = ({
203203

204204
return (
205205
<div>
206-
<MapDiv
207-
id="map"
208-
ref={mapRef}
209-
style={{ width: '100%', height: '675px' }}
210-
/>
211-
{showSignUp && <SignUpPage setShowSignUp={setShowSignUp} />}
206+
<MapDiv id="map" ref={mapRef} style={{ width: '100%', height: '675px' }} />
207+
{}
208+
{showSignUp && <SignUpPage setShowSignUp={setShowSignUp} siteID={selectedSiteId} />}
212209
</div>
213210
);
214211
};

apps/frontend/src/components/mapIcon/PopupBox.tsx

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default function PopupBox({
4444
svgFunction,
4545
}: Props) {
4646
const openSignUp = () => {
47+
// Triggers the sign-up form to open (the siteId was already set on marker click)
4748
setShowSignUp(true);
4849
};
4950

@@ -73,75 +74,45 @@ export default function PopupBox({
7374
>
7475
{type}
7576
</text>
76-
<div
77-
style={{ marginTop: '9%' }}
78-
dangerouslySetInnerHTML={{ __html: svgFunction('#ffffff') }}
79-
/>
77+
<div style={{ marginTop: '9%' }} dangerouslySetInnerHTML={{ __html: svgFunction('#ffffff') }} />
8078
</div>
8179

8280
<div style={popupStyles.details}>
83-
<div
84-
style={{
85-
display: 'flex',
86-
flexDirection: 'row',
87-
marginTop: '5%',
88-
gap: '5px',
89-
}}
90-
>
91-
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>
92-
NAME:
93-
</text>
94-
<text style={{ fontFamily: 'system-ui', whiteSpace: 'nowrap' }}>
95-
{name}
96-
</text>
81+
<div style={{ display: 'flex', flexDirection: 'row', marginTop: '5%', gap: '5px' }}>
82+
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>NAME:</text>
83+
<text style={{ fontFamily: 'system-ui', whiteSpace: 'nowrap' }}>{name}</text>
9784
</div>
98-
<div
99-
style={{
100-
display: 'flex',
101-
flexDirection: 'row',
102-
marginTop: '5%',
103-
gap: '5px',
104-
}}
105-
>
106-
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>
107-
LOCATION:
108-
</text>
85+
<div style={{ display: 'flex', flexDirection: 'row', marginTop: '5%', gap: '5px' }}>
86+
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>LOCATION:</text>
10987
<text>{location}</text>
11088
</div>
111-
<div
112-
style={{
113-
display: 'flex',
114-
flexDirection: 'row',
115-
marginTop: '5%',
116-
gap: '5px',
117-
}}
118-
>
119-
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>
120-
STATUS:
121-
</text>
89+
<div style={{ display: 'flex', flexDirection: 'row', marginTop: '5%', gap: '5px' }}>
90+
<text style={{ fontFamily: 'system-ui', fontWeight: '700' }}>STATUS:</text>
12291
<text>{status}</text>
12392
</div>
12493

125-
{(status === 'Available') && <button
126-
style={{
127-
display: 'flex',
128-
justifyContent: 'flex-start',
129-
marginTop: '7%',
130-
fontFamily: 'Lora',
131-
fontStyle: 'italic',
132-
fontSize: '15px',
133-
color: '#288BE4',
134-
backgroundColor: '#ffffff',
135-
border: '0',
136-
marginLeft: '0',
137-
paddingLeft: '0',
138-
borderLeft: '0',
139-
textDecoration: 'underline',
140-
}}
141-
onClick={openSignUp}
142-
>
143-
Interested in adopting →
144-
</button>}
94+
{status === 'Available' && (
95+
<button
96+
style={{
97+
display: 'flex',
98+
justifyContent: 'flex-start',
99+
marginTop: '7%',
100+
fontFamily: 'Lora',
101+
fontStyle: 'italic',
102+
fontSize: '15px',
103+
color: '#288BE4',
104+
backgroundColor: '#ffffff',
105+
border: '0',
106+
marginLeft: '0',
107+
paddingLeft: '0',
108+
borderLeft: '0',
109+
textDecoration: 'underline',
110+
}}
111+
onClick={openSignUp}
112+
>
113+
Interested in adopting →
114+
</button>
115+
)}
145116
</div>
146117
</div>
147118
);

apps/frontend/src/components/volunteer/signup/SignUpPage.tsx

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined';
1717
import { Formik, Form, Field } from 'formik';
1818
import * as Yup from 'yup';
1919

20+
21+
// CHANGED: Props now include the siteId.
22+
interface Props {
23+
setShowSignUp: (value: boolean) => void;
24+
siteID: string | null;
25+
}
26+
2027
interface InputField {
2128
label: string;
2229
width?: string;
@@ -390,6 +397,7 @@ function PersonalInfo({ onSubmit, setIsFormValid }: PersonalInfoProps) {
390397
);
391398
}}
392399
</Formik>
400+
393401
);
394402
}
395403

@@ -411,6 +419,7 @@ function TermsAndConditions({
411419
};
412420
return (
413421
<Box className="terms-and-conditions-box">
422+
414423
<VStack
415424
spacing={6}
416425
marginTop={'20px'}
@@ -419,6 +428,7 @@ function TermsAndConditions({
419428
paddingBottom="20px"
420429
>
421430
{termsAndConditionsCheckboxesMap.map((field, i) => (
431+
422432
<HStack key={i} width="100%" alignItems="center">
423433
<Text
424434
textDecoration="underline"
@@ -455,16 +465,14 @@ function TermsAndConditions({
455465
);
456466
}
457467

458-
export default function SignUpPage({
459-
setShowSignUp,
460-
}: {
461-
setShowSignUp: (show: boolean) => void;
462-
}) {
463-
const [isSubmitted, setIsSubmitted] = useState(false);
468+
469+
export default function SignUpPage({ setShowSignUp, siteID }: Props) {
470+
464471
const [isChecked, setIsChecked] = useState(
465472
new Array(termsAndConditionsCheckboxesMap.length).fill(false),
466473
);
467474
const [isFormValid, setIsFormValid] = useState(false); // Track form validity
475+
468476
const navigate = useNavigate();
469477
const [step, setStep] = useState(1);
470478

@@ -481,23 +489,28 @@ export default function SignUpPage({
481489
};
482490

483491
const handleSubmit = () => {
484-
if (isChecked.every(Boolean)) {
485-
setIsSubmitted(true);
486-
navigate('/success');
487-
}
488-
};
492+
if (isChecked.every(Boolean)) {
493+
console.log("Submitting application for siteID:", siteID);
494+
navigate('/success');
495+
}
496+
};
489497

490498
return (
491499
<Box
500+
501+
className="outermost-box"
492502
position="absolute"
493503
top="10%"
494-
left="15%"
504+
left="10%"
505+
495506
display="flex"
496507
alignItems="center"
497508
justifyContent="center"
498509
bg="#D9D9D9"
499-
width="70%"
500-
height="100%"
510+
511+
width="80%"
512+
height="140%"
513+
501514
zIndex="200"
502515
>
503516
<IconButton
@@ -511,6 +524,9 @@ export default function SignUpPage({
511524
<CloseIcon />
512525
</IconButton>
513526
<Box
527+
528+
className="inner-box"
529+
514530
bg="#FFFDFD"
515531
height="90%"
516532
width="90%"
@@ -521,20 +537,19 @@ export default function SignUpPage({
521537
paddingTop="30px"
522538
>
523539
<Box
540+
541+
className="header-box"
524542
height="5%"
525-
width="70%"
543+
width="90%"
544+
526545
borderBottom="2px solid #000000"
527546
display="flex"
528547
justifyContent="center"
529548
alignItems="center"
530549
>
531-
<Text
532-
fontFamily="Montserrat"
533-
fontSize="28px"
534-
fontWeight={700}
535-
paddingTop="20px"
536-
paddingBottom="30px"
537-
>
550+
551+
<Text fontFamily="Montserrat" fontSize="28px" fontWeight={700} paddingBottom="30px">
552+
538553
Welcome, Volunteer!
539554
</Text>
540555
</Box>
@@ -548,12 +563,10 @@ export default function SignUpPage({
548563
{step === 2 && <TermsAndConditions onCheckboxChange={setIsChecked} />}
549564
</Box>
550565

551-
<HStack
552-
width="100%"
553-
justifyContent="space-between"
554-
marginBottom="4%"
555-
paddingX="5%"
556-
>
566+
567+
{/* Navigation Buttons */}
568+
<HStack width="100%" justifyContent="space-between" marginBottom="7%" paddingX="5%">
569+
557570
{step > 1 ? (
558571
<Button
559572
onClick={handleBack}
@@ -566,7 +579,9 @@ export default function SignUpPage({
566579
Back
567580
</Button>
568581
) : (
569-
<Box width="45%" />
582+
583+
<Box width="150px" />
584+
570585
)}
571586
{step === 2 && (
572587
<Button

0 commit comments

Comments
 (0)