Commit Graph

226 Commits

Author SHA1 Message Date
dwindown
47d78cbd98 Fix consulting slots ordering and add debug logging
Changes:
- Sort consulting slots by start_time before processing
- Ensures correct first/last slot selection for calendar events
- Add debug logging to track time slot calculations
- Fixes end time calculation for multi-slot consulting orders

This ensures that when multiple slots are booked:
- Slots are processed in chronological order
- Calendar event uses first slot's start and last slot's end
- Event duration correctly covers all booked slots

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 08:27:34 +07:00
dwindown
42d6bd98e2 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>
2025-12-27 01:34:40 +07:00
dwindown
3f0acca658 Fix admin consulting page query
Change from relationship query to manual join to avoid foreign key issues with profiles table

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 01:22:15 +07:00
dwindown
17440cdf89 Fix consulting order processing and display
- Fix consulting history to show continuous time range (09:00 - 11:00) instead of listing individual slots
- Add foreign key relationships for consulting_slots (order_id and user_id)
- Fix handle-order-paid to query profiles(email, name) instead of full_name
- Add completed consulting sessions with recordings to Member Access page
- Add user_id foreign key constraint to consulting_slots table
- Add orders foreign key constraint for consulting_slots relationship

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 01:17:47 +07:00
dwindown
73c03285ea Debug: Add extensive logging to handle-order-paid
Added detailed logging to diagnose why consulting slots aren't being updated:
- Log order details including consulting_slots count
- Log whether order is detected as consulting order
- Log slot update result and any errors

This will help identify where the process is failing.
2025-12-27 00:07:00 +07:00
dwindown
293d5bd65d Fix: Call handle-order-paid directly from webhook instead of relying on DB trigger
The database trigger approach wasn't working because the trigger either doesn't
exist or the required database settings (app.base_url, app.service_role_key) aren't
configured.

This is a simpler, more reliable solution:
- pakasir-webhook updates order to 'paid' status
- pakasir-webhook then directly calls handle-order-paid edge function
- No dependency on database triggers or settings

This matches how other parts of the system work - direct function calls with
environment variables, not database triggers.
2025-12-26 23:54:13 +07:00
dwindown
390fde9bf2 Fix: Handle consulting orders properly in handle-order-paid edge function
Critical bug fix: Consulting orders were not being processed after payment because
the function checked order_items for consulting products, but consulting orders
don't have order_items - they have consulting_slots instead.

Changes:
- Fetch consulting_slots along with order_items in the query
- Check for consulting_slots.length > 0 to detect consulting orders
- Update consulting_slots status from 'pending_payment' to 'confirmed'
- Create Google Meet events for each consulting slot
- Send consulting_scheduled notification

This fixes the issue where:
- Consulting slots stayed in 'pending_payment' status after payment
- No meet links were generated
- No access was granted
- Schedules didn't show up in admin or member dashboard
2025-12-26 23:25:55 +07:00
dwindown
1743f95000 Fix: Add missing payment_method to consulting order creation
The consulting booking flow was missing payment_method: 'qris' when creating
orders. This caused the OrderDetail page to skip rendering the QR code section
because it checks order.payment_method === 'qris'.

Product orders already had this field, which is why QR codes displayed correctly
for them but not for consulting orders.

The root cause was in ConsultingBooking.tsx line 303-314 where the order insert
was missing the payment_method field that was present in Checkout.tsx.
2025-12-26 22:49:09 +07:00
dwindown
a567b683af Fix consulting order QR display and remove duplicate slots card
1. QR Code Display Fix:
   - Removed qr_string from required condition
   - Added fallback for when QR is still processing
   - Shows payment_url button if QR string not available yet
   - Helps users pay while QR code is being generated

2. Consulting Slots Display Fix:
   - Removed duplicate "Detail Jadwal" card
   - Slots now only shown once in main session card
   - Displays as continuous time range (start to end)
   - Shows total duration (e.g., "3 blok (135 menit)")

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 22:24:21 +07:00
dwindown
2dae2fdc33 Fix consulting order detail to show slots and QR code
Fixed isConsultingOrder detection:
- Now checks consultingSlots.length > 0 instead of only checking order_items
- Consulting orders don't have order_items, only consulting_slots

Always fetch consulting slots:
- Removed conditional check that only fetched slots for consulting products
- Now always queries consulting_slots table for any order
- This ensures consulting booking info displays correctly

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 21:32:13 +07:00
dwindown
c09d8b0c2a Fix consulting booking flow and export CSV format
1. CSV Export: Use raw numbers for Total and Refund Amount columns
   - Changed from formatted IDR (with dots) to plain numbers
   - Prevents Excel from breaking values with thousand separators

2. Consulting Booking Flow:
   - Fixed "Booking Sekarang" to navigate to order detail instead of redirecting to Pakasir
   - Payment QR code now displays in OrderDetail page
   - Consulting orders show slot details instead of empty items list

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 21:09:06 +07:00
dwindown
bf212fb973 Add CSV export functionality for admin orders
- Created exportCSV utility with convertToCSV, downloadCSV, formatExportDate, formatExportIDR
- Added export button to AdminOrders page with loading state
- Export includes all order fields: ID, email, total, status, payment method, date, refund info
- CSV format compatible with Excel and Google Sheets

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 18:25:43 +07:00
dwindown
5a05203f2b Update all pages to use centralized status helpers
Changes:
- Update MemberOrders to use getPaymentStatusLabel and getPaymentStatusColor
- Update OrderDetail to use centralized helpers
- Remove duplicate getStatusColor and getStatusLabel functions
- Dashboard.tsx already using imported helpers

Benefits:
- DRY principle - single source of truth
- Consistent Indonesian labels everywhere
- Easy to update status styling in one place

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 18:19:23 +07:00
dwindown
d089fcc769 Create centralized status management system
- Add statusHelpers.ts with single source of truth for all status labels/colors
- Update AdminOrders to use centralized helpers
- Add utility functions: canRefundOrder, canCancelOrder, canMarkAsPaid
- Improve consistency across payment status handling

Benefits:
- Consistent Indonesian labels everywhere
- DRY principle - no more duplicate switch statements
- Easy to update status styling in one place
- Reusable across all components

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 17:07:56 +07:00
dwindown
81bbafcff0 Add refund system and meet link management
Refund System:
- Add refund processing with amount and reason tracking
- Auto-revoke product access on refund
- Support full and partial refunds
- Add database fields for refund tracking

Meet Link Management:
- Show meet link status badge (Ready/Not Ready)
- Add manual meet link creation/update form
- Allow admin to create meet links if auto-creation fails

Database Migration:
- Add refund_amount, refund_reason, refunded_at, refunded_by to orders
- Add cancellation_reason to orders and consulting_slots

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 17:05:25 +07:00
dwindown
b955445dea Add filters to Member Access and Member Orders pages
- Member Access: Add product kind filter pills + search input
- Member Orders: Add order status filter pills with counts
- Both pages show results count and empty state when no results
- Include reset filter button and clear search functionality

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 16:10:26 +07:00
dwindown
a824e101ed Use live profile data for reviews instead of frozen reviewer_name
Changes:
- Revert to using profiles!user_id (name, avatar_url) JOIN for reviews
- Remove reviewer_name storage from ReviewModal (no longer needed)
- Add avatar display to ReviewCard component
- Reviews now sync automatically with profile changes
- Public queries safely expose only name + avatar via RLS

This ensures:
- Name/avatar changes update across all reviews automatically
- No frozen/outdated reviewer data
- Only public profile fields exposed (secure)
- Reviews serve as live, credible social proof

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 15:39:58 +07:00
dwindown
74b7dd09ea Fix reviewer name priority to use live profile data first
Changed fallback order from:
  reviewer_name || profiles.name || 'Anonymous'
To:
  profiles.name || reviewer_name || 'Anonymous'

This ensures:
1. Live profile name is always shown (current data)
2. Falls back to stored reviewer_name if profile deleted
3. Shows "Anonymous" as last resort

Fixes issue where name changes don't reflect on old reviews

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 09:36:54 +07:00
dwindown
9b2ac9beee Hide Quick Access section when no scheduled events available
- Check if quickAccessItems has any items before rendering section
- If no consulting/webinar events qualify, entire section is hidden
- Prevents empty "Akses Cepat" section from showing

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 01:53:30 +07:00
dwindown
734aa967ac Refactor quick access section to only show scheduled events
Changes:
- Add consulting slots fetching to get confirmed upcoming sessions
- Update getQuickAction logic:
  * Consulting: Only show if has confirmed upcoming slot with meet_link
  * Webinar: Only show if event_start + duration hasn't ended
  * Bootcamp: Removed from quick access (self-paced, not scheduled)
- Filter out items without valid quick actions
- Remove unused Calendar and BookOpen imports

Quick access now truly means "it is scheduled, here's the shortcut to join"

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 01:40:52 +07:00
dwindown
91bec42c4b Add missing Badge import to Bootcamp page
Fixes "Badge is not defined" error in bootcamp focus page.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 01:14:43 +07:00
dwindown
e512956444 Add celebratory review UI to Bootcamp page & fix access page
Bootcamp page changes:
- Add UserReview interface to store full review data
- Fetch review data with is_approved status
- Add celebratory UI when review is approved:
  - Gradient background with brand accent
  - "Ulasan Anda Terbit!" heading with "Disetujui" badge
  - Display user's review with stars, title, body
  - Publication date
- Show pending state with clock icon while waiting approval
- Update onSuccess callback to refresh review data

MemberAccess page changes:
- Change "Lanjutkan Bootcamp" to "Mulai Bootcamp" (clearer)
- Fix webinar action buttons:
  - Check if event_start has passed
  - Only show "Gabung Webinar" if webinar hasn't ended
  - Show "Tonton Rekaman" button if recording_url exists
  - Show "Rekaman segera tersedia" badge for passed webinars without recording

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 01:11:11 +07:00
dwindown
f1fb2758f8 Fix webinar join logic to use event_start + duration
Users can now join webinar even if it's already started:
- isWebinarJoinable(): returns true if current time <= event_start + duration
- isWebinarEnded(): returns true if current time > event_start + duration
- "Gabung Webinar" button shows as long as webinar hasn't ended
- This allows latecomers to join immediately

Previously used only event_start which prevented joining after start time.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:56:03 +07:00
dwindown
ae2a0bf3a1 Fix bootcamp and webinar action buttons
Bootcamp fixes:
- Change "Sudah Selesai" to "Selesai" (shorter, cleaner)
- Replace "Selanjutnya" button with "Beri Ulasan" when all lessons completed
- Makes more sense than "Lanjutkan" when there's nothing to continue

Webinar fixes:
- Check if webinar has ended based on event_start date
- Only show "Gabung Webinar" button if webinar hasn't ended AND has meeting link
- Show "Rekaman segera tersedia" badge for passed webinars without recording
- Only show recording player/video if recording_url exists

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:53:54 +07:00
dwindown
ed0d1b0ac8 Add celebratory review display after approval
Changes:
- Fetch user's full review data (not just approval status)
- Show celebratory UI when review is approved:
  - Gradient background with brand accent colors
  - "Ulasan Anda Terbit!" heading with approval badge
  - Display user's review with star rating
  - Thank you message for contributing
- Show pending state with clock icon while waiting approval
- Update review modal to refresh data after submission

This creates a proud moment for users when their review is approved!

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:41:12 +07:00
dwindown
b4d3b1a580 Remove debug console logs from review components
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:33:29 +07:00
dwindown
50a642b07b Fix reviewer name display in TestimonialsSection
- Change from INNER JOIN to LEFT JOIN (profiles:user_id → profiles!user_id)
- Add reviewer_name to SELECT clause
- Update fallback logic to prioritize reviewer_name over profiles.name
- Add debug console logging

This fixes the "Anonymous" reviewer name issue on homepage.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:29:39 +07:00
dwindown
a412baad53 Add enhanced debugging for review API response
Added console logging to track:
- When fetchReviews is called
- Raw API response data
- Any errors from Supabase

This will help debug why reviewer_name is not appearing
in the API response.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 00:10:07 +07:00
dwindown
196d3e9211 Fix review name capture with auth metadata fallback
Changes:
- ReviewModal now fetches name from profiles, auth metadata, or email
- Added console logging to debug review data
- Falls back to email username if no name found
- This ensures reviewer_name is always populated

For existing reviews without names, run:
UPDATE reviews r
SET reviewer_name = (
  SELECT COALESCE(
    raw_user_meta_data->>'name',
    SPLIT_PART(email, '@', 1)
  )
  FROM auth.users WHERE id = r.user_id
)
WHERE reviewer_name IS NULL;

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 23:35:40 +07:00
dwindown
2dd9d544ee Add webinar recording page with embedded video player
Changes:
- Create WebinarRecording page with embedded video player
- Supports YouTube, Vimeo, Google Drive, and direct MP4
- Check access via user_access or paid orders
- Update webinar recording buttons to navigate to page instead of new tab
- Add route /webinar/:slug

This keeps users on the platform for better UX instead of
redirecting to external video sites.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 23:05:32 +07:00
dwindown
e347a780f8 Fix review system: display real names and check approval status
Changes:
- ProductReviews.tsx: Use LEFT JOIN and fetch reviewer_name field
- ReviewModal.tsx: Store reviewer_name at submission time
- ProductDetail.tsx: Check is_approved=true in checkUserReview()
- Add migration for reviewer_name column and approval index

This fixes two issues:
1. Reviews now show real account names instead of "Anonymous"
2. Members no longer see "menunggu moderasi" after approval

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 22:29:48 +07:00
dwindown
466cca5cb4 Make all status badges pill-shaped and standardize pending color
- Add rounded-full to all status badges across admin and member pages
- Change Pending badge color from bg-secondary to bg-amber-500 text-white
- Update AdminDashboard to use Badge component instead of inline span
- Standardize badge colors everywhere:
  - Paid (Lunas): bg-brand-accent text-white
  - Pending: bg-amber-500 text-white
  - Cancelled: bg-destructive text-white

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:23:56 +07:00
dwindown
24826a3ea4 Fix badge colors and show paid webinars in access pages
- Change "Lunas" badge to use brand accent color instead of hardcoded green
- Fix "Aktif" badge with white text and border for better contrast
- Update MemberAccess page to fetch from paid orders (webinars now show)
- Remove payment_provider filter completely since only Pakasir is used

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 18:08:37 +07:00
dwindown
fe9a8bde1d Fix member dashboard issues and webinar datetime loading
- Remove payment_provider filter to show all paid products (webinars now appear)
- Fix webinar event_start field loading in AdminProducts (format to datetime-local)
- Update order status badge colors for better visibility (green for paid, amber for pending)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 17:56:51 +07:00
dwindown
f381c68371 Fix paragraph spacing in Tiptap editor output
Add [&_p]:my-4 to EditorContent className to ensure paragraphs
rendered from Tiptap editor have proper vertical spacing.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 14:06:17 +07:00
dwindown
4ccd1cb96f Add paragraph spacing to prose content styling
Add proper margin (my-4) to paragraphs in Tiptap-rendered content.
This ensures proper spacing between paragraphs when displaying
rich text content in product detail pages and other areas.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 13:57:53 +07:00
dwindown
711a5c5d6b Add webinar calendar integration and consulting slot blocking
- Fix webinar duration field reference in Calendar (duration_minutes)
- Calculate and display webinar end times in calendar view
- Fetch webinars for selected date in consulting booking
- Block consulting slots that overlap with webinar times
- Show warning when webinars are scheduled on selected date
- Properly handle webinar time range conflicts

This prevents booking conflicts when users try to schedule
consulting sessions during webinar times.

Example: Webinar 20:15-22:15 blocks consulting slots 20:00-22:30

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 13:46:03 +07:00
dwindown
eea3a1f8d8 Add Tiptap enhancements and webinar date/time fields
- Add text alignment controls to Tiptap editor (left, center, right, justify)
- Add horizontal rule/spacer button to Tiptap toolbar
- Add event_start and duration_minutes fields to webinar products
- Add webinar status badges (Recording Available, Coming Soon, Ended)
- Install @tiptap/extension-text-align package

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 13:41:51 +07:00
dwindown
fa274bd8cc Hide cart for admin users and remove confirmation from view-only modals
Admin Cart Visibility:
- Hide cart icon/badge in mobile header for admin users
- Cart was already hidden in desktop sidebar
- Admins don't need to purchase products

Modal Confirmation Improvements:
- Removed confirmation from AdminOrders detail dialog (view-only)
- Removed confirmation from AdminMembers detail dialog (view-only)
- Kept confirmation on AdminProducts form dialog (has form inputs)
- Kept confirmation on AdminEvents form dialogs (Event and Block forms)
- Kept confirmation on AdminConsulting meet link dialog (has form input)

This prevents annoying confirmations on simple view/close actions while
still protecting users from accidentally closing forms with unsaved data.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 13:21:06 +07:00
dwindown
f407723a8c Fix public header mobile menu and content formatting
Public Header Mobile Menu:
- Added hamburger menu for non-logged-in visitors on mobile
- Desktop shows full navigation, mobile shows slide-out menu with icons
- Cart icon remains visible on mobile alongside hamburger

Tiptap Editor List Formatting:
- Added visual styling for bullet lists (disc markers, padding, spacing)
- Added visual styling for ordered lists (decimal markers, padding, spacing)
- List markers now use primary color for better visibility

Product Content HTML Formatting:
- Enhanced prose styling with proper heading sizes (h1, h2, h3)
- Improved list formatting with proper indentation and markers
- Added blockquote styling with left border and italic text
- Added code and preformatted text styling
- Ensures all formatted content displays properly on product detail pages

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 13:11:04 +07:00
dwindown
52190ff26d Fix Tiptap editor visual formatting and improve badge contrast
Tiptap Editor Improvements:
- Active toolbar buttons now use primary background (black) instead of accent (gray) for better visibility
- Added visual formatting for headings (h1: 2xl bold, h2: xl bold with proper spacing)
- Added visual styling for blockquotes (left border, italic, muted foreground)

Badge Contrast Fixes:
- Product detail page badges now use primary background (black with white text) instead of secondary/accent (gray)
- Fixed product type badge and "Anda memiliki akses" badge
- Fixed "Rekaman segera tersedia" badge

API Query Fix:
- Fixed consulting_slots 400 error by removing unsupported nested relationship filter
- Changed to filter in JavaScript after fetching data from Supabase

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 11:51:46 +07:00
dwindown
5ae1632684 Make admin modals non-dismissible with confirmation
Prevent accidental data loss by requiring confirmation before closing any admin modal via backdrop click. Applied to all admin pages with dialogs.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 11:50:00 +07:00
dwindown
8c7f4000a9 Add shadows to mobile cards and fix AdminProducts wrapper
- Add shadow-sm to all mobile row cards for consistency
- Hide Card wrapper on mobile for AdminProducts page
- Add shadows to review cards in AdminReviews
- Applied to AdminMembers, AdminOrders, AdminConsulting,
  AdminEvents, AdminProducts, AdminReviews

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 11:02:55 +07:00
dwindown
bc88c0590d Hide Card wrapper on mobile for cleaner layout
- Desktop: Show table in bordered Card wrapper
- Mobile: Remove wrapper padding and hide Card border
- Individual cards now display directly without outer container
- Applied to AdminMembers, AdminOrders, AdminConsulting, AdminEvents

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 10:51:06 +07:00
dwindown
534c9629ea Fix JSX tag mismatches in mobile card layouts
Fixed build errors caused by incomplete sed script replacement.
Changed mismatched closing </CardContent> and </Card> tags to </div>
in mobile card layouts across admin pages.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 10:40:47 +07:00
dwindown
3d7408a607 Optimize mobile layouts and fix integration tab overflow
Mobile Card Layout Improvements:
- Remove redundant Card/CardContent wrappers in mobile layouts
- Use simple div with border-2 border-border rounded-lg p-4 space-y-3 bg-card
- This provides wider cards without extra padding from wrapper div
- Applied to all admin pages: AdminProducts, AdminOrders, AdminMembers, AdminConsulting, AdminEvents

Integration Tab Fix:
- Remove redundant Calendar ID display in Alert component
- The Calendar ID is already visible in the input field above
- This Alert was causing horizontal overflow on mobile
- Alert showed 'OAuth configured. Calendar ID: {long_email}@group.calendar.google.com'
- Removing this eliminates the overflow issue
2025-12-25 10:33:54 +07:00
dwindown
d07c32db1d Add mobile-stacked card layout for all admin tables
Implemented responsive card layout for mobile devices across all admin pages:

- Desktop (md+): Shows traditional table layout
- Mobile (<md): Shows stacked card layout with better readability

AdminProducts.tsx:
- Mobile cards display title, type, price (with sale badge), status
- Action buttons (edit/delete) in header

AdminOrders.tsx:
- Mobile cards display order ID, email, status badge, total, payment method, date
- View detail button in header

AdminMembers.tsx:
- Mobile cards display name, email, role badge, join date
- Action buttons (detail/toggle admin) at bottom with full width

AdminConsulting.tsx (upcoming & past tabs):
- Mobile cards display date, time, client, category, status, meet link
- Action buttons (link/complete/cancel) stacked at bottom

AdminEvents.tsx (events & availability tabs):
- Mobile cards display title/event type or block type, dates, status, notes
- Action buttons (edit/delete) at bottom

This approach provides much better UX on mobile compared to horizontal scrolling,
especially for complex cells like sale prices with badges and multiple action buttons.
2025-12-25 09:53:33 +07:00
dwindown
af40df2c9c Fix responsiveness in remaining admin pages
AdminMembers.tsx:
- Wrap table in overflow-x-auto div for horizontal scrolling
- Add whitespace-nowrap to TableHead cells

AdminConsulting.tsx:
- Wrap both tables (upcoming and past) in overflow-x-auto div
- Add whitespace-nowrap to all TableHead cells
- Change stats grid from grid-cols-1 md:grid-cols-4 to grid-cols-2 md:grid-cols-4 for better mobile layout

AdminEvents.tsx:
- Wrap both tables (events and availability) in overflow-x-auto div
- Add whitespace-nowrap to all TableHead cells
- Change dialog form grids from grid-cols-2 to grid-cols-1 md:grid-cols-2

CurriculumEditor.tsx:
- Make curriculum header responsive (flex-col sm:flex-row)
- Make module card headers responsive (stack title and buttons on mobile)
- Make lesson items responsive (stack title and buttons on mobile)

All admin pages are now fully responsive with proper horizontal scrolling for tables on mobile and stacked layouts for forms and button groups.
2025-12-25 08:57:08 +07:00
dwindown
ad95a15310 Fix table responsiveness in admin pages
AdminProducts.tsx:
- Wrap table in overflow-x-auto div for horizontal scrolling
- Add whitespace-nowrap to TableHead cells
- Change form grid from grid-cols-2 to grid-cols-1 md:grid-cols-2

AdminOrders.tsx:
- Wrap table in overflow-x-auto div for horizontal scrolling
- Add whitespace-nowrap to TableHead cells
- Change detail dialog grid from grid-cols-2 to grid-cols-1 sm:grid-cols-2
- Change action buttons from flex to flex-col sm:flex-row for mobile stacking

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 08:50:17 +07:00
dwindown
c653a174f4 Remove debug logging from Layout component
- Remove useEffect that logged branding data to console
- Remove unused useEffect import
- Keep mobile header structure (already correct)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 08:44:26 +07:00