feat: Wabenhain Honig-Shop Anwendung
Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei: Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich (Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung, PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma- Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
This commit is contained in:
1 parent
5c76fcc266
commit
c7927f2883
240 files changed
+26096
-137
No files matched your search
@@ -0,0 +1,107 @@
|
||||
import Link from "next/link";
|
||||
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
||||
|
||||
export function Container({
|
||||
id,
|
||||
className = "",
|
||||
children,
|
||||
}: {
|
||||
id?: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div id={id} className={`mx-auto w-full max-w-6xl px-6 md:px-10 ${className}`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type ButtonVariant = "primary" | "secondary" | "ghost";
|
||||
|
||||
const buttonStyles: Record<ButtonVariant, string> = {
|
||||
primary:
|
||||
"bg-forest text-cream hover:bg-[#1a271f] border border-forest",
|
||||
secondary:
|
||||
"bg-transparent text-forest border border-forest hover:bg-forest hover:text-cream",
|
||||
ghost: "bg-transparent text-ink border border-ink/20 hover:border-ink",
|
||||
};
|
||||
|
||||
interface LinkButtonProps extends ComponentPropsWithoutRef<typeof Link> {
|
||||
variant?: ButtonVariant;
|
||||
}
|
||||
|
||||
export function LinkButton({
|
||||
variant = "primary",
|
||||
className = "",
|
||||
children,
|
||||
...props
|
||||
}: LinkButtonProps) {
|
||||
return (
|
||||
<Link
|
||||
className={`inline-flex items-center justify-center gap-2 px-7 py-3 text-sm tracking-wide-caps transition-[color,background-color,border-color,transform] duration-300 active:scale-[0.97] ${buttonStyles[variant]} ${className}`}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
|
||||
variant?: ButtonVariant;
|
||||
}
|
||||
|
||||
export function Button({
|
||||
variant = "primary",
|
||||
className = "",
|
||||
children,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={`inline-flex items-center justify-center gap-2 px-7 py-3 text-sm tracking-wide-caps transition-[color,background-color,border-color,transform] duration-300 active:scale-[0.97] disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100 ${buttonStyles[variant]} ${className}`}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function SectionHeading({
|
||||
eyebrow,
|
||||
title,
|
||||
subtitle,
|
||||
align = "left",
|
||||
className = "",
|
||||
level = "h2",
|
||||
tone = "default",
|
||||
}: {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
align?: "left" | "center";
|
||||
className?: string;
|
||||
/** "h1" fuer Seiten, auf denen diese Komponente die einzige/primaere Ueberschrift ist (SEO-Heading-Hierarchie). Default h2, da die meisten Verwendungen einzelne Abschnitte innerhalb einer Seite mit eigenem h1 sind. */
|
||||
level?: "h1" | "h2";
|
||||
/** "inverted" fuer Abschnitte auf dunklem Grund (z.B. bg-forest) — steuert die Eyebrow-Farbe fuer ausreichenden Kontrast. */
|
||||
tone?: "default" | "inverted";
|
||||
}) {
|
||||
const Heading = level;
|
||||
return (
|
||||
<div
|
||||
className={`${align === "center" ? "text-center mx-auto" : "text-left"} max-w-2xl ${className}`}
|
||||
>
|
||||
{eyebrow ? (
|
||||
<p
|
||||
className={`tracking-wide-caps text-xs mb-3 ${tone === "inverted" ? "text-honey-light" : "text-honey-dark"}`}
|
||||
>
|
||||
{eyebrow}
|
||||
</p>
|
||||
) : null}
|
||||
<Heading className="text-3xl md:text-4xl text-forest">{title}</Heading>
|
||||
{subtitle ? (
|
||||
<p className="mt-4 text-ink/70 leading-relaxed">{subtitle}</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user