Skip to content

Commit

Permalink
feat: ability to load colors via searchParams
Browse files Browse the repository at this point in the history
  • Loading branch information
fluid-design-io committed Oct 18, 2023
1 parent b3a71e0 commit 1435cec
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 39 deletions.
1 change: 1 addition & 0 deletions apps/web/app/color-store-initializer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useColorStore } from "@/store/store";
import { useSearchParams } from "next/navigation";
import { useRef } from "react";

function ColorStoreInitializer({ ...props }) {
Expand Down
51 changes: 51 additions & 0 deletions apps/web/app/existingColorsOverwritter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"use client";

import { colorHelper } from "@/lib/colorHelper";
import { useColorStore } from "@/store/store";
import { AnimatePresence, motion } from "framer-motion";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";

function ExistingColorsOverwritter({ searchParams }) {
const { updateBaseColor } = useColorStore();
const colors = searchParams.colors;
const [loading, setLoading] = useState(colors ? true : false);
useEffect(() => {
if (!colors) return;
const colorArray = colors.split(",");
const baseColors = {
primary: colorHelper.toRaw(colorArray[0]),
secondary: colorHelper.toRaw(colorArray[1]),
accent: colorHelper.toRaw(colorArray[2]),
};
setTimeout(() => {
updateBaseColor("primary", baseColors.primary);
updateBaseColor("secondary", baseColors.secondary);
updateBaseColor("accent", baseColors.accent);
setLoading(false);
}, 200);
}, []);
return (
<AnimatePresence>
{loading && (
<motion.div
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { delay: 0.3 } }}
className="fixed left-0 top-0 z-50 flex h-screen w-screen items-center justify-center bg-background"
>
<div className="flex flex-col items-center space-y-4">
<div className="text-primary">Loading</div>
<div className="flex space-x-2">
<div className="h-4 w-4 animate-bounce rounded-full bg-primary transition-colors"></div>
<div className="h-4 w-4 animate-bounce rounded-full bg-secondary transition-colors"></div>
<div className="h-4 w-4 animate-bounce rounded-full bg-accent transition-colors"></div>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
);
}

export default ExistingColorsOverwritter;
46 changes: 17 additions & 29 deletions apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PerformanceChecker from "@/components/core/performance-checker";
import Toolbar from "@/components/core/toobar";
import StyleSheetInitializer from "./stylesheet-initializer";
import { cookies } from "next/headers";
import { getServerColors } from "@/lib/getServerColors";

const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const comfortaa = Comfortaa({
Expand All @@ -26,38 +27,25 @@ export const metadata: Metadata = {
default: "Fluid Colors",
template: "%s | Fluid Colors",
},
description: "Mordern color palette generator",
description: "Next-gen color palette generator",
viewport:
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no",
};

const getServerColors = async () => {
const newBaseColors = generateBaseColors();
const cookieStore = cookies();
const mode = cookieStore.get("colorMode");
// short-hand
const [primaryPalette, secondaryPalette, accentPalette, grayPalette] = [
"primary",
"secondary",
"accent",
"gray",
].map((color) =>
generateColorPalette({
color: color === "gray" ? newBaseColors.primary : newBaseColors[color],
type: color as BaseColorTypes,
colorMode: mode ? (mode.value as ColorMode) : ColorMode.HEX,
}),
);
return {
baseColors: newBaseColors,
colorPalettes: {
primary: primaryPalette,
secondary: secondaryPalette,
accent: accentPalette,
gray: grayPalette,
openGraph: {
images: ["/og-default.jpg"],
},
robots: {
index: false,
follow: true,
nocache: true,
googleBot: {
index: true,
follow: false,
noimageindex: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
colorMode: mode ? (mode.value as ColorMode) : ColorMode.HEX,
};
},
};

export default async function RootLayout({
Expand Down
26 changes: 16 additions & 10 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BaseColors } from "@/types/app";
import { colorHelper } from "@/lib/colorHelper";

import RootSkipNavContent from "./root-skip-nav-content";
import ExistingColorsOverwritter from "./existingColorsOverwritter";

type Props = {
searchParams: { colors: string } | undefined;
Expand All @@ -15,33 +16,38 @@ export async function generateMetadata(
): Promise<Metadata> {
const colors = searchParams?.colors;
let paletteColors = "";
let opengraphImage = "/og-default.jpg";
if (colors) {
const parsedColors: { state: { baseColors: BaseColors } } =
JSON.parse(colors);
const { primary, secondary, accent } = parsedColors.state.baseColors;
const [primary, secondary, accent] = colors.split(",");
if (primary && secondary && accent) {
paletteColors = `${primary}, ${secondary}, ${accent}`;
}
// console.log(primary, secondary, accent);
paletteColors = `${colorHelper.toHex(primary)}, ${colorHelper.toHex(
secondary,
)}, ${colorHelper.toHex(accent)}`;
// fetch dynamic og
const colorsUrl = encodeURIComponent(paletteColors);
opengraphImage = `${process.env.NEXT_PUBLIC_URL}/api/og?colors=${colorsUrl}`;
}
// // fetch data
// const product = await fetch(`https://.../${id}`).then((res) => res.json())

// optionally access and extend (rather than replace) parent metadata
const previousImages = (await parent).openGraph?.images || [];
return {
title: `${paletteColors}`,
// openGraph: {
// images: ['/some-specific-page-image.jpg', ...previousImages],
// },
title: "Check out this palette",
description: `Generated with Fluid Colors: ${paletteColors}`,
openGraph: {
images: [opengraphImage, ...previousImages],
},
};
}

export default async function Page() {
export default async function Page({ searchParams }: Props) {
return (
<div className="site-padding mx-auto flex w-full max-w-[120rem] flex-1 flex-col pb-20 sm:pb-24">
<RootSkipNavContent />
<ColorPalette />
<ExistingColorsOverwritter searchParams={searchParams} />
</div>
);
}

0 comments on commit 1435cec

Please sign in to comment.