Skip to content

Commit bb9e204

Browse files
committed
CMS-45730 Update Alloy template: Refactor next.config, enhance page layout with Header and Footer, improve News component image handling, and enforce Button link requirement
1 parent 151674e commit bb9e204

File tree

5 files changed

+34
-36
lines changed

5 files changed

+34
-36
lines changed

templates/alloy-template/next.config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import type { NextConfig } from 'next';
22

3+
const CMS_DOMAIN =
4+
process.env.OPTIMIZELY_CMS_URL?.replace('https://', '') || '';
5+
36
const nextConfig: NextConfig = {
47
images: {
5-
domains: ['app-opinjssdk1sob7t001.cms.optimizely.com'],
8+
domains: [CMS_DOMAIN],
69
remotePatterns: [
710
{
811
protocol: 'https',

templates/alloy-template/src/app/preview/page.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { GraphClient, type PreviewParams } from '@optimizely/cms-sdk';
22
import { OptimizelyComponent } from '@optimizely/cms-sdk/react/server';
33
import { PreviewComponent } from '@optimizely/cms-sdk/react/client';
44
import Script from 'next/script';
5+
import Header from '@/components/base/Header';
6+
import Footer from '@/components/base/Footer';
57

68
type Props = {
79
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
@@ -29,7 +31,11 @@ export default async function Page({ searchParams }: Props) {
2931
src={`${process.env.OPTIMIZELY_CMS_URL}/util/javascript/communicationinjector.js`}
3032
></Script>
3133
<PreviewComponent />
32-
<OptimizelyComponent opti={response} />
34+
<Header client={client} currentPath={'/'} />
35+
<div className="container mx-auto p-10">
36+
<OptimizelyComponent opti={response} />
37+
</div>
38+
<Footer client={client} />
3339
</>
3440
);
3541
}

templates/alloy-template/src/components/News.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { contentType, Infer } from '@optimizely/cms-sdk';
1+
import { contentType, Infer, damAssets } from '@optimizely/cms-sdk';
22
import { RichText } from '@optimizely/cms-sdk/react/richText';
33
import {
44
ComponentContainerProps,
@@ -48,7 +48,8 @@ function ComponentWrapper({ children, node }: ComponentContainerProps) {
4848
}
4949

5050
function News({ opti }: NewsPageProps) {
51-
const { pa } = getPreviewUtils(opti);
51+
const { pa, src } = getPreviewUtils(opti);
52+
const { getAlt, getSrcset } = damAssets(opti);
5253
return (
5354
<main className="min-h-screen bg-white">
5455
<div className="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
@@ -75,6 +76,13 @@ function News({ opti }: NewsPageProps) {
7576
<div className="space-y-6">
7677
<RichText {...pa('main_body')} content={opti.main_body?.json} />
7778
</div>
79+
80+
<img
81+
{...pa('image')}
82+
src={src(opti.image)}
83+
alt={getAlt(opti.image, 'Teaser Image')}
84+
className="w-full rounded-lg object-cover"
85+
/>
7886
</div>
7987

8088
<OptimizelyExperience

templates/alloy-template/src/components/base/Button.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const ButtonContentType = contentType({
1111
type: 'url',
1212
displayName: 'Button Link',
1313
group: 'Information',
14+
required: true,
1415
},
1516
text: {
1617
type: 'string',

templates/alloy-template/src/components/base/Footer.tsx

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,50 +14,30 @@ interface FooterProps {
1414
client: GraphClient;
1515
}
1616

17+
const mapToLinks = (items: any[] | null) =>
18+
items?.map((item: any) => ({
19+
label: item._metadata?.displayName,
20+
href: item._metadata?.url?.hierarchical,
21+
})) ?? [];
22+
1723
async function Footer({ client }: FooterProps) {
18-
const allLinks = await Promise.all([
24+
const [products, company, newsEvents] = await Promise.all([
1925
client.getItems('/en/'),
2026
client.getItems('/en/about-us'),
2127
client.getItems('/en/about-us/news-events'),
2228
]);
2329

24-
// Flatten the array of arrays and map to FooterLink format
25-
const footerLinks = allLinks.flat().map((ancestor: any) => ({
26-
key: ancestor._metadata?.key,
27-
label: ancestor._metadata?.displayName,
28-
href: ancestor._metadata?.url?.hierarchical,
29-
}));
30-
31-
// Group links by category based on URL patterns
32-
const categorizedLinks = footerLinks.reduce<{
33-
products: FooterLink[];
34-
company: FooterLink[];
35-
news: FooterLink[];
36-
}>(
37-
(acc, link) => {
38-
if (link.href?.match(/\/about-us\/news-events\/.+/)) {
39-
acc.news.push({ label: link.label, href: link.href });
40-
} else if (link.href?.includes('/about-us')) {
41-
acc.company.push({ label: link.label, href: link.href });
42-
} else if (link.href) {
43-
acc.products.push({ label: link.label, href: link.href });
44-
}
45-
return acc;
46-
},
47-
{ products: [], company: [], news: [] }
48-
);
49-
50-
const formattedFooterLink: FooterSection[] = [
51-
{ title: 'PRODUCTS', links: categorizedLinks.products },
52-
{ title: 'THE COMPANY', links: categorizedLinks.company },
53-
{ title: 'NEWS & EVENTS', links: categorizedLinks.news },
30+
const sections: FooterSection[] = [
31+
{ title: 'PRODUCTS', links: mapToLinks(products) },
32+
{ title: 'THE COMPANY', links: mapToLinks(company) },
33+
{ title: 'NEWS & EVENTS', links: mapToLinks(newsEvents) },
5434
];
5535

5636
return (
5737
<footer className="bg-gray-800 text-white">
5838
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
5939
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
60-
{formattedFooterLink.map((section, index) => (
40+
{sections.map((section, index) => (
6141
<div key={index} className="space-y-4">
6242
<h3 className="text-sm font-bold uppercase tracking-wider text-white">
6343
{section.title}

0 commit comments

Comments
 (0)