feat: update some shit

This commit is contained in:
2023-10-16 01:40:10 +02:00
parent 799a736f36
commit 03d17569da
10 changed files with 336 additions and 191 deletions

154
components/PageHero.tsx Normal file
View File

@ -0,0 +1,154 @@
import { withSubComponents } from "@components/helpers/withSubComponents.ts";
import Image from "@components/Image.tsx";
import { IconExternalLink } from "@components/icons.tsx";
import { type ComponentChildren, createContext } from "preact";
import { IconArrowNarrowLeft } from "@components/icons.tsx";
import { IconEdit } from "@components/icons.tsx";
import { useContext } from "preact/hooks";
import { GenericResource } from "@lib/types.ts";
const HeroContext = createContext<{ image?: string; thumbnail?: string }>({
image: undefined,
thumbnail: undefined,
});
function Wrapper(
{ children, image, thumbnail }: {
children: ComponentChildren;
image?: string;
thumbnail?: string;
},
) {
return (
<div
class={`flex justify-between flex-col relative w-full min-h-[${
image ? 400 : 200
}px] rounded-3xl overflow-hidden`}
>
<HeroContext.Provider value={{ image }}>
{image &&
(
<Image
fill
src={image}
thumbnail={thumbnail}
alt="Recipe Banner"
// style={{ objectPosition: "0% 25%" }}
class="absolute object-cover w-full h-full -z-10"
/>
)}
{children}
</HeroContext.Provider>
</div>
);
}
function Title(
{ children, link }: { children: ComponentChildren; link?: string },
) {
const ctx = useContext(HeroContext);
return (
<div
class={`${
ctx.image ? "noisy-gradient" : ""
} after:opacity-90 flex gap-4 items-center ${ctx.image ? "pt-12" : ""}`}
>
<h2
class="relative text-4xl font-bold z-10"
style={{ color: ctx.image ? "#1F1F1F" : "white" }}
>
{children}
{link &&
(
<a
href={link}
target="__blank"
class="p-2 inline-flex"
>
<IconExternalLink />
</a>
)}
</h2>
</div>
);
}
function BackLink({ href }: { href: string }) {
return (
<a
class="px-4 py-2 bg-gray-300 text-gray-800 rounded-lg flex gap-1 items-center"
href={href}
>
<IconArrowNarrowLeft class="w-5 h-5" /> Back
</a>
);
}
function EditLink({ href }: { href: string }) {
const ctx = useContext(HeroContext);
return (
<a
class={`px-4 py-2 ${
ctx.image ? "bg-gray-300 text-gray-800" : "text-gray-200"
} rounded-lg flex gap-1 items-center`}
href={href}
>
<IconEdit class="w-5 h-5" />
</a>
);
}
function Header({ children }: { children: ComponentChildren }) {
return (
<div class="flex justify-between mx-8 mt-8">
{children}
</div>
);
}
function Subline(
{ entries, children }: {
children?: ComponentChildren;
entries: (string | { href: string; title: string })[];
},
) {
const ctx = useContext(HeroContext);
return (
<div
class={`relative flex items-center z-50 flex gap-5 font-sm text-light mt-3`}
style={{ color: ctx.image ? "#1F1F1F" : "white" }}
>
{children}
{entries.filter((s) =>
s && (typeof s === "string" ? s?.length > 1 : true)
).map((s) => {
if (typeof s === "string") {
return <span>{s}</span>;
} else {
return <a href={s.href}>{s.title}</a>;
}
})}
</div>
);
}
function Footer({ children }: { children: ComponentChildren }) {
const ctx = useContext(HeroContext);
return (
<div
class={`relative inset-x-0 py-4 px-8 ${ctx.image ? "py-8" : ""} `}
>
{children}
</div>
);
}
export default withSubComponents(Wrapper, {
EditLink,
BackLink,
Footer,
Subline,
Header,
Title,
});

View File

@ -1,106 +0,0 @@
import { Star } from "@components/Stars.tsx";
import {
IconArrowNarrowLeft,
IconEdit,
IconExternalLink,
} from "@components/icons.tsx";
import Image from "@components/Image.tsx";
import { GenericResource } from "@lib/types.ts";
export function RecipeHero(
{ data, subline, backlink, editLink }: {
backlink: string;
subline?: (string | { title: string; href: string })[];
editLink?: string;
data: GenericResource;
},
) {
const { meta: { image } = {} } = data;
return (
<div
class={`flex justify-between flex-col relative w-full min-h-[${
image ? 400 : 200
}px] rounded-3xl overflow-hidden`}
>
{image &&
(
<Image
fill
src={image}
thumbnail={data.meta?.thumbnail}
alt="Recipe Banner"
style={{ objectPosition: "0% 25%" }}
class="absolute object-cover w-full h-full -z-10"
/>
)}
<div class="flex justify-between mx-8 mt-8">
<a
class="px-4 py-2 bg-gray-300 text-gray-800 rounded-lg flex gap-1 items-center"
href={backlink}
>
<IconArrowNarrowLeft class="w-5 h-5" /> Back
</a>
{editLink &&
(
<a
class={`px-4 py-2 ${
image ? "bg-gray-300 text-gray-800" : "text-gray-200"
} rounded-lg flex gap-1 items-center`}
href={editLink}
>
<IconEdit class="w-5 h-5" />
</a>
)}
</div>
<div
class={`relative inset-x-0 py-4 px-8 ${image ? "py-8" : ""} `}
>
<div
class={`${
image ? "noisy-gradient" : ""
} after:opacity-90 flex gap-4 items-center ${image ? "pt-12" : ""}`}
>
<h2
class="relative text-4xl font-bold z-10"
style={{ color: image ? "#1F1F1F" : "white" }}
>
{data.name}
{data.meta?.link &&
(
<a
href={data.meta.link}
target="__blank"
class="p-2 inline-flex"
name="Link to Original recipe"
>
<IconExternalLink />
</a>
)}
</h2>
{data.meta?.rating && <Star rating={data.meta.rating} />}
</div>
{subline?.length &&
(
<div
class={`relative z-50 flex gap-5 font-sm text-light mt-3`}
style={{ color: image ? "#1F1F1F" : "white" }}
>
{subline.filter((s) =>
s && (typeof s === "string" ? s?.length > 1 : true)
).map((s) => {
if (typeof s === "string") {
return <span>{s}</span>;
} else {
return <a href={s.href}>{s.title}</a>;
}
})}
</div>
)}
</div>
</div>
);
}

View File

@ -0,0 +1,11 @@
// deno-lint-ignore no-explicit-any
export function withSubComponents<A, B extends Record<string, any>>(
component: A,
subcomponents: B,
): A & B {
Object.keys(subcomponents).forEach((key) => {
// deno-lint-ignore no-explicit-any
(component as any)[key] = (subcomponents as any)[key];
});
return component as A & B;
}

View File

@ -16,3 +16,4 @@ export { default as IconLogout } from "https://deno.land/x/tabler_icons_tsx@0.0.
export { default as IconSearch } from "https://deno.land/x/tabler_icons_tsx@0.0.3/tsx/search.tsx";
export { default as IconGhost } from "https://deno.land/x/tabler_icons_tsx@0.0.3/tsx/ghost.tsx";
export { default as IconBrandYoutube } from "https://deno.land/x/tabler_icons_tsx@0.0.3/tsx/brand-youtube.tsx";
export { default as IconWand } from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/wand.tsx";