Skip to content

Commit 01ac017

Browse files
committed
refactor(promises): improve promise components and types
- Add interfaceName to PromiseList block - Update styling in Profile and DesktopMenu components - Fix children rendering order in PostCard - Comment out unused originalArticleUrl button - Improve key usage and props handling in PromiseCard and related components - Refactor Promises component with better typing and status handling - Extract PromiseListBlock type and update related interfaces
1 parent 0db2599 commit 01ac017

File tree

10 files changed

+87
-73
lines changed

10 files changed

+87
-73
lines changed

src/app/(frontend)/[entitySlug]/promises/[promiseId]/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ export default async function PromiseDetailPage({
369369
{descriptionText}
370370
</Typography>
371371
) : null}
372-
{originalArticleUrl ? (
372+
{/* {originalArticleUrl ? (
373373
<Button
374374
component="a"
375375
href={originalArticleUrl}
@@ -384,7 +384,7 @@ export default async function PromiseDetailPage({
384384
>
385385
Read the full report
386386
</Button>
387-
) : null}
387+
) : null} */}
388388
</Grid>
389389
<Grid size={{ xs: 12, lg: 4 }}>
390390
{statusDoc ? (

src/blocks/PromiseList.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Block } from "payload";
33
const PromiseList: Block = {
44
slug: "promise-list",
55
imageURL: "/cms/promises-list.png",
6+
interfaceName: "PromiseListBlock",
67
labels: {
78
singular: "Promise List",
89
plural: "Promise Lists",

src/components/Hero/Profile/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const Profile = ({
9191
color: theme.palette.primary.main,
9292
textTransform: "uppercase",
9393
mb: theme.typography.pxToRem(6),
94+
whiteSpace: "nowrap",
9495
})}
9596
>
9697
{profileTitle}

src/components/LatestPromises/LatestPromises.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,21 @@ const LatestPromises: React.FC<Props> = forwardRef(function LatestPromises({
3939
<Grid container spacing={2}>
4040
{items.map((promise: P) => (
4141
<Grid
42-
key={promise.title}
42+
key={promise.id}
4343
size={{
4444
xs: 12,
4545
lg: 4,
4646
}}
4747
>
4848
<PromiseCard
49-
{...promise}
5049
image={
5150
typeof promise.image === "string" ? undefined : promise.image
5251
}
5352
title={promise.title ?? null}
5453
status={promise.status as PromiseStatus}
54+
description={promise.description ?? null}
55+
createdAt={promise.createdAt}
56+
href={promise.url ?? undefined}
5557
/>
5658
</Grid>
5759
))}

src/components/Navigation/DesktopMenu.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export function DesktopMenu({ menus, entitySlug }: DesktopMenuProps) {
3535
height: 48,
3636
border: 0,
3737
color: theme.palette.primary.main,
38-
padding: "0.8rem 1.2rem",
3938
margin: "0.3rem",
4039
textTransform: "uppercase",
4140
fontFamily: theme.typography.fontFamily,

src/components/PostCard/PostCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,14 @@ const PostCard: FC<Props> = function PostCard({
148148
sx={mediaSx}
149149
/>
150150
) : null}
151-
{children}
152151
{description && (
153152
<CardContent sx={contentSx}>
154153
<Box display="flex" sx={descriptionContainerSx}>
155154
<Typography variant="body2">{description}</Typography>
156155
</Box>
157156
</CardContent>
158157
)}
158+
{children}
159159
</CardActionArea>
160160
</Card>
161161
);

src/components/PromiseCard/PromiseCard.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,31 @@ import React, { FC } from "react";
22

33
import PostCard from "@/components/PostCard/PostCard";
44
import Status from "@/components/PromiseStatus/PromiseStatus";
5-
import { PromiseStatus, Promise as P, Media } from "@/payload-types";
5+
import { PromiseStatus, Media } from "@/payload-types";
66

77
interface Props {
88
status: PromiseStatus;
99
href?: string;
10-
title: string | null;
10+
title?: string | null;
1111
image?: Media | null;
12+
description?: string | null;
13+
createdAt?: string;
1214
}
15+
1316
const PromiseCard: FC<Props> = function PromiseCard({
1417
status,
1518
href,
1619
title,
1720
image,
18-
...props
21+
description,
22+
createdAt,
1923
}) {
2024
return (
2125
<PostCard
22-
{...props}
26+
createdAt={createdAt}
27+
description={description ?? undefined}
2328
image={image}
24-
title={title}
29+
title={title ?? null}
2530
href={href}
2631
imageSx={{
2732
border: `8px solid ${status.colors?.color}`,

src/components/Promises/Promises.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { slugify } from "@/utils/utils";
88
import { Promise as PromiseItem, PromiseStatus } from "@/payload-types";
99
import PromiseCard from "../PromiseCard";
1010

11+
type PromiseWithHref = PromiseItem & { href?: string };
12+
1113
interface SortItem {
1214
name: string;
1315
slug: string;
@@ -22,7 +24,7 @@ interface FilterSort {
2224
items: SortItem[];
2325
}
2426
interface PromisesProps {
25-
items: PromiseItem[];
27+
items: PromiseWithHref[];
2628
title?: string;
2729
withFilter?: boolean;
2830
projectMeta?: ProjectMeta;
@@ -115,7 +117,7 @@ function Promises({
115117

116118
useEffect(() => {
117119
if (withFilter) {
118-
const hasStatus = (item: PromiseItem) => {
120+
const hasStatus = (item: PromiseWithHref) => {
119121
const promiseSlug =
120122
typeof item?.status === "object" &&
121123
item?.status !== null &&
@@ -125,7 +127,7 @@ function Promises({
125127
return selectedFilters.some((c) => c.slug === promiseSlug);
126128
};
127129

128-
let filteredItems: PromiseItem[] = [];
130+
let filteredItems: PromiseWithHref[] = [];
129131
if (filterBy === "status") {
130132
filteredItems = itemsProp.filter(hasStatus);
131133
}
@@ -232,9 +234,9 @@ function Promises({
232234
</Grid>
233235
)}
234236
<Grid spacing={1} justifyContent="space-between" container>
235-
{items.map((card: PromiseItem) => (
237+
{items.map((card: PromiseWithHref) => (
236238
<Grid
237-
key={card.title}
239+
key={card.id}
238240
size={{ xs: 12, lg: 4 }}
239241
sx={{
240242
pb: {
@@ -244,10 +246,12 @@ function Promises({
244246
}}
245247
>
246248
<PromiseCard
247-
{...card}
249+
href={card.href}
248250
title={card.title ?? null}
249251
image={typeof card.image === "string" ? undefined : card.image}
252+
description={card.description ?? null}
250253
status={card.status as PromiseStatus}
254+
createdAt={card.createdAt}
251255
/>
252256
</Grid>
253257
))}

src/components/Promises/index.tsx

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
// Create a component that renders a Promises Component
2-
31
import { getGlobalPayload } from "@/lib/payload";
42
import Promises from "./Promises";
53
import { slugify } from "@/utils/utils";
4+
import { PromiseListBlock } from "@/payload-types";
65

7-
interface Props {
8-
title?: string;
9-
filterBy?: string[];
10-
sortBy?: string[];
11-
filterByLabel?: string;
12-
sortByLabel?: string;
6+
export type PromiseListProps = PromiseListBlock & {
137
entitySlug?: string;
14-
}
15-
async function Index({
16-
title,
17-
filterBy,
18-
sortBy,
19-
filterByLabel,
20-
sortByLabel,
21-
entitySlug,
22-
}: Props) {
8+
};
9+
10+
async function Index(props: PromiseListProps) {
11+
const { title, filterBy, sortBy, filterByLabel, sortByLabel, entitySlug } =
12+
props;
2313
const payload = await getGlobalPayload();
2414

2515
const entityQuery = await payload.find({
@@ -61,22 +51,27 @@ async function Index({
6151
};
6252
}) ?? [];
6353

64-
const promiseStatuses = [
65-
...new Set(
66-
promises.map((promise) => {
67-
if (typeof promise?.status === "object" && promise?.status !== null) {
68-
return {
69-
slug: slugify(promise.status.label ?? ""),
70-
name: promise.status.label ?? "",
71-
};
72-
}
73-
return {
74-
slug: slugify(promise.status ?? ""),
75-
name: promise.status ?? "",
76-
};
77-
}),
78-
),
79-
];
54+
const promiseStatusesMap = new Map<string, { slug: string; name: string }>();
55+
56+
promises.forEach((promise) => {
57+
const statusLabel =
58+
typeof promise?.status === "object" && promise?.status !== null
59+
? promise.status.label ?? ""
60+
: (promise.status as string) ?? "";
61+
62+
const slug = slugify(statusLabel);
63+
64+
if (!slug || promiseStatusesMap.has(slug)) {
65+
return;
66+
}
67+
68+
promiseStatusesMap.set(slug, {
69+
slug,
70+
name: statusLabel,
71+
});
72+
});
73+
74+
const promiseStatuses = Array.from(promiseStatusesMap.values());
8075
const filterByOptions = {
8176
label: filterByLabel ?? "",
8277
items:
@@ -93,10 +88,9 @@ async function Index({
9388
slug: sort,
9489
})) ?? [],
9590
};
96-
// Get all promises per entity
9791
return (
9892
<Promises
99-
title={title}
93+
title={title!}
10094
items={promises}
10195
withFilter={!!sortBy?.length}
10296
filterByConfig={filterByOptions}

src/payload-types.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,7 @@ export interface Page {
436436
blockType: 'partners';
437437
}
438438
| PartnerDetailsBlock
439-
| {
440-
title?: string | null;
441-
filterByLabel?: string | null;
442-
sortByLabel?: string | null;
443-
filterBy?: ('status' | 'category')[] | null;
444-
sortBy?: ('mostRecent' | 'deadline')[] | null;
445-
id?: string | null;
446-
blockName?: string | null;
447-
blockType: 'promise-list';
448-
}
439+
| PromiseListBlock
449440
)[]
450441
| null;
451442
meta?: {
@@ -642,6 +633,20 @@ export interface PartnerDetailsBlock {
642633
blockName?: string | null;
643634
blockType: 'partner-details';
644635
}
636+
/**
637+
* This interface was referenced by `Config`'s JSON-Schema
638+
* via the `definition` "PromiseListBlock".
639+
*/
640+
export interface PromiseListBlock {
641+
title?: string | null;
642+
filterByLabel?: string | null;
643+
sortByLabel?: string | null;
644+
filterBy?: ('status' | 'category')[] | null;
645+
sortBy?: ('mostRecent' | 'deadline')[] | null;
646+
id?: string | null;
647+
blockName?: string | null;
648+
blockType: 'promise-list';
649+
}
645650
/**
646651
* This interface was referenced by `Config`'s JSON-Schema
647652
* via the `definition` "users".
@@ -1164,17 +1169,7 @@ export interface PagesSelect<T extends boolean = true> {
11641169
blockName?: T;
11651170
};
11661171
'partner-details'?: T | PartnerDetailsBlockSelect<T>;
1167-
'promise-list'?:
1168-
| T
1169-
| {
1170-
title?: T;
1171-
filterByLabel?: T;
1172-
sortByLabel?: T;
1173-
filterBy?: T;
1174-
sortBy?: T;
1175-
id?: T;
1176-
blockName?: T;
1177-
};
1172+
'promise-list'?: T | PromiseListBlockSelect<T>;
11781173
};
11791174
meta?:
11801175
| T
@@ -1283,6 +1278,19 @@ export interface PartnerDetailsBlockSelect<T extends boolean = true> {
12831278
id?: T;
12841279
blockName?: T;
12851280
}
1281+
/**
1282+
* This interface was referenced by `Config`'s JSON-Schema
1283+
* via the `definition` "PromiseListBlock_select".
1284+
*/
1285+
export interface PromiseListBlockSelect<T extends boolean = true> {
1286+
title?: T;
1287+
filterByLabel?: T;
1288+
sortByLabel?: T;
1289+
filterBy?: T;
1290+
sortBy?: T;
1291+
id?: T;
1292+
blockName?: T;
1293+
}
12861294
/**
12871295
* This interface was referenced by `Config`'s JSON-Schema
12881296
* via the `definition` "users_select".

0 commit comments

Comments
 (0)