dev #59
@@ -2,7 +2,7 @@ import { useEffect } from "react";
|
||||
|
||||
const DEFAULT_TITLE = "Şase Numarası Sorgulama & OEM Parça Kataloğu | Sase.tr";
|
||||
const DEFAULT_DESCRIPTION =
|
||||
"Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 50+ marka, 1M+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.";
|
||||
"Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 27 marka, 1M+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.";
|
||||
const DEFAULT_CANONICAL = "https://sase.tr";
|
||||
|
||||
interface PageMetaOptions {
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
"brandCountAll": "All",
|
||||
"planHelper": "Which plan should I pick? Choose the number of brands you work with. For 4+ brands, the Full Package is cheaper per brand.",
|
||||
"credibility": {
|
||||
"brands": "50+ brands",
|
||||
"brands": "27 brands",
|
||||
"parts": "1M+ parts",
|
||||
"oem": "OEM + alternative codes",
|
||||
"speed": "Results in seconds",
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
"brandCountAll": "Tümü",
|
||||
"planHelper": "Hangi planı seçmeliyim? İşine giren marka sayısını seç. 4+ marka için Full Paket marka başına daha avantajlı.",
|
||||
"credibility": {
|
||||
"brands": "50+ marka",
|
||||
"brands": "27 marka",
|
||||
"parts": "1M+ parça",
|
||||
"oem": "OEM + alternatif kodlar",
|
||||
"speed": "Saniyede sonuç",
|
||||
|
||||
@@ -109,7 +109,7 @@ function AuthLayout() {
|
||||
<circle cx="7" cy="17" r="2" />
|
||||
<circle cx="17" cy="17" r="2" />
|
||||
</svg>
|
||||
50+ Marka
|
||||
27 Marka
|
||||
</span>
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full border border-border bg-surface/60 px-3 py-1.5 text-xs text-foreground/80 backdrop-blur-sm">
|
||||
<Database className="size-3" />
|
||||
|
||||
@@ -14,14 +14,21 @@ import { useRef, useState } from "react";
|
||||
|
||||
export const Route = createFileRoute("/_auth/register")({
|
||||
component: RegisterPage,
|
||||
validateSearch: (search: Record<string, unknown>): { vin?: string; ref?: string } => ({
|
||||
validateSearch: (
|
||||
search: Record<string, unknown>,
|
||||
): { vin?: string; ref?: string; plan?: string } => ({
|
||||
vin: (search.vin as string) || undefined,
|
||||
ref: (search.ref as string) || undefined,
|
||||
plan: (search.plan as string) || undefined,
|
||||
}),
|
||||
});
|
||||
|
||||
// Carry a plan chosen on the marketing pricing through the value-first
|
||||
// onboarding detour so the subscription page can preselect it later.
|
||||
const PENDING_PLAN_KEY = "sase-pending-plan";
|
||||
|
||||
function RegisterPage() {
|
||||
const { vin, ref } = Route.useSearch();
|
||||
const { vin, ref, plan } = Route.useSearch();
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
@@ -92,6 +99,7 @@ function RegisterPage() {
|
||||
// (covers both email and Google OAuth signups).
|
||||
capture("user_signed_up", { method: "email" });
|
||||
trackMeta("CompleteRegistration", { method: "email" });
|
||||
if (plan) localStorage.setItem(PENDING_PLAN_KEY, plan);
|
||||
toast.success("Hesap oluşturuldu!");
|
||||
window.location.href = redirectUrl;
|
||||
} catch {
|
||||
@@ -123,6 +131,7 @@ function RegisterPage() {
|
||||
startAction("register", { method: "google" });
|
||||
capture("user_signed_up", { method: "google" });
|
||||
trackMeta("CompleteRegistration", { method: "google" });
|
||||
if (plan) localStorage.setItem(PENDING_PLAN_KEY, plan);
|
||||
signIn.social({ provider: "google", callbackURL: redirectUrl });
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -252,7 +252,7 @@ const POSTS: Record<string, BlogPost> = {
|
||||
<p>
|
||||
Sase.tr, Türkiye'nin yedek parça sektörüne özgü geliştirilen bu dijital dönüşümün
|
||||
öncüsüdür. VIN/şase numarası sorgulama, çoklu katalog entegrasyonu ve interaktif şema
|
||||
görüntüleme özellikleriyle geleneksel iş yapış biçimlerini dönüştürmektedir. Platform, 50+
|
||||
görüntüleme özellikleriyle geleneksel iş yapış biçimlerini dönüştürmektedir. Platform, 27
|
||||
marka ve 1 milyondan fazla OEM parça numarasıyla sektörün en kapsamlı dijital kataloğunu
|
||||
sunmaktadır.
|
||||
</p>
|
||||
@@ -331,7 +331,7 @@ const POSTS: Record<string, BlogPost> = {
|
||||
Parça bulamadığınızda kategori ağacında bir seviye yukarı çıkarak daha geniş bir arama
|
||||
yapabilirsiniz.
|
||||
</li>
|
||||
<li>50+ markanın tamamına erişmek için Full Paket aboneliği en avantajlı seçenektir.</li>
|
||||
<li>27 markanın tamamına erişmek için Full Paket aboneliği en avantajlı seçenektir.</li>
|
||||
</ul>
|
||||
|
||||
<h2 className="text-xl font-semibold text-foreground">Sonuç</h2>
|
||||
|
||||
@@ -75,6 +75,7 @@ interface SubscriptionSearch {
|
||||
ref?: string | null;
|
||||
stripe?: string;
|
||||
session_id?: string;
|
||||
plan?: string;
|
||||
}
|
||||
|
||||
export const Route = createFileRoute("/dashboard/subscription/")({
|
||||
@@ -83,10 +84,15 @@ export const Route = createFileRoute("/dashboard/subscription/")({
|
||||
ref: search.ref ? String(search.ref) : undefined,
|
||||
stripe: search.stripe ? String(search.stripe) : undefined,
|
||||
session_id: search.session_id ? String(search.session_id) : undefined,
|
||||
plan: search.plan ? String(search.plan) : undefined,
|
||||
}),
|
||||
component: SubscriptionPage,
|
||||
});
|
||||
|
||||
/** localStorage carrier so a plan chosen pre-signup survives the value-first
|
||||
* onboarding detour (register → search) and preselects on the next visit. */
|
||||
export const PENDING_PLAN_KEY = "sase-pending-plan";
|
||||
|
||||
interface SubscriptionBrand {
|
||||
brandId: string;
|
||||
brandName: string;
|
||||
@@ -414,6 +420,24 @@ export function SubscriptionPage() {
|
||||
setStep("payment");
|
||||
}, [subscription, selectedPlanKey]);
|
||||
|
||||
// Preselect a plan chosen from the marketing pricing — via ?plan= or the
|
||||
// pre-signup localStorage carrier. Skipped for active/pending subscriptions,
|
||||
// during the welcome onboarding, or once the user has started selecting.
|
||||
const hasPreselectedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (hasPreselectedRef.current || isLoading || welcome || selectedPlanKey) return;
|
||||
if (subscription?.status === "active" || subscription?.status === "pending") return;
|
||||
const stored = typeof window !== "undefined" ? localStorage.getItem(PENDING_PLAN_KEY) : null;
|
||||
const planKey = search.plan ?? stored ?? null;
|
||||
if (!planKey || !plans.some((p) => p.key === planKey)) return;
|
||||
hasPreselectedRef.current = true;
|
||||
localStorage.removeItem(PENDING_PLAN_KEY);
|
||||
capture("plan_selected", { plan: planKey, source: "marketing_preselect" });
|
||||
setSelectedPlanKey(planKey);
|
||||
setSelectedBrandIds([]);
|
||||
setStep(planKey === "full" ? "payment" : "brands");
|
||||
}, [isLoading, welcome, selectedPlanKey, subscription, search.plan]);
|
||||
|
||||
const cancelPendingMutation = useMutation({
|
||||
mutationFn: () => api.patch("/subscriptions/cancel-pending"),
|
||||
onSuccess: () => {
|
||||
|
||||
@@ -263,7 +263,7 @@ const BENTO_ITEMS = [
|
||||
},
|
||||
{
|
||||
icon: Car,
|
||||
title: "50+ Marka",
|
||||
title: "27 Marka",
|
||||
description: "Avrupa, Asya ve Amerikan markaları tek çatı altında.",
|
||||
stat: null,
|
||||
wide: false,
|
||||
@@ -317,6 +317,33 @@ const COMPARISON = [
|
||||
{ label: "Aylık zaman tasarrufu", manual: "—", sase: "~40 saat" },
|
||||
];
|
||||
|
||||
const FAQ = [
|
||||
{
|
||||
q: "Hangi markaları destekliyorsunuz?",
|
||||
a: "Şu an 27 otomobil markası destekleniyor ve liste sürekli genişliyor. Şase numaranızı arama kutusuna girerek aracınızın desteklenip desteklenmediğini hemen görebilirsiniz.",
|
||||
},
|
||||
{
|
||||
q: "Verilerim güvende mi?",
|
||||
a: "Tüm trafik SSL ile şifrelenir ve verileriniz KVKK'ya uygun şekilde işlenir. Sorgu geçmişiniz yalnızca size özeldir.",
|
||||
},
|
||||
{
|
||||
q: "Kart bilgisi gerekiyor mu?",
|
||||
a: "Hayır. 30 günlük ücretsiz deneme için kredi kartı bilgisi istemiyoruz; dilediğiniz an vazgeçebilirsiniz.",
|
||||
},
|
||||
{
|
||||
q: "İstediğim zaman iptal edebilir miyim?",
|
||||
a: "Evet, taahhüt yok. Aboneliğinizi panelden tek tıkla iptal edebilirsiniz.",
|
||||
},
|
||||
{
|
||||
q: "Mevcut e-ticaret veya servis sistemime entegre olur mu?",
|
||||
a: "Full Paket'te API erişimi ve toplu sorgu ile sistemlerinize entegre edebilirsiniz (talep üzerine kurulum desteği).",
|
||||
},
|
||||
{
|
||||
q: "Şase numarasını bilmiyorsam ne olur?",
|
||||
a: "Marka ve model üzerinden de katalogda gezebilir, ya da ana sayfadaki örnek aramayı deneyerek platformu test edebilirsiniz.",
|
||||
},
|
||||
];
|
||||
|
||||
const TESTIMONIALS = [
|
||||
{
|
||||
name: "Ahmet Y.",
|
||||
@@ -392,7 +419,7 @@ export function HomePage() {
|
||||
usePageMeta({
|
||||
title: "Şase Numarası Sorgulama & OEM Parça Kataloğu | Sase.tr",
|
||||
description:
|
||||
"Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 50+ marka, 1M+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.",
|
||||
"Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 27 marka, 1M+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.",
|
||||
canonical: "https://sase.tr",
|
||||
});
|
||||
|
||||
@@ -799,7 +826,7 @@ export function HomePage() {
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-destructive/60 opacity-75" />
|
||||
<span className="relative inline-flex size-2 rounded-full bg-destructive" />
|
||||
</span>
|
||||
Her yanlış parça siparişi ortalama 450 TL'ye mal olur
|
||||
Her yanlış parça siparişi 200-500 TL'ye mal olur
|
||||
</div>
|
||||
|
||||
{/* Social proof badge */}
|
||||
@@ -956,7 +983,7 @@ export function HomePage() {
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-4 sm:gap-6">
|
||||
{[
|
||||
{ icon: Zap, label: "Ortalama 1.2sn Sonuç" },
|
||||
{ icon: Car, label: "50+ Marka Desteği" },
|
||||
{ icon: Car, label: "27 Marka Desteği" },
|
||||
{ icon: Database, label: "1M+ OEM Parça" },
|
||||
].map(({ icon: Icon, label }) => (
|
||||
<div
|
||||
@@ -983,7 +1010,7 @@ export function HomePage() {
|
||||
/>
|
||||
) : (
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Desteklenen 50+ Otomobil Markası
|
||||
Desteklenen 27 Otomobil Markası
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
@@ -1298,13 +1325,15 @@ export function HomePage() {
|
||||
Özel entegrasyon veya toplu sorgulama ihtiyacınız varsa bize ulaşın.
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="mt-4 rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
Bize Ulaşın
|
||||
<ChevronRight className="ml-1 size-4" />
|
||||
</Button>
|
||||
<Link to="/contact" className="mt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
Bize Ulaşın
|
||||
<ChevronRight className="ml-1 size-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1577,6 +1606,7 @@ export function HomePage() {
|
||||
{[
|
||||
{
|
||||
name: "1 Marka",
|
||||
planKey: "brand1",
|
||||
description: "Tek marka için erişim",
|
||||
price: "200",
|
||||
yearly: "2.000",
|
||||
@@ -1589,6 +1619,7 @@ export function HomePage() {
|
||||
},
|
||||
{
|
||||
name: "2 Marka",
|
||||
planKey: "brand2",
|
||||
description: "İki farklı marka",
|
||||
price: "350",
|
||||
yearly: "3.500",
|
||||
@@ -1601,6 +1632,7 @@ export function HomePage() {
|
||||
},
|
||||
{
|
||||
name: "3 Marka",
|
||||
planKey: "brand3",
|
||||
description: "Üç marka kapsamlı",
|
||||
price: "500",
|
||||
yearly: "5.000",
|
||||
@@ -1611,10 +1643,10 @@ export function HomePage() {
|
||||
"Öncelikli destek",
|
||||
],
|
||||
},
|
||||
].map((plan, idx) => (
|
||||
].map((plan) => (
|
||||
<div
|
||||
key={plan.name}
|
||||
className={`group relative flex flex-col rounded-2xl border border-border bg-surface p-7 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)] ${idx === 1 ? "sm:translate-y-3" : ""} ${idx === 2 ? "sm:translate-y-6" : ""}`}
|
||||
className="group relative flex flex-col rounded-2xl border border-border bg-surface p-7 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)]"
|
||||
>
|
||||
<div className="flex items-baseline justify-between">
|
||||
<h3 className="font-[family-name:var(--font-display)] text-lg font-semibold">
|
||||
@@ -1640,11 +1672,23 @@ export function HomePage() {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Link to="/register" className="mt-7">
|
||||
<Button variant="outline" className="w-full rounded-full">
|
||||
30 gün ücretsiz dene
|
||||
</Button>
|
||||
</Link>
|
||||
{isAuthenticated ? (
|
||||
<Link
|
||||
to="/dashboard/subscription"
|
||||
search={{ plan: plan.planKey }}
|
||||
className="mt-7"
|
||||
>
|
||||
<Button variant="outline" className="w-full rounded-full">
|
||||
30 gün ücretsiz dene
|
||||
</Button>
|
||||
</Link>
|
||||
) : (
|
||||
<Link to="/register" search={{ plan: plan.planKey }} className="mt-7">
|
||||
<Button variant="outline" className="w-full rounded-full">
|
||||
30 gün ücretsiz dene
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -1680,7 +1724,11 @@ export function HomePage() {
|
||||
yıllık 9.990 TL — ayda 832 TL'ye denk gelir
|
||||
</p>
|
||||
|
||||
<Link to="/register" className="mt-8 inline-block">
|
||||
<Link
|
||||
to={isAuthenticated ? "/dashboard/subscription" : "/register"}
|
||||
search={{ plan: "full" }}
|
||||
className="mt-8 inline-block"
|
||||
>
|
||||
<Button variant="brand" size="lg" className="rounded-full">
|
||||
30 gün ücretsiz dene
|
||||
<ArrowRight className="ml-2 size-4" />
|
||||
@@ -1698,7 +1746,7 @@ export function HomePage() {
|
||||
</p>
|
||||
<ul className="mt-5 grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-2">
|
||||
{[
|
||||
"Tüm 50+ markaya erişim",
|
||||
"Tüm 27 markaya erişim",
|
||||
"Sınırsız VIN arama",
|
||||
"OEM parça kataloğu",
|
||||
"İnteraktif şema görüntüleyici",
|
||||
@@ -1730,32 +1778,27 @@ export function HomePage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 11. REFERRAL BANNER (YENİ) ───────────────────────────────── */}
|
||||
<section className="px-4 py-10 sm:px-6">
|
||||
<div className="mx-auto max-w-4xl overflow-hidden rounded-2xl border border-border bg-surface p-8 sm:p-12">
|
||||
<div className="flex flex-col items-center gap-6 text-center sm:flex-row sm:text-left">
|
||||
<div className="flex size-14 shrink-0 items-center justify-center rounded-xl bg-muted">
|
||||
<Gift className="size-6 text-muted-foreground" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-[family-name:var(--font-display)] text-xl font-bold sm:text-2xl">
|
||||
Arkadaşını Davet Et
|
||||
</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
3 davet = +7 gün ücretsiz, 5 davet = +1 ay ücretsiz
|
||||
</p>
|
||||
</div>
|
||||
<Link to="/register">
|
||||
<Button className="shrink-0 rounded-full bg-foreground text-background hover:bg-foreground/90">
|
||||
Davet Kodunuzu Alın
|
||||
<ArrowRight className="ml-2 size-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
{/* ─── 10.5. SSS / FAQ ──────────────────────────────────────────── */}
|
||||
<section className="px-4 py-20 sm:px-6">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<div className="text-center">
|
||||
<SectionBadge>SSS</SectionBadge>
|
||||
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
|
||||
Sık Sorulan Sorular
|
||||
</h2>
|
||||
</div>
|
||||
<dl className="mt-12 grid gap-x-10 gap-y-8 sm:grid-cols-2">
|
||||
{FAQ.map((item) => (
|
||||
<div key={item.q}>
|
||||
<dt className="font-semibold text-foreground">{item.q}</dt>
|
||||
<dd className="mt-2 text-sm leading-relaxed text-muted-foreground">{item.a}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 12. SON CTA ──────────────────────────────────────────────── */}
|
||||
{/* ─── 11. SON CTA ──────────────────────────────────────────────── */}
|
||||
<section className="relative overflow-hidden bg-surface-alt px-4 py-20 sm:px-6 sm:py-24">
|
||||
{/* SVG grid pattern */}
|
||||
<div className="pointer-events-none absolute inset-0 opacity-[0.03]">
|
||||
@@ -1783,14 +1826,40 @@ export function HomePage() {
|
||||
bulun.
|
||||
</p>
|
||||
<Link to="/register">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="mt-8 rounded-full border-border px-8 py-3 text-base text-foreground hover:bg-foreground hover:text-background"
|
||||
>
|
||||
Ücretsiz Deneyin — Kart Gerekmez
|
||||
<Button variant="brand" size="lg" className="mt-8 rounded-full px-8 text-base">
|
||||
30 Gün Ücretsiz Başla — Kart Gerekmez
|
||||
<ArrowRight className="ml-2 size-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 text-xs text-muted-foreground">
|
||||
<ShieldCheck className="size-4 text-brand" />
|
||||
KVKK uyumlu · SSL şifreli · Kart bilgisi gerekmez
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 12. REFERRAL BANNER ──────────────────────────────────────── */}
|
||||
<section className="px-4 py-10 sm:px-6">
|
||||
<div className="mx-auto max-w-4xl overflow-hidden rounded-2xl border border-border bg-surface p-8 sm:p-12">
|
||||
<div className="flex flex-col items-center gap-6 text-center sm:flex-row sm:text-left">
|
||||
<div className="flex size-14 shrink-0 items-center justify-center rounded-xl bg-muted">
|
||||
<Gift className="size-6 text-muted-foreground" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-[family-name:var(--font-display)] text-xl font-bold sm:text-2xl">
|
||||
Arkadaşını Davet Et
|
||||
</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
3 davet = +7 gün ücretsiz, 5 davet = +1 ay ücretsiz
|
||||
</p>
|
||||
</div>
|
||||
<Link to="/register">
|
||||
<Button className="shrink-0 rounded-full bg-foreground text-background hover:bg-foreground/90">
|
||||
Davet Kodunuzu Alın
|
||||
<ArrowRight className="ml-2 size-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user