Skip to content

Commit

Permalink
feat: allow installer to pull the installerId from searchParams
Browse files Browse the repository at this point in the history
this required a refactor of the root layout and modifications to the way
we handle `Metadata`.

- [ ] figure out how to use `searchParams` in the `generateMetadata`
- [ ] ensure the metadata is generated well regardless of what method we
      use to get the installerId.
  • Loading branch information
fidiego committed Aug 28, 2024
1 parent 9c03a62 commit 23aa4d1
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 85 deletions.
6 changes: 5 additions & 1 deletion app/[installer-slug]/[install-id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {
} from "@/app/[installer-slug]/actions";
import { getAppBySlug, getInstaller } from "@/common";
import { Link } from "@/components";

import { Footer } from "@/components/Footer";

import InstallStepper from "@/components/InstallStepper";
import { getCloudPlatformRegions } from "@/common";

Expand All @@ -14,7 +17,7 @@ export default async function Installer({ params, searchParams }) {

const [app, installer, install] = await Promise.all([
getAppBySlug(slug),
getInstaller(),
getInstaller(searchParams ? searchParams.installerId : null),
getInstall(installId),
]);
const regions = await getCloudPlatformRegions(app.cloud_platform);
Expand Down Expand Up @@ -55,6 +58,7 @@ export default async function Installer({ params, searchParams }) {
regions={regions}
/>
</main>
<Footer {...installer.metadata} />
</>
);
}
5 changes: 3 additions & 2 deletions app/[installer-slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import {
} from "@/app/[installer-slug]/actions";
import { getAppBySlug, getInstaller } from "@/common";
import { Link } from "@/components";
import { Footer } from "@/components/Footer";
import InstallStepper from "@/components/InstallStepper";
import { getCloudPlatformRegions } from "@/common";

export default async function Installer({ params, searchParams }) {
const slug = params?.["installer-slug"];
const [app, installer] = await Promise.all([
getAppBySlug(slug),
getInstaller(),
getInstaller(searchParams ? searchParams.installerId : null),
]);
const regions = await getCloudPlatformRegions(app.cloud_platform);

Expand All @@ -39,7 +40,6 @@ export default async function Installer({ params, searchParams }) {
<p>{app?.description}</p>
</div>
</header>

<main className="flex-auto" id="steps">
<InstallStepper
app={app}
Expand All @@ -52,6 +52,7 @@ export default async function Installer({ params, searchParams }) {
regions={regions}
/>
</main>
<Footer {...installer.metadata} />
</>
);
}
76 changes: 5 additions & 71 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,27 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import React from "react";
import { getInstaller } from "@/common";
import { Link, PoweredByNuon } from "@/components";
import { Markdown } from "@/components/Markdown";
import "./globals.css";
import theme from "@/theme";

const inter = Inter({ subsets: ["latin"] });

export async function generateMetadata(): Promise<Metadata> {
const { metadata } = await getInstaller();

return {
title: metadata.name,
description: metadata.description,
icons: {
icon: metadata.favicon_url,
shortcut: metadata.favicon_url,
},
openGraph: {
title: metadata.name,
description: metadata.description,
type: "website",
images: [
{
url: metadata.og_image_url,
},
],
},
twitter: {
title: metadata.name,
description: metadata.description,
images: [
{
url: metadata.logo_url,
},
],
},
};
}

const missingData = {
orgName: "Nuon",
};

export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { metadata } = await getInstaller();

return (
<html
className={`${theme.forceDarkMode ? "dark" : ""} bg-white dark:bg-black text-black dark:text-white`}
lang="en"
>
<body className={`${inter.className} w-full h-dvh`}>
<div className="flex flex-col w-full max-w-5xl mx-auto p-6 py-12 gap-6 md:gap-12">
<div
className="flex flex-col w-full max-w-5xl mx-auto p-6 py-12 gap-6 md:gap-12"
id="content-wapper
"
>
{children}
<footer className="flex items-center justify-between">
<div className="flex gap-2 items-center">
{metadata.copyright_markdown ? (
<Markdown content={metadata.copyright_markdown} />
) : (
<>
<span className="text-xs">
&copy; {new Date().getFullYear()}
</span>
<Link
href={metadata.homepage_url}
className="text-xs"
target="_blank"
rel="noreferrer"
>
{missingData.orgName}
</Link>
</>
)}
</div>
<div className="flex gap-6 items-center">
{metadata.footer_markdown ? (
<Markdown content={metadata.footer_markdown} />
) : (
<PoweredByNuon />
)}
</div>
</footer>
</div>
</body>
</html>
Expand Down
51 changes: 50 additions & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,56 @@
import { getInstaller } from "@/common";
import { Link, Video, Card } from "@/components";
import { Footer } from "@/components/Footer";

import type { Metadata } from "next";

type Props = {
searchParams: { [key: string]: string | string[] | undefined };
};

export async function generateMetadata({
searchParams,
}: Props): Promise<Metadata> {
const { metadata } = await getInstaller(
searchParams ? searchParams.installerId : null,
);

// TODO(fd): we need to address this.
if (!!!metadata) {
return {};
}

return {
title: metadata.name,
description: metadata.description,
icons: {
icon: metadata.favicon_url,
shortcut: metadata.favicon_url,
},
openGraph: {
title: metadata.name,
description: metadata.description,
type: "website",
images: [
{
url: metadata.og_image_url,
},
],
},
twitter: {
title: metadata.name,
description: metadata.description,
images: [
{
url: metadata.logo_url,
},
],
},
};
}

export default async function Home({ searchParams }) {
const { metadata, apps } = await getInstaller();
const { metadata, apps } = await getInstaller(searchParams.installerId);
const queryString = new URLSearchParams(searchParams).toString();
const demoUrl = metadata.formatted_demo_url || metadata.demo_url;
const isDemoUrlValid = /^((http|https):\/\/)/.test(demoUrl);
Expand Down Expand Up @@ -50,6 +98,7 @@ export default async function Home({ searchParams }) {
))}
</div>
</main>
<Footer {...metadata} />
</>
);
}
32 changes: 22 additions & 10 deletions common/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
export const NUON_API_URL =
process?.env?.NUON_API_URL || "https://ctl.prod.nuon.co";

export async function getInstaller(): Promise<Record<string, any>> {
const res = await fetch(
`${NUON_API_URL}/v1/installers/${process.env?.NUON_INSTALLER_ID}`,
{
cache: "no-store",
headers: {
Authorization: `Bearer ${process?.env?.NUON_API_TOKEN}`,
"X-Nuon-Org-ID": process.env?.NUON_ORG_ID || "",
},
export async function getInstaller(
installerId: string[] | string | null | undefined, // man, this is why we use any
): Promise<Record<string, any>> {
let nuonInstallerId = process.env?.NUON_INSTALLER_ID;
if (installerId !== null && installerId !== undefined) {
nuonInstallerId = String(installerId); // cast here to silence the linter
console.debug(`Using installerId from arg: ${nuonInstallerId}`);
} else {
console.debug(`Using installerId from env: ${nuonInstallerId}`);
}
let url = `${NUON_API_URL}/v1/installers/${nuonInstallerId}`;
const res = await fetch(url, {
cache: "no-store",
headers: {
Authorization: `Bearer ${process?.env?.NUON_API_TOKEN}`,
"X-Nuon-Org-ID": process.env?.NUON_ORG_ID || "",
},
);
});
if (res.status > 300) {
console.error(
`[${res.status}] Encountered an error while fetching installer. url=${url}`,
);
}

return res.json();
}
Expand Down
35 changes: 35 additions & 0 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Link, PoweredByNuon } from "@/components";
import { Markdown } from "@/components/Markdown";

const missingData = {
orgName: "Nuon",
};

export const Footer = (metadata: any) => (
<footer className="flex items-center justify-between">
<div className="flex gap-2 items-center">
{metadata.copyright_markdown ? (
<Markdown content={metadata.copyright_markdown} />
) : (
<>
<span className="text-xs">&copy; {new Date().getFullYear()}</span>
<Link
href={metadata.homepage_url}
className="text-xs"
target="_blank"
rel="noreferrer"
>
{missingData.orgName}
</Link>
</>
)}
</div>
<div className="flex gap-6 items-center">
{metadata.footer_markdown ? (
<Markdown content={metadata.footer_markdown} />
) : (
<PoweredByNuon />
)}
</div>
</footer>
);

0 comments on commit 23aa4d1

Please sign in to comment.