diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx index e67d9ee..9dab76d 100644 --- a/frontend/src/components/Navbar.jsx +++ b/frontend/src/components/Navbar.jsx @@ -2,6 +2,7 @@ import { useNavigate, useLocation } from 'react-router-dom'; import { motion } from 'framer-motion'; import './Navbar.css' import { GiFamilyHouse } from 'react-icons/gi'; +import Profile from './Profile'; const Navbar = () => { const navigate = useNavigate(); const location = useLocation(); @@ -55,6 +56,7 @@ const Navbar = () => { Compare Suburbs + ) } diff --git a/frontend/src/components/Profile.jsx b/frontend/src/components/Profile.jsx new file mode 100644 index 0000000..42aa8e0 --- /dev/null +++ b/frontend/src/components/Profile.jsx @@ -0,0 +1,92 @@ +import { useEffect, useState } from "react"; +import { FiDatabase } from "react-icons/fi"; +import BasicInput from "./Inputs"; + +const Profile = () => { + const [modal, setModal] = useState(false); + const [cusId, setCusId] = useState(''); + const [index, setIndex] = useState(0); + + const baseSelections = ['Default', 'Default (small)']; + const [selections, setSelections] = useState(baseSelections); + + const defaultIds = [ + "76d3b838-5880-4320-b42f-8bd8273ab6a0", + "34c762a2-e1cd-44a7-a9ea-56f22d64989e" + ]; + + useEffect(() => { + const savedId = localStorage.getItem('id'); + if (savedId && !defaultIds.includes(savedId)) { + setCusId(savedId); + setSelections([...baseSelections, 'Custom']); + setIndex(2); + } else if (savedId) { + const foundIndex = defaultIds.indexOf(savedId); + setIndex(foundIndex !== -1 ? foundIndex : 0); + } + }, []); + + const handleSelectChange = (e) => { + const newIndex = parseInt(e.target.value); + setIndex(newIndex); + + if (newIndex < 2) { + localStorage.setItem('id', defaultIds[newIndex]); + } else if (cusId) { + localStorage.setItem('id', cusId); + } + }; + + const handleCusIdChange = (e) => { + const value = e.target.value.trim(); + setCusId(value); + + if (value) { + localStorage.setItem('id', value); + if (!selections.includes('Custom')) { + setSelections([...baseSelections, 'Custom']); + setIndex(2); // auto-select custom + } + } else { + localStorage.removeItem('id'); + setSelections(baseSelections); + if (index === 2) setIndex(0); // Reset to Default + } + }; + + return ( +
+ setModal(!modal)} /> + {modal && ( +
+

Dataset

+ + + +
+ )} +
+ ); +}; + +export default Profile; diff --git a/frontend/src/pages/CommercialRecs.jsx b/frontend/src/pages/CommercialRecs.jsx index fea9dde..ade2fd4 100644 --- a/frontend/src/pages/CommercialRecs.jsx +++ b/frontend/src/pages/CommercialRecs.jsx @@ -17,13 +17,19 @@ import { } from "recharts"; const CommercialRecs = () => { - const [id, setId] = useState(null); const [topN, setTopN] = useState(10); const [loading, setLoading] = useState(false); const [recs, setRecs] = useState(null); const [isOpen, setIsOpen] = useState(false); + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchPrice = async () => { + const id = getId(); if (id == null) { alert("no id given"); return; @@ -66,13 +72,6 @@ const CommercialRecs = () => { ]} loading={loading} > - setId(e.target.value || null)} - /> - { - const [id, setId] = useState(null); const [topN, setTopN] = useState(10); const [loading, setLoading] = useState(false); const [recs, setRecs] = useState(null); const [isOpen, setIsOpen] = useState(false); + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; + const fetchPrice = async () => { + const id = getId(); if (id == null) { alert("no id given"); return; @@ -69,12 +76,6 @@ const CommercialRecommendationsTargeted = () => { ]} loading={loading} > - setId(e.target.value || null)} - /> { - const [id, setId] = useState(null); const [suburbInput, setSuburbInput] = useState(""); const [suburbs, setSuburbs] = useState([]); const [loading, setLoading] = useState(false); @@ -24,7 +23,15 @@ const CrimeWeight = () => { setSuburbs(suburbs.filter((s) => s !== sub)); }; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; + const fetchData = async () => { + const id = getId(); if (!id) { alert("Please enter an ID"); return; @@ -77,14 +84,6 @@ const CrimeWeight = () => { description="Check the weighted crime rate per 10,000 population by suburbs. Crimes are weighted by their severity." loading={loading} > - setId(e.target.value)} - /> -
{ const [loading, setLoading] = useState(false); const [factor, setFactor] = useState(null); - const [id, setId] = useState(null); const [targetCol, setTargetCol] = useState(null); const [filterCol, setFilterCol] = useState(null); const [filterVal, setFilterVal] = useState(null); const [dropCol, setDropCol] = useState(null); + + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id === null) { alert("missing id"); return; @@ -51,18 +58,6 @@ const InfluenceFactor = () => { description="Provides a ranked list of real estate features effecting the target variable (from most impactful to least impactful)" loading={loading} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [loading, setLoading] = useState(false); const [investPotential, setInvestPotential] = useState(null); - const [id, setId] = useState(null); const [topN, setTopN] = useState(null); + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; + + return storedId; + }; const fetchData = async () => { + const id = getId(); if (id == null) { alert("missing id"); return; @@ -63,18 +69,6 @@ const InvestmentPotential = () => { ]} loading={loading} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [income, setIncome] = useState("32292"); const [affordabilityData, setAffordabilityData] = useState(null); const [mapHtml, setMapHtml] = useState(null); - const [id, setId] = useState(null); const [minIndex, setMinIndex] = useState(0); const [sortConfig, setSortConfig] = useState({ key: "norm_affordability_index", @@ -46,7 +45,14 @@ const PropertyAffordabilityIndex = () => { }, 10000); }; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -110,18 +116,6 @@ const PropertyAffordabilityIndex = () => { } loading={loading} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [loading, setLoading] = useState(false); const [loaded, setLoaded] = useState(false); const [price, setPrice] = useState(""); - const [id, setId] = useState(null); const [minPrice, setMinPrice] = useState(null); const [maxPrice, setMaxPrice] = useState(null); @@ -22,7 +21,15 @@ const PropertyPrices = () => { const [maxSize, setMaxSize] = useState(null); const [type, setType] = useState(null); + + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchPrice = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -85,18 +92,6 @@ const PropertyPrices = () => { description="Explore average property prices with optional filters like suburb, size and features. " loading={loading} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - />

Price range:

{ const [density, setDensity] = useState(0.1); const [crimeRiskWeight, setCrimeRiskWeight] = useState(0.1); const [weatherRiskWeight, setWeatherRiskWeight] = useState(0.1); - const [id, setId] = useState(null); const [livabilityData, setLivabilityData] = useState(null); const [mapHtml, setMapHtml] = useState(null); const [minIndex, setMinIndex] = useState(0); @@ -47,7 +46,15 @@ const SuburbLivability = () => { }, 15000); }; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; + const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -123,18 +130,6 @@ const SuburbLivability = () => { description="Discover the best suburbs to live in based on livability score given weightings of proximity to CBD, property size, population density, crime risk and weather risk" loading={loading} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [loading, setLoading] = useState(false); const [ret, setRet] = useState(null); - const [id, setId] = useState(null); + + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -44,22 +51,10 @@ const SuburbPriceMap = () => { > {!ret ? ( <> - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> {loading ? ( ) : ( - + )} ) : ( diff --git a/frontend/src/pages/TopSchoolArea.jsx b/frontend/src/pages/TopSchoolArea.jsx index 7035761..6aa6edd 100644 --- a/frontend/src/pages/TopSchoolArea.jsx +++ b/frontend/src/pages/TopSchoolArea.jsx @@ -14,7 +14,6 @@ const TopSchoolArea = () => { const [schoolTypeIndex, setSchoolTypeIndex] = useState(0); const [districtIndex, setDistrictIndex] = useState(0); const [radius, setRadius] = useState(10); - const [id, setId] = useState(null); const [sortConfig, setSortConfig] = useState({ key: "avg_property_price", direction: "desc" }); const schoolTypes = ["Secondary School", "Primary School", "Infants School"]; @@ -28,7 +27,14 @@ const TopSchoolArea = () => { "Nepean Blue Mountains", ]; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; + + return storedId; + }; const fetchData = async () => { + const id = getId(); if (!id) { alert("Please enter a valid ID."); return; @@ -60,7 +66,6 @@ const TopSchoolArea = () => { }; const handleSort = (key) => { - console.log(key); setSortConfig((prev) => prev.key === key ? { key, direction: prev.direction === "asc" ? "desc" : "asc" } @@ -90,14 +95,6 @@ const TopSchoolArea = () => { description="Check top schools accessibility and property prices in educational hotspots for your family." loading={loading} > - {/* ID Input */} - setId(e.target.value || null)} - /> - {/* School Level Dropdown */} { const [income, setIncome] = useState("32292"); const [affordabilityData, setAffordabilityData] = useState(null); const [mapHtml, setMapHtml] = useState(null); - const [id, setId] = useState(null); const [minIndex, setMinIndex] = useState(0); const pollForResult = () => { @@ -39,8 +38,15 @@ const DemoPropertyAfford = () => { } }, 10000); }; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -78,18 +84,6 @@ const DemoPropertyAfford = () => { title="Property Affordability Index" description={"How affordable each suburb is based on given income"} > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [density, setDensity] = useState(0.1); const [crimeRiskWeight, setCrimeRiskWeight] = useState(0.1); const [weatherRiskWeight, setWeatherRiskWeight] = useState(0.1); - const [id, setId] = useState(null); const [livabilityData, setLivabilityData] = useState(null); const [mapHtml, setMapHtml] = useState(null); const [minIndex, setMinIndex] = useState(0); @@ -64,7 +63,15 @@ const DemoSuburbLivability = () => { // }, 3000); // }; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; + const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -113,18 +120,6 @@ const DemoSuburbLivability = () => { title="Suburb Livability Score" description="Calculates livability score given weightings of proximity to CBD, property size, population density, crime risk and weather risk" > - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> { const [loading, setLoading] = useState(false); const [ret, setRet] = useState(null); - const [id, setId] = useState(null); + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -44,19 +50,7 @@ const DemoSuburbPriceMap = () => { {loading &&

Loading...

} {!ret ? ( <> - { - if (e.target.value !== "") { - setId(e.target.value); - } else { - setId(null); - } - }} - /> - + ) : (
{ const [option, setOption] = useState(0); const [option1, setOption1] = useState(0); const [radius, setRadius] = useState(10); - const [id, setId] = useState(null); const districts = [ "Central Coast", @@ -25,7 +24,14 @@ const DemoTopSchoolArea = () => { const schoolTypes = ["Secondary School", "Primary School", "Infants School"]; + const getId = () => { + const storedId = localStorage.getItem('id'); + if (!storedId) return "76d3b838-5880-4320-b42f-8bd8273ab6a0"; // fallback to 'Default' + + return storedId; + }; const fetchData = async () => { + const id = getId() if (id == null) { alert("missing id"); return; @@ -65,14 +71,6 @@ const DemoTopSchoolArea = () => { title="Schools Nearby" description="Find out how many properties are near a school and what the average property price is." > -

Id:

- setId(e.target.value || null)} - /> -