From 9a9ca454ab41cea2c13c73bfdc6574c2052380f7 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 11:30:59 +0200 Subject: [PATCH 01/12] create ExplorePage.tsx and .css files --- .../src/pages/explorePage/ExplorePage.css | 0 .../src/pages/explorePage/ExplorePage.tsx | 76 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 frontend/src/pages/explorePage/ExplorePage.css create mode 100644 frontend/src/pages/explorePage/ExplorePage.tsx diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx new file mode 100644 index 00000000..e0593fbc --- /dev/null +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -0,0 +1,76 @@ +import { useTranslation } from "react-i18next" +import "./ExplorePage.css" + +const plants = [ + { id: 1, name: "Hydrangea", watering: "Average", sunlight: "Part shade" }, + { id: 2, name: "Orchid", watering: "Minimum", sunlight: "Part sun" }, + { id: 3, name: "Fig Tree", watering: "Average", sunlight: "Full sun" }, + { id: 4, name: "Monstera", watering: "Average", sunlight: "Part shade" }, + { id: 5, name: "Peony", watering: "Frequent", sunlight: "Full sun" }, + { id: 6, name: "Lily", watering: "Average", sunlight: "Part sun" }, + { id: 7, name: "Rose", watering: "Frequent", sunlight: "Full sun" }, + { id: 8, name: "Tulip", watering: "Minimum", sunlight: "Full sun" }, + { id: 9, name: "Daisy", watering: "Average", sunlight: "Full sun" }, + { id: 10, name: "Sunflower", watering: "Average", sunlight: "Full sun" }, + { id: 11, name: "Lavender", watering: "Minimum", sunlight: "Full sun" }, + { id: 12, name: "Jasmine", watering: "Average", sunlight: "Part sun" }, + { id: 13, name: "Marigold", watering: "Average", sunlight: "Full sun" }, + { id: 14, name: "Daffodil", watering: "Average", sunlight: "Part sun" }, + { id: 15, name: "Carnation", watering: "Average", sunlight: "Full sun" }, +] + +export default function ExplorePage() { + const { t } = useTranslation() + + return ( +
+ {/* Søk og filtre */} +
+ + +
+ {t("explore.filters", "Filters")} + + + + +
+
+ + {/* Plantekort */} + +
+ ) +} \ No newline at end of file From 2a3e8dce91e838f62a97cf5ed5b9b137fc8b4194 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 11:39:03 +0200 Subject: [PATCH 02/12] add routing for ExplorePage --- frontend/src/AppRoutes.tsx | 9 ++++++--- frontend/src/components/header/Header.tsx | 3 ++- frontend/src/components/sidebar/Sidebar.tsx | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/AppRoutes.tsx b/frontend/src/AppRoutes.tsx index 8bb18020..e8045f46 100644 --- a/frontend/src/AppRoutes.tsx +++ b/frontend/src/AppRoutes.tsx @@ -1,21 +1,24 @@ import { Route, Routes } from "react-router-dom"; import PlantMatchPage from "./components/plantMatch/PlantMatchPage.tsx"; -import Profile from "./components/profile/Profile.tsx"; +import ExplorePage from "./pages/explorePage/ExplorePage.tsx"; import MyMatchesPage from "./pages/MyMatches/MyMatchesPage.tsx"; +import Profile from "./components/profile/Profile.tsx"; // eslint-disable-next-line react-refresh/only-export-components export const ROUTES = { plantMatch: "/", - profile: "/profile", + explore: "/explorePlants", myMatches: "/my-matches", + profile: "/profile", } as const; function AppRoutes() { return ( } /> - } /> + } /> } /> + } /> ); } diff --git a/frontend/src/components/header/Header.tsx b/frontend/src/components/header/Header.tsx index fdaac430..75cf9c43 100644 --- a/frontend/src/components/header/Header.tsx +++ b/frontend/src/components/header/Header.tsx @@ -6,8 +6,9 @@ import { ROUTES } from "../../AppRoutes"; // Maps each route path to the translation key used for its title const pageTitles: Record = { [ROUTES.plantMatch]: "sidebar.plantMatch", - [ROUTES.profile]: "sidebar.profile", + [ROUTES.explore]: "sidebar.explorePlants", [ROUTES.myMatches]: "sidebar.myMatches", + [ROUTES.profile]: "sidebar.profile", }; export default function Header() { diff --git a/frontend/src/components/sidebar/Sidebar.tsx b/frontend/src/components/sidebar/Sidebar.tsx index 0f208193..03af4072 100644 --- a/frontend/src/components/sidebar/Sidebar.tsx +++ b/frontend/src/components/sidebar/Sidebar.tsx @@ -24,9 +24,9 @@ export default function Sidebar({ isOpen }: SidebarProps) {
  • - + {t("sidebar.explorePlants")} - +
  • From 83ba225e1715e280d272b617399a2b81e5635880 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 13:52:39 +0200 Subject: [PATCH 03/12] add styling to the Explore page and add possibility to filter with mock-data --- .../src/pages/explorePage/ExplorePage.css | 115 ++++++++++++++++++ .../src/pages/explorePage/ExplorePage.tsx | 70 ++++++----- 2 files changed, 155 insertions(+), 30 deletions(-) diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index e69de29b..efb8e300 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -0,0 +1,115 @@ +.explore-page { + margin-left: var(--sidebar-width); + width: calc(100% - var(--sidebar-width)); + min-height: 100vh; + padding: 40px; + box-sizing: border-box; + + display: flex; + flex-direction: column; + align-items: center; + gap: 30px; + + font-family: Georgia, serif; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; +} + +.explore-form, +.plant-grid { + width: 100%; +} + +.explore-search { + display: block; +} +.explore-search input:focus { + outline: none; + border-color: var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-green); +} + +.explore-search input { + width: 100%; + padding: 0.75rem 1rem; + font-size: 1rem; + border: 1px solid var(--border-soft); + border-radius: 8px; + box-sizing: border-box; +} + +.explore-filters { + display: flex; + flex-wrap: wrap; + gap: 1rem; + margin: 1rem 0 0; + padding: 0; + border: 0; +} + +.explore-filters :focus { + outline: none; + border-color: var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-green); +} + +.filter { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.filter select { + padding: 0.5rem; + border: 1px solid var(--border-soft); + border-radius: 8px; + min-width: 160px; +} + +.plant-grid { + list-style: none; + margin: 0; + padding: 0; + + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; +} + +.plant-card-placeholder { + height: 500px; + border-radius: 12px; + overflow: hidden; + padding: 1rem; + box-sizing: border-box; +} + +.plant-card-placeholder h2 { + margin: 0 0 0.5rem; + font-size: 16px; +} + +@media (max-width: 767px) { + .explore-page { + margin-left: 0; + width: 100%; + padding: 20px; + gap: 20px; + } + + .plant-grid { + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 15px; + } + + .plant-card { + height: 300px; + } +} \ No newline at end of file diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index e0593fbc..571d0e71 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -1,34 +1,52 @@ +import { useState } from "react" import { useTranslation } from "react-i18next" import "./ExplorePage.css" const plants = [ - { id: 1, name: "Hydrangea", watering: "Average", sunlight: "Part shade" }, - { id: 2, name: "Orchid", watering: "Minimum", sunlight: "Part sun" }, - { id: 3, name: "Fig Tree", watering: "Average", sunlight: "Full sun" }, - { id: 4, name: "Monstera", watering: "Average", sunlight: "Part shade" }, - { id: 5, name: "Peony", watering: "Frequent", sunlight: "Full sun" }, - { id: 6, name: "Lily", watering: "Average", sunlight: "Part sun" }, - { id: 7, name: "Rose", watering: "Frequent", sunlight: "Full sun" }, - { id: 8, name: "Tulip", watering: "Minimum", sunlight: "Full sun" }, - { id: 9, name: "Daisy", watering: "Average", sunlight: "Full sun" }, - { id: 10, name: "Sunflower", watering: "Average", sunlight: "Full sun" }, - { id: 11, name: "Lavender", watering: "Minimum", sunlight: "Full sun" }, - { id: 12, name: "Jasmine", watering: "Average", sunlight: "Part sun" }, - { id: 13, name: "Marigold", watering: "Average", sunlight: "Full sun" }, - { id: 14, name: "Daffodil", watering: "Average", sunlight: "Part sun" }, - { id: 15, name: "Carnation", watering: "Average", sunlight: "Full sun" }, + { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade" }, + { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun" }, + { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun" }, + { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade" }, + { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun" }, + { id: 6, name: "Lily", watering: "average", sunlight: "part_sun" }, + { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun" }, + { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun" }, + { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun" }, + { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun" }, + { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun" }, + { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun" }, + { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun" }, + { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun" }, + { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun" }, ] export default function ExplorePage() { const { t } = useTranslation() + const [search, setSearch] = useState("") + const [watering, setWatering] = useState("") + const [sunlight, setSunlight] = useState("") + + const filteredPlants = plants.filter( + (plant) => + plant.name.toLowerCase().includes(search.toLowerCase()) && + (watering === "" || plant.watering === watering) && + (sunlight === "" || plant.sunlight === sunlight) + ) + return (
    - {/* Søk og filtre */} -
    +

    {t("explore.title", "Explore plants")}

    + + e.preventDefault()}>
    @@ -36,7 +54,7 @@ export default function ExplorePage() {
    - {/* Plantekort */}
      - {plants.map((plant) => ( -
    • -
      + {filteredPlants.map((plant) => ( +
    • {plant.name}

      -
      -
      {t("explore.watering", "Watering needs")}
      -
      {plant.watering}
      -
      {t("explore.sunlight", "Sun requirements")}
      -
      {plant.sunlight}
      -
    • ))}
    From 783e0b2e5fe78600aecfe57b403b5b2cb27e934d Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 14:10:53 +0200 Subject: [PATCH 04/12] add translation to the Explore page --- frontend/src/i18n/locales/en/translation.json | 12 +++++++++ frontend/src/i18n/locales/no/translation.json | 12 +++++++++ .../src/pages/explorePage/ExplorePage.tsx | 26 +++++++++---------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index 8453d76d..9581f60a 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -33,6 +33,18 @@ "small": "small", "succulents": "succulent" }, + "explorePage": { + "search": "Search for plants", + "watering": "Watering needs", + "all": "All", + "minimum": "Minimum", + "average": "Average", + "frequent": "Frequent", + "sunlight": "Sun requirements", + "full_sun": "Full sun", + "part_sun": "Part sun", + "part_shade": "Part shade" + }, "myMatchesPage": { "guide": "These are your matches:" } diff --git a/frontend/src/i18n/locales/no/translation.json b/frontend/src/i18n/locales/no/translation.json index 03da998b..ed8ae77b 100644 --- a/frontend/src/i18n/locales/no/translation.json +++ b/frontend/src/i18n/locales/no/translation.json @@ -33,6 +33,18 @@ "small": "liten", "succulents": "sukkulent" }, + "explorePage": { + "search": "Søk etter planter", + "watering": "Vanningsbehov", + "all": "Alle", + "minimum": "Sjeldent", + "average": "Jevnlig", + "frequent": "Ofte", + "sunlight": "Solforhold", + "full_sun": "Full sol", + "part_sun": "Delvis sol", + "part_shade": "Delvis skygge" + }, "myMatchesPage": { "guide": "Dette er dine matcher:" } diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 571d0e71..5c47021a 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -40,35 +40,35 @@ export default function ExplorePage() {
    e.preventDefault()}>
    - {t("explore.filters", "Filters")} + {t("explorePage.filters", "Filters")}
    From 6c94323cba201ad37f80842cb72b0f4ef87a2673 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 15:01:21 +0200 Subject: [PATCH 05/12] add debounce for search functionality and message for no results --- frontend/src/hooks/useDebounce.ts | 13 +++++ frontend/src/i18n/locales/en/translation.json | 3 +- frontend/src/i18n/locales/no/translation.json | 3 +- .../src/pages/explorePage/ExplorePage.css | 53 ++++++++++++------- .../src/pages/explorePage/ExplorePage.tsx | 10 +++- 5 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 frontend/src/hooks/useDebounce.ts diff --git a/frontend/src/hooks/useDebounce.ts b/frontend/src/hooks/useDebounce.ts new file mode 100644 index 00000000..3f6a43d3 --- /dev/null +++ b/frontend/src/hooks/useDebounce.ts @@ -0,0 +1,13 @@ +import { useEffect, useState } from "react" + +export function useDebounce(value: T, delay = 800): T { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay) + + return () => clearTimeout(timer) + }, [value, delay]) + + return debouncedValue +} \ No newline at end of file diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index 9581f60a..e7b8f89a 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -43,7 +43,8 @@ "sunlight": "Sun requirements", "full_sun": "Full sun", "part_sun": "Part sun", - "part_shade": "Part shade" + "part_shade": "Part shade", + "noResults": "No results found" }, "myMatchesPage": { "guide": "These are your matches:" diff --git a/frontend/src/i18n/locales/no/translation.json b/frontend/src/i18n/locales/no/translation.json index ed8ae77b..9640b1bf 100644 --- a/frontend/src/i18n/locales/no/translation.json +++ b/frontend/src/i18n/locales/no/translation.json @@ -43,7 +43,8 @@ "sunlight": "Solforhold", "full_sun": "Full sol", "part_sun": "Delvis sol", - "part_shade": "Delvis skygge" + "part_shade": "Delvis skygge", + "noResults": "Ingen resultater funnet" }, "myMatchesPage": { "guide": "Dette er dine matcher:" diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index efb8e300..34c50b42 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -27,15 +27,6 @@ width: 100%; } -.explore-search { - display: block; -} -.explore-search input:focus { - outline: none; - border-color: var(--dark-green); - box-shadow: 0 0 0 2px var(--dark-green); -} - .explore-search input { width: 100%; padding: 0.75rem 1rem; @@ -45,6 +36,12 @@ box-sizing: border-box; } +.explore-search input:focus { + outline: none; + border-color: var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-green); +} + .explore-filters { display: flex; flex-wrap: wrap; @@ -54,12 +51,6 @@ border: 0; } -.explore-filters :focus { - outline: none; - border-color: var(--dark-green); - box-shadow: 0 0 0 2px var(--dark-green); -} - .filter { display: flex; flex-direction: column; @@ -73,6 +64,12 @@ min-width: 160px; } +.filter select:focus { + outline: none; + border-color: var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-green); +} + .plant-grid { list-style: none; margin: 0; @@ -87,13 +84,29 @@ height: 500px; border-radius: 12px; overflow: hidden; - padding: 1rem; box-sizing: border-box; + border: 3px solid var(--border-soft); +} + +.plant-card-placeholder:focus-within { + border-color: var(--dark-green); +} + +.plant-card-button { + width: 100%; + height: 100%; + padding: 1rem; + text-align: center; + background: none; + border: none; + outline: none; + font: inherit; + color: inherit; + cursor: pointer; } -.plant-card-placeholder h2 { - margin: 0 0 0.5rem; - font-size: 16px; +.plant-card-name { + font-size: 16px; } @media (max-width: 767px) { @@ -109,7 +122,7 @@ gap: 15px; } - .plant-card { + .plant-card-placeholder { height: 300px; } } \ No newline at end of file diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 5c47021a..3370e224 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -1,5 +1,6 @@ import { useState } from "react" import { useTranslation } from "react-i18next" +import { useDebounce } from "../../hooks/useDebounce" import "./ExplorePage.css" const plants = [ @@ -24,12 +25,13 @@ export default function ExplorePage() { const { t } = useTranslation() const [search, setSearch] = useState("") + const debouncedSearch = useDebounce(search, 800) const [watering, setWatering] = useState("") const [sunlight, setSunlight] = useState("") const filteredPlants = plants.filter( (plant) => - plant.name.toLowerCase().includes(search.toLowerCase()) && + plant.name.toLowerCase().includes(debouncedSearch.toLowerCase()) && (watering === "" || plant.watering === watering) && (sunlight === "" || plant.sunlight === sunlight) ) @@ -74,10 +76,14 @@ export default function ExplorePage() { + {filteredPlants.length === 0 &&

    {t("explorePage.noResults")}

    } +
      {filteredPlants.map((plant) => (
    • -

      {plant.name}

      +
    • ))}
    From f71c35f0153b4e8d1c10ff9a013afc4bc3df493f Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 15:05:17 +0200 Subject: [PATCH 06/12] run lint, install and run prettier --- frontend/src/hooks/useDebounce.ts | 16 +- .../src/pages/explorePage/ExplorePage.css | 5 +- .../src/pages/explorePage/ExplorePage.tsx | 172 ++++++++++-------- 3 files changed, 103 insertions(+), 90 deletions(-) diff --git a/frontend/src/hooks/useDebounce.ts b/frontend/src/hooks/useDebounce.ts index 3f6a43d3..24205b9e 100644 --- a/frontend/src/hooks/useDebounce.ts +++ b/frontend/src/hooks/useDebounce.ts @@ -1,13 +1,13 @@ -import { useEffect, useState } from "react" +import { useEffect, useState } from "react"; export function useDebounce(value: T, delay = 800): T { - const [debouncedValue, setDebouncedValue] = useState(value) + const [debouncedValue, setDebouncedValue] = useState(value); - useEffect(() => { - const timer = setTimeout(() => setDebouncedValue(value), delay) + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay); - return () => clearTimeout(timer) - }, [value, delay]) + return () => clearTimeout(timer); + }, [value, delay]); - return debouncedValue -} \ No newline at end of file + return debouncedValue; +} diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index 34c50b42..ee1d8279 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -74,7 +74,6 @@ list-style: none; margin: 0; padding: 0; - display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; @@ -106,7 +105,7 @@ } .plant-card-name { - font-size: 16px; + font-size: 16px; } @media (max-width: 767px) { @@ -125,4 +124,4 @@ .plant-card-placeholder { height: 300px; } -} \ No newline at end of file +} diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 3370e224..572c1ea6 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -1,92 +1,106 @@ -import { useState } from "react" -import { useTranslation } from "react-i18next" -import { useDebounce } from "../../hooks/useDebounce" -import "./ExplorePage.css" +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useDebounce } from "../../hooks/useDebounce"; +import "./ExplorePage.css"; const plants = [ - { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade" }, - { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun" }, - { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun" }, - { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade" }, - { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun" }, - { id: 6, name: "Lily", watering: "average", sunlight: "part_sun" }, - { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun" }, - { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun" }, - { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun" }, - { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun" }, - { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun" }, - { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun" }, - { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun" }, - { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun" }, - { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun" }, -] + { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade" }, + { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun" }, + { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun" }, + { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade" }, + { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun" }, + { id: 6, name: "Lily", watering: "average", sunlight: "part_sun" }, + { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun" }, + { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun" }, + { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun" }, + { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun" }, + { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun" }, + { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun" }, + { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun" }, + { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun" }, + { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun" }, +]; export default function ExplorePage() { - const { t } = useTranslation() + const { t } = useTranslation(); - const [search, setSearch] = useState("") - const debouncedSearch = useDebounce(search, 800) - const [watering, setWatering] = useState("") - const [sunlight, setSunlight] = useState("") + const [search, setSearch] = useState(""); + const debouncedSearch = useDebounce(search, 800); + const [watering, setWatering] = useState(""); + const [sunlight, setSunlight] = useState(""); - const filteredPlants = plants.filter( - (plant) => - plant.name.toLowerCase().includes(debouncedSearch.toLowerCase()) && - (watering === "" || plant.watering === watering) && - (sunlight === "" || plant.sunlight === sunlight) - ) + const filteredPlants = plants.filter( + (plant) => + plant.name.toLowerCase().includes(debouncedSearch.toLowerCase()) && + (watering === "" || plant.watering === watering) && + (sunlight === "" || plant.sunlight === sunlight), + ); - return ( -
    -

    {t("explore.title", "Explore plants")}

    + return ( +
    +

    + {t("explore.title", "Explore plants")} +

    -
    e.preventDefault()}> - + e.preventDefault()} + > + -
    - {t("explorePage.filters", "Filters")} +
    + + {t("explorePage.filters", "Filters")} + - + - -
    - + +
    + - {filteredPlants.length === 0 &&

    {t("explorePage.noResults")}

    } + {filteredPlants.length === 0 &&

    {t("explorePage.noResults")}

    } -
      - {filteredPlants.map((plant) => ( -
    • - -
    • - ))} -
    -
    - ) -} \ No newline at end of file +
      + {filteredPlants.map((plant) => ( +
    • + +
    • + ))} +
    +
    + ); +} From dcaa68906fc011806b229a7ec2b3bf6918f3fec6 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 16:14:17 +0200 Subject: [PATCH 07/12] add extra filters and reset button for filters and search --- frontend/src/i18n/locales/en/translation.json | 7 ++ frontend/src/i18n/locales/no/translation.json | 7 ++ .../src/pages/explorePage/ExplorePage.css | 20 ++++- .../src/pages/explorePage/ExplorePage.tsx | 74 +++++++++++++++---- 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index e7b8f89a..761a5ba1 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -44,6 +44,13 @@ "full_sun": "Full sun", "part_sun": "Part sun", "part_shade": "Part shade", + "location": "Location", + "indoor": "Indoor", + "outdoor": "Outdoor", + "edibility": "Edibility", + "edible": "Edible", + "poison": "Poisonous", + "reset": "Reset", "noResults": "No results found" }, "myMatchesPage": { diff --git a/frontend/src/i18n/locales/no/translation.json b/frontend/src/i18n/locales/no/translation.json index 9640b1bf..35a14f64 100644 --- a/frontend/src/i18n/locales/no/translation.json +++ b/frontend/src/i18n/locales/no/translation.json @@ -44,6 +44,13 @@ "full_sun": "Full sol", "part_sun": "Delvis sol", "part_shade": "Delvis skygge", + "location": "Plassering", + "indoor": "Innendørs", + "outdoor": "Utendørs", + "edibility": "Spiselighet", + "edible": "Spiselig", + "poison": "Giftig", + "reset": "Nullstill", "noResults": "Ingen resultater funnet" }, "myMatchesPage": { diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index ee1d8279..33210486 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -70,6 +70,23 @@ box-shadow: 0 0 0 2px var(--dark-green); } +.reset-button { + align-self: flex-start; + width: 74px; + height: 38px; + border: 1px solid var(--border-soft); + border-radius: 8px; + background-color: var(--light-green); + color: var(--text-dark); + font-size: 16px; + cursor: pointer; +} + +.reset-button:hover { + background-color: var(--dark-green); + color: var(--text-light); +} + .plant-grid { list-style: none; margin: 0; @@ -117,11 +134,12 @@ } .plant-grid { - grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-template-columns: 1fr; gap: 15px; } .plant-card-placeholder { height: 300px; + margin: 0 auto; } } diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 572c1ea6..e8a60b3d 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -4,21 +4,21 @@ import { useDebounce } from "../../hooks/useDebounce"; import "./ExplorePage.css"; const plants = [ - { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade" }, - { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun" }, - { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun" }, - { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade" }, - { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun" }, - { id: 6, name: "Lily", watering: "average", sunlight: "part_sun" }, - { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun" }, - { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun" }, - { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun" }, - { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun" }, - { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun" }, - { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun" }, - { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun" }, - { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun" }, - { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun" }, + { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade", indoor: false, edible: false }, + { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun", indoor: true, edible: false }, + { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun", indoor: true, edible: true }, + { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade", indoor: true, edible: false }, + { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, + { id: 6, name: "Lily", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, + { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, + { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun", indoor: false, edible: false }, + { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun", indoor: true, edible: true }, + { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, + { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun", indoor: false, edible: false }, + { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, ]; export default function ExplorePage() { @@ -28,12 +28,20 @@ export default function ExplorePage() { const debouncedSearch = useDebounce(search, 800); const [watering, setWatering] = useState(""); const [sunlight, setSunlight] = useState(""); + const [location, setLocation] = useState(""); + const [edibility, setEdibility] = useState(""); const filteredPlants = plants.filter( (plant) => plant.name.toLowerCase().includes(debouncedSearch.toLowerCase()) && (watering === "" || plant.watering === watering) && - (sunlight === "" || plant.sunlight === sunlight), + (sunlight === "" || plant.sunlight === sunlight)&& + (location === "" || + (location === "indoor" && plant.indoor) || + (location === "outdoor" && !plant.indoor)) && + (edibility === "" || + (edibility === "edible" && plant.edible) || + (edibility === "poison" && !plant.edible)), ); return ( @@ -87,9 +95,43 @@ export default function ExplorePage() { + + + + + + {filteredPlants.length === 0 &&

    {t("explorePage.noResults")}

    }
      From 282382815421d1b6dbf10b0c6d7a1aad1ca862e5 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 22:07:05 +0200 Subject: [PATCH 08/12] fix better explore page for mobile use --- frontend/src/pages/explorePage/ExplorePage.css | 12 +++++++----- frontend/src/pages/explorePage/ExplorePage.tsx | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index 33210486..3f8cf633 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -96,7 +96,7 @@ gap: 20px; } -.plant-card-placeholder { +.explore-plant-card-placeholder { height: 500px; border-radius: 12px; overflow: hidden; @@ -104,7 +104,7 @@ border: 3px solid var(--border-soft); } -.plant-card-placeholder:focus-within { +.explore-plant-card-placeholder:focus-within { border-color: var(--dark-green); } @@ -134,12 +134,14 @@ } .plant-grid { - grid-template-columns: 1fr; + grid-template-columns: repeat(2, 1fr); gap: 15px; } - .plant-card-placeholder { - height: 300px; + .explore-plant-card-placeholder { + height: auto; + width: 100%; + aspect-ratio: 3 / 4; margin: 0 auto; } } diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index e8a60b3d..25c35e2a 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -136,7 +136,7 @@ export default function ExplorePage() {
        {filteredPlants.map((plant) => ( -
      • +
      • From 2ee1ad810b8925795de0ac726fcf7ff394059c38 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 22:17:18 +0200 Subject: [PATCH 09/12] remove excess styling for explore page --- frontend/src/pages/explorePage/ExplorePage.css | 15 ++------------- frontend/src/pages/explorePage/ExplorePage.tsx | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index 3f8cf633..58e02923 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -92,12 +92,12 @@ margin: 0; padding: 0; display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + grid-template-columns: repeat(4, 1fr); gap: 20px; } .explore-plant-card-placeholder { - height: 500px; + aspect-ratio: 3 / 4; border-radius: 12px; overflow: hidden; box-sizing: border-box; @@ -121,10 +121,6 @@ cursor: pointer; } -.plant-card-name { - font-size: 16px; -} - @media (max-width: 767px) { .explore-page { margin-left: 0; @@ -137,11 +133,4 @@ grid-template-columns: repeat(2, 1fr); gap: 15px; } - - .explore-plant-card-placeholder { - height: auto; - width: 100%; - aspect-ratio: 3 / 4; - margin: 0 auto; - } } diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 25c35e2a..e5130b17 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -138,7 +138,7 @@ export default function ExplorePage() { {filteredPlants.map((plant) => (
      • ))} From a1b832809d902f4c5abc07bc1d7e3a1a3b8c5582 Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 22:35:50 +0200 Subject: [PATCH 10/12] add function to plant-card placeholder to show information about the plant --- .../src/pages/explorePage/ExplorePage.css | 18 +- .../src/pages/explorePage/ExplorePage.tsx | 212 +++++++++++++++--- 2 files changed, 204 insertions(+), 26 deletions(-) diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index 58e02923..39ad1add 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -80,7 +80,7 @@ color: var(--text-dark); font-size: 16px; cursor: pointer; -} +} .reset-button:hover { background-color: var(--dark-green); @@ -121,6 +121,13 @@ cursor: pointer; } +.plant-card-info { + display: flex; + flex-direction: column; + gap: 0.75rem; + text-align: left; +} + @media (max-width: 767px) { .explore-page { margin-left: 0; @@ -133,4 +140,13 @@ grid-template-columns: repeat(2, 1fr); gap: 15px; } + + .plant-card-button { + padding: 0.5rem; + } + + .plant-card-info { + font-size: 13px; + gap: 0.4rem; + } } diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index e5130b17..88e906bc 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -4,21 +4,126 @@ import { useDebounce } from "../../hooks/useDebounce"; import "./ExplorePage.css"; const plants = [ - { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade", indoor: false, edible: false }, - { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun", indoor: true, edible: false }, - { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun", indoor: true, edible: true }, - { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade", indoor: true, edible: false }, - { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, - { id: 6, name: "Lily", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, - { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, - { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun", indoor: false, edible: false }, - { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, - { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, - { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun", indoor: true, edible: true }, - { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, - { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, - { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun", indoor: false, edible: false }, - { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { + id: 1, + name: "Hydrangea", + watering: "average", + sunlight: "part_shade", + indoor: false, + edible: false, + }, + { + id: 2, + name: "Orchid", + watering: "minimum", + sunlight: "part_sun", + indoor: true, + edible: false, + }, + { + id: 3, + name: "Fig Tree", + watering: "average", + sunlight: "full_sun", + indoor: true, + edible: true, + }, + { + id: 4, + name: "Monstera", + watering: "average", + sunlight: "part_shade", + indoor: true, + edible: false, + }, + { + id: 5, + name: "Peony", + watering: "frequent", + sunlight: "full_sun", + indoor: false, + edible: false, + }, + { + id: 6, + name: "Lily", + watering: "average", + sunlight: "part_sun", + indoor: true, + edible: false, + }, + { + id: 7, + name: "Rose", + watering: "frequent", + sunlight: "full_sun", + indoor: false, + edible: false, + }, + { + id: 8, + name: "Tulip", + watering: "minimum", + sunlight: "full_sun", + indoor: false, + edible: false, + }, + { + id: 9, + name: "Daisy", + watering: "average", + sunlight: "full_sun", + indoor: false, + edible: true, + }, + { + id: 10, + name: "Sunflower", + watering: "average", + sunlight: "full_sun", + indoor: false, + edible: true, + }, + { + id: 11, + name: "Lavender", + watering: "minimum", + sunlight: "full_sun", + indoor: true, + edible: true, + }, + { + id: 12, + name: "Jasmine", + watering: "average", + sunlight: "part_sun", + indoor: true, + edible: false, + }, + { + id: 13, + name: "Marigold", + watering: "average", + sunlight: "full_sun", + indoor: false, + edible: true, + }, + { + id: 14, + name: "Daffodil", + watering: "average", + sunlight: "part_sun", + indoor: false, + edible: false, + }, + { + id: 15, + name: "Carnation", + watering: "average", + sunlight: "full_sun", + indoor: false, + edible: true, + }, ]; export default function ExplorePage() { @@ -26,6 +131,7 @@ export default function ExplorePage() { const [search, setSearch] = useState(""); const debouncedSearch = useDebounce(search, 800); + const [openId, setOpenId] = useState(null); const [watering, setWatering] = useState(""); const [sunlight, setSunlight] = useState(""); const [location, setLocation] = useState(""); @@ -35,7 +141,7 @@ export default function ExplorePage() { (plant) => plant.name.toLowerCase().includes(debouncedSearch.toLowerCase()) && (watering === "" || plant.watering === watering) && - (sunlight === "" || plant.sunlight === sunlight)&& + (sunlight === "" || plant.sunlight === sunlight) && (location === "" || (location === "indoor" && plant.indoor) || (location === "outdoor" && !plant.indoor)) && @@ -122,19 +228,23 @@ export default function ExplorePage() { - {filteredPlants.length === 0 &&

        {t("explorePage.noResults")}

        } -
          + {/**
            {filteredPlants.map((plant) => (
          • ))}
          + */} + +
            + {filteredPlants.map((plant) => { + const isOpen = openId === plant.id; + return ( +
          • + +
          • + ); + })} +
    ); } From 9a0c79698a18715b20f8e686c9c9b98c8fdd721e Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 22:43:14 +0200 Subject: [PATCH 11/12] fix reset button for search and filtering --- frontend/src/pages/explorePage/ExplorePage.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/pages/explorePage/ExplorePage.css b/frontend/src/pages/explorePage/ExplorePage.css index 39ad1add..8a74a7b1 100644 --- a/frontend/src/pages/explorePage/ExplorePage.css +++ b/frontend/src/pages/explorePage/ExplorePage.css @@ -87,6 +87,12 @@ color: var(--text-light); } +.reset-button:focus-within { + outline: none; + border: var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-green); +} + .plant-grid { list-style: none; margin: 0; From 9f03356986b5a5875d5710787cb76e0007f63c9d Mon Sep 17 00:00:00 2001 From: Helene Lotsberg Date: Thu, 1 Oct 2026 23:02:42 +0200 Subject: [PATCH 12/12] add hook for sessionStorage --- frontend/src/hooks/useSessionState.ts | 22 +++ .../src/pages/explorePage/ExplorePage.tsx | 158 +++--------------- 2 files changed, 44 insertions(+), 136 deletions(-) create mode 100644 frontend/src/hooks/useSessionState.ts diff --git a/frontend/src/hooks/useSessionState.ts b/frontend/src/hooks/useSessionState.ts new file mode 100644 index 00000000..6200f6e1 --- /dev/null +++ b/frontend/src/hooks/useSessionState.ts @@ -0,0 +1,22 @@ +import { useEffect, useState } from "react"; + +export function useSessionState(key: string, initialValue = "") { + const [value, setValue] = useState(() => { + try { + return sessionStorage.getItem(key) ?? initialValue; + } catch { + return initialValue; + } + }); + + useEffect(() => { + try { + sessionStorage.setItem(key, value); + } catch { + // Storage can fail (private mode, full quota). The app still works, + // the value just won't be remembered. + } + }, [key, value]); + + return [value, setValue] as const; +} diff --git a/frontend/src/pages/explorePage/ExplorePage.tsx b/frontend/src/pages/explorePage/ExplorePage.tsx index 88e906bc..bef0c339 100644 --- a/frontend/src/pages/explorePage/ExplorePage.tsx +++ b/frontend/src/pages/explorePage/ExplorePage.tsx @@ -1,141 +1,38 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useDebounce } from "../../hooks/useDebounce"; +import { useSessionState } from "../../hooks/useSessionState"; import "./ExplorePage.css"; +// prettier-ignore const plants = [ - { - id: 1, - name: "Hydrangea", - watering: "average", - sunlight: "part_shade", - indoor: false, - edible: false, - }, - { - id: 2, - name: "Orchid", - watering: "minimum", - sunlight: "part_sun", - indoor: true, - edible: false, - }, - { - id: 3, - name: "Fig Tree", - watering: "average", - sunlight: "full_sun", - indoor: true, - edible: true, - }, - { - id: 4, - name: "Monstera", - watering: "average", - sunlight: "part_shade", - indoor: true, - edible: false, - }, - { - id: 5, - name: "Peony", - watering: "frequent", - sunlight: "full_sun", - indoor: false, - edible: false, - }, - { - id: 6, - name: "Lily", - watering: "average", - sunlight: "part_sun", - indoor: true, - edible: false, - }, - { - id: 7, - name: "Rose", - watering: "frequent", - sunlight: "full_sun", - indoor: false, - edible: false, - }, - { - id: 8, - name: "Tulip", - watering: "minimum", - sunlight: "full_sun", - indoor: false, - edible: false, - }, - { - id: 9, - name: "Daisy", - watering: "average", - sunlight: "full_sun", - indoor: false, - edible: true, - }, - { - id: 10, - name: "Sunflower", - watering: "average", - sunlight: "full_sun", - indoor: false, - edible: true, - }, - { - id: 11, - name: "Lavender", - watering: "minimum", - sunlight: "full_sun", - indoor: true, - edible: true, - }, - { - id: 12, - name: "Jasmine", - watering: "average", - sunlight: "part_sun", - indoor: true, - edible: false, - }, - { - id: 13, - name: "Marigold", - watering: "average", - sunlight: "full_sun", - indoor: false, - edible: true, - }, - { - id: 14, - name: "Daffodil", - watering: "average", - sunlight: "part_sun", - indoor: false, - edible: false, - }, - { - id: 15, - name: "Carnation", - watering: "average", - sunlight: "full_sun", - indoor: false, - edible: true, - }, + { id: 1, name: "Hydrangea", watering: "average", sunlight: "part_shade", indoor: false, edible: false }, + { id: 2, name: "Orchid", watering: "minimum", sunlight: "part_sun", indoor: true, edible: false }, + { id: 3, name: "Fig Tree", watering: "average", sunlight: "full_sun", indoor: true, edible: true }, + { id: 4, name: "Monstera", watering: "average", sunlight: "part_shade", indoor: true, edible: false }, + { id: 5, name: "Peony", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, + { id: 6, name: "Lily", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, + { id: 7, name: "Rose", watering: "frequent", sunlight: "full_sun", indoor: false, edible: false }, + { id: 8, name: "Tulip", watering: "minimum", sunlight: "full_sun", indoor: false, edible: false }, + { id: 9, name: "Daisy", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 10, name: "Sunflower", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 11, name: "Lavender", watering: "minimum", sunlight: "full_sun", indoor: true, edible: true }, + { id: 12, name: "Jasmine", watering: "average", sunlight: "part_sun", indoor: true, edible: false }, + { id: 13, name: "Marigold", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, + { id: 14, name: "Daffodil", watering: "average", sunlight: "part_sun", indoor: false, edible: false }, + { id: 15, name: "Carnation", watering: "average", sunlight: "full_sun", indoor: false, edible: true }, ]; export default function ExplorePage() { const { t } = useTranslation(); - const [search, setSearch] = useState(""); + const [search, setSearch] = useSessionState("explorePage.search"); const debouncedSearch = useDebounce(search, 800); const [openId, setOpenId] = useState(null); - const [watering, setWatering] = useState(""); - const [sunlight, setSunlight] = useState(""); - const [location, setLocation] = useState(""); - const [edibility, setEdibility] = useState(""); + const [watering, setWatering] = useSessionState("explorePage.watering"); + const [sunlight, setSunlight] = useSessionState("explorePage.sunlight"); + const [location, setLocation] = useSessionState("explorePage.location"); + const [edibility, setEdibility] = useSessionState("explorePage.edibility"); const filteredPlants = plants.filter( (plant) => @@ -244,17 +141,6 @@ export default function ExplorePage() { {filteredPlants.length === 0 &&

    {t("explorePage.noResults")}

    } - {/**
      - {filteredPlants.map((plant) => ( -
    • - -
    • - ))} -
    - */} -
      {filteredPlants.map((plant) => { const isOpen = openId === plant.id;