From 6def6791b38fdc71a0548b71dda883f410034c70 Mon Sep 17 00:00:00 2001 From: Legrand Thomas Date: Fri, 27 Feb 2026 12:16:43 +0100 Subject: [PATCH 1/6] feat: define new component + activity_reports field --- .../api/about/content-types/about/schema.json | 5 + .../file-list-with-dates/file-with-date.json | 26 +++ .../1.0.0/full_documentation.json | 161 +++++++++++++++++- backend/types/generated/components.d.ts | 14 ++ backend/types/generated/contentTypes.d.ts | 4 + 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 backend/src/components/file-list-with-dates/file-with-date.json diff --git a/backend/src/api/about/content-types/about/schema.json b/backend/src/api/about/content-types/about/schema.json index 48d1d160..b5fdd1ff 100644 --- a/backend/src/api/about/content-types/about/schema.json +++ b/backend/src/api/about/content-types/about/schema.json @@ -74,6 +74,11 @@ "type": "relation", "relation": "oneToMany", "target": "api::volunteer.volunteer" + }, + "activity_reports": { + "type": "component", + "component": "file-list-with-dates.file-with-date", + "repeatable": true } } } diff --git a/backend/src/components/file-list-with-dates/file-with-date.json b/backend/src/components/file-list-with-dates/file-with-date.json new file mode 100644 index 00000000..e23a1925 --- /dev/null +++ b/backend/src/components/file-list-with-dates/file-with-date.json @@ -0,0 +1,26 @@ +{ + "collectionName": "components_file_list_with_dates_file_with_dates", + "info": { + "displayName": "File-with-date", + "icon": "filePdf" + }, + "options": {}, + "attributes": { + "date": { + "type": "date", + "required": true + }, + "file": { + "type": "media", + "multiple": false, + "required": true, + "allowedTypes": [ + "images", + "files", + "videos", + "audios" + ] + } + }, + "config": {} +} diff --git a/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json b/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json index 03adfad1..b6cce2a0 100644 --- a/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json +++ b/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json @@ -14,7 +14,7 @@ "name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html" }, - "x-generation-date": "2025-10-01T08:09:20.342Z" + "x-generation-date": "2026-02-27T11:12:11.224Z" }, "x-strapi-config": { "plugins": [ @@ -12524,6 +12524,12 @@ "example": "string or id" } }, + "activity_reports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileListWithDatesFileWithDateComponent" + } + }, "locale": { "type": "string" }, @@ -15083,6 +15089,12 @@ } } }, + "activity_reports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileListWithDatesFileWithDateComponent" + } + }, "createdAt": { "type": "string", "format": "date-time" @@ -15239,6 +15251,12 @@ } } }, + "activity_reports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileListWithDatesFileWithDateComponent" + } + }, "createdAt": { "type": "string", "format": "date-time" @@ -15764,6 +15782,147 @@ } } }, + "FileListWithDatesFileWithDateComponent": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "date": { + "type": "string", + "format": "date" + }, + "file": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "alternativeText": { + "type": "string" + }, + "caption": { + "type": "string" + }, + "width": { + "type": "integer" + }, + "height": { + "type": "integer" + }, + "formats": {}, + "hash": { + "type": "string" + }, + "ext": { + "type": "string" + }, + "mime": { + "type": "string" + }, + "size": { + "type": "number", + "format": "float" + }, + "url": { + "type": "string" + }, + "previewUrl": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "provider_metadata": {}, + "related": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + } + } + } + }, + "folder": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + } + } + }, + "folderPath": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "publishedAt": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + } + } + }, + "updatedBy": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + } + } + }, + "locale": { + "type": "string" + }, + "localizations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "documentId": { + "type": "string" + } + } + } + } + } + } + } + }, "KpiKpiComponent": { "type": "object", "properties": { diff --git a/backend/types/generated/components.d.ts b/backend/types/generated/components.d.ts index 4638836a..dcd1d134 100644 --- a/backend/types/generated/components.d.ts +++ b/backend/types/generated/components.d.ts @@ -40,6 +40,19 @@ export interface EditoEdito extends Struct.ComponentSchema { }; } +export interface FileListWithDatesFileWithDate extends Struct.ComponentSchema { + collectionName: 'components_file_list_with_dates_file_with_dates'; + info: { + displayName: 'File-with-date'; + icon: 'filePdf'; + }; + attributes: { + date: Schema.Attribute.Date & Schema.Attribute.Required; + file: Schema.Attribute.Media<'images' | 'files' | 'videos' | 'audios'> & + Schema.Attribute.Required; + }; +} + export interface GoalGoal extends Struct.ComponentSchema { collectionName: 'components_goal_goals'; info: { @@ -157,6 +170,7 @@ declare module '@strapi/strapi' { 'call-to-action.call-to-action': CallToActionCallToAction; 'call-to-action.call-to-action-with-image': CallToActionCallToActionWithImage; 'edito.edito': EditoEdito; + 'file-list-with-dates.file-with-date': FileListWithDatesFileWithDate; 'goal.goal': GoalGoal; 'hero.hero': HeroHero; 'information.information-block': InformationInformationBlock; diff --git a/backend/types/generated/contentTypes.d.ts b/backend/types/generated/contentTypes.d.ts index e4a5a042..e1c0154f 100644 --- a/backend/types/generated/contentTypes.d.ts +++ b/backend/types/generated/contentTypes.d.ts @@ -385,6 +385,10 @@ export interface ApiAboutAbout extends Struct.SingleTypeSchema { draftAndPublish: true; }; attributes: { + activity_reports: Schema.Attribute.Component< + 'file-list-with-dates.file-with-date', + true + >; board_of_directors: Schema.Attribute.Relation< 'oneToMany', 'api::volunteer.volunteer' From d3db319317a4695d6ba5df8b65c9c3d184c78266 Mon Sep 17 00:00:00 2001 From: Legrand Thomas Date: Fri, 27 Feb 2026 12:17:03 +0100 Subject: [PATCH 2/6] feat: new client types --- .../src/types/strapi/generated/components.d.ts | 14 ++++++++++++++ .../src/types/strapi/generated/contentTypes.d.ts | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/frontend/src/types/strapi/generated/components.d.ts b/frontend/src/types/strapi/generated/components.d.ts index 4638836a..dcd1d134 100644 --- a/frontend/src/types/strapi/generated/components.d.ts +++ b/frontend/src/types/strapi/generated/components.d.ts @@ -40,6 +40,19 @@ export interface EditoEdito extends Struct.ComponentSchema { }; } +export interface FileListWithDatesFileWithDate extends Struct.ComponentSchema { + collectionName: 'components_file_list_with_dates_file_with_dates'; + info: { + displayName: 'File-with-date'; + icon: 'filePdf'; + }; + attributes: { + date: Schema.Attribute.Date & Schema.Attribute.Required; + file: Schema.Attribute.Media<'images' | 'files' | 'videos' | 'audios'> & + Schema.Attribute.Required; + }; +} + export interface GoalGoal extends Struct.ComponentSchema { collectionName: 'components_goal_goals'; info: { @@ -157,6 +170,7 @@ declare module '@strapi/strapi' { 'call-to-action.call-to-action': CallToActionCallToAction; 'call-to-action.call-to-action-with-image': CallToActionCallToActionWithImage; 'edito.edito': EditoEdito; + 'file-list-with-dates.file-with-date': FileListWithDatesFileWithDate; 'goal.goal': GoalGoal; 'hero.hero': HeroHero; 'information.information-block': InformationInformationBlock; diff --git a/frontend/src/types/strapi/generated/contentTypes.d.ts b/frontend/src/types/strapi/generated/contentTypes.d.ts index e4a5a042..e1c0154f 100644 --- a/frontend/src/types/strapi/generated/contentTypes.d.ts +++ b/frontend/src/types/strapi/generated/contentTypes.d.ts @@ -385,6 +385,10 @@ export interface ApiAboutAbout extends Struct.SingleTypeSchema { draftAndPublish: true; }; attributes: { + activity_reports: Schema.Attribute.Component< + 'file-list-with-dates.file-with-date', + true + >; board_of_directors: Schema.Attribute.Relation< 'oneToMany', 'api::volunteer.volunteer' From c78eb64107c1ca30adcb93f0e8d607ba6d6d06b4 Mon Sep 17 00:00:00 2001 From: Legrand Thomas Date: Fri, 27 Feb 2026 12:17:24 +0100 Subject: [PATCH 3/6] feat: new CTA List molecule --- .../components/molecules/CtaList/CtaList.tsx | 37 +++++++++++++++++++ frontend/src/components/molecules/index.ts | 3 ++ 2 files changed, 40 insertions(+) create mode 100644 frontend/src/components/molecules/CtaList/CtaList.tsx diff --git a/frontend/src/components/molecules/CtaList/CtaList.tsx b/frontend/src/components/molecules/CtaList/CtaList.tsx new file mode 100644 index 00000000..35af04ea --- /dev/null +++ b/frontend/src/components/molecules/CtaList/CtaList.tsx @@ -0,0 +1,37 @@ +'use client'; + +import clsx from 'clsx'; +import Link from 'next/link'; +import { ArrowIcon } from '@/components'; + +export type CtaListItem = { + id: string | number; + text: string; + link: string; +}; + +export type CtaListProps = { + items: CtaListItem[]; + className?: string; +}; + +const CtaList: React.FC = ({ items, className }) => { + return ( +
+ {items.map((item) => ( + + + {item.text} + + + + ))} +
+ ); +}; + +export default CtaList; diff --git a/frontend/src/components/molecules/index.ts b/frontend/src/components/molecules/index.ts index 4509d424..80b36574 100644 --- a/frontend/src/components/molecules/index.ts +++ b/frontend/src/components/molecules/index.ts @@ -52,3 +52,6 @@ export type { LargeTextImageDonationProps } from './LargeTextImageDonation/Large export { default as CampaignBanner } from './CampaignBanner/CampaignBanner'; export type { CampaignBannerProps } from './CampaignBanner/CampaignBanner'; + +export { default as CtaList } from './CtaList/CtaList'; +export type { CtaListProps, CtaListItem } from './CtaList/CtaList'; From 65a181768ea33063d7430b4ed75b89001f23e7e0 Mon Sep 17 00:00:00 2001 From: Legrand Thomas Date: Fri, 27 Feb 2026 12:17:36 +0100 Subject: [PATCH 4/6] feat: add activity reports to about page --- frontend/src/app/[locale]/about/about.tsx | 23 ++++++++++++++++ frontend/src/app/[locale]/about/page.tsx | 33 ++++++++++++++--------- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/[locale]/about/about.tsx b/frontend/src/app/[locale]/about/about.tsx index 857a5ed3..eaace936 100644 --- a/frontend/src/app/[locale]/about/about.tsx +++ b/frontend/src/app/[locale]/about/about.tsx @@ -9,6 +9,7 @@ import { PartnersBlock, Title, TestimoniesCarousel, + CtaList, } from '@/components'; import { IMembers } from '@/lib/types'; import { AboutPageData } from './page'; @@ -84,6 +85,16 @@ function transformMembers({ ]; } +function transformActivityReports( + reports: NonNullable +) { + return reports.map(report => ({ + id: report.documentId || report.id, + text: report.date, + link: report.file?.url || '#', + })); +} + type AboutProps = { data: AboutPageData; }; @@ -100,6 +111,9 @@ export default function AboutPage({ data }: AboutProps) { strategic_committee: data.strategic_committee, division_managers: data.division_managers, }); + const activityReports = data.activity_reports + ? transformActivityReports(data.activity_reports) + : []; return ( <> @@ -198,6 +212,15 @@ export default function AboutPage({ data }: AboutProps) { categories={members} className="my-lg" /> + + {activityReports.length > 0 && ( +
+ + Rapports d'activités + + +
+ )} ); } diff --git a/frontend/src/app/[locale]/about/page.tsx b/frontend/src/app/[locale]/about/page.tsx index 9c7382d2..2ca9e4d5 100644 --- a/frontend/src/app/[locale]/about/page.tsx +++ b/frontend/src/app/[locale]/about/page.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import AboutPage from './about'; import client from '@/lib/strapi-client'; import { generateMetadataFromSeo } from '@/lib/utils'; +import AboutPage from './about'; export async function generateMetadata({ params: { locale }, @@ -49,15 +48,22 @@ async function fetchAboutPageData() { scientific_committee: { populate: "*" }, - strategic_committee: { - populate: "*" - }, - division_managers: { - populate: "*" - }, - seo_meta: { - populate: "*" - } + strategic_committee: { + populate: "*" + }, + division_managers: { + populate: "*" + }, + seo_meta: { + populate: "*" + }, + activity_reports: { + populate: { + file: { + populate: '*' + } + } + } } } } @@ -68,9 +74,10 @@ export type AboutPageData = NonNullable Date: Fri, 13 Mar 2026 16:55:41 +0100 Subject: [PATCH 5/6] fix: display year only --- frontend/src/app/[locale]/about/about.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/[locale]/about/about.tsx b/frontend/src/app/[locale]/about/about.tsx index eaace936..7e0efb6a 100644 --- a/frontend/src/app/[locale]/about/about.tsx +++ b/frontend/src/app/[locale]/about/about.tsx @@ -90,7 +90,7 @@ function transformActivityReports( ) { return reports.map(report => ({ id: report.documentId || report.id, - text: report.date, + text: new Date(report.date).getFullYear().toString(), link: report.file?.url || '#', })); } From 594cac7a487c7ffe74689f4a3e094a7085a8c77a Mon Sep 17 00:00:00 2001 From: Legrand Thomas Date: Fri, 27 Mar 2026 18:25:50 +0100 Subject: [PATCH 6/6] fix: design --- .../components/atoms/ArrowIcon/ArrowIcon.tsx | 27 ++++++++++++------- .../components/molecules/CtaList/CtaList.tsx | 12 +++++---- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/atoms/ArrowIcon/ArrowIcon.tsx b/frontend/src/components/atoms/ArrowIcon/ArrowIcon.tsx index f7cf7154..abca59b3 100644 --- a/frontend/src/components/atoms/ArrowIcon/ArrowIcon.tsx +++ b/frontend/src/components/atoms/ArrowIcon/ArrowIcon.tsx @@ -2,7 +2,7 @@ import type { HTMLAttributes } from 'react'; import clsx from 'clsx'; export type ArrowIconProps = HTMLAttributes & { - direction?: 'up' | 'down' | 'left' | 'right'; + direction?: 'up' | 'down' | 'left' | 'right' | 'download'; className?: string; }; @@ -16,13 +16,14 @@ const ArrowIcon: React.FC = ({ down: 'rotate-90', left: 'rotate-180', right: 'rotate-0', + download: 'rotate-0', }; return ( = ({ )} {...props} > - + {direction === 'download' ? ( + + ) : ( + + )} ); }; diff --git a/frontend/src/components/molecules/CtaList/CtaList.tsx b/frontend/src/components/molecules/CtaList/CtaList.tsx index 35af04ea..8742be04 100644 --- a/frontend/src/components/molecules/CtaList/CtaList.tsx +++ b/frontend/src/components/molecules/CtaList/CtaList.tsx @@ -22,12 +22,14 @@ const CtaList: React.FC = ({ items, className }) => { - - {item.text} - - +
+ + {item.text} + + +
))}