Files
isletmem-kovakcrm/src/lib/appwrite/lead-activity-actions.ts
T

146 lines
4.3 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 { revalidatePath } from "next/cache";
import { ID, Permission, Role } from "node-appwrite";
import { DATABASE_ID, TABLES, type Lead, type LeadActivityType } from "./schema";
import { createAdminClient } from "./server";
import { requireTenant } from "./tenant-guard";
export type ActivityActionState = { ok: boolean; error?: string };
export async function addLeadActivityAction(
_prev: ActivityActionState,
formData: FormData,
): Promise<ActivityActionState> {
const leadId = String(formData.get("leadId") ?? "");
const type = String(formData.get("type") ?? "note") as LeadActivityType;
const content = String(formData.get("content") ?? "").trim();
const occurredAt = String(formData.get("occurredAt") ?? "") || new Date().toISOString();
if (!leadId || !content) return { ok: false, error: "Zorunlu alanlar eksik." };
let ctx;
try {
ctx = await requireTenant();
} catch {
return { ok: false, error: "Yetkiniz yok." };
}
try {
const { tablesDB } = createAdminClient();
const lead = (await tablesDB.getRow(DATABASE_ID, TABLES.leads, leadId)) as unknown as Lead;
if (lead.tenantId !== ctx.tenantId) return { ok: false, error: "Erişim engellendi." };
await tablesDB.createRow(
DATABASE_ID,
TABLES.leadActivities,
ID.unique(),
{
tenantId: ctx.tenantId,
createdBy: ctx.user.id,
leadId,
type,
content,
occurredAt,
},
[
Permission.read(Role.team(ctx.tenantId)),
Permission.update(Role.team(ctx.tenantId)),
Permission.delete(Role.team(ctx.tenantId, "owner")),
],
);
// Update lastContactAt on the lead
await tablesDB.updateRow(DATABASE_ID, TABLES.leads, leadId, {
lastContactAt: new Date().toISOString(),
});
revalidatePath("/leads");
return { ok: true };
} catch (e) {
return { ok: false, error: e instanceof Error ? e.message : "Hata oluştu." };
}
}
export async function scheduleFollowUpAction(
_prev: ActivityActionState,
formData: FormData,
): Promise<ActivityActionState> {
const leadId = String(formData.get("leadId") ?? "");
const followUpAt = String(formData.get("followUpAt") ?? "");
const note = String(formData.get("note") ?? "").trim();
if (!leadId || !followUpAt) return { ok: false, error: "Tarih seçin." };
let ctx;
try {
ctx = await requireTenant();
} catch {
return { ok: false, error: "Yetkiniz yok." };
}
try {
const { tablesDB } = createAdminClient();
const lead = (await tablesDB.getRow(DATABASE_ID, TABLES.leads, leadId)) as unknown as Lead;
if (lead.tenantId !== ctx.tenantId) return { ok: false, error: "Erişim engellendi." };
const followUpDate = new Date(followUpAt);
const endDate = new Date(followUpDate.getTime() + 60 * 60 * 1000); // +1h
const permissions = [
Permission.read(Role.team(ctx.tenantId)),
Permission.update(Role.team(ctx.tenantId)),
Permission.delete(Role.team(ctx.tenantId, "owner")),
];
// Create calendar event
const event = await tablesDB.createRow(
DATABASE_ID,
TABLES.calendarEvents,
ID.unique(),
{
tenantId: ctx.tenantId,
createdBy: ctx.user.id,
title: `Takip: ${lead.contactName || lead.name}`,
description: note || `Lead takip görüşmesi — ${lead.name}`,
start: followUpDate.toISOString(),
end: endDate.toISOString(),
allDay: false,
leadId,
color: "#f97316", // orange — lead events
},
permissions,
);
// Update lead nextFollowUpAt + calendarEventId
await tablesDB.updateRow(DATABASE_ID, TABLES.leads, leadId, {
nextFollowUpAt: followUpDate.toISOString(),
calendarEventId: event.$id,
});
// Log activity
await tablesDB.createRow(
DATABASE_ID,
TABLES.leadActivities,
ID.unique(),
{
tenantId: ctx.tenantId,
createdBy: ctx.user.id,
leadId,
type: "meeting",
content: `Takip planlandı: ${followUpDate.toLocaleString("tr-TR")}${note ? `${note}` : ""}`,
calendarEventId: event.$id,
occurredAt: new Date().toISOString(),
},
permissions,
);
revalidatePath("/leads");
revalidatePath("/calendar");
return { ok: true };
} catch (e) {
return { ok: false, error: e instanceof Error ? e.message : "Hata oluştu." };
}
}