131 lines
3.1 KiB
TypeScript
131 lines
3.1 KiB
TypeScript
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import type { ReactNode } from "react";
|
|
|
|
type HomeElementProps = {
|
|
title: string;
|
|
description: string;
|
|
href?: string;
|
|
actionLabel: string;
|
|
variant: "jellyfin" | "seerr" | "minecraft" | "astroneer";
|
|
external?: boolean;
|
|
children: ReactNode;
|
|
};
|
|
|
|
export default function HomeElement({
|
|
title,
|
|
description,
|
|
href,
|
|
actionLabel,
|
|
variant,
|
|
external = false,
|
|
children,
|
|
}: HomeElementProps) {
|
|
const content = (
|
|
<>
|
|
<span className="service-status" aria-label="Service en ligne" />
|
|
<span className="service-icon-shell">{children}</span>
|
|
<span className="service-copy">
|
|
<strong>{title}</strong>
|
|
<span>{description}</span>
|
|
</span>
|
|
<span className="service-action">
|
|
<span className="service-action-label">{actionLabel}</span>
|
|
{href ? <ArrowIcon /> : <SignalIcon />}
|
|
</span>
|
|
</>
|
|
);
|
|
|
|
const className = `service-card service-card--${variant}`;
|
|
|
|
if (!href) {
|
|
return <article className={className}>{content}</article>;
|
|
}
|
|
|
|
if (external) {
|
|
return (
|
|
<a href={href} className={className} target="_blank" rel="noopener noreferrer">
|
|
{content}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Link href={href} className={className}>
|
|
{content}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
export function StreamingIcon() {
|
|
return (
|
|
<svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
|
|
<defs>
|
|
<linearGradient id="streaming-gradient" x1="14" y1="80" x2="82" y2="16">
|
|
<stop stopColor="#8b4dff" />
|
|
<stop offset="0.5" stopColor="#c395fc" />
|
|
<stop offset="1" stopColor="#6df4ff" />
|
|
</linearGradient>
|
|
</defs>
|
|
<rect x="10" y="18" width="76" height="56" rx="9" fill="#11182d" stroke="url(#streaming-gradient)" strokeWidth="6" />
|
|
<path d="m41 34 22 12.5L41 59z" fill="url(#streaming-gradient)" />
|
|
<path d="M31 85h34M39 74v11m18-11v11" fill="none" stroke="#c395fc" strokeLinecap="round" strokeWidth="6" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
export function JellyseerrIcon() {
|
|
return (
|
|
<Image
|
|
className="service-brand-icon service-brand-icon--jellyseerr"
|
|
src="/assets/jellyseerr.svg"
|
|
alt=""
|
|
width={96}
|
|
height={96}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function MinecraftIcon() {
|
|
return (
|
|
<Image
|
|
className="service-brand-icon service-brand-icon--minecraft"
|
|
src="/assets/minecraft.svg"
|
|
alt=""
|
|
width={192}
|
|
height={192}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function AstroneerIcon() {
|
|
return (
|
|
<Image
|
|
className="service-brand-icon service-brand-icon--astroneer"
|
|
src="/assets/astroneer.svg"
|
|
alt=""
|
|
width={192}
|
|
height={192}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function ArrowIcon() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
<path d="M5 12h12" />
|
|
<path d="m13 6 6 6-6 6" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
function SignalIcon() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
<path d="M5 12.5a10 10 0 0 1 14 0" />
|
|
<path d="M8.5 16a5 5 0 0 1 7 0" />
|
|
<path d="M12 19h.01" />
|
|
</svg>
|
|
);
|
|
}
|