Files
neta/app/(dashboard)/calendar/actions.ts
T
Poyraz Avsever 7ee3104158 feat(calendar): implement calendar event management with create, update, and delete functionalities
- Added actions for creating, updating, and deleting calendar events in `actions.ts`.
- Introduced `CalendarClient` component to handle event display and interaction in `calendar-client.tsx`.
- Refactored `CalendarPage` to fetch events, clients, projects, and tasks from Supabase and pass them to `CalendarClient`.
- Enhanced form handling for event creation and editing with proper validation and error handling.
2026-06-04 19:53:44 +03:00

107 lines
2.9 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 { createClient } from "@/lib/supabase/server";
import { revalidatePath } from "next/cache";
const EVENT_TYPES = ["meeting", "focus", "deadline", "personal", "finance"] as const;
function cleanText(value: FormDataEntryValue | null) {
const text = typeof value === "string" ? value.trim() : "";
return text.length > 0 && text !== "__none" ? text : null;
}
function readType(value: FormDataEntryValue | null) {
const type = typeof value === "string" ? value : "focus";
return EVENT_TYPES.includes(type as (typeof EVENT_TYPES)[number]) ? type : "focus";
}
async function getCurrentUserId() {
const supabase = await createClient();
const {
data: { user },
error,
} = await supabase.auth.getUser();
if (error || !user) {
throw new Error("Takvim işlemi için giriş yapmış kullanıcı bulunamadı.");
}
return { supabase, userId: user.id };
}
function readPayload(formData: FormData) {
return {
title: cleanText(formData.get("title")),
description: cleanText(formData.get("description")),
type: readType(formData.get("type")),
starts_at: cleanText(formData.get("starts_at")),
ends_at: cleanText(formData.get("ends_at")),
client_id: cleanText(formData.get("client_id")),
project_id: cleanText(formData.get("project_id")),
task_id: cleanText(formData.get("task_id")),
};
}
export async function createCalendarEventRecord(formData: FormData) {
const { supabase, userId } = await getCurrentUserId();
const payload = readPayload(formData);
if (!payload.title || !payload.starts_at) {
throw new Error("Etkinlik başlığı ve başlangıç zamanı zorunludur.");
}
const { error } = await supabase.from("calendar_events").insert({
user_id: userId,
...payload,
});
if (error) {
throw new Error(`Etkinlik eklenemedi: ${error.message}`);
}
revalidatePath("/calendar");
}
export async function updateCalendarEventRecord(formData: FormData) {
const { supabase, userId } = await getCurrentUserId();
const id = cleanText(formData.get("id"));
const payload = readPayload(formData);
if (!id || !payload.title || !payload.starts_at) {
throw new Error("Etkinlik güncellemek için başlık, başlangıç ve kayıt kimliği zorunludur.");
}
const { error } = await supabase
.from("calendar_events")
.update(payload)
.eq("id", id)
.eq("user_id", userId);
if (error) {
throw new Error(`Etkinlik güncellenemedi: ${error.message}`);
}
revalidatePath("/calendar");
}
export async function deleteCalendarEventRecord(formData: FormData) {
const { supabase, userId } = await getCurrentUserId();
const id = cleanText(formData.get("id"));
if (!id) {
throw new Error("Silinecek etkinlik bulunamadı.");
}
const { error } = await supabase
.from("calendar_events")
.delete()
.eq("id", id)
.eq("user_id", userId);
if (error) {
throw new Error(`Etkinlik silinemedi: ${error.message}`);
}
revalidatePath("/calendar");
}