From d8c141e3b9e5f3e2cd421aae33d97ae02aa9e0db Mon Sep 17 00:00:00 2001 From: DarrellRoberts Date: Mon, 27 Apr 2026 16:41:32 +0200 Subject: [PATCH 1/2] adds newest opportunities and volunteers to dashboard home page --- public/locales/de/translations.json | 6 ++++ public/locales/en/translations.json | 6 ++++ src/components/Dashboard/Home/Home.tsx | 9 +----- src/components/Dashboard/Home/HomeContent.tsx | 23 +++++++++----- .../Dashboard/Home/NewestOpportunities.tsx | 31 +++++++++++++++++++ .../Dashboard/Home/NewestVolunteers.tsx | 27 ++++++++++++++++ src/components/Dashboard/Home/styles.ts | 19 ++++++++++++ 7 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 src/components/Dashboard/Home/NewestOpportunities.tsx create mode 100644 src/components/Dashboard/Home/NewestVolunteers.tsx create mode 100644 src/components/Dashboard/Home/styles.ts diff --git a/public/locales/de/translations.json b/public/locales/de/translations.json index 22136abf..00afde9c 100644 --- a/public/locales/de/translations.json +++ b/public/locales/de/translations.json @@ -399,6 +399,12 @@ } }, "home": { + "content": { + "header": "Dashboard Startseite", + "newOpportunities": "Neueste Möglichkeiten", + "newVolunteers": "Neueste Freiwillige", + "loading": "Wird geladen..." + }, "sidebar": { "home": "Startseite", "volunteers": "Freiwillige", diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index fed0d78f..95509e2e 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -399,6 +399,12 @@ } }, "home": { + "content": { + "header": "Dashboard Home", + "newOpportunities": "Newest Opportunities", + "newVolunteers": "Newest Volunteers", + "loading": "Loading..." + }, "sidebar": { "home": "Home", "volunteers": "Volunteers", diff --git a/src/components/Dashboard/Home/Home.tsx b/src/components/Dashboard/Home/Home.tsx index 48ce7c79..4b92eb91 100644 --- a/src/components/Dashboard/Home/Home.tsx +++ b/src/components/Dashboard/Home/Home.tsx @@ -1,15 +1,8 @@ "use client"; -import styled from "styled-components"; import DashboardHomeContent from "./HomeContent"; import { DashboardLayout } from "@/components/Layout"; - -const HomeContainer = styled.div` - display: flex; - flex-direction: row; - padding: var(--dashboard-home-container-padding); - gap: var(--dashboard-home-container-gap); -`; +import { HomeContainer } from "./styles"; export function DashboardHome() { return ( diff --git a/src/components/Dashboard/Home/HomeContent.tsx b/src/components/Dashboard/Home/HomeContent.tsx index 115b8880..8ecc381b 100644 --- a/src/components/Dashboard/Home/HomeContent.tsx +++ b/src/components/Dashboard/Home/HomeContent.tsx @@ -1,16 +1,23 @@ -import { Heading2 } from "@/components/styled/text"; +import { Heading2, Heading3 } from "@/components/styled/text"; import React from "react"; -import styled from "styled-components"; - -const DashboardContentContainer = styled.div` - display: flex; - height: 300px; -`; +import { NewestOpportunities } from "./NewestOpportunities"; +import { NewestVolunteers } from "./NewestVolunteers"; +import { DashboardCardContainer, DashboardContentContainer } from "./styles"; +import { useTranslation } from "react-i18next"; export default function DashboardHomeContent() { + const { t } = useTranslation(); return ( - Dashboard Content... + {t("dashboard.home.content.header")} + {t("dashboard.home.content.newOpportunities")} + + + + {t("dashboard.home.content.newVolunteers")} + + + ); } diff --git a/src/components/Dashboard/Home/NewestOpportunities.tsx b/src/components/Dashboard/Home/NewestOpportunities.tsx new file mode 100644 index 00000000..2275339c --- /dev/null +++ b/src/components/Dashboard/Home/NewestOpportunities.tsx @@ -0,0 +1,31 @@ +import { apiPathOpportunity, apiPathOption, cacheTTL } from "@/config/constants"; +import { useGetQuery } from "@/hooks"; +import { ApiOptionLists, ApiVolunteerOpportunityGetList, OpportunityStatusType, SortOrder } from "need4deed-sdk"; +import { OpportunityCard } from "../Opportunities/OpportunityCard"; +import { useTranslation } from "react-i18next"; +import { Heading4 } from "@/components/styled/text"; + +export function NewestOpportunities() { + const { t } = useTranslation(); + const { data: apiFilterOptions } = useGetQuery({ queryKey: ["options"], apiPath: apiPathOption }); + const { data: opportunities } = useGetQuery({ + queryKey: ["opportunities"], + apiPath: `${apiPathOpportunity}/`, + params: { + limit: 2, + page: 1, + sortOrder: SortOrder.NewToOld, + filter: { status: OpportunityStatusType.NEW }, + }, + staleTime: cacheTTL, + }); + const activitiesList = apiFilterOptions?.activity; + + if (opportunities?.length === 0) { + {t("dashboard.home.content.loading")}; + } + + return opportunities?.map((opp) => ( + + )); +} diff --git a/src/components/Dashboard/Home/NewestVolunteers.tsx b/src/components/Dashboard/Home/NewestVolunteers.tsx new file mode 100644 index 00000000..16cfff19 --- /dev/null +++ b/src/components/Dashboard/Home/NewestVolunteers.tsx @@ -0,0 +1,27 @@ +import { apiPathVolunteer, cacheTTL } from "@/config/constants"; +import { useGetQuery } from "@/hooks"; +import { ApiVolunteerGetList, SortOrder, VolunteerStateEngagementType } from "need4deed-sdk"; +import VolunteerCard from "../Volunteers/VolunteerCard"; +import { Heading4 } from "@/components/styled/text"; +import { useTranslation } from "react-i18next"; + +export function NewestVolunteers() { + const { t } = useTranslation(); + const { data: volunteers } = useGetQuery({ + queryKey: ["volunteers"], + apiPath: `${apiPathVolunteer}/`, + params: { + limit: 2, + page: 1, + sortOrder: SortOrder.NewToOld, + filter: { status: VolunteerStateEngagementType.NEW }, + }, + staleTime: cacheTTL, + }); + + if (volunteers?.length === 0) { + {t("dashboard.home.content.loading")}; + } + + return volunteers?.map((vol) => ); +} diff --git a/src/components/Dashboard/Home/styles.ts b/src/components/Dashboard/Home/styles.ts new file mode 100644 index 00000000..ce5bb70e --- /dev/null +++ b/src/components/Dashboard/Home/styles.ts @@ -0,0 +1,19 @@ +import styled from "styled-components"; + +export const HomeContainer = styled.div` + display: flex; + flex-direction: row; + padding: var(--dashboard-home-container-padding); + gap: var(--dashboard-home-container-gap); +`; + +export const DashboardContentContainer = styled.div` + display: flex; + flex-direction: column; + gap: var(--dashboard-home-container-gap); +`; + +export const DashboardCardContainer = styled.div` + display: flex; + gap: var(--dashboard-home-container-gap); +`; From a4b464c9435aca12d1657db79eb5d95f59c5305a Mon Sep 17 00:00:00 2001 From: DarrellRoberts Date: Mon, 27 Apr 2026 19:20:13 +0200 Subject: [PATCH 2/2] adds correct queries, corrects loading condition & adds min height --- src/app/[lang]/globals.css | 1 + src/components/Dashboard/Home/NewestOpportunities.tsx | 8 ++++---- src/components/Dashboard/Home/NewestVolunteers.tsx | 8 ++++---- src/components/Dashboard/Home/styles.ts | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/app/[lang]/globals.css b/src/app/[lang]/globals.css index 501ea213..1ec48c5b 100644 --- a/src/app/[lang]/globals.css +++ b/src/app/[lang]/globals.css @@ -1305,6 +1305,7 @@ html { --dashboard-home-container-padding: 40px 120px 100px 132px; --dashboard-home-container-gap: 20px; + --dashboard-home-container-min-height: 300px; --search-container-height: 64px; --search-container-border-radius: 160px; diff --git a/src/components/Dashboard/Home/NewestOpportunities.tsx b/src/components/Dashboard/Home/NewestOpportunities.tsx index 2275339c..dbf62457 100644 --- a/src/components/Dashboard/Home/NewestOpportunities.tsx +++ b/src/components/Dashboard/Home/NewestOpportunities.tsx @@ -8,8 +8,8 @@ import { Heading4 } from "@/components/styled/text"; export function NewestOpportunities() { const { t } = useTranslation(); const { data: apiFilterOptions } = useGetQuery({ queryKey: ["options"], apiPath: apiPathOption }); - const { data: opportunities } = useGetQuery({ - queryKey: ["opportunities"], + const { data: opportunities, isLoading } = useGetQuery({ + queryKey: ["opportunities", "newest"], apiPath: `${apiPathOpportunity}/`, params: { limit: 2, @@ -21,8 +21,8 @@ export function NewestOpportunities() { }); const activitiesList = apiFilterOptions?.activity; - if (opportunities?.length === 0) { - {t("dashboard.home.content.loading")}; + if (isLoading) { + return {t("dashboard.home.content.loading")}; } return opportunities?.map((opp) => ( diff --git a/src/components/Dashboard/Home/NewestVolunteers.tsx b/src/components/Dashboard/Home/NewestVolunteers.tsx index 16cfff19..5674a990 100644 --- a/src/components/Dashboard/Home/NewestVolunteers.tsx +++ b/src/components/Dashboard/Home/NewestVolunteers.tsx @@ -7,8 +7,8 @@ import { useTranslation } from "react-i18next"; export function NewestVolunteers() { const { t } = useTranslation(); - const { data: volunteers } = useGetQuery({ - queryKey: ["volunteers"], + const { data: volunteers, isLoading } = useGetQuery({ + queryKey: ["volunteers", "newest"], apiPath: `${apiPathVolunteer}/`, params: { limit: 2, @@ -19,8 +19,8 @@ export function NewestVolunteers() { staleTime: cacheTTL, }); - if (volunteers?.length === 0) { - {t("dashboard.home.content.loading")}; + if (isLoading) { + return {t("dashboard.home.content.loading")}; } return volunteers?.map((vol) => ); diff --git a/src/components/Dashboard/Home/styles.ts b/src/components/Dashboard/Home/styles.ts index ce5bb70e..8a2fb268 100644 --- a/src/components/Dashboard/Home/styles.ts +++ b/src/components/Dashboard/Home/styles.ts @@ -11,6 +11,7 @@ export const DashboardContentContainer = styled.div` display: flex; flex-direction: column; gap: var(--dashboard-home-container-gap); + min-height: var(--dashboard-home-container-min-height); `; export const DashboardCardContainer = styled.div`