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
+54
View File
@@ -0,0 +1,54 @@
import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { UsageBanner } from "@/components/billing/usage-banner";
import { listCustomers } from "@/lib/appwrite/customer-queries";
import { getPlanUsage } from "@/lib/appwrite/plan-limits";
import { requireTenant } from "@/lib/appwrite/tenant-guard";
import { CustomersClient } from "./components/customers-client";
export const metadata: Metadata = {
title: "İşletmem — Müşteriler",
};
export default async function CustomersPage() {
let ctx;
try {
ctx = await requireTenant();
} catch {
redirect("/onboarding");
}
const [customers, usage] = await Promise.all([
listCustomers(ctx.tenantId),
getPlanUsage(ctx),
]);
return (
<div className="flex-1 space-y-6 px-6 pt-0">
<div className="flex flex-col gap-1">
<p className="text-muted-foreground text-sm">{ctx.settings?.companyName ?? "Çalışma alanı"}</p>
<h1 className="text-2xl font-bold tracking-tight">Müşteriler</h1>
<p className="text-muted-foreground text-sm">
Müşterilerinizi yönetin, hizmet ve yazılım ilişkilerini buradan kurun.
</p>
</div>
<UsageBanner usage={usage} resource="customers" />
<CustomersClient
customers={customers.map((c) => ({
id: c.$id,
name: c.name,
email: c.email ?? "",
phone: c.phone ?? "",
taxId: c.taxId ?? "",
address: c.address ?? "",
notes: c.notes ?? "",
status: (c.status ?? "active") as "active" | "passive",
createdAt: c.$createdAt,
}))}
/>
</div>
);
}