diff --git a/frontend/src/components/plantCard/PlantCard.css b/frontend/src/components/plantCard/PlantCard.css index 87a310e..853bb95 100644 --- a/frontend/src/components/plantCard/PlantCard.css +++ b/frontend/src/components/plantCard/PlantCard.css @@ -87,7 +87,7 @@ height: var(--card-name-height); margin: 0; - padding: 16px 28px; + padding: 5px 40px; display: flex; align-items: center; @@ -95,7 +95,7 @@ color: var(--dark-green); - font-size: 1.65rem; + font-size: 1.5rem; font-weight: 700; line-height: 1.1; text-align: center; @@ -255,7 +255,7 @@ height: auto; min-height: 62px; - padding: 0 10px; + padding: 0 24px; color: var(--light-green); diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index 53b0d75..3e779f7 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -67,7 +67,9 @@ "pagination": "Page navigation", "pageOf": "Page {{page}} of {{totalPages}}", "previous": "Previous", - "next": "Next" + "next": "Next", + "addMatch": "Add to My Matches", + "alreadyMatched": "Already in My Matches" }, "myMatchesPage": { "noMatches": "You have no matches yet. Press the flower on the match page to match with a plant.", diff --git a/frontend/src/i18n/locales/no/translation.json b/frontend/src/i18n/locales/no/translation.json index 371dbb8..77c5176 100644 --- a/frontend/src/i18n/locales/no/translation.json +++ b/frontend/src/i18n/locales/no/translation.json @@ -67,7 +67,9 @@ "pagination": "Sidenavigasjon", "pageOf": "Side {{page}} av {{totalPages}}", "previous": "Forrige", - "next": "Neste" + "next": "Neste", + "addMatch": "Legg til i Mine Matches", + "alreadyMatched": "Allerede i Mine Matches" }, "myMatchesPage": { "noMatches": "Du har ingen matcher ennå. Trykk på blomsten på match-siden for å matche med en plante.", diff --git a/frontend/src/pages/explorePlants/ExplorePlants.css b/frontend/src/pages/explorePlants/ExplorePlants.css index 6d06402..487e7a9 100644 --- a/frontend/src/pages/explorePlants/ExplorePlants.css +++ b/frontend/src/pages/explorePlants/ExplorePlants.css @@ -28,19 +28,40 @@ width: 100%; } +.explore-search { + position: relative; + display: block; +} + +.explore-search-icon { + position: absolute; + top: 50%; + left: 1rem; + font-size: 1.25rem; + transform: translateY(-50%); + color: var(--dark-pink); + pointer-events: none; +} + .explore-search input { width: 100%; - padding: 0.75rem 1rem; - font-size: 1rem; - border: 1px solid var(--border-soft); + padding: 0.75rem 1rem 0.75rem 2.75rem; + font-size: 1.25rem; + color: var(--text-dark); + background-color: var(--light-pink); + border: 1px solid var(--dark-pink); border-radius: 8px; box-sizing: border-box; } .explore-search input:focus { outline: none; - border-color: var(--dark-green); - box-shadow: 0 0 0 2px var(--dark-green); + border-color: var(--dark-pink); + box-shadow: 0 0 0 2px var(--dark-pink); +} + +.explore-search input::placeholder { + color: var(--text-dark); } .explore-filters { @@ -56,42 +77,46 @@ display: flex; flex-direction: column; gap: 0.25rem; + font-size: 1rem; } .filter select { padding: 0.5rem; - border: 1px solid var(--border-soft); + border: 1px solid var(--dark-pink); border-radius: 8px; min-width: 160px; + font-size: 15px; + background-color: var(--light-background); + color: var(--text-dark); } .filter select:focus { outline: none; - border-color: var(--dark-green); - box-shadow: 0 0 0 2px var(--dark-green); + border-color: var(--dark-pink); + box-shadow: 0 0 0 2px var(--dark-pink); } .reset-button { align-self: flex-start; width: 74px; height: 38px; - border: 1px solid var(--border-soft); + border: 1px solid var(--dark-pink); border-radius: 8px; - background-color: var(--light-green); + background-color: var(--light-background); color: var(--text-dark); - font-size: 16px; + font-size: 15px; cursor: pointer; } .reset-button:hover { - background-color: var(--dark-green); + background-color: var(--dark-pink); color: var(--text-light); } .reset-button:focus-within { outline: none; - border: var(--dark-green); - box-shadow: 0 0 0 2px var(--dark-green); + border: var(--dark-pink); + box-shadow: 0 0 0 2px var(--dark-pink); } .explore-results { @@ -102,6 +127,12 @@ background-color: var(--light-pink); } +.explore-results p { + font-size: 20px; + text-align: center; + font-family: Georgia, serif; +} + .plant-grid { list-style: none; margin: 0; @@ -118,6 +149,7 @@ width: calc(390px * var(--card-scale)); height: calc(620px * var(--card-scale)); justify-self: center; + position: relative; } .explore-plant-item .plant-card-flipper { @@ -138,7 +170,7 @@ .pagination button { padding: 0.5rem 1rem; - border: 1px solid var(--border-soft); + border: 1px solid var(--dark-green); border-radius: 8px; background-color: var(--light-green); color: var(--text-dark); @@ -172,23 +204,23 @@ justify-content: center; width: 40px; height: 40px; - border: 1px solid var(--border-soft); + border: 1px solid var(--dark-pink); border-radius: 8px; - background-color: var(--light-green); + background-color: var(--light-background); color: var(--text-dark); - font-size: 1.4rem; + font-size: 1.5rem; cursor: pointer; } .sort-button:hover { - background-color: var(--dark-green); + background-color: var(--dark-pink); color: var(--text-light); } .sort-button:focus-visible, .sort-option:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--dark-green); + box-shadow: 0 0 0 2px var(--dark-pink); } .sort-options { @@ -201,7 +233,7 @@ padding: 0.25rem; list-style: none; background-color: var(--light-background); - border: 1px solid var(--border-soft); + border: 1px solid var(--dark-pink); border-radius: 8px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); } @@ -219,14 +251,73 @@ } .sort-option:hover { - background-color: var(--light-green); + background-color: var(--light-pink); } .sort-option--active { - background-color: var(--light-green); + background-color: var(--light-pink); font-weight: 700; } +.add-match { + position: absolute; + top: -15px; + right: -15px; + z-index: 2; +} + +.add-match-tooltip { + position: absolute; + top: calc(100% + 8px); + right: 0; + z-index: 20; + padding: 8px 12px; + background: var(--light-background); + color: var(--pink-text); + border-radius: 10px; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); + font-size: 14px; + white-space: nowrap; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: + opacity 0.15s ease, + visibility 0.15s ease; +} + +.add-match:hover .add-match-tooltip, +.add-match:focus-within .add-match-tooltip { + opacity: 1; + visibility: visible; +} + +.add-match-button { + width: 50px; + height: 50px; + display: flex; + align-items: center; + justify-content: center; + border: none; + border-radius: 50%; + background-color: var(--dark-pink); + color: var(--text-light); + font-size: 18px; + line-height: 1; + cursor: pointer; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); +} + +.add-match-button:not(:disabled):hover { + transform: scale(1.1); +} + +.add-match-button:disabled { + opacity: 0.5; + cursor: default; + pointer-events: none; +} + @media (max-width: 767px) { .explore-page { margin-left: 0; @@ -255,4 +346,9 @@ height: 100%; transform: none; } + + .add-match-button { + width: 35px; + height: 35px; + } } diff --git a/frontend/src/pages/explorePlants/ExplorePlants.tsx b/frontend/src/pages/explorePlants/ExplorePlants.tsx index dbcd700..6a03e44 100644 --- a/frontend/src/pages/explorePlants/ExplorePlants.tsx +++ b/frontend/src/pages/explorePlants/ExplorePlants.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from "react"; import { BiSortAlt2 } from "react-icons/bi"; +import { FaSearch } from "react-icons/fa"; import { useTranslation } from "react-i18next"; import { useQuery } from "@apollo/client/react"; import { useDebounce } from "../../hooks/useDebounce"; @@ -9,6 +10,7 @@ import { type ExplorePlantsData, } from "./explorePlantsQuery.ts"; import PlantCard from "../../components/plantCard/PlantCard.tsx"; +import { useMatchedPlants } from "../../hooks/useMatchedPlants.ts"; import "./ExplorePlants.css"; const PAGE_SIZE = 12; @@ -18,6 +20,9 @@ const SORT_OPTIONS = ["name_asc", "name_desc", "watering_asc", "careLevel_asc"]; export default function ExplorePlants() { const { t } = useTranslation(); + // Same hook as PlantMatch, so both pages share the same matches + const { matches, addMatch } = useMatchedPlants(); + const [search, setSearch] = useSessionState("ExplorePlants.search"); const debouncedSearch = useDebounce(search, 800); const [watering, setWatering] = useSessionState("ExplorePlants.watering"); @@ -77,6 +82,7 @@ export default function ExplorePlants() { >