Skip to content

Commit cabd3f5

Browse files
committed
refactor(media): remove payload param from resolveMedia and use global payload
refactor(homepage): simplify CommonHomePage and TenantList components - Remove unused imports and simplify component logic - Move tenant selector settings to global payload feat(homepage): add entity selector settings and empty state labels - Add emptyListLabel for tenant selector - Add emptyTitle and EmptySubtitle for entity selector chore: remove LocalhostWarning component and related checks
1 parent 85427bc commit cabd3f5

File tree

9 files changed

+116
-134
lines changed

9 files changed

+116
-134
lines changed

src/app/(frontend)/[...slugs]/page.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import React, { Suspense } from "react";
33
import { queryPageBySlug } from "@/lib/payload";
44
import { notFound } from "next/navigation";
55
import { getDomain } from "@/lib/domain";
6-
import { LocalhostWarning } from "@/components/LocalhostWarning";
76
import { CommonHomePage } from "@/components/CommonHomePage";
87
import { BlockRenderer } from "@/components/BlockRenderer";
98
import Navigation from "@/components/Navigation";
@@ -22,11 +21,7 @@ type Args = {
2221
};
2322

2423
export default async function Page(params: Args) {
25-
const { isLocalhost, subdomain } = await getDomain();
26-
27-
if (isLocalhost) {
28-
return <LocalhostWarning />;
29-
}
24+
const { subdomain } = await getDomain();
3025

3126
const tenant = await getTenantBySubDomain(subdomain);
3227

@@ -44,13 +39,13 @@ export default async function Page(params: Args) {
4439
const politicalEntities = await getPoliticalEntitiesByTenant(tenant);
4540

4641
const politicalEntity = politicalEntities.find(
47-
(entity) => entity.slug === maybePoliticalEntitySlug,
42+
(entity) => entity.slug === maybePoliticalEntitySlug
4843
);
4944

5045
if (!politicalEntity) {
5146
const fallbackPageSlugs = slugs.length > 0 ? slugs : ["index"];
5247
const extractionCounts = await getExtractionCountsForEntities(
53-
politicalEntities.map((entity) => entity.id),
48+
politicalEntities.map((entity) => entity.id)
5449
);
5550

5651
return (

src/components/CommonHomePage.tsx

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,11 @@
1-
import { TenantList, getTenantLinks } from "./TenantList";
2-
import { getGlobalPayload } from "@/lib/payload";
3-
import type { HomePage as HomePageSettings } from "@/payload-types";
4-
import { Box, Card, CardContent, Container, Typography } from "@mui/material";
1+
import { TenantList } from "./TenantList";
2+
import { Box, Container } from "@mui/material";
53

64
export const CommonHomePage = async () => {
7-
const payload = await getGlobalPayload();
8-
9-
const settings = await payload.findGlobal({
10-
slug: "home-page",
11-
});
12-
13-
const tenantLinks = await getTenantLinks();
14-
155
return (
166
<Box component="main" sx={{ bgcolor: "background.default" }}>
177
<Container maxWidth="lg" sx={{ py: { xs: 6, md: 10 } }}>
18-
{tenantLinks.length === 0 ? (
19-
<Card variant="outlined">
20-
<CardContent>
21-
<Typography variant="h6" sx={{ fontWeight: 600 }}>
22-
No tenants available yet
23-
</Typography>
24-
<Typography variant="body2">
25-
Once tenants are published they will appear here automatically.
26-
</Typography>
27-
</CardContent>
28-
</Card>
29-
) : (
30-
<TenantList
31-
items={tenantLinks}
32-
title={settings.tenantSelector.title}
33-
subtitle={settings.tenantSelector.subtitle}
34-
/>
35-
)}
8+
<TenantList />
369
</Container>
3710
</Box>
3811
);

src/components/Hero/index.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,11 @@ export const Hero = async ({ entitySlug, ...block }: HeroProps) => {
263263

264264
const groups = buildChartGroups(block.chartGroups, statusSummaries);
265265

266-
const summaries: HeroStatusSummary[] = Array.from(statusSummaries.values()).map(
267-
(summary) => ({ ...summary })
268-
);
266+
const summaries: HeroStatusSummary[] = Array.from(
267+
statusSummaries.values()
268+
).map((summary) => ({ ...summary }));
269269

270-
const entityImage = await resolveMedia(payload, entity.image);
270+
const entityImage = await resolveMedia(entity.image);
271271

272272
const taglineText = block.tagline?.trim();
273273
const headline = {
@@ -283,7 +283,8 @@ export const Hero = async ({ entitySlug, ...block }: HeroProps) => {
283283

284284
const copyPromiseLabel = block.promiseLabel?.trim() || "promises tracked";
285285
const copyTrailText = block.trailText?.trim() || "tracked on PromiseTracker.";
286-
const statusListTitle = block.statusListTitle?.trim() || "Promise status definitions";
286+
const statusListTitle =
287+
block.statusListTitle?.trim() || "Promise status definitions";
287288
const updatedAtLabel = block.updatedAtLabel?.trim() || "Last updated";
288289

289290
const resolvedData: HeroResolvedData = {

src/components/LocalhostWarning.tsx

Lines changed: 0 additions & 51 deletions
This file was deleted.

src/components/PoliticalEntityList.tsx

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import {
1414
Stack,
1515
Typography,
1616
} from "@mui/material";
17-
import type { Media, PoliticalEntity, Tenant } from "@/payload-types";
17+
import type { PoliticalEntity, Tenant } from "@/payload-types";
18+
import { getGlobalPayload } from "@/lib/payload";
19+
import { resolveMedia } from "@/lib/data/media";
1820

1921
type PoliticalEntityListProps = {
2022
tenant: Tenant;
@@ -36,36 +38,28 @@ const buildHref = (entity: PoliticalEntity, pageSlugs: string[] = []) => {
3638
return `/${segments.join("/")}`;
3739
};
3840

39-
const resolveImage = (image: PoliticalEntity["image"]): Media | null => {
40-
if (!image || typeof image === "string") return null;
41-
return image as Media;
42-
};
43-
44-
export const PoliticalEntityList = ({
45-
tenant,
41+
export const PoliticalEntityList = async ({
4642
politicalEntities,
4743
pageSlugs = [],
4844
extractionCounts = {},
4945
}: PoliticalEntityListProps) => {
5046
const hasEntities = politicalEntities.length > 0;
5147

48+
const payload = await getGlobalPayload();
49+
50+
const { entitySelector } = await payload.findGlobal({
51+
slug: "home-page",
52+
});
53+
5254
return (
5355
<Container component="section" sx={{ py: { xs: 6, md: 8 } }}>
54-
<Stack spacing={2} sx={{ mb: { xs: 4, md: 5 } }}>
55-
<Typography variant="body1">
56-
{hasEntities
57-
? "Choose a political entity to explore their campaign promises."
58-
: "No political entities are available for this tenant yet."}
59-
</Typography>
60-
</Stack>
61-
6256
{hasEntities ? (
6357
<Card variant="outlined" sx={{ borderRadius: 2 }}>
6458
<CardContent sx={{ p: { xs: 2, md: 3 } }}>
6559
<List disablePadding sx={{ "& > * + *": { mt: 1 } }}>
66-
{politicalEntities.map((entity, index) => {
60+
{politicalEntities.map(async (entity, index) => {
6761
const href = buildHref(entity, pageSlugs);
68-
const media = resolveImage(entity.image);
62+
const media = await resolveMedia(entity.image);
6963
const extractionCount = extractionCounts[entity.id] ?? 0;
7064
const initials = entity.name
7165
.split(" ")
@@ -154,10 +148,10 @@ export const PoliticalEntityList = ({
154148
<Card variant="outlined">
155149
<CardContent>
156150
<Typography variant="h6" sx={{ fontWeight: 600 }}>
157-
No political entities have been published yet
151+
{entitySelector.emptyTitle}
158152
</Typography>
159153
<Typography variant="body2">
160-
Check back soon for newly tracked leaders and their promises.
154+
{entitySelector.EmptySubtitle}
161155
</Typography>
162156
</CardContent>
163157
</Card>

src/components/TenantList.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ListItemText,
1616
Typography,
1717
} from "@mui/material";
18+
import { getGlobalPayload } from "@/lib/payload";
1819

1920
export type TenantLink = {
2021
id: string;
@@ -88,32 +89,37 @@ export const getTenantLinks = async (): Promise<TenantLink[]> => {
8889
};
8990

9091
type TenantListProps = {
91-
items?: TenantLink[];
9292
dense?: boolean;
93-
title?: string;
94-
subtitle?: string;
9593
};
9694

97-
export const TenantList = async ({
98-
items,
99-
dense = false,
100-
title = "Available Tenants",
101-
subtitle = "Open a tenant site to explore its promises",
102-
}: TenantListProps) => {
103-
const tenantLinks = items ?? (await getTenantLinks());
95+
export const TenantList = async ({ dense = false }: TenantListProps) => {
96+
const tenantLinks = await getTenantLinks();
97+
const payload = await getGlobalPayload();
98+
99+
const { tenantSelector } = await payload.findGlobal({
100+
slug: "home-page",
101+
});
104102

105103
if (tenantLinks.length === 0) {
106-
return null;
104+
return (
105+
<Card>
106+
<CardContent sx={{ p: { xs: 2, md: 3 } }}>
107+
<Typography variant="body1">
108+
{tenantSelector.emptyListLabel}
109+
</Typography>
110+
</CardContent>
111+
</Card>
112+
);
107113
}
108114

109115
return (
110116
<Card variant="outlined" sx={{ borderRadius: 2 }}>
111117
<CardContent sx={{ p: { xs: 2, md: 3 } }}>
112118
<Typography variant="h5" sx={{ fontWeight: 600 }}>
113-
{title}
119+
{tenantSelector.title}
114120
</Typography>
115121
<Typography variant="body2" sx={{ mb: 3 }}>
116-
{subtitle}
122+
{tenantSelector.subtitle}
117123
</Typography>
118124
<List disablePadding dense={dense}>
119125
{tenantLinks.map((tenant, index) => {
@@ -156,7 +162,7 @@ export const TenantList = async ({
156162
href={tenant.url}
157163
target="_blank"
158164
rel="noopener noreferrer"
159-
label="Visit"
165+
label={tenantSelector.ctaLabel}
160166
clickable
161167
color="primary"
162168
sx={{ ml: 2 }}

src/globals/HomePage.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ export const HomePage: GlobalConfig = {
1313
},
1414
},
1515
fields: [
16+
{
17+
name: "title",
18+
type: "text",
19+
admin: {
20+
hidden: true,
21+
},
22+
},
1623
{
1724
type: "tabs",
1825
tabs: [
@@ -61,6 +68,52 @@ export const HomePage: GlobalConfig = {
6168
},
6269
defaultValue: "Open tenant site",
6370
},
71+
{
72+
name: "emptyListLabel",
73+
type: "text",
74+
required: true,
75+
label: {
76+
en: "Empty Tenant List Label",
77+
fr: "Étiquette de liste de locataires vide",
78+
},
79+
defaultValue: "No tenants created yet",
80+
},
81+
],
82+
},
83+
],
84+
},
85+
{
86+
label: {
87+
en: "Entity Selector",
88+
fr: "Sélecteur d'entité",
89+
},
90+
fields: [
91+
{
92+
name: "entitySelector",
93+
type: "group",
94+
fields: [
95+
{
96+
name: "emptyTitle",
97+
type: "text",
98+
required: true,
99+
label: {
100+
en: "Empty List Title",
101+
fr: "Titre de la liste vide",
102+
},
103+
defaultValue:
104+
"No political entities have been published yet for this tenant",
105+
},
106+
{
107+
name: "EmptySubtitle",
108+
type: "textarea",
109+
required: true,
110+
label: {
111+
en: "Empty List Subtitle",
112+
fr: "Sous-titre de la liste vide",
113+
},
114+
defaultValue:
115+
"Check back soon for newly tracked leaders and their promises.",
116+
},
64117
],
65118
},
66119
],

src/lib/data/media.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
"use server";
22
import type { Media } from "@/payload-types";
3-
import type { BasePayload } from "payload";
3+
import { getGlobalPayload } from "@/lib/payload";
44

55
type ResolvedMedia = {
66
url: string;
77
alt: string;
88
};
99

10-
/**
11-
* Resolve a media relationship into a usable URL + alt pair.
12-
* Returns null when the media record cannot be found or is missing a URL.
13-
*/
1410
export const resolveMedia = async (
15-
payload: BasePayload,
1611
media: string | Media | null | undefined
1712
): Promise<ResolvedMedia | null> => {
13+
const payload = await getGlobalPayload();
14+
1815
if (!media) {
1916
return null;
2017
}

0 commit comments

Comments
 (0)