Skip to content

Commit

Permalink
Brochure rework
Browse files Browse the repository at this point in the history
Brochures are now generated client-side on the fly and with an upgraded UI.
  • Loading branch information
gregory-buffard committed Oct 21, 2024
1 parent a0371d2 commit cf334f0
Show file tree
Hide file tree
Showing 12 changed files with 714 additions and 9 deletions.
66 changes: 65 additions & 1 deletion web/actions/yachts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import { getClient } from "@/apollo";
import { gql } from "@apollo/client";
import { IFeatured, IFeatured as SFeatured } from "@/types/sale";
import { ICharter, INewConstruction, ISale } from "@/types/yacht";
import IYacht, { ICharter, INewConstruction, ISale } from "@/types/yacht";
import { IDestination } from "@/types/destination";
import { ICFeatured } from "@/types/charter";
import { IShipyard } from "@/types/shipyard";
import puppeteer from "puppeteer";
import { PDFDocument, PDFPage } from "pdf-lib";
import { IContext } from "@/context/view";

export const fetchFeaturedSales = async (
locale: "en" | "fr",
Expand Down Expand Up @@ -1136,3 +1139,64 @@ export const fetchSimilarNewConstructions = async (
...smallerLength.NewConstructions.docs,
];
};

export const brochurize = async ({
type,
photos,
locale,
id,
currency,
units,
}: {
type: "sale" | "charter" | "new-construction";
photos: IYacht["photos"];
locale: "en" | "fr";
id: string;
currency: IContext["currency"];
units: IContext["units"];
}) => {
const baseUrl = (
brochure: "hero" | "details" | "key-features" | number | "footer",
) => {
return `https://g-yachts.com/${locale}/brochure/${id}?type=${type}&brochure=${brochure}&currency=${currency}&length=${units.length}&weight=${units.weight}`;
},
urls = [
baseUrl("hero"),
baseUrl("details"),
/*`http://localhost:3000/${locale}/${type}/${id}/key-features`,*/ // key-features page will be available once new key-features component is implemented
...photos.gallery.map((_, i) => baseUrl(i)),
baseUrl("footer"),
],
browser = await puppeteer.launch({
headless: true,
args: ["--no-sandbox", "--disable-setuid-sandbox"],
}),
pdfBuffers: Uint8Array[] = [];

for (const url of urls) {
const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle0" });

const pdfBuffer = await page.pdf({
width: "2048px",
height: "1536px",
printBackground: true,
});

pdfBuffers.push(pdfBuffer);
await page.close();
}

await browser.close();

const mergedPdf = await PDFDocument.create();

for (const pdfBuffer of pdfBuffers) {
const pdf = await PDFDocument.load(pdfBuffer),
copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());

copiedPages.forEach((page: PDFPage) => mergedPdf.addPage(page));
}

return Buffer.from(await mergedPdf.save()).toString("base64");
};
87 changes: 87 additions & 0 deletions web/app/[locale]/brochure/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { YachtProvider } from "@/context/yacht";
import {
fetchCharter,
fetchNewConstruction,
fetchSale,
} from "@/actions/yachts";
import { getLocale } from "next-intl/server";
import {
Hero,
Details,
About,
KeyFeatures,
Photo,
Footer,
} from "@/components/yachts/yacht/brochure";
import { IContext } from "@/context/view";

const Brochure = async ({
params,
searchParams,
}: {
params: {
id: string;
};
searchParams: {
type: "sale" | "charter" | "new-construction";
brochure: "hero" | "details" | "about" | "key-features" | "footer" | string;
currency: IContext["currency"];
length: IContext["units"]["length"];
weight: IContext["units"]["weight"];
};
}) => {
const yacht = await (async () => {
switch (searchParams.type) {
case "sale":
return await fetchSale(params.id, (await getLocale()) as "en" | "fr");
case "charter":
return await fetchCharter(
params.id,
(await getLocale()) as "en" | "fr",
);
case "new-construction":
return await fetchNewConstruction(
params.id,
(await getLocale()) as "en" | "fr",
);
default:
return await fetchSale(params.id, (await getLocale()) as "en" | "fr");
}
})(),
units: IContext["units"] = {
length: searchParams.length,
weight: searchParams.weight,
};

const renderComponent = () => {
switch (searchParams.brochure) {
case "hero":
return <Hero units={units} />;
case "details":
return <Details currency={searchParams.currency} units={units} />;
case "about":
return <About />;
case "key-features":
return <KeyFeatures />;
case "footer":
return <Footer />;
default:
if (parseInt(searchParams.brochure) >= 0) {
return (
<Photo index={parseInt(searchParams.brochure)} units={units} />
);
}
return null;
}
};

return (
<YachtProvider data={yacht} type={searchParams.type}>
<main className="w-full flex flex-col justify-start items-center">
{renderComponent()}
</main>
</YachtProvider>
);
};

export default Brochure;
2 changes: 1 addition & 1 deletion web/app/[locale]/charters/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const Charter = async ({ params }: { params: { id: string } }) => {
: await fetchSimilarCharters(yacht.length)
}
title={(await getTranslations("charters")).rich("similar", {
classic: (chunks) => (
classic: (chunks: React.ReactNode) => (
<span className={"font-classic uppercase"}>{chunks}</span>
),
})}
Expand Down
Loading

0 comments on commit cf334f0

Please sign in to comment.