feat: redesign auth layout, dashboard sidebar, landing page social proof & new static pages

Split-panel auth layout with dark promo panel, sectioned dashboard nav with theme toggle,
testimonials/social proof on landing page, e-commerce Remotion demo, and static pages
(about, blog, contact, terms, privacy, KVKK).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sase Dev
2026-02-15 11:34:09 +00:00
parent bcc614a0c8
commit 6d7d1873ee
64 changed files with 8283 additions and 434 deletions

View File

@@ -2,7 +2,6 @@ import { useState } from "react";
import { Link, createFileRoute } from "@tanstack/react-router";
import { Button } from "@sase/ui";
import { Input } from "@sase/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sase/ui";
import { Label } from "@sase/ui";
import { toast } from "sonner";
@@ -36,57 +35,63 @@ function ForgotPasswordPage() {
if (sent) {
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle>E-posta Gönderildi</CardTitle>
<CardDescription>
Şifre sıfırlama bağlantısı {email} adresine gönderildi. Lütfen e-postanızı kontrol edin.
</CardDescription>
</CardHeader>
<CardContent>
<Link to="/login">
<Button variant="outline" className="w-full">
Giriş Sayfasına Dön
</Button>
</Link>
</CardContent>
</Card>
<div className="space-y-8">
<div>
<h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
E-posta Gönderildi
</h1>
<p className="mt-2 text-sm text-muted-foreground">
Şifre sıfırlama bağlantısı {email} adresine gönderildi. Lütfen
e-postanızı kontrol edin.
</p>
</div>
<Link to="/login">
<Button variant="outline" className="w-full">
Giriş Sayfasına Dön
</Button>
</Link>
</div>
);
}
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle className="text-2xl">Şifremi Unuttum</CardTitle>
<CardDescription>E-posta adresinize şifre sıfırlama bağlantısı göndereceğiz</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Gönderiliyor..." : "Bağlantı Gönder"}
</Button>
</form>
<div className="mt-4 text-center text-sm">
<Link to="/login" className="text-muted-foreground hover:underline">
Giriş Sayfasına Dön
</Link>
</div>
</CardContent>
</Card>
<div className="space-y-8">
{/* Heading */}
<div>
<h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
Şifremi Unuttum
</h1>
<p className="mt-2 text-sm text-muted-foreground">
E-posta adresinize şifre sıfırlama bağlantısı göndereceğiz
</p>
</div>
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-5">
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Gönderiliyor..." : "Bağlantı Gönder"}
</Button>
</form>
<p className="text-center text-sm">
<Link
to="/login"
className="text-muted-foreground hover:underline"
>
Giriş Sayfasına Dön
</Link>
</p>
</div>
);
}

View File

@@ -2,7 +2,6 @@ import { useState } from "react";
import { Link, createFileRoute, useNavigate } from "@tanstack/react-router";
import { Button } from "@sase/ui";
import { Input } from "@sase/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sase/ui";
import { Label } from "@sase/ui";
import { signIn } from "@/lib/auth-client";
import { toast } from "sonner";
@@ -32,72 +31,92 @@ function LoginPage() {
}
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle className="text-2xl">Giriş Yap</CardTitle>
<CardDescription>Sase.tr hesabınıza giriş yapın</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Şifre</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Giriş yapılıyor..." : "Giriş Yap"}
</Button>
</form>
<div className="space-y-8">
{/* Heading */}
<div>
<h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
Hesabınıza Giriş Yapın
</h1>
<p className="mt-2 text-sm text-muted-foreground">
Şase çözme ve parça kataloğuna erişmek için giriş yapın
</p>
</div>
<div className="mt-4 space-y-3">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t" />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background px-2 text-muted-foreground">veya</span>
</div>
</div>
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-5">
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Şifre</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<Button
variant="outline"
className="w-full"
onClick={() => signIn.social({ provider: "google" })}
>
Google ile Giriş Yap
</Button>
</div>
{/* Remember me + Forgot password */}
<div className="flex items-center justify-between">
<label className="flex items-center gap-2 text-sm">
<input
type="checkbox"
className="size-4 rounded border-input accent-primary"
/>
Beni hatırla
</label>
<Link
to="/forgot-password"
className="text-sm text-muted-foreground hover:underline"
>
Şifremi Unuttum
</Link>
</div>
<div className="mt-4 text-center text-sm">
<Link to="/forgot-password" className="text-muted-foreground hover:underline">
Şifremi Unuttum
</Link>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Giriş yapılıyor..." : "Giriş Yap"}
</Button>
</form>
{/* Divider + Google */}
<div className="space-y-3">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t" />
</div>
<div className="mt-2 text-center text-sm">
Hesabınız yok mu?{" "}
<Link to="/register" className="font-medium hover:underline">
Kayıt Ol
</Link>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background px-2 text-muted-foreground">
veya
</span>
</div>
</CardContent>
</Card>
</div>
<Button
variant="outline"
className="w-full"
onClick={() => signIn.social({ provider: "google" })}
>
Google ile Giriş Yap
</Button>
</div>
{/* Register link */}
<p className="text-center text-sm">
Hesabınız yok mu?{" "}
<Link to="/register" className="font-medium hover:underline">
Kayıt Ol
</Link>
</p>
</div>
);
}

View File

@@ -2,7 +2,6 @@ import { useState } from "react";
import { Link, createFileRoute, useNavigate } from "@tanstack/react-router";
import { Button } from "@sase/ui";
import { Input } from "@sase/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sase/ui";
import { Label } from "@sase/ui";
import { signUp } from "@/lib/auth-client";
import { toast } from "sonner";
@@ -40,71 +39,74 @@ function RegisterPage() {
}
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle className="text-2xl">Kayıt Ol</CardTitle>
<CardDescription>Yeni bir Sase.tr hesabı oluşturun</CardDescription>
<div className="space-y-8">
{/* Heading */}
<div>
<h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
Kayıt Ol
</h1>
<p className="mt-2 text-sm text-muted-foreground">
Yeni bir Sase.tr hesabı oluşturun
</p>
{/* Trial messaging */}
<div className="mt-3 flex items-center justify-center gap-2 rounded-lg bg-emerald-500/10 px-3 py-2 text-sm text-emerald-600 dark:text-emerald-400">
<ShieldCheck className="size-4 shrink-0" />
7 gün ücretsiz deneyin kredi kartı gerekmez
</div>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="name">Ad Soyad</Label>
<Input
id="name"
type="text"
placeholder="Ad Soyad"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Şifre</Label>
<Input
id="password"
type="password"
placeholder="En az 8 karakter, 1 büyük harf, 1 rakam"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={8}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Kayıt yapılıyor..." : "Kayıt Ol"}
</Button>
</form>
{/* Trial messaging */}
<div className="mt-3 flex items-center gap-2 rounded-lg bg-emerald-500/10 px-3 py-2 text-sm text-emerald-600 dark:text-emerald-400">
<ShieldCheck className="size-4 shrink-0" />
7 gün ücretsiz deneyin kredi kartı gerekmez
</div>
</div>
<p className="mt-3 text-center text-xs text-muted-foreground">
Kayıt olunca hemen VIN aramaya başlayın
</p>
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-5">
<div className="space-y-2">
<Label htmlFor="name">Ad Soyad</Label>
<Input
id="name"
type="text"
placeholder="Ad Soyad"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="email">E-posta</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Şifre</Label>
<Input
id="password"
type="password"
placeholder="En az 8 karakter, 1 büyük harf, 1 rakam"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={8}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Kayıt yapılıyor..." : "Kayıt Ol"}
</Button>
</form>
<div className="mt-4 text-center text-sm">
Zaten hesabınız var mı?{" "}
<Link to="/login" className="font-medium hover:underline">
Giriş Yap
</Link>
</div>
</CardContent>
</Card>
<p className="text-center text-xs text-muted-foreground">
Kayıt olunca hemen VIN aramaya başlayın
</p>
<p className="text-center text-sm">
Zaten hesabınız var mı?{" "}
<Link to="/login" className="font-medium hover:underline">
Giriş Yap
</Link>
</p>
</div>
);
}

View File

@@ -2,7 +2,6 @@ import { useState } from "react";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { Button } from "@sase/ui";
import { Input } from "@sase/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sase/ui";
import { Label } from "@sase/ui";
import { toast } from "sonner";
@@ -32,39 +31,44 @@ function ResetPasswordPage() {
toast.success("Şifreniz başarıyla güncellendi.");
navigate({ to: "/login" });
} catch {
toast.error("Şifre sıfırlama başarısız. Bağlantı süresi dolmuş olabilir.");
toast.error(
"Şifre sıfırlama başarısız. Bağlantı süresi dolmuş olabilir.",
);
} finally {
setLoading(false);
}
}
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle className="text-2xl">Şifre Sıfırla</CardTitle>
<CardDescription>Yeni şifrenizi belirleyin</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="password">Yeni Şifre</Label>
<Input
id="password"
type="password"
placeholder="En az 8 karakter"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={8}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Güncelleniyor..." : "Şifreyi Güncelle"}
</Button>
</form>
</CardContent>
</Card>
<div className="space-y-8">
{/* Heading */}
<div>
<h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
Şifre Sıfırla
</h1>
<p className="mt-2 text-sm text-muted-foreground">
Yeni şifrenizi belirleyin
</p>
</div>
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-5">
<div className="space-y-2">
<Label htmlFor="password">Yeni Şifre</Label>
<Input
id="password"
type="password"
placeholder="En az 8 karakter"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={8}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
{loading ? "Güncelleniyor..." : "Şifreyi Güncelle"}
</Button>
</form>
</div>
);
}