Commit Graph

284 Commits

Author SHA1 Message Date
dwindown
0a299466d8 Replace dropdown filters with tab buttons across admin pages
Update all admin pages to use tab button filters instead of dropdown selects, following the pattern from MemberAccess.tsx:

Changes:
- AdminProducts: Tab buttons for product type (only bootcamp/webinar shown) and status (active/inactive)
- AdminConsulting: Added status filter with tab buttons (pending payment, confirmed, completed, cancelled)
- AdminOrders: Tab buttons for status filter (all, paid, pending, refunded)
- AdminMembers: Tab buttons for role filter (all, admin, member)
- AdminReviews: Tab buttons for both type (all, consulting, bootcamp, webinar, general) and status (all, pending, approved)

Features added:
- Clear button (X) on search input when text is present
- Reset button appears when any filter is active
- Consistent styling with shadow-sm for active tabs and border-2 for outline tabs
- All filters in vertical stack layout for better mobile responsiveness
- Active state visually distinct with default variant and shadow

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 00:33:43 +07:00
dwindown
c993abe1e9 Add search and filter features to admin pages
Implement comprehensive search and filter functionality across all admin dashboard pages:

- AdminProducts: Search by title/description, filter by type/status
- AdminBootcamp: Search by bootcamp title
- AdminConsulting: Search by client name, email, category, or order ID
- AdminOrders: Search by order ID/email, filter by payment status
- AdminMembers: Search by name/email, filter by role (admin/member)
- AdminReviews: Enhanced with search by title, body, reviewer, product; existing filters maintained

Features:
- Consistent UI pattern with search icon and border styling
- Result count display showing filtered vs total items
- Contextual empty state messages
- Responsive grid layout for filters
- Real-time filtering without page reload

Also fix admin page reload redirect race condition where pages would redirect to /dashboard instead of staying on current page after reload. The loading state now properly waits for admin role check to complete.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 00:17:53 +07:00
dwindown
690268362a feat: add search to AdminConsulting page
- Add search by client name, email, category, or order ID
- Show result count for filtered data
- Integrate with existing upcoming/past tabs

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 00:08:21 +07:00
dwindown
3e418759a1 feat: add search and filter to admin pages
- Add search and filter (type, status) to AdminProducts
- Add search to AdminBootcamp
- Change mobile admin nav "Pesanan" to "Order"
- Show result counts for filtered data
- Handle empty states with helpful messages

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 00:07:07 +07:00
dwindown
0e3a45cfe2 fix: prevent admin page reload redirect to dashboard
Wait for admin role check to complete before setting loading to false.
This prevents race condition where:
1. authLoading becomes false after session loads
2. isAdmin is still false (async check in progress)
3. Page redirects to /dashboard before isAdmin is set to true

Now loading stays true until BOTH session and admin role are loaded,
ensuring admin pages don't redirect on reload.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 23:55:46 +07:00
dwindown
79e1bd82fc fix: consulting slots display and auth reload redirect
- Group consulting slots by date in admin order detail modal
- Show time range from first slot start to last slot end
- Display session count badge for multi-slot orders
- Fix page reload redirecting to main page by ensuring loading state
  is properly synchronized with Supabase session initialization
- Add mounted flag to prevent state updates after unmount

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 23:47:53 +07:00
dwindown
777d989d34 feat: improve consulting booking UX - allow single slot selection
- Add pending slot state to distinguish between selected and confirmed slots
- First click: slot shows as pending (amber) with "Pilih" label
- Second click (same slot): confirms single slot selection
- Second click (different slot): creates range from pending to clicked slot
- Fix "Body already consumed" error in OAuth token refresh
- Enhance admin consulting slot display with category and notes

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 23:40:54 +07:00
dwindown
4d8f66ed3a Fix meet link creation to use edge function instead of n8n webhook
Changes:
1. AdminConsulting.tsx: Update createMeetLink to call Supabase edge function
   - Remove dependency on n8n webhook URL
   - Call create-google-meet-event edge function directly
   - Use environment variables for Supabase URL and anon key
   - Improve error handling and user feedback

2. handle-order-paid: Add comprehensive error logging
   - Log meet response status
   - Log full response data
   - Log errors when meet_link update fails
   - Log error response text when request fails
   - Better debugging for troubleshooting meet creation issues

This fixes:
- CORS issues when calling n8n webhook
- 404 errors from deleted /webhook-test/create-link endpoint
- Manual meet link creation now uses same flow as automatic
- Better visibility into meet creation failures via logs

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 08:46:55 +07:00
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