init: kovakemlak-crm project scaffold

- Next.js 16 + Appwrite multi-tenant emlak CRM
- Database: kovakemlak-db (properties, customers, customer_searches, property_matches, presentations, investors, activities, tenant_settings)
- Same stack as isletmem-kovakcrm (shadcn/ui template base)
- Modules: portföy, müşteri takibi, arama kriterleri, otomatik eşleştirme, sunum linki, yatırımcı portalı
This commit is contained in:
egecankomur
2026-05-05 04:37:04 +03:00
commit 37679e83e6
383 changed files with 53525 additions and 0 deletions
@@ -0,0 +1,88 @@
"use client";
import Link from "next/link";
import { useActionState } from "react";
import { ArrowLeft, Loader2, MailCheck } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { forgotPasswordAction } from "@/lib/appwrite/auth-actions";
import { initialAuthState } from "@/lib/appwrite/auth-types";
export function ForgotPasswordForm1({ className, ...props }: React.ComponentProps<"div">) {
const [state, formAction, isPending] = useActionState(forgotPasswordAction, initialAuthState);
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<Card>
<CardHeader className="text-center">
<CardTitle className="text-xl">Şifremi unuttum</CardTitle>
<CardDescription>
Email adresinizi girin, sıfırlama bağlantısı gönderelim.
</CardDescription>
</CardHeader>
<CardContent>
{state.ok ? (
<div className="flex flex-col items-center gap-3 py-4 text-center">
<div className="bg-primary/10 text-primary flex size-12 items-center justify-center rounded-full">
<MailCheck className="size-6" />
</div>
<p className="text-sm">
Bağlantı emailinize gönderildi. Gelen kutusunu kontrol edin.
</p>
<Link
href="/sign-in"
className="text-muted-foreground hover:text-foreground mt-2 flex items-center gap-1 text-sm underline-offset-4 hover:underline"
>
<ArrowLeft className="size-3.5" />
Giriş sayfasına dön
</Link>
</div>
) : (
<form action={formAction} className="flex flex-col gap-4">
<div className="grid gap-3">
<Label htmlFor="email">Email</Label>
<Input
id="email"
name="email"
type="email"
placeholder="ornek@firma.com"
autoComplete="email"
required
/>
</div>
{state.error && (
<p className="text-destructive text-sm text-center" role="alert">
{state.error}
</p>
)}
<Button type="submit" className="w-full" disabled={isPending}>
{isPending ? (
<>
<Loader2 className="size-4 animate-spin" />
Gönderiliyor...
</>
) : (
"Sıfırlama bağlantısı gönder"
)}
</Button>
<Link
href="/sign-in"
className="text-muted-foreground hover:text-foreground flex items-center justify-center gap-1 text-sm underline-offset-4 hover:underline"
>
<ArrowLeft className="size-3.5" />
Giriş sayfasına dön
</Link>
</form>
)}
</CardContent>
</Card>
</div>
);
}
+20
View File
@@ -0,0 +1,20 @@
import Link from "next/link";
import { ForgotPasswordForm1 } from "./components/forgot-password-form-1";
import { Logo } from "@/components/logo";
export default function ForgotPasswordPage() {
return (
<div className="bg-muted flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
<div className="flex w-full max-w-sm flex-col gap-6">
<Link href="/" className="flex items-center gap-2 self-center font-medium">
<div className="bg-primary text-primary-foreground flex size-9 items-center justify-center rounded-md">
<Logo size={24} />
</div>
<span className="text-lg font-semibold">İşletmem</span>
</Link>
<ForgotPasswordForm1 />
</div>
</div>
);
}