diff --git a/frontend/src/assets/avatars/anthurium.png b/frontend/src/assets/avatars/anthurium.png new file mode 100644 index 00000000..321b47dd Binary files /dev/null and b/frontend/src/assets/avatars/anthurium.png differ diff --git a/frontend/src/assets/avatars/fern.png b/frontend/src/assets/avatars/fern.png new file mode 100644 index 00000000..ee25fa9e Binary files /dev/null and b/frontend/src/assets/avatars/fern.png differ diff --git a/frontend/src/assets/avatars/monstera.png b/frontend/src/assets/avatars/monstera.png new file mode 100644 index 00000000..1a2ecf06 Binary files /dev/null and b/frontend/src/assets/avatars/monstera.png differ diff --git a/frontend/src/assets/avatars/orchid.png b/frontend/src/assets/avatars/orchid.png new file mode 100644 index 00000000..e56d69f1 Binary files /dev/null and b/frontend/src/assets/avatars/orchid.png differ diff --git a/frontend/src/assets/avatars/pothos.png b/frontend/src/assets/avatars/pothos.png new file mode 100644 index 00000000..a929145a Binary files /dev/null and b/frontend/src/assets/avatars/pothos.png differ diff --git a/frontend/src/assets/avatars/snake-plant.png b/frontend/src/assets/avatars/snake-plant.png new file mode 100644 index 00000000..9c758f42 Binary files /dev/null and b/frontend/src/assets/avatars/snake-plant.png differ diff --git a/frontend/src/assets/avatars/succulent.png b/frontend/src/assets/avatars/succulent.png new file mode 100644 index 00000000..d1b7b4e0 Binary files /dev/null and b/frontend/src/assets/avatars/succulent.png differ diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index b2e9aa0e..1088aa3e 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -66,8 +66,20 @@ "name": "Name Surname", "description": "Description", "preferences": "Preferences", - "savedPlants": "Saved plants", - "imageAlt": "Profile image" + "editProfile": "Edit profile", + "imageAlt": "Profile image", + "enterName": "Write your name", + "aboutYou": "Write something about you", + "avatarChooser": "Choose your avatar:", + "monstera": "Monstera", + "pothos": "Pothos", + "snake-plant": "Snake plant", + "anthurium": "Anthurium", + "succulent": "Succulent", + "fern": "Fern", + "orchid": "Orchid", + "placeholderName": "Enter your name", + "placeholderAbout": "Something about you..." }, "plantCard": { "information": "Information", diff --git a/frontend/src/i18n/locales/no/translation.json b/frontend/src/i18n/locales/no/translation.json index f93bd346..54e43d18 100644 --- a/frontend/src/i18n/locales/no/translation.json +++ b/frontend/src/i18n/locales/no/translation.json @@ -66,8 +66,20 @@ "name": "Navn Etternavn", "description": "Beskrivelse", "preferences": "Preferanser", - "savedPlants": "Lagrede planter", - "imageAlt": "Profilbilde" + "editProfile": "Endre profil", + "imageAlt": "Profilbilde", + "enterName": "Skriv ditt navn", + "aboutYou": "Skriv noe om deg selv", + "avatarChooser": "Velg din avatar:", + "monstera": "Monstera", + "pothos": "Gullranke", + "snake-plant": "Bajonettplante", + "anthurium": "Flamingoblomst", + "succulent": "Sukkulent", + "fern": "Bregne", + "orchid": "Orkidé", + "placeholderName": "Skriv inn navnet ditt", + "placeholderAbout": "Noe om deg..." }, "plantCard": { "information": "Informasjon", diff --git a/frontend/src/pages/profile/Profile.css b/frontend/src/pages/profile/Profile.css index 519b02ef..dc297a7a 100644 --- a/frontend/src/pages/profile/Profile.css +++ b/frontend/src/pages/profile/Profile.css @@ -2,18 +2,12 @@ margin-left: var(--sidebar-width); padding: 60px 40px 60px 100px; box-sizing: border-box; - margin-left: var(--sidebar-width); - padding: 60px 40px 200px 100px; - box-sizing: border-box; } .profile-info { display: flex; align-items: flex-start; gap: 40px; - display: flex; - align-items: flex-start; - gap: 40px; } .profile-img { @@ -21,22 +15,15 @@ height: 170px; object-fit: cover; border-radius: 50%; - width: 170px; - height: 170px; - object-fit: cover; - border-radius: 50%; } .profile-text h1 { margin-top: 0; padding-top: 20px; - margin-top: 0; - padding-top: 20px; } .profile-preferences { margin-top: 50px; - margin-top: 50px; } .profile-tabs { @@ -75,7 +62,7 @@ color: var(--text); } -.saved-plants { +.edit-profile { margin: 50px auto 0; width: 100%; background-color: var(--light-pink); @@ -84,32 +71,74 @@ box-sizing: border-box; } -.saved-plants h2 { +.edit-profile h2 { display: flex; align-items: center; justify-content: center; } -.plant-card-holder { - width: 260px; - height: 300px; - box-sizing: border-box; +.edit-profile-form { + max-width: 800px; + margin: 30px auto 0; +} + +.edit-profile-form label { + display: block; + margin-bottom: 10px; + font-weight: 600; +} - background-color: var(--light-background); +.edit-profile-form input { + width: 100%; + padding: 12px; + margin-bottom: 20px; border: 1px solid var(--dark-green); - border-radius: 12px; + border-radius: 8px; + box-sizing: border-box; + font: inherit; +} - display: flex; - align-items: center; - justify-content: center; +.edit-profile-form h3 { + margin-top: 35px; } -.saved-plants-display { - margin-top: 50px; +.edit-profile-display { display: grid; - grid-template-columns: repeat(auto-fit, 260px); - gap: 40px; - justify-content: center; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); + gap: 20px; + margin-top: 20px; +} + +.avatar-option { + padding: 10px; + border: 2px solid transparent; + border-radius: 14px; + background: var(--light-background); + cursor: pointer; + color: var(--text); +} + +.avatar-option img { + display: block; + width: 100%; + aspect-ratio: 1; + object-fit: cover; + border-radius: 50%; +} + +.avatar-option span { + display: block; + margin-top: 8px; +} + +.avatar-option.selected { + border-color: var(--dark-green); + background: var(--light-green); +} + +.avatar-option:focus-visible { + outline: 2px solid var(--dark-green); + outline-offset: 3px; } @media (max-width: 767px) { diff --git a/frontend/src/pages/profile/Profile.tsx b/frontend/src/pages/profile/Profile.tsx index 1a2d0495..3dd6eb58 100644 --- a/frontend/src/pages/profile/Profile.tsx +++ b/frontend/src/pages/profile/Profile.tsx @@ -2,25 +2,63 @@ import "./Profile.css"; import profileImg from "../../assets/profile.png"; import type { Preference } from "../../types/Preference.ts"; import { useTranslation } from "react-i18next"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import PlantPreferences from "../../components/plantPreferences/PlantPreferences.tsx"; +import monstera from "../../assets/avatars/monstera.png"; +import anthurium from "../../assets/avatars/anthurium.png"; +import fern from "../../assets/avatars/fern.png"; +import orchid from "../../assets/avatars/orchid.png"; +import pothos from "../../assets/avatars/pothos.png"; +import snakePlant from "../../assets/avatars/snake-plant.png"; +import succulent from "../../assets/avatars/succulent.png"; export default function Profile() { const { t } = useTranslation(); - const [activeTab, setActiveTab] = useState<"preferences" | "savedPlants">( - "preferences", + const [name, setName] = useState( + () => localStorage.getItem("profileName") ?? t("profile.name"), + ); + + const [description, setDescription] = useState( + () => localStorage.getItem("description") ?? t("profile.description"), ); - const plants = [ - { name: "Hydrangea" }, - { name: "Orchid" }, - { name: "Fig Tree" }, - { name: "Monstera" }, - { name: "Peony" }, - { name: "Lily" }, + const [selectedAvatar, setSelectedAvatar] = useState( + () => localStorage.getItem("profileAvatar") ?? "default", + ); + + const avatars = [ + { id: "monstera", name: t("profile.monstera"), src: monstera }, + { id: "pothos", name: t("profile.pothos"), src: pothos }, + { id: "snake-plant", name: t("profile.snake-plant"), src: snakePlant }, + { id: "anthurium", name: t("profile.anthurium"), src: anthurium }, + { id: "succulent", name: t("profile.succulent"), src: succulent }, + { id: "fern", name: t("profile.fern"), src: fern }, + { id: "orchid", name: t("profile.orchid"), src: orchid }, ]; + const currentAvatar = + selectedAvatar === "default" + ? profileImg + : (avatars.find((avatar) => avatar.id === selectedAvatar)?.src ?? + profileImg); + + useEffect(() => { + localStorage.setItem("profileName", name); + }, [name]); + + useEffect(() => { + localStorage.setItem("description", description); + }, [description]); + + useEffect(() => { + localStorage.setItem("profileAvatar", selectedAvatar); + }, [selectedAvatar]); + + const [activeTab, setActiveTab] = useState<"preferences" | "editProfile">( + "preferences", + ); + const preferences: Preference[] = [ { id: "minimumWater", translationKey: "preferences.minimumWater" }, { id: "averageWater", translationKey: "preferences.averageWater" }, @@ -38,14 +76,10 @@ export default function Profile() { return (
- {t("profile.imageAlt")} + {name}
-

{t("profile.name")}

-

{t("profile.description")}

+

{name}

+

{description}

@@ -58,10 +92,10 @@ export default function Profile() { @@ -72,15 +106,48 @@ export default function Profile() { )} - {activeTab === "savedPlants" && ( -
-

𖤘 {t("profile.savedPlants")}

-
- {plants.map((plant) => ( -
-

{plant.name}

-
- ))} + {activeTab === "editProfile" && ( +
+

⚙︎ {t("profile.editProfile")}

+
+ + setName(event.target.value)} + maxLength={40} + placeholder={t("profile.placeholderName")} + /> + + + setDescription(event.target.value)} + maxLength={100} + placeholder= {t("profile.placeholderAbout")} + /> + +

{t("profile.avatarChooser")}

+
+ {avatars.map((avatar) => ( + + ))} +
)}