Skip to content

Commit

Permalink
Merge pull request #247 from roodjong/add-boardmember-collection
Browse files Browse the repository at this point in the history
Add boardmember collectiontype for nicer layout
  • Loading branch information
pingiun authored Oct 13, 2024
2 parents 11a1e76 + 3d9e6bb commit 997425c
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 5 deletions.
42 changes: 42 additions & 0 deletions backend/src/api/boardmember/content-types/boardmember/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"kind": "collectionType",
"collectionName": "boardmembers",
"info": {
"singularName": "boardmember",
"pluralName": "boardmembers",
"displayName": "Bestuurslid",
"description": ""
},
"options": {
"draftAndPublish": true
},
"pluginOptions": {},
"attributes": {
"name": {
"type": "string",
"required": true
},
"role": {
"type": "string",
"required": false
},
"email": {
"type": "email",
"required": false
},
"extra": {
"type": "richtext"
},
"photo": {
"type": "media",
"multiple": false,
"required": false,
"allowedTypes": ["images"]
},
"order": {
"type": "integer",
"required": true,
"default": 10
}
}
}
9 changes: 9 additions & 0 deletions backend/src/api/boardmember/controllers/boardmember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use strict";

/**
* boardmember controller
*/

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::boardmember.boardmember");
9 changes: 9 additions & 0 deletions backend/src/api/boardmember/routes/boardmember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use strict";

/**
* boardmember router
*/

const { createCoreRouter } = require("@strapi/strapi").factories;

module.exports = createCoreRouter("api::boardmember.boardmember");
9 changes: 9 additions & 0 deletions backend/src/api/boardmember/services/boardmember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use strict";

/**
* boardmember service
*/

const { createCoreService } = require("@strapi/strapi").factories;

module.exports = createCoreService("api::boardmember.boardmember");
54 changes: 54 additions & 0 deletions frontend/src/components/BoardmemberCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Image from "next/image";
import imageLoader from "../utils/image-loader";
import { Boardmember } from "../models/Boardmember";
import Subheader from "./Subheader";
import { IconContext } from "react-icons";
import { FaEnvelope, FaPhone } from "react-icons/fa";
import Markdown from "./Markdown";

interface Props {
boardmember: Boardmember;
}

export default function BoardmemberCard(props: Props) {
const boardmember = props.boardmember;
return (
<div className="flex flex-col md:flex-row gap-8 mb-8 shadow-inner bg-gray-50 p-4 rounded">
<div className="float-right relative md:min-w-[10rem] h-[10rem] rounded shadow-lg overflow-hidden">
{boardmember.photo && (
<Image
src={boardmember.photo}
fill
sizes="10rem"
className="object-cover"
loader={imageLoader}
alt={`Foto van ${boardmember.name}`}
/>
)}
</div>
<div>
<Subheader>{boardmember.name}</Subheader>
<p>{boardmember.role}</p>
<div className="flex flex-col text-base my-4 gap-4 text-primary">
<IconContext.Provider
value={{
className:
"!text-primary origin-center group-hover:scale-125 transition-transform inline mr-2",
}}
>
<p>
<a
className="group hover:underline"
href={`mailto:${boardmember.email}`}
>
{boardmember.email && <FaEnvelope />}
{boardmember.email}
</a>
</p>
</IconContext.Provider>
</div>
<Markdown content={boardmember.extra} />
</div>
</div>
);
}
7 changes: 7 additions & 0 deletions frontend/src/models/Boardmember.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface Boardmember {
name: string;
role: string;
email: string;
extra: string;
photo: string;
}
21 changes: 16 additions & 5 deletions frontend/src/pages/over-ons.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { fetchAboutUs } from "../utils/backend";
import { fetchAboutUs, fetchBoardmembers } from "../utils/backend";
import AboutUsContent from "../models/AboutUsContent";
import Markdown from "../components/Markdown";
import Banner from "../components/Banner";
import Main from "../components/Main";
import { GetStaticPropsResult } from "next";
import { revalidate } from "../utils/revalidate";
import HeadPage from "../components/HeadPage";
import BoardmemberCard from "../components/BoardmemberCard";
import { Boardmember } from "../models/Boardmember";

interface Props {
content: AboutUsContent;
boardmembers: Boardmember[];
}

export default function OverOnsPage(props: Props) {
Expand All @@ -21,17 +24,25 @@ export default function OverOnsPage(props: Props) {
/>
<Banner title="Over ons" background={props.content.banner} compact />
<Main className="container">
<Markdown content={props.content.content} />
<div className="mb-8">
<Markdown content={props.content.content} />
</div>
{props.boardmembers.map((boardmember) => (
<BoardmemberCard key={boardmember.name} boardmember={boardmember} />
))}
</Main>
</div>
);
}

export async function getStaticProps(): Promise<GetStaticPropsResult<Props>> {
const [content, boardmembers] = await Promise.all([
fetchAboutUs(),
fetchBoardmembers(),
]);

return {
props: {
content: await fetchAboutUs(),
},
props: { content, boardmembers },
revalidate,
};
}
21 changes: 21 additions & 0 deletions frontend/src/utils/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ProgramContent from "../models/ProgramContent";
import Fallback from "../models/Fallback";
import { PetitionDetail } from "../models/Petition";
import WorkgroupPageContent from "../models/WorkgroupPageContent";
import { Boardmember } from "../models/Boardmember";

export const backendBaseUrl =
process.env.BACKEND_URL ?? process.env.NEXT_PUBLIC_BACKEND_URL ?? "";
Expand Down Expand Up @@ -84,6 +85,26 @@ export async function fetchAboutUs(): Promise<AboutUsContent> {
return sanitise(response.data.data.attributes);
}

export async function fetchBoardmembers(): Promise<Boardmember[]> {
const response = await backend.get<StrapiListResponse<Boardmember>>("/boardmembers", {
params: {
sort: "order",
populate: {
photo: {
fields: ["url"],
},
},
},
});

function sanitise(boardmember: any): Boardmember {
boardmember.photo = boardmember.photo.data?.attributes?.url ?? null;
return boardmember;
}

return response.data.data.map((it) => sanitise(it.attributes));
}

export async function fetchProgram(): Promise<ProgramContent> {
const response = await backend.get<StrapiResponse<ProgramContent>>("/program", {
params: {
Expand Down

0 comments on commit 997425c

Please sign in to comment.