Files
kovakemlak-crm/src/lib/appwrite/property-actions.ts
T
egecankomur 4ef0482732 feat: all core modules — properties, customers, searches, matches, presentations, activities, investors + public sunum page
- Server actions: property/customer/search/presentation/activity/investor CRUD
- Matching engine: matchPropertyToSearches + syncMatchesForSearch on search save
- UI: form sheets + table clients for all modules
- Public /sunum/[token] page (no auth) with property card grid + expiry check
- All pages force-dynamic for auth guard compatibility
2026-05-05 12:03:48 +03:00

144 lines
4.1 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.
"use server";
import { ID, Permission, Role } from "node-appwrite";
import { revalidatePath } from "next/cache";
import { propertySchema } from "@/lib/validation/properties";
import { DATABASE_ID, TABLES, type Property } from "./schema";
import { createAdminClient } from "./server";
import { requireTenant } from "@/lib/appwrite/tenant-guard";
import { matchPropertyToSearches } from "./matching";
type ActionState = { ok: boolean; error?: string; fieldErrors?: Record<string, string[]> };
export async function createPropertyAction(
_prev: ActionState,
formData: FormData,
): Promise<ActionState> {
const ctx = await requireTenant();
const raw = Object.fromEntries(formData.entries());
const parsed = propertySchema.safeParse(raw);
if (!parsed.success) {
return { ok: false, fieldErrors: parsed.error.flatten().fieldErrors };
}
const { tablesDB } = createAdminClient();
const id = ID.unique();
const data = parsed.data;
try {
const row = await tablesDB.createRow(
DATABASE_ID,
TABLES.properties,
id,
{
tenantId: ctx.tenantId,
title: data.title,
description: data.description,
propertyType: data.propertyType,
listingType: data.listingType,
status: data.status ?? "aktif",
price: data.price,
currency: data.currency ?? "TRY",
roomCount: data.roomCount,
grossM2: data.grossM2,
netM2: data.netM2,
floor: data.floor,
totalFloors: data.totalFloors,
buildingAge: data.buildingAge,
city: data.city,
district: data.district,
neighborhood: data.neighborhood,
address: data.address,
mapLat: data.mapLat,
mapLng: data.mapLng,
featuresJson: data.featuresJson,
imageIds: data.imageIds,
createdBy: ctx.user.id,
assigneeId: data.assigneeId,
},
[
Permission.read(Role.team(ctx.tenantId)),
Permission.update(Role.team(ctx.tenantId)),
Permission.delete(Role.team(ctx.tenantId, "owner")),
Permission.delete(Role.team(ctx.tenantId, "admin")),
],
);
await matchPropertyToSearches(row as unknown as Property, ctx.tenantId, ctx.user.id).catch(
() => {},
);
} catch {
return { ok: false, error: "İlan oluşturulamadı." };
}
revalidatePath("/properties");
return { ok: true };
}
export async function updatePropertyAction(
id: string,
_prev: ActionState,
formData: FormData,
): Promise<ActionState> {
const ctx = await requireTenant();
const raw = Object.fromEntries(formData.entries());
const parsed = propertySchema.safeParse(raw);
if (!parsed.success) {
return { ok: false, fieldErrors: parsed.error.flatten().fieldErrors };
}
const { tablesDB } = createAdminClient();
const data = parsed.data;
try {
const row = await tablesDB.updateRow(DATABASE_ID, TABLES.properties, id, {
title: data.title,
description: data.description,
propertyType: data.propertyType,
listingType: data.listingType,
status: data.status,
price: data.price,
currency: data.currency,
roomCount: data.roomCount,
grossM2: data.grossM2,
netM2: data.netM2,
floor: data.floor,
totalFloors: data.totalFloors,
buildingAge: data.buildingAge,
city: data.city,
district: data.district,
neighborhood: data.neighborhood,
address: data.address,
mapLat: data.mapLat,
mapLng: data.mapLng,
featuresJson: data.featuresJson,
imageIds: data.imageIds,
assigneeId: data.assigneeId,
});
await matchPropertyToSearches(row as unknown as Property, ctx.tenantId, ctx.user.id).catch(
() => {},
);
} catch {
return { ok: false, error: "İlan güncellenemedi." };
}
revalidatePath("/properties");
return { ok: true };
}
export async function deletePropertyAction(id: string): Promise<ActionState> {
await requireTenant();
const { tablesDB } = createAdminClient();
try {
await tablesDB.deleteRow(DATABASE_ID, TABLES.properties, id);
} catch {
return { ok: false, error: "İlan silinemedi." };
}
revalidatePath("/properties");
return { ok: true };
}