Fix calendar timezone and group consulting slots by order
Calendar Timezone Fix: - Add +07:00 timezone offset to date strings in create-google-meet-event - Fixes 13:00 appearing as 20:00 in Google Calendar - Now treats times as Asia/Jakarta time explicitly Single Calendar Event per Order: - handle-order-paid now creates ONE event for all slots in an order - Uses first slot's start time and last slot's end time - Updates all slots with the same meet_link - Prevents duplicate calendar events for multi-slot orders Admin Consulting Page Improvements: - Group consulting slots by order_id - Display as single row with continuous time range (start-end) - Show session count when multiple slots (e.g., "2 sesi") - Consistent with member-facing ConsultingHistory component - Updated both desktop table and mobile card layouts - Updated both upcoming and past tabs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,42 +113,50 @@ serve(async (req: Request): Promise<Response> => {
|
||||
}
|
||||
|
||||
if (consultingSlots && consultingSlots.length > 0) {
|
||||
for (const slot of consultingSlots) {
|
||||
try {
|
||||
console.log("[HANDLE-PAID] Creating Google Meet for slot:", slot.id);
|
||||
try {
|
||||
console.log("[HANDLE-PAID] Creating Google Meet for order:", order_id);
|
||||
|
||||
const topic = "Konsultasi 1-on-1";
|
||||
// Group slots by order - use first slot's start time and last slot's end time
|
||||
const firstSlot = consultingSlots[0];
|
||||
const lastSlot = consultingSlots[consultingSlots.length - 1];
|
||||
const topic = "Konsultasi 1-on-1";
|
||||
|
||||
const meetResponse = await fetch(
|
||||
`${supabaseUrl}/functions/v1/create-google-meet-event`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${Deno.env.get("SUPABASE_ANON_KEY")}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slot_id: slot.id,
|
||||
date: slot.date,
|
||||
start_time: slot.start_time,
|
||||
end_time: slot.end_time,
|
||||
client_name: userName,
|
||||
client_email: userEmail,
|
||||
topic: topic,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (meetResponse.ok) {
|
||||
const meetData = await meetResponse.json();
|
||||
if (meetData.success) {
|
||||
console.log("[HANDLE-PAID] Meet created:", meetData.meet_link);
|
||||
}
|
||||
const meetResponse = await fetch(
|
||||
`${supabaseUrl}/functions/v1/create-google-meet-event`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${Deno.env.get("SUPABASE_ANON_KEY")}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slot_id: firstSlot.id, // Use first slot ID
|
||||
date: firstSlot.date,
|
||||
start_time: firstSlot.start_time,
|
||||
end_time: lastSlot.end_time, // Use last slot's end time for continuous block
|
||||
client_name: userName,
|
||||
client_email: userEmail,
|
||||
topic: topic,
|
||||
notes: `${consultingSlots.length} sesi: ${consultingSlots.map(s => s.start_time.substring(0, 5)).join(', ')}`,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (meetResponse.ok) {
|
||||
const meetData = await meetResponse.json();
|
||||
if (meetData.success) {
|
||||
console.log("[HANDLE-PAID] Meet created:", meetData.meet_link);
|
||||
|
||||
// Update all slots with the same meet link
|
||||
await supabase
|
||||
.from("consulting_slots")
|
||||
.update({ meet_link: meetData.meet_link })
|
||||
.eq("order_id", order_id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[HANDLE-PAID] Meet creation failed:", error);
|
||||
// Don't fail the entire process
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[HANDLE-PAID] Meet creation failed:", error);
|
||||
// Don't fail the entire process
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user