Files
isletmem-kovakcrm/src/app/(dashboard)/settings/workspace/page.tsx
T
kovakmedya fc091b9e0d feat(settings): /settings/workspace — edit company info + invoice defaults
Owner/admin edit, member read-only.

Schema/validation:
- lib/validation/workspace.ts (workspaceSettingsSchema)
- lib/appwrite/workspace-actions.ts:
  * updateWorkspaceSettingsAction — requireRole owner|admin, upserts the
    tenant_settings row (creates one with team-scoped perms if absent,
    e.g. for tenants created before tenant_settings was a table; just
    defense). Audit-logged.
  * Forces invoicePrefix to uppercase. defaultVatRate clamped to [0, 100].
  * revalidatePath('/', 'layout') so the new company name updates in
    sidebar header and dashboard greeting on next render.

UI:
- /settings/workspace page (server) — pulls active tenant settings
  via requireTenant, shows form pre-filled.
- WorkspaceSettingsForm: 2 cards
  * Şirket — name (required), tax id, phone, email, address
  * Faturalama — invoicePrefix, defaultVatRate, read-only invoiceCounter
- All inputs disabled if user is a member (canEdit=false). Submit button
  hidden in that case. Description on the page changes accordingly.
- Toast feedback for success/error.

Skipped: logo upload (storage bucket pending). Will revisit.
2026-04-30 06:44:11 +03:00

51 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { requireTenant } from "@/lib/appwrite/tenant-guard";
import { WorkspaceSettingsForm } from "./components/workspace-form";
export const metadata: Metadata = {
title: "İşletmem — Şirket bilgileri",
};
export default async function WorkspaceSettingsPage() {
let ctx;
try {
ctx = await requireTenant();
} catch {
redirect("/onboarding");
}
const canEdit = ctx.role === "owner" || ctx.role === "admin";
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">Şirket bilgileri</h1>
<p className="text-muted-foreground text-sm">
Faturalarda ve panel başlığında görünecek şirket bilgileri.
{!canEdit && " Düzenlemek için yönetici yetkisine ihtiyacınız var."}
</p>
</div>
<WorkspaceSettingsForm
canEdit={canEdit}
defaults={{
companyName: ctx.settings?.companyName ?? "",
companyTaxId: ctx.settings?.companyTaxId ?? "",
companyAddress: ctx.settings?.companyAddress ?? "",
companyEmail: ctx.settings?.companyEmail ?? "",
companyPhone: ctx.settings?.companyPhone ?? "",
defaultVatRate:
typeof ctx.settings?.defaultVatRate === "number"
? ctx.settings.defaultVatRate
: 20,
invoicePrefix: ctx.settings?.invoicePrefix ?? "INV",
invoiceCounter: ctx.settings?.invoiceCounter ?? 0,
}}
/>
</div>
);
}