Auto-cancel expired consulting orders and prefill re-booking
**Features Implemented:**
1. **Auto-Cancel Expired Consulting Orders:**
- New edge function: cancel-expired-consulting-orders
- Changes order status from 'pending' → 'cancelled'
- Cancels all associated consulting_sessions
- Deletes calendar events via delete-calendar-event
- Releases consulting_time_slots (deletes booked slots)
- Properly cleans up all resources
2. **Smart Re-Booking with Pre-filled Data:**
- OrderDetail.tsx stores expired order data in sessionStorage:
- fromExpiredOrder flag
- Original orderId
- topicCategory
- notes
- ConsultingBooking.tsx retrieves and pre-fills form on mount
- Auto-clears sessionStorage after use
3. **Improved UX for Expired Orders:**
- Clear message: "Order ini telah dibatalkan secara otomatis"
- Helpful hint: "Kategori dan catatan akan terisi otomatis"
- One-click re-booking with pre-filled data
- Member only needs to select new time slot
**How It Works:**
Flow:
1. QRIS expires → Order shows expired message
2. Member clicks "Buat Booking Baru"
3. Data stored in sessionStorage (category, notes)
4. Navigates to /consulting
5. Form auto-fills with previous data
6. Member selects new time → Books new session
**Edge Function Details:**
- Finds orders where: payment_status='pending' AND qr_expires_at < NOW()
- Cancels order status
- Cancels consulting_sessions
- Deletes consulting_time_slots
- Invokes delete-calendar-event for each session
- Returns count of processed orders
**To Deploy:**
1. Deploy cancel-expired-consulting-orders edge function
2. Set up cron job to run every 5-15 minutes:
`curl -X POST https://your-domain/functions/v1/cancel-expired-consulting-orders`
**Benefits:**
✅ Orders properly cancelled when QR expires
✅ Time slots released for other users
✅ Calendar events cleaned up
✅ Easy re-booking without re-typing data
✅ Better UX for expired payment situations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,31 @@ export default function ConsultingBooking() {
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
|
||||
// Check for pre-filled data from expired order
|
||||
const expiredOrderData = sessionStorage.getItem('expiredConsultingOrder');
|
||||
if (expiredOrderData) {
|
||||
try {
|
||||
const data = JSON.parse(expiredOrderData);
|
||||
if (data.fromExpiredOrder) {
|
||||
// Prefill form with expired order data
|
||||
if (data.topicCategory) setSelectedCategory(data.topicCategory);
|
||||
if (data.notes) setNotes(data.notes);
|
||||
|
||||
// Show notification to user
|
||||
setTimeout(() => {
|
||||
// You could add a toast notification here if you have toast set up
|
||||
console.log('Pre-filled data from expired order:', data);
|
||||
}, 100);
|
||||
|
||||
// Clear the stored data after using it
|
||||
sessionStorage.removeItem('expiredConsultingOrder');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error parsing expired order data:', err);
|
||||
sessionStorage.removeItem('expiredConsultingOrder');
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user