cb150f7a24
- 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
119 lines
3.6 KiB
TypeScript
119 lines
3.6 KiB
TypeScript
"use server";
|
|
|
|
import { ID, Permission, Query, Role } from "node-appwrite";
|
|
|
|
import { createAdminClient, createSessionClient } from "./server";
|
|
import { DATABASE_ID, TABLES } from "./schema";
|
|
|
|
export interface UserPrefs {
|
|
theme?: "dark" | "light" | "system";
|
|
colorTheme?: string;
|
|
tweakcnTheme?: string;
|
|
radius?: string;
|
|
sidebarVariant?: "sidebar" | "floating" | "inset";
|
|
sidebarCollapsible?: "offcanvas" | "icon" | "none";
|
|
sidebarSide?: "left" | "right";
|
|
}
|
|
|
|
export async function getUserPrefs(): Promise<UserPrefs> {
|
|
try {
|
|
const { account } = await createSessionClient();
|
|
const user = await account.get();
|
|
const { tablesDB } = createAdminClient();
|
|
|
|
const result = await tablesDB.listRows({
|
|
databaseId: DATABASE_ID,
|
|
tableId: TABLES.userPreferences,
|
|
queries: [Query.equal("userId", user.$id), Query.limit(1)],
|
|
});
|
|
|
|
if (result.rows.length === 0) {
|
|
// Pre-create an empty row so saveUserPrefsAction always calls updateRow
|
|
// (createRow inside a Server Action causes router cache invalidation → remount loop)
|
|
try {
|
|
await tablesDB.createRow(
|
|
DATABASE_ID,
|
|
TABLES.userPreferences,
|
|
ID.unique(),
|
|
{ userId: user.$id },
|
|
[
|
|
Permission.read(Role.user(user.$id)),
|
|
Permission.update(Role.user(user.$id)),
|
|
Permission.delete(Role.user(user.$id)),
|
|
],
|
|
);
|
|
} catch {
|
|
// race condition or already exists — fine
|
|
}
|
|
return {};
|
|
}
|
|
|
|
const row = result.rows[0] as Record<string, unknown>;
|
|
const str = (v: unknown) => (v && typeof v === "string" ? v : undefined);
|
|
return {
|
|
theme: (row.theme as UserPrefs["theme"]) ?? undefined,
|
|
colorTheme: str(row.colorTheme),
|
|
tweakcnTheme: str(row.tweakcnTheme),
|
|
radius: str(row.radius),
|
|
sidebarVariant: (row.sidebarVariant as UserPrefs["sidebarVariant"]) ?? undefined,
|
|
sidebarCollapsible: (row.sidebarCollapsible as UserPrefs["sidebarCollapsible"]) ?? undefined,
|
|
sidebarSide: (row.sidebarSide as UserPrefs["sidebarSide"]) ?? undefined,
|
|
};
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export async function saveUserPrefsAction(
|
|
update: Partial<UserPrefs>,
|
|
): Promise<{ ok: boolean; error?: string }> {
|
|
try {
|
|
const { account } = await createSessionClient();
|
|
const user = await account.get();
|
|
const { tablesDB } = createAdminClient();
|
|
|
|
// undefined → skip, "" → null (Appwrite rejects empty strings on nullable attrs)
|
|
const clean: Record<string, unknown> = {};
|
|
for (const [k, v] of Object.entries(update)) {
|
|
if (v === undefined) continue;
|
|
clean[k] = v === "" ? null : v;
|
|
}
|
|
if (Object.keys(clean).length === 0) return { ok: true };
|
|
|
|
const existing = await tablesDB.listRows({
|
|
databaseId: DATABASE_ID,
|
|
tableId: TABLES.userPreferences,
|
|
queries: [Query.equal("userId", user.$id), Query.limit(1)],
|
|
});
|
|
|
|
const perms = [
|
|
Permission.read(Role.user(user.$id)),
|
|
Permission.update(Role.user(user.$id)),
|
|
Permission.delete(Role.user(user.$id)),
|
|
];
|
|
|
|
if (existing.rows.length === 0) {
|
|
await tablesDB.createRow(
|
|
DATABASE_ID,
|
|
TABLES.userPreferences,
|
|
ID.unique(),
|
|
{ userId: user.$id, ...clean },
|
|
perms,
|
|
);
|
|
} else {
|
|
await tablesDB.updateRow(
|
|
DATABASE_ID,
|
|
TABLES.userPreferences,
|
|
existing.rows[0].$id,
|
|
clean,
|
|
);
|
|
}
|
|
|
|
return { ok: true };
|
|
} catch (err) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
console.error("[saveUserPrefsAction]", msg);
|
|
return { ok: false, error: msg };
|
|
}
|
|
}
|