Add calendar cleanup button to admin consulting page

Adds a manual button for admins to trigger Google Calendar event cleanup for cancelled consulting sessions. This works around Docker networking limitations.

Features:
- Button to trigger cleanup
- Confirmation dialog
- Loading state
- Success/error toast notifications

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-01-11 23:32:06 +07:00
parent d0d824a661
commit 9c2f367447

View File

@@ -77,6 +77,7 @@ export default function AdminConsulting() {
const [editTotalDuration, setEditTotalDuration] = useState(0);
const [isRescheduling, setIsRescheduling] = useState(false);
const [notifyMember, setNotifyMember] = useState(true);
const [cleaningCalendar, setCleaningCalendar] = useState(false);
useEffect(() => {
if (user && isAdmin) {
@@ -111,10 +112,40 @@ export default function AdminConsulting() {
.from('platform_settings')
.select('integration_n8n_base_url, integration_google_calendar_id')
.single();
if (data) setSettings(data);
};
const handleCalendarCleanup = async () => {
if (!confirm('Bersihkan Google Calendar events untuk semua sesi yang sudah dibatalkan?')) {
return;
}
setCleaningCalendar(true);
try {
const { data, error } = await supabase.functions.invoke('trigger-calendar-cleanup');
if (error) {
throw error;
}
const result = data as { processed?: number; message?: string };
toast({
title: 'Berhasil',
description: result.message || `Calendar events dibersihkan untuk ${result.processed || 0} sesi`,
});
} catch (error: any) {
console.error('Calendar cleanup error:', error);
toast({
title: 'Gagal',
description: error.message || 'Gagal membersihkan calendar events',
variant: 'destructive',
});
} finally {
setCleaningCalendar(false);
}
};
const openMeetDialog = (session: ConsultingSession, rescheduleMode: boolean = false) => {
setSelectedSession(session);
setMeetLink(session.meet_link || '');
@@ -421,10 +452,36 @@ export default function AdminConsulting() {
<Video className="w-10 h-10" />
Manajemen Konsultasi
</h1>
<p className="text-muted-foreground mb-8">
<p className="text-muted-foreground mb-4">
Kelola jadwal dan link Google Meet untuk sesi konsultasi
</p>
{/* Calendar Cleanup Button */}
<div className="mb-6">
<Button
variant="outline"
size="sm"
onClick={handleCalendarCleanup}
disabled={cleaningCalendar}
className="border-orange-600 text-orange-600 hover:bg-orange-50"
>
{cleaningCalendar ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Membersihkan Calendar Events...
</>
) : (
<>
<AlertCircle className="w-4 h-4 mr-2" />
Cleanup Calendar Events (Cancelled Sessions)
</>
)}
</Button>
<p className="text-xs text-muted-foreground mt-2">
Membersihkan Google Calendar events untuk sesi yang sudah dibatalkan
</p>
</div>
{/* Passed Confirmed Sessions Alert */}
{passedConfirmedSessions.length > 0 && (
<Card className="border-2 border-orange-500 bg-orange-50 dark:bg-orange-950 mb-6">