- Introduced `Field` and `Label` components for better form handling. - Refactored `Input` and `Textarea` components to use forward refs and improved styling. - Updated `PendingSubmitButton` to use the new `Button` component. - Enhanced `Skeleton` component for better layout handling. - Revamped `Toast` component to support live regions and improved accessibility. - Updated sidebar configuration to use typed icons. - Added phase 3 UI boundary checks to prevent usage of deprecated imports. - Implemented new authentication action handler for better cookie management. - Improved setup logic for freelancer accounts with repair functionality.
167 lines
5.7 KiB
TypeScript
167 lines
5.7 KiB
TypeScript
"use client";
|
||
|
||
import type { ReactNode } from "react";
|
||
import Image from "next/image";
|
||
import Link from "next/link";
|
||
import { motion, useReducedMotion } from "framer-motion";
|
||
import {
|
||
ArrowUpRight,
|
||
BarChart3,
|
||
CalendarDays,
|
||
Kanban,
|
||
Wallet,
|
||
} from "lucide-react";
|
||
|
||
type AuthPageShellProps = {
|
||
title: string;
|
||
description: string;
|
||
imageSrc?: string;
|
||
imageAlt?: string;
|
||
imageSide?: "left" | "right";
|
||
form: ReactNode;
|
||
secondaryAction?: ReactNode;
|
||
footer: ReactNode;
|
||
};
|
||
|
||
const highlights = [
|
||
{ label: "Müşteriler", icon: Kanban },
|
||
{ label: "Takvim", icon: CalendarDays },
|
||
{ label: "Finans", icon: Wallet },
|
||
{ label: "Raporlar", icon: BarChart3 },
|
||
];
|
||
|
||
export function AuthPageShell({
|
||
title,
|
||
description,
|
||
form,
|
||
secondaryAction,
|
||
footer,
|
||
}: AuthPageShellProps) {
|
||
const reducedMotion = useReducedMotion();
|
||
|
||
const fadeUp = {
|
||
initial: reducedMotion ? false : { opacity: 0, y: 18 },
|
||
animate: { opacity: 1, y: 0 },
|
||
transition: {
|
||
duration: reducedMotion ? 0 : 0.55,
|
||
ease: [0.22, 1, 0.36, 1] as const,
|
||
},
|
||
};
|
||
|
||
return (
|
||
<main className="min-h-screen bg-background text-foreground">
|
||
<div className="grid min-h-screen grid-cols-1 lg:grid-cols-[minmax(0,1fr)_480px]">
|
||
<motion.section
|
||
initial={reducedMotion ? false : { opacity: 0, x: -28 }}
|
||
animate={{ opacity: 1, x: 0 }}
|
||
transition={{
|
||
duration: reducedMotion ? 0 : 0.75,
|
||
ease: [0.22, 1, 0.36, 1],
|
||
}}
|
||
className="relative hidden overflow-hidden bg-primary text-primary-foreground lg:flex lg:flex-col lg:justify-between"
|
||
>
|
||
<div className="absolute inset-0 opacity-20 bg-[linear-gradient(rgba(255,255,255,.18)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,.18)_1px,transparent_1px)] bg-size-[32px_32px]" />
|
||
<div className="relative z-10 flex items-center gap-4 p-10">
|
||
<Image
|
||
src="/logo/lightLogoLong.png"
|
||
alt="Neta"
|
||
width={240}
|
||
height={64}
|
||
className="h-16 w-auto object-contain"
|
||
style={{ width: "auto" }}
|
||
priority
|
||
/>
|
||
</div>
|
||
|
||
<div className="relative z-10 px-10">
|
||
<motion.div {...fadeUp}>
|
||
<h1 className="max-w-2xl text-5xl font-semibold leading-[1.02] text-primary-foreground">
|
||
Freelancer işlerini, müşterilerini ve finansını tek yerde yönet.
|
||
</h1>
|
||
<p className="mt-6 max-w-xl text-lg leading-8 text-primary-foreground/78">
|
||
Neta, günlük operasyonunu, projelerini, side projectlerini ve
|
||
temel finans durumunu sade raporlarla takip etmen için
|
||
tasarlanır.
|
||
</p>
|
||
</motion.div>
|
||
|
||
<motion.div
|
||
initial={reducedMotion ? false : { opacity: 0, y: 18 }}
|
||
animate={{ opacity: 1, y: 0 }}
|
||
transition={{ duration: reducedMotion ? 0 : 0.55, delay: 0.16 }}
|
||
className="mt-10 grid max-w-xl grid-cols-2 gap-3"
|
||
>
|
||
{highlights.map((item) => {
|
||
const Icon = item.icon;
|
||
return (
|
||
<div
|
||
key={item.label}
|
||
className="flex items-center gap-3 rounded-sm border border-white/18 bg-white/10 px-4 py-3 text-sm font-medium backdrop-blur"
|
||
>
|
||
<Icon className="h-4 w-4" />
|
||
{item.label}
|
||
</div>
|
||
);
|
||
})}
|
||
</motion.div>
|
||
</div>
|
||
|
||
<div className="w-full relative z-10 p-10 text-sm text-primary-foreground/78">
|
||
<span>Açık kaynak ve self-host edilebilir.</span>{" "}
|
||
<Link
|
||
href="https://github.com/poyrazavsever/neta"
|
||
className="font-semibold text-primary-foreground underline-offset-4 hover:underline"
|
||
target="_blank"
|
||
>
|
||
GitHub <ArrowUpRight className="h-3.5 w-3.5 inline" />
|
||
</Link>
|
||
<span> üzerinden ulaşabilirsin. </span>
|
||
<Link
|
||
href="https://poyrazavsever.com"
|
||
className="inline-flex items-center gap-1 font-semibold text-primary-foreground underline-offset-4 hover:underline"
|
||
target="_blank"
|
||
>
|
||
Poyraz Avsever <ArrowUpRight className="h-3.5 w-3.5 inline" />
|
||
</Link>
|
||
<span> tarafından kodlandı.</span>
|
||
</div>
|
||
</motion.section>
|
||
|
||
<section className="flex min-h-screen items-center justify-center px-6 py-8 lg:px-12">
|
||
<motion.div
|
||
initial={reducedMotion ? false : { opacity: 0, y: 18 }}
|
||
animate={{ opacity: 1, y: 0 }}
|
||
transition={{ duration: reducedMotion ? 0 : 0.6, delay: 0.08 }}
|
||
className="w-full max-w-sm"
|
||
>
|
||
<div className="mb-8 flex justify-center lg:hidden">
|
||
<Image
|
||
src="/logo/blackLogoLong.png"
|
||
alt="Neta logo"
|
||
width={180}
|
||
height={56}
|
||
className="h-14 w-auto object-contain"
|
||
style={{ width: "auto" }}
|
||
priority
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2 text-center lg:text-left">
|
||
<h2 className="text-3xl font-semibold tracking-normal text-foreground">
|
||
{title}
|
||
</h2>
|
||
<p className="text-sm leading-6 text-muted-foreground">{description}</p>
|
||
</div>
|
||
|
||
<div className="mt-8 space-y-6">
|
||
{form}
|
||
{secondaryAction}
|
||
{footer}
|
||
</div>
|
||
</motion.div>
|
||
</section>
|
||
</div>
|
||
</main>
|
||
);
|
||
}
|