161 lines
6.6 KiB
TypeScript
161 lines
6.6 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { AppStoreGrid } from "@/components/AppStoreGrid";
|
||
import { TenantSitePage } from "@/components/TenantSitePage";
|
||
import { Badge, Button, Container } from "@/components/ui";
|
||
import { PLATFORM_APPS } from "@/lib/apps-catalog";
|
||
import { useAuth } from "@/hooks/useAuth";
|
||
import { useTenantHost } from "@/hooks/useTenantHost";
|
||
import { useTheme } from "@/hooks/useTheme";
|
||
|
||
export default function HomePage() {
|
||
const host = useTenantHost();
|
||
if (host.isTenantHost) {
|
||
return <TenantSitePage />;
|
||
}
|
||
return <PlatformHomePage />;
|
||
}
|
||
|
||
const FEATURES = [
|
||
{ icon: "🔐", label: "ورود واحد SSO" },
|
||
{ icon: "🏢", label: "چند کسبوکار" },
|
||
{ icon: "☁️", label: "ابری و مقیاسپذیر" },
|
||
{ icon: "🎨", label: "White-label" },
|
||
];
|
||
|
||
function PlatformHomePage() {
|
||
const { theme } = useTheme();
|
||
const { isAuthenticated, login, loading } = useAuth();
|
||
const siteName = theme?.site_name ?? "Torbatyar";
|
||
const availableCount = PLATFORM_APPS.filter((app) => app.status === "available").length;
|
||
const quickApps = PLATFORM_APPS.filter((app) => app.status === "available" && app.href).slice(0, 4);
|
||
|
||
return (
|
||
<div className="pb-16">
|
||
{/* Hero */}
|
||
<section className="relative overflow-hidden">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-[var(--color-primary-soft)] via-white to-[var(--color-secondary-muted)]" />
|
||
<div
|
||
className="absolute inset-0 opacity-[0.35]"
|
||
style={{
|
||
backgroundImage:
|
||
"radial-gradient(circle at 1px 1px, rgba(2,132,199,0.15) 1px, transparent 0)",
|
||
backgroundSize: "28px 28px",
|
||
}}
|
||
/>
|
||
<div className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-[var(--color-primary-muted)] blur-3xl" />
|
||
<div className="pointer-events-none absolute -right-20 bottom-0 h-72 w-72 rounded-full bg-[var(--color-secondary-muted)] blur-3xl" />
|
||
|
||
<Container className="relative py-14 sm:py-20">
|
||
<div className="mx-auto max-w-3xl text-center">
|
||
<Badge variant="primary" className="mb-5 px-4 py-1.5 text-sm">
|
||
نسل جدید SuperApp
|
||
</Badge>
|
||
|
||
<h1 className="text-4xl font-extrabold leading-tight tracking-tight text-secondary sm:text-5xl lg:text-6xl">
|
||
{siteName}
|
||
</h1>
|
||
|
||
<p className="mx-auto mt-5 max-w-xl text-base leading-8 text-gray-600 sm:text-lg">
|
||
یک پلتفرم، دهها سرویس — حسابداری، CRM، سلامت، زیبایی و بیشتر.
|
||
همه با یک ورود واحد.
|
||
</p>
|
||
|
||
<div className="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||
{isAuthenticated ? (
|
||
<Link href="/dashboard">
|
||
<Button size="lg" className="min-w-[160px] shadow-lg shadow-primary/20">
|
||
رفتن به داشبورد
|
||
</Button>
|
||
</Link>
|
||
) : (
|
||
<Button
|
||
size="lg"
|
||
className="min-w-[160px] shadow-lg shadow-primary/20"
|
||
onClick={() => login()}
|
||
loading={loading}
|
||
loadingText="..."
|
||
>
|
||
ورود / ثبتنام
|
||
</Button>
|
||
)}
|
||
<a href="#apps">
|
||
<Button variant="outline" size="lg">
|
||
مشاهده اپلیکیشنها
|
||
</Button>
|
||
</a>
|
||
</div>
|
||
|
||
{/* Stats */}
|
||
<div className="mt-10 flex flex-wrap items-center justify-center gap-6 sm:gap-10">
|
||
<div className="text-center">
|
||
<p className="text-3xl font-extrabold text-primary">{availableCount}+</p>
|
||
<p className="mt-0.5 text-sm text-gray-500">اپلیکیشن فعال</p>
|
||
</div>
|
||
<div className="hidden h-10 w-px bg-gray-200 sm:block" />
|
||
<div className="text-center">
|
||
<p className="text-3xl font-extrabold text-primary">۱</p>
|
||
<p className="mt-0.5 text-sm text-gray-500">ورود واحد</p>
|
||
</div>
|
||
<div className="hidden h-10 w-px bg-gray-200 sm:block" />
|
||
<div className="text-center">
|
||
<p className="text-3xl font-extrabold text-primary">∞</p>
|
||
<p className="mt-0.5 text-sm text-gray-500">کسبوکار</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Quick access chips */}
|
||
<div className="mx-auto mt-12 max-w-2xl">
|
||
<p className="mb-3 text-center text-xs font-medium text-gray-400">دسترسی سریع</p>
|
||
<div className="flex flex-wrap items-center justify-center gap-2">
|
||
{quickApps.map((app) => (
|
||
<Link
|
||
key={app.id}
|
||
href={app.href!}
|
||
className="inline-flex items-center gap-2 rounded-full border border-gray-200 bg-white/80 px-4 py-2 text-sm font-medium text-secondary shadow-sm backdrop-blur-sm transition-all hover:border-primary hover:text-primary hover:shadow-md"
|
||
>
|
||
<span>{app.icon}</span>
|
||
<span>{app.name}</span>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</Container>
|
||
</section>
|
||
|
||
{/* Features strip */}
|
||
<section className="border-y border-gray-100 bg-white/60 backdrop-blur-sm">
|
||
<Container className="py-5">
|
||
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-3">
|
||
{FEATURES.map((f) => (
|
||
<div key={f.label} className="flex items-center gap-2 text-sm text-gray-600">
|
||
<span className="text-base">{f.icon}</span>
|
||
<span className="font-medium">{f.label}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</Container>
|
||
</section>
|
||
|
||
{/* App grid */}
|
||
<section id="apps" className="scroll-mt-20">
|
||
<Container className="py-12 sm:py-16">
|
||
<AppStoreGrid />
|
||
</Container>
|
||
</section>
|
||
|
||
{/* Footer */}
|
||
<footer className="border-t border-gray-100 bg-gray-50/80">
|
||
<Container className="flex flex-col items-center justify-between gap-3 py-6 text-center text-sm text-gray-500 sm:flex-row sm:text-right">
|
||
<p>
|
||
© {new Date().getFullYear()} {siteName} — White-label SaaS Platform
|
||
</p>
|
||
<p>{theme?.support_email ?? "support@example.com"}</p>
|
||
</Container>
|
||
</footer>
|
||
</div>
|
||
);
|
||
}
|