diff --git a/frontend/src/assets/data/staticText.json b/frontend/src/assets/data/staticText.json index 0ea6551..cd2c0ec 100644 --- a/frontend/src/assets/data/staticText.json +++ b/frontend/src/assets/data/staticText.json @@ -6,11 +6,7 @@ }, "location": { "title": "Right Plant Right Place Right Time\nPlant Selector Tool for New Zealand.", - "description": "Your native plant selection starts here! Use the map to select a planting site location within New Zealand. On the following pages you will provide more details on your project until the system has enough information to create your plant species list and planting plan. To start, click on the map and pan and zoom to the site location. Once the location is selected, click on the “next step” button to complete the process. Repeat this process for sites at different locations." - }, - "address": { - "title": "Address", - "description": "Thank you for purchasing an activation key. Please start entering your address and select an option from the suggestions provided. On the following pages, you will provide more details on your project until the system has enough information to create your plant species list and planting plan. Once the location is selected, click on the “next step” button to complete the process." + "description": "Your native plant selection starts here! Use the map or enter an address to select a planting site location within New Zealand. On the following pages you will provide more details on your project until the system has enough information to create your plant species list and planting plan. To start, click on the map and pan and zoom to the site location. Once the location is selected, click on the “next step” button to complete the process. Repeat this process for sites at different locations." }, "soil": { "title": "Soil Variant Selection", @@ -39,10 +35,6 @@ "results": { "title": "Plant List Results", "forestDiagramDescription": "Forest Position Information Diagram" - }, - "complete": { - "title": "Application Complete", - "description": "You have completed your application and submitted your results. You may now return to the homepage or fill out another application for a different habitat or zone." } } } diff --git a/frontend/src/components/providers/ActivationProvider.jsx b/frontend/src/components/providers/ActivationProvider.jsx new file mode 100644 index 0000000..4020c7c --- /dev/null +++ b/frontend/src/components/providers/ActivationProvider.jsx @@ -0,0 +1,68 @@ +import { createContext, useState, useContext } from 'react'; +import Repository from '../../repository/Repository'; +import { useError } from './ErrorProvider'; + +const ActivationContext = createContext(null); + +const ActivationProvider = ({children}) => { + const [key, setKey] = useState(""); + const [isPhysicalKey, setIsPhysicalKey] = useState(false); + const { setError, resetError } = useError(); + + const validateKey = (value) => new Promise(resolve => { + + const data = {key: value}; + + setKey(value); + + Repository.post("/key/validate/", data).then(resp => { + if (resp.data) { + setIsPhysicalKey(resp.data?.type === "Stripe - physical"); + resetError(); + try { + const coordinates = resp.data.location.match(/(-?\d+\.\d+)\s(-?\d+\.\d+)/); + resolve({ + coordinates: { + lng: parseFloat(coordinates[1]), + lat: parseFloat(coordinates[2]), + }, + soilVariant: resp.data.soil_variant[0], + zone: {id: resp.data.zone}, + ...data, + }); + } catch { + resolve({...data, ...resp.data}); + } + } else { + resolve(null); + } + }).catch(e => { + switch (e.response.status) { + case 400: + case 404: + setError("Invalid or expired activation key. Please try again."); + break; + default: + setError("Something went wrong. Please try again."); + break; + } + resolve(null); + }); + }); + + const value = { + key, + isDigitalKey: !isPhysicalKey, + isPhysicalKey, + validateKey, + }; + + return {children}; +}; + +const useActivator = () => useContext(ActivationContext); + +export { + ActivationProvider, + useActivator, +}; diff --git a/frontend/src/components/providers/ErrorProvider.jsx b/frontend/src/components/providers/ErrorProvider.jsx new file mode 100644 index 0000000..9fbf123 --- /dev/null +++ b/frontend/src/components/providers/ErrorProvider.jsx @@ -0,0 +1,24 @@ +import { createContext, useState, useContext } from 'react'; + +const ErrorContext = createContext(null); + +const ErrorProvider = ({children}) => { + const [error, setError] = useState(""); + + const resetError = () => setError(""); + + const value = { + error, + setError, + resetError, + }; + + return {children}; +}; + +const useError = () => useContext(ErrorContext); + +export { + ErrorProvider, + useError, +}; diff --git a/frontend/src/components/providers/StepperProvider.jsx b/frontend/src/components/providers/StepperProvider.jsx index c22608d..b64251a 100644 --- a/frontend/src/components/providers/StepperProvider.jsx +++ b/frontend/src/components/providers/StepperProvider.jsx @@ -15,12 +15,14 @@ const StepperWizard = ({children}) => { const isStep = n => (0 <= n && n < children.length); const setStepNext = () => setStep(n => isStep(n + 1) ? n + 1 : n); const setStepBack = () => setStep(n => isStep(n - 1) ? n - 1 : n); + const setStepLast = () => setStep(children.length - 1); const value = { step, setStep, setStepNext, setStepBack, + setStepLast, isStep, }; diff --git a/frontend/src/components/steps/activation/ActivationStep.jsx b/frontend/src/components/steps/activation/ActivationStep.jsx index 1bbee8d..ef0c60f 100644 --- a/frontend/src/components/steps/activation/ActivationStep.jsx +++ b/frontend/src/components/steps/activation/ActivationStep.jsx @@ -4,39 +4,36 @@ import StepInformation from '../StepInformation'; import staticText from '../../../assets/data/staticText.json' import keyBackgroundImage from '../../../assets/img/stepBackgrounds/step6.jpg'; import { StepperFooter, useStepper } from '../../providers/StepperProvider'; +import { useActivator } from '../../providers/ActivationProvider'; import { useFilter } from '../../providers/FilterProvider'; import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; -import Repository from '../../../repository/Repository'; +import PurchaseButton from './PurchaseButton'; const ActivationStep = () => { const MAX_LENGTH = 20; const [value, setValue] = useState(new URLSearchParams(window.location.search).get("key") || ""); const [nextDisabled, setNextDisabled] = useState(value.length < MAX_LENGTH); - const [error, setError] = useState(""); - const { updateFilters } = useFilter(); - const { setStepNext } = useStepper(); + const { setFilters, updateFilters } = useFilter(); + const { setStepNext, setStepLast } = useStepper(); + const { validateKey } = useActivator(); const onChange = e => { const newValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, MAX_LENGTH); setNextDisabled(newValue.length !== MAX_LENGTH); setValue(newValue); - setError(""); }; - const onNext = () => { - const data = { key: value }; - Repository.post("/key/validate/", data).then(resp => { + const onNext = async () => { + const data = await validateKey(value); + + if (data?.coordinates) { + setFilters(data); + setStepLast(); + } else if (data) { updateFilters(data); setStepNext(); - }).catch(e => { - setError( - e.response.status === 404 - ? "Invalid or expired activation key. Please try again." - : "Something went wrong. Please try again." - ); - }); + } }; const keyPanel = ( @@ -51,14 +48,12 @@ const ActivationStep = () => { variant="outlined" placeholder="Enter activation key..." autoComplete="off" - error={error.length > 0} - helperText={error} onChange={onChange} value={value} /> - + diff --git a/frontend/src/components/steps/activation/PurchaseButton.jsx b/frontend/src/components/steps/activation/PurchaseButton.jsx new file mode 100644 index 0000000..ceab5ce --- /dev/null +++ b/frontend/src/components/steps/activation/PurchaseButton.jsx @@ -0,0 +1,44 @@ +import { useState } from 'react'; +import Button from '@mui/material/Button'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; + +const PurchaseButton = () => { + const [anchor, setAnchor] = useState(null); + const isOpen = Boolean(anchor); + + const toggleMenu = (e) => { + setAnchor(isOpen ? null : e.currentTarget); + }; + + const onSelect = (href) => { + setAnchor(null); + window.location = href; + }; + + return ( + <> + + toggleMenu(null)} + MenuListProps={{"aria-labelledby": "purchase-button"}} + > + onSelect("/api/key/purchase")}>Purchase digital copy + onSelect("/api/key/purchase?physical=true")}>Purchase physical copy + + + ); +}; + +export default PurchaseButton; diff --git a/frontend/src/components/steps/address/AddressStep.jsx b/frontend/src/components/steps/address/AddressStep.jsx deleted file mode 100644 index 47abb6b..0000000 --- a/frontend/src/components/steps/address/AddressStep.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useState } from 'react'; -import Step from '../Step'; -import StepInformation from '../StepInformation'; -import staticText from '../../../assets/data/staticText.json' -import addressBackgroundImage from '../../../assets/img/stepBackgrounds/step1.jpg'; -import AddressSearch from './AddressSearch'; -import { StepperFooter } from '../../providers/StepperProvider'; -import { useFilter } from '../../providers/FilterProvider'; - - -const AddressStep = () => { - const [nextDisabled, setNextDisabled] = useState(true); - const { updateFilters } = useFilter(); - - const addressPanel = ( -
- {staticText.steps.address.description}

} - /> -
- { - if (address) { - setNextDisabled(false); - updateFilters({ - coordinates: { - lat: address.coordinates[1], - lng: address.coordinates[0], - }, - }); - } else { - setNextDisabled(true); - } - }}/> -
-
- ); - - return ( - <> - - - ); -}; - -export default AddressStep; diff --git a/frontend/src/components/steps/complete/CompleteStep.jsx b/frontend/src/components/steps/complete/CompleteStep.jsx deleted file mode 100644 index 59ac5eb..0000000 --- a/frontend/src/components/steps/complete/CompleteStep.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import Step from "../Step"; -import StepInformation from "../StepInformation"; -import completeBackgroundImage from "../../../assets/img/stepBackgrounds/step6.jpg"; -import staticText from "../../../assets/data/staticText.json"; -import { StepperFooter } from "../../providers/StepperProvider"; - -export default function CompleteStep() { - const completeInfoPanel = ( - {staticText.steps.complete.description}

} - /> - ); - - return ( - <> - - - - ); -}; diff --git a/frontend/src/components/steps/address/AddressSearch.jsx b/frontend/src/components/steps/location/AddressSearch.jsx similarity index 95% rename from frontend/src/components/steps/address/AddressSearch.jsx rename to frontend/src/components/steps/location/AddressSearch.jsx index 688b5dd..145ad1d 100644 --- a/frontend/src/components/steps/address/AddressSearch.jsx +++ b/frontend/src/components/steps/location/AddressSearch.jsx @@ -25,7 +25,7 @@ const AddressSearchSuggestions = ({results, onClick}) => (
: null); -const AddressSearch = ({onSelect, classNames}) => { +const AddressSearch = ({onSelect}) => { const [value, setValue] = useState(""); const [enable, setEnable] = useState(true); const [selected, setSelected] = useState(null); @@ -53,7 +53,7 @@ const AddressSearch = ({onSelect, classNames}) => { }, [selected, onSelect]); return ( -
+ { } }} value={value} + sx={{top: 0}} /> { setSelected(r); }} /> -
); + ); }; export default AddressSearch; diff --git a/frontend/src/components/steps/location/LocationStep.jsx b/frontend/src/components/steps/location/LocationStep.jsx index b5dcd13..5cde6e3 100644 --- a/frontend/src/components/steps/location/LocationStep.jsx +++ b/frontend/src/components/steps/location/LocationStep.jsx @@ -1,31 +1,57 @@ import { useState } from "react"; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; import Step from "../Step"; import LocationSelectorMap from "./Map"; import StepInformation from "../StepInformation"; import staticText from "../../../assets/data/staticText.json"; import locationBackgroundImage from "../../../assets/img/stepBackgrounds/step1.jpg"; import { StepperFooter } from '../../providers/StepperProvider'; +import AddressSearch from "./AddressSearch"; +import { useFilter } from '../../providers/FilterProvider'; -export default function LocationStep(props) { +export default function LocationStep({defaultIsSearch = false}) { const [nextDisabled, setNextDisabled] = useState(true); + const [showSearch, setShowSearch] = useState(defaultIsSearch); + const { updateFilters } = useFilter(); const locationInfoPanel = ( - {staticText.steps.location.description}

} - /> +
+ {staticText.steps.location.description}

} + /> + + + + +
); - const locationSelectionPanel = ; + const selectionComponent = showSearch + ? { + if (address) { + setNextDisabled(false); + updateFilters({ + coordinates: { + lat: address.coordinates[1], + lng: address.coordinates[0], + }, + }); + } else { + setNextDisabled(true); + } + }}/> + : ; return ( <> ); -} +}; diff --git a/frontend/src/components/steps/results/PlantList.jsx b/frontend/src/components/steps/results/PlantList.jsx index 217428b..84675d8 100644 --- a/frontend/src/components/steps/results/PlantList.jsx +++ b/frontend/src/components/steps/results/PlantList.jsx @@ -23,9 +23,8 @@ import staticText from "../../../assets/data/staticText.json"; import forestGraphic from "../../../assets/img/habitats/1a_Forest_Section.png"; import { CircularProgress } from "@mui/material"; -function TablePaginationActions(props) { +function TablePaginationActions({ count, page, rowsPerPage, onPageChange }) { const theme = useTheme(); - const { count, page, rowsPerPage, onPageChange } = props; const handleFirstPageButtonClick = (event) => { onPageChange(event, 0); @@ -95,18 +94,21 @@ TablePaginationActions.propTypes = { export default function PlantResultsTable(props) { const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(25); + const isLoading = props?.rows === null; let rows = []; - if (props.rows) { + if (!isLoading) { rows = rowsPerPage > 0 ? props.rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : props.rows; } + const totalRows = props?.rows?.length ?? 0; + // Avoid a layout jump when reaching the last page with empty rows. const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - props.rows.length) : 0; + page > 0 ? Math.max(0, (1 + page) * rowsPerPage - totalRows) : 0; const handleChangePage = (event, newPage) => { setPage(newPage); @@ -157,30 +159,28 @@ export default function PlantResultsTable(props) { - {rows.length === 0 && ( - - - - - - - - )} - {rows.length > 0 && - rows.map((row) => ( - - - {row.name} + {isLoading + ? + + + + - {row.growthForm} - {row.moisturePreferences} - {row.plantTolerances} - {row.ecosystemServices} - {row.carbonSequestration} - {row.plantingStage} - ))} - + : rows.map((row) => ( + + + {row.name} + + {row.growthForm} + {row.moisturePreferences} + {row.plantTolerances} + {row.ecosystemServices} + {row.carbonSequestration} + {row.plantingStage} + + )) + } {emptyRows > 0 && ( @@ -193,7 +193,7 @@ export default function PlantResultsTable(props) { className="plant-list-pagination" rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]} colSpan={7} - count={props.rows.length} + count={totalRows} rowsPerPage={rowsPerPage} page={page} SelectProps={{ diff --git a/frontend/src/components/steps/results/ResultsStep.jsx b/frontend/src/components/steps/results/ResultsStep.jsx index 578b416..f98eedb 100644 --- a/frontend/src/components/steps/results/ResultsStep.jsx +++ b/frontend/src/components/steps/results/ResultsStep.jsx @@ -5,10 +5,10 @@ import PlantList from "./PlantList"; import Stack from "@mui/material/Stack"; import Button from "@mui/material/Button"; import PlantRepository from "../../../repository/PlantRepository"; -import { Typography, Box } from "@mui/material"; +import { Typography, Box, Modal } from "@mui/material"; import resultsBackgroundImage from "../../../assets/img/stepBackgrounds/step6.jpg"; import staticText from "../../../assets/data/staticText.json"; -import { useFilter } from "../../providers/FilterProvider"; +import { useActivator } from "../../providers/ActivationProvider"; import { StepperFooter } from "../../providers/StepperProvider"; const RESULTS_DESCRIPTION = ( @@ -30,56 +30,32 @@ const RESULTS_DESCRIPTION = ( ); export default function ResultsStep(props) { - const [plants, setPlants] = useState([]); - const { filters } = useFilter(); + const [plants, setPlants] = useState(null); + const [showModal, setShowModal] = useState(true); + const { key } = useActivator(); + + const closeModal = () => setShowModal(false); useEffect(() => { - const updatePlants = () => { - PlantRepository.getFilteredPlants(filters) - .then((response) => { - if (response.status === 200) { - setPlants(response.data); - } - }) - .catch((e) => { - this.setState({ plants: ["No plants found."] }); - }); - }; - updatePlants(); - }, [filters]); - - function createData( - name, - growthForm, - moisturePreferences, - plantTolerances, - ecosystemServices, - carbonSequestration, - plantingStage - ) { - return { - name, - growthForm, - moisturePreferences, - plantTolerances, - ecosystemServices, - carbonSequestration, - plantingStage, - }; - } + PlantRepository.getFilteredPlants(key) + .then((response) => { + setPlants(response.status === 200 ? response.data : []); + }).catch(e => { + setPlants([]); + }); + }, [key]); const getTableRows = () => { - return plants.map((plant) => { - return createData( - plant.display_name, - plant.display_growth_form, - plant.moisture_preferences, - plant.plant_tolerances, - plant.ecosystem_services, - plant.carbon_sequestration, - plant.stage - ); - }); + // null if unloaded, empty if loaded but no results + return plants?.map((plant) => ({ + name: plant.display_name, + growthForm: plant.display_growth_form, + moisturePreferences: plant.moisture_preferences, + plantTolerances: plant.plant_tolerances, + ecosystemServices: plant.ecosystem_services, + carbonSequestration: plant.carbon_sequestration, + stage: plant.stage, + })) ?? null; }; const download = (response, fileType, fileName) => { @@ -94,13 +70,13 @@ export default function ResultsStep(props) { }; const downloadCSV = () => { - PlantRepository.getPlantsCSV(filters).then((response) => { + PlantRepository.getPlantsCSV(key).then((response) => { download(response, "text/csv", "plants.csv"); }); }; const downloadPDF = () => { - PlantRepository.getPlantsPDF(filters).then((response) => { + PlantRepository.getPlantsPDF(key).then((response) => { download(response, "application/pdf", "planting_guide.pdf"); }); }; @@ -142,6 +118,28 @@ export default function ResultsStep(props) { backgroundImage={resultsBackgroundImage} /> + + + Questionnaire Complete + You have completed the questionnaire for your chosen habitat. If you have purchased a physical copy of the planting guide, it should arrive at your chosen delivery address in a number of business days. + You may now dismiss this popup to view a table of results. You are able to access this page at any time in future by supplying the activation key used at the start of this questionnaire. + + + + + + ); } diff --git a/frontend/src/components/steps/summary/SummaryContent.jsx b/frontend/src/components/steps/summary/SummaryContent.jsx index 0ebf0f2..fa4bb0a 100644 --- a/frontend/src/components/steps/summary/SummaryContent.jsx +++ b/frontend/src/components/steps/summary/SummaryContent.jsx @@ -29,45 +29,53 @@ export default function SummaryContent() { !Object.keys(locationDetails).length && getLocationDetails(); }); - function createData(name, value) { - return { name, value }; - } - const locationData = [ - createData( - "Geographical Coordinates (latitude, longitude)", - `(${filters.coordinates.lat}, ${filters.coordinates.lng})` - ), - createData("Ecological Region", locationDetails.ecological_region || ""), - createData( - "Ecological District", - locationDetails.ecological_district || "" - ), - createData("Property Name", locationDetails.full_address || ""), + { + name: "Geographical Coordinates (latitude, longitude)", + value: `(${filters.coordinates.lat}, ${filters.coordinates.lng})`, + }, + { + name: "Ecological Region", + value: locationDetails.ecological_region || "", + }, + { + name: "Ecological District", + value: locationDetails.ecological_district || "", + }, + { + name: "Property Name", + value: locationDetails.full_address || "", + }, ]; const soilData = [ - createData( - "Soil Order", - `${locationDetails.soil_name} (${locationDetails.soil_code})` || "" - ), - createData("Soil Variant", filters.soilVariant), + { + name: "Soil Order", + value: `${locationDetails.soil_name} (${locationDetails.soil_code})` || "", + }, + { + name: "Soil Variant", + value: filters.soilVariant, + }, ]; const siteData = [ - createData("Habitat", filters.habitat.name ?? ""), - createData( - "Zone Name", - (filters.zone && filters.zone.name) ?? "" - ), - createData( - "Zone Variant", - (filters.zone && filters.zone.variant) ?? "" - ), - createData( - "Zone Refined Variant", - (filters.zone && filters.zone.refined_variant) ?? "" - ), + { + name: "Habitat", + value: filters.habitat.name ?? "", + }, + { + name: "Zone Name", + value: (filters.zone && filters.zone.name) ?? "", + }, + { + name: "Zone Variant", + value: (filters.zone && filters.zone.variant) ?? "", + }, + { + name: "Zone Refined Variant", + value: (filters.zone && filters.zone.refined_variant) ?? "", + }, ]; const regionInformation = () => { diff --git a/frontend/src/index.js b/frontend/src/index.js index ffff73c..98a31b9 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -9,17 +9,14 @@ import { FilterProvider } from "./components/providers/FilterProvider"; // Styles import "./assets/styles/main.scss"; import "bootstrap/dist/css/bootstrap.min.css"; -import ApplyPage from "./pages/ApplyPage"; +import { ActivationProvider } from "./components/providers/ActivationProvider"; +import { ErrorProvider } from "./components/providers/ErrorProvider"; const router = createBrowserRouter([ { path: "/", element: , }, - { - path: "/apply", - element: , - }, ]); const darkTheme = createTheme({ @@ -34,11 +31,15 @@ const darkTheme = createTheme({ ReactDOM.render(
- - - - - + + + + + + + + +
, document.getElementById("root") diff --git a/frontend/src/pages/ApplyPage.jsx b/frontend/src/pages/ApplyPage.jsx deleted file mode 100644 index c41020e..0000000 --- a/frontend/src/pages/ApplyPage.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useState } from 'react'; -import { Container } from "reactstrap"; -import Header from "../components/Header"; -import ActivationStep from "../components/steps/activation/ActivationStep"; -import AddressStep from "../components/steps/address/AddressStep"; -import SoilStep from "../components/steps/soilvariant/SoilStep"; -import HabitatStep from "../components/steps/habitat/HabitatStep"; -import ZoneStep from "../components/steps/zone/ZoneStep"; -import SummaryStep from "../components/steps/summary/SummaryStep"; -import CompleteStep from "../components/steps/complete/CompleteStep"; -import { StepperWizard } from "../components/providers/StepperProvider"; -import { useFilter } from "../components/providers/FilterProvider"; -import { Box, Typography, Modal, Button } from '@mui/material'; - - -const ApplyPage = () => { - const [error, setError] = useState(""); - const { submit } = useFilter(); - - const onSubmit = async () => { - try { - await submit(); - } catch (e) { - setError("There was a problem sending data to the API. Please try again."); - throw e; - } - } - - return ( - <> - -
- - - - - - - - - - - 0} onClose={() => setError("")}> - - Error - {error} - - - - - - - ); -}; - -export default ApplyPage; diff --git a/frontend/src/pages/MainPage.jsx b/frontend/src/pages/MainPage.jsx index f56f66e..a816664 100644 --- a/frontend/src/pages/MainPage.jsx +++ b/frontend/src/pages/MainPage.jsx @@ -1,5 +1,7 @@ +import { useState } from 'react'; import { Container } from "reactstrap"; import Header from "../components/Header"; +import ActivationStep from "../components/steps/activation/ActivationStep"; import LocationStep from "../components/steps/location/LocationStep"; import SoilStep from "../components/steps/soilvariant/SoilStep"; import HabitatStep from "../components/steps/habitat/HabitatStep"; @@ -7,20 +9,52 @@ import ZoneStep from "../components/steps/zone/ZoneStep"; import SummaryStep from "../components/steps/summary/SummaryStep"; import ResultsStep from "../components/steps/results/ResultsStep"; import { StepperWizard } from "../components/providers/StepperProvider"; +import { useFilter } from "../components/providers/FilterProvider"; +import { Box, Typography, Modal, Button } from '@mui/material'; +import { useActivator } from '../components/providers/ActivationProvider'; +import { useError } from '../components/providers/ErrorProvider'; const MainPage = () => { + const { isPhysicalKey } = useActivator(); + const { submit } = useFilter(); + const { error, resetError } = useError(); + return ( - -
- - - - - - - - - ); + <> + +
+ + + + + + + + + + + 0} onClose={resetError}> + + Error + {error} + + + + + + + ); }; export default MainPage; diff --git a/frontend/src/repository/LocationRepository.js b/frontend/src/repository/LocationRepository.js index bfcdb48..9cd53e8 100644 --- a/frontend/src/repository/LocationRepository.js +++ b/frontend/src/repository/LocationRepository.js @@ -1,33 +1,34 @@ import API from "./Repository"; const LocationRepsostory = { - getSoilDetails(filters) { - return API.get(`/soil/`, { params: filters }); + getSoilDetails(params) { + return API.get(`/soil/`, {params}); }, - getEcologicalDistrictDetails(filters) { - return API.get(`/ecologicaldistrict/`, { params: filters }); + getEcologicalDistrictDetails(params) { + return API.get(`/ecologicaldistrict/`, {params}); }, - getRegionDetails(filters) { - return API.get(`/region/`, { params: filters }); + getRegionDetails(params) { + return API.get(`/region/`, {params}); }, - getPropertyDetails(filters) { - return API.get(`/address/`, { params: filters }); + getPropertyDetails(params) { + return API.get(`/address/`, {params}); }, async getLocationData(filters) { + const params = { lat: filters.coordinates.lat, lng: filters.coordinates.lng }; const [ soilDetails, ecologicalDistrictDetails, propertyDetails, regionDetails, ] = await Promise.all([ - this.getSoilDetails(filters), - this.getEcologicalDistrictDetails(filters), - this.getPropertyDetails(filters), - this.getRegionDetails(filters), + this.getSoilDetails(params), + this.getEcologicalDistrictDetails(params), + this.getPropertyDetails(params), + this.getRegionDetails(params), ]); let locationData = {}; diff --git a/frontend/src/repository/PlantRepository.js b/frontend/src/repository/PlantRepository.js index 59589e4..6e39527 100644 --- a/frontend/src/repository/PlantRepository.js +++ b/frontend/src/repository/PlantRepository.js @@ -1,17 +1,17 @@ import Repository from "./Repository"; const PlantRepository = { - getFilteredPlants(filters) { - return Repository.get(`/plants/`, { params: filters }); + getFilteredPlants(key) { + return Repository.get(`/plants/`, { params: {key} }); }, - getPlantsCSV(filters) { - return Repository.get("/download/csv/", { params: filters }); + getPlantsCSV(key) { + return Repository.get("/download/csv/", { params: {key} }); }, - getPlantsPDF(filters) { + getPlantsPDF(key) { return Repository.get("/download/pdf/", { - params: filters, + params: {key}, responseType: "arraybuffer", }); },