init: lab project bootstrapped from isletmem-kovakcrm

- CRM domain modules removed (customers, services, software, calendar, tasks, invoices, leads, finance, etc.)
- DLS branding: package name=lab, logo wordmark, sidebar nav, header CTA
- Tenant layer extended with kind dimension (lab|clinic) + requireTenantKind helper
- Schema rewritten for DLS domain: jobs, job_files, job_status_history, prosthetics, connections, finance_entries, notifications
- Onboarding form: clinic/lab account-type selection + auto-generated memberNumber
- Placeholder routes for jobs/{inbound,outbound,new}, products, finance, connections
- PDF spec + spec.md under belgeler/
- db: lab database + 13 collections + indexes + storage bucket (job-files) provisioned via Appwrite MCP

Ref: belgeler/dls-ui-tasarim.pdf
This commit is contained in:
kovakmedya
2026-05-21 18:28:38 +03:00
commit cb150f7a24
215 changed files with 54262 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
"use client";
import * as React from "react";
import {
Inbox,
LayoutDashboard,
Link2,
Package,
Send,
Settings,
Wallet,
} from "lucide-react";
import Link from "next/link";
import { Logo } from "@/components/logo";
import { NavMain } from "@/components/nav-main";
import { NavUser } from "@/components/nav-user";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
import type { ShellCompany, ShellUser } from "@/app/(dashboard)/dashboard-shell";
type NavItem = {
title: string;
url: string;
icon?: typeof LayoutDashboard;
};
type NavGroup = {
label: string;
items: NavItem[];
};
function buildNavGroups(kind: ShellCompany["kind"]): NavGroup[] {
const isLab = kind === "lab";
const operationsItems: NavItem[] = [
{ title: "Gelen İşler", url: "/jobs/inbound", icon: Inbox },
{ title: "Giden İşler", url: "/jobs/outbound", icon: Send },
];
if (isLab) {
operationsItems.push({ title: "Ürünler", url: "/products", icon: Package });
}
return [
{
label: "Genel",
items: [{ title: "Anasayfa", url: "/dashboard", icon: LayoutDashboard }],
},
{
label: "Operasyon",
items: operationsItems,
},
{
label: "Finans",
items: [{ title: "Finans", url: "/finance", icon: Wallet }],
},
{
label: "Hesap",
items: [
{ title: "Bağlantı Kur", url: "/connections", icon: Link2 },
{ title: "Ayarlar", url: "/settings/workspace", icon: Settings },
],
},
];
}
export function AppSidebar({
user,
company,
...props
}: React.ComponentProps<typeof Sidebar> & {
user: ShellUser;
company: ShellCompany;
}) {
const navGroups = buildNavGroups(company.kind);
return (
<Sidebar {...props}>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg" asChild>
<Link href="/dashboard">
{company.logoUrl ? (
<div className="bg-background flex aspect-square size-8 items-center justify-center overflow-hidden rounded-lg border">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={company.logoUrl}
alt={`${company.name} logo`}
className="size-full object-contain"
/>
</div>
) : (
<div className="bg-primary text-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
<Logo size={20} className="text-current" />
</div>
)}
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">DLS</span>
<span className="text-muted-foreground truncate text-xs">{company.name}</span>
</div>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
{navGroups.map((group) => (
<NavMain key={group.label} label={group.label} items={group.items} />
))}
</SidebarContent>
<SidebarFooter>
<NavUser user={user} />
</SidebarFooter>
</Sidebar>
);
}