Commit Graph

151 Commits

Author SHA1 Message Date
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
dwindown
21f337cece Fix card height alignment and remove banner border radius
Changes:
1. Remove rounded-xl from consulting banner (conflicts with narrow border theme)
2. Make all cards equal height with h-full flex flex-col
3. Simplify consulting card to match product card structure:
   - Remove Clock/Calendar feature icons (made card too tall)
   - Use line-clamp-2 for description (same as products)
   - Add line-clamp-1 to title (same as products)
   - Use flex-1 justify-end on CardContent (same as products)
   - Keep decorative element and gradient background
4. Remove unused Clock and Calendar imports

Result: All cards in the grid now have equal height and aligned bottoms

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 01:48:28 +07:00
dwindown
608fae740a Improve Products page with search, filters, and enhanced UX
Enhancements:
- Add search bar with real-time filtering
- Add category filter buttons (Semua, Webinar, Bootcamp, etc.)
- Show result count ("Menampilkan X dari Y produk")
- Add clear/reset filters button
- Remove booking button from banner (redundant with card)
- Improve banner styling with gradient and rounded-xl

Consulting card improvements:
- Add decorative background element
- Better description of service
- Add feature icons (Clock, Calendar)
- Change price display from "menit" to "sesi" (more premium)
- Improve button text ("Booking Jadwal")
- Use primary color for price and icons

Product card improvements:
- Use stripHtml() for description instead of dangerouslySetInnerHTML
- Fix spacing: add gap-2 between title and badge, shrink-0 on badge
- Larger price display (text-3xl)
- Add discount percentage badge for sale items
- Color sale price with primary color
- Add Check icon for "in cart" state
- Green background for added items (bg-green-500)
- Items-baseline for better price alignment
- Change grid from lg: to xl: for better responsiveness

Empty states:
- Better empty state with Package icon for no products
- New "no results found" state with Search icon
- Add reset filter button to empty state

Technical:
- Add filteredProducts state and logic
- Add searchQuery and selectedType states
- Add clearFilters function
- Import new icons: Clock, Calendar, Check, Search, X
- Import Input component for search bar

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 01:32:36 +07:00
dwindown
9a7fb695f9 Move opengraph.png to public folder for correct static asset serving
- Moved opengraph.png from src/ to public/ directory
- This ensures the file is accessible at https://with.dwindi.com/opengraph.png
- Vite serves files in public/ at root level without path prefix

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 01:14:20 +07:00
dwindown
ce6b2139c2 Fix Open Graph image URLs to use absolute URLs
- Changed og:image and twitter:image to use full URL instead of relative path
- Added og:url meta tag for proper social media sharing
- Fixes "not a valid URL" error from social media scrapers

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 01:11:50 +07:00
dwindown
dd4474a4cd Add Open Graph image dimensions for better social media sharing
- Added og:image:width (1200) and og:image:height (629) meta tags
- Added og:image:alt and twitter:image:alt tags for accessibility
- Fixes Facebook async image processing warning

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 01:02:01 +07:00
dwindown
a8d91ee19b Require login for consulting booking and add availability banner on products page
- Consulting booking now requires authentication upfront (shows login prompt to non-users)
- Added prominent consultation availability banner on products page when enabled
- Added debug logging to Layout component for branding troubleshooting
- Mobile Layout header shows responsive platform name sizing

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 00:53:51 +07:00
dwindown
428314d5bf Fix sidebar header to show logo + brand name inline, improve favicon update logic
- Update AppLayout to display logo and brand name together in all headers (sidebar, public, mobile)
- Improve favicon update in useBranding to create link element if not exists
- Update opengraph metadata to use local image instead of lovable.dev URL
- Change author/meta to WithDwindi branding

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 15:50:50 +07:00
dwindown
dfbabddd98 Add debug logging for logo/favicon upload state
- Add console.log to track URL generation
- Use functional setState to avoid stale closure issues
- Log settings state before save

This will help diagnose why URLs are empty in save payload

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:50:02 +07:00
dwindown
8441063f0c Fix SQL errors in RLS policy scripts
- Remove profiles.role reference (column doesn't exist)
- Use simplified policies (all authenticated users can modify)
- Drop all existing storage policies before creating new ones to avoid conflicts
- Fix policy already exists error in STORAGE_RLS_FIX.sql

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:42:37 +07:00
dwindown
9fdcf07439 Add RLS policy fixes for platform_settings and storage
- PLATFORM_SETTINGS_RLS_FIX.sql: Allow public read access to branding settings
- STORAGE_RLS_FIX.sql: Fix upload permissions for logo/favicon

These fixes:
1. Allow non-admin users to see branding (logo, favicon, colors)
2. Fix empty JSON response on platform_settings fetch
3. Fix storage upload 403 errors

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:40:14 +07:00
dwindown
7a8f9cb9a9 Fix logo/favicon upload, badge colors, and page title issues
Issue 1 - Logo/Favicon Upload:
- Add preview before upload (user must confirm)
- Show selected file preview with confirm/cancel buttons
- Fallback to current image if preview cancelled
- File size validation (2MB logo, 1MB favicon)
- Add STORAGE_RLS_FIX.sql for storage policy setup

Issue 2 - Badge Colors:
- Already implemented correctly in all files
- All "Lunas" badges use bg-brand-accent class
- Verified: OrderDetail, MemberOrders, Dashboard, MemberDashboard

Issue 3 - Page Title Error:
- Change .single() to .maybeSingle() in useBranding hook
- Handle error case gracefully with default branding
- Set default title even when platform_settings is empty
- This fixes the "JSON object requested, multiple (or no) rows returned" error

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 12:31:48 +07:00
dwindown
3af2787d03 Add deployment guide for post-implementation refinements 2025-12-24 11:42:51 +07:00
dwindown
fb24e77e42 Implement post-implementation refinements
Features implemented:
1. Expired QRIS order handling with dual-path approach
   - Product orders: QR regeneration button
   - Consulting orders: Immediate cancellation with slot release
2. Standardized status badge wording to "Pending"
3. Fixed TypeScript error in MemberDashboard
4. Dynamic badge colors from branding settings
5. Dynamic page title from branding settings
6. Logo/favicon file upload with auto-delete

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 11:42:20 +07:00
dwindown
4b8765885b Fix broken Checkout.tsx - remove leftover waiting step code 2025-12-24 00:32:14 +07:00
dwindown
35a003e35c Add QR code display and polling to OrderDetail page
- Add qr_string and qr_expires_at to Order interface
- Implement 10-second polling for payment status
- Add countdown timer for QR expiration
- Display QR code inline for pending QRIS payments
- Show "Menunggu pembayaran" with spinner while polling
- Add fallback button for payments without QR

Features:
- QR code rendered with qrcode.react library
- Real-time countdown timer (minutes:seconds)
- Auto-refresh when payment detected
- Clean up polling interval on unmount
- Memoized fetchOrder to prevent excessive re-renders

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 00:25:27 +07:00
dwindown
eba37df4d7 Remove PayPal, simplify to QRIS-only with in-app QR display
- Remove PayPal payment option from checkout
- Add qr_string and qr_expires_at columns to orders table
- Update create-payment to store QR string in database
- Update pakasir-webhook to clear QR string after payment
- Simplify Checkout to redirect to order detail page
- Clean up unused imports and components

Flow:
1. User checks out with QRIS (only option)
2. Order created with payment_method='qris'
3. QR string stored in database
4. User redirected to Order Detail page
5. QR code displayed in-app with polling
6. After payment, QR string cleared, access granted

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 00:12:04 +07:00
dwindown
1a36f831cc Refactor: Rename create-pakasir-payment to create-payment
- Rename function to abstract payment provider details
- Add support for both QRIS and PayPal methods
- Update frontend to use generic create-payment function
- Remove provider-specific naming from UI/UX
- Payment provider (Pakasir) is now an implementation detail

Response format:
- QRIS: returns qr_string for in-app display, payment_url as fallback
- PayPal: returns payment_url for redirect

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 21:41:47 +07:00
dwindown
a9f7c9b07a Create Pakasir payment edge function to fix CORS issue
- Create create-pakasir-payment edge function to handle payment creation server-side
- Update ConsultingBooking.tsx to use edge function instead of direct API call
- Update Checkout.tsx to use edge function instead of direct API call
- Add config.toml entry for create-pakasir-payment function
- Removes CORS errors when calling Pakasir API from frontend

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 21:20:40 +07:00
dwindown
94403bd634 Add order deletion functionality
- Add delete button to AdminOrders dialog with Trash2 and AlertTriangle icons
- Create delete-order edge function to handle deletion requests
- Add database migration for delete_order function with comprehensive cleanup
- Update config.toml to register delete-order edge function
- Deletion sequence: reviews → consulting slots → order items → user access → order

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 18:06:40 +07:00
dwindown
e6b1e02e5f Fix consulting payment: call Pakasir API directly from frontend
The create-pakasir-payment edge function doesn't exist.
Instead, call Pakasir API directly from the frontend (same as Checkout page).
Uses VITE_PAKASIR_PROJECT_SLUG and VITE_PAKASIR_API_KEY env vars.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 17:21:01 +07:00
dwindown
ecab3eb22a Fix consulting booking: bypass cart, go directly to payment
Consulting is a service, not a product. It doesn't have order_items.
- Removed cart integration for consulting bookings
- Now calls create-pakasir-payment edge function directly
- Redirects to payment URL without going through checkout
- Removed useCart dependency

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 17:16:20 +07:00
dwindown
01579ac299 Refactor payment flow to use database triggers (Clean Architecture)
BREAKING CHANGE: Complete refactor of payment handling

New Architecture:
1. pakasir-webhook (120 lines -> was 535 lines)
   - Only verifies signature and updates order status
   - Removed: SMTP, email templates, notification logic

2. Database Trigger (NEW)
   - Automatically fires when payment_status = 'paid'
   - Calls handle-order-paid edge function
   - Works for webhook AND manual admin updates

3. handle-order-paid (NEW edge function)
   - Grants user access for products
   - Creates Google Meet events for consulting
   - Sends notifications via send-email-v2
   - Triggers webhooks

Benefits:
- Single Responsibility: Each function has one clear purpose
- Trigger works for both webhook and manual admin actions
- Easier to debug and maintain
- Reusable notification system

Migration required: Run 20241223_payment_trigger.sql

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 16:59:13 +07:00
dwindown
9d7d76b04d Add consulting slots display with Join Meet button
- Member OrderDetail page: Shows consulting slots with date/time and Join Meet button
- Admin Orders dialog: Shows consulting slots with meet link access
- Meet button only visible when payment_status is 'paid'
- Both pages show slot status (confirmed/pending)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 16:45:48 +07:00
dwindown
ce531c8d46 Add Google Meet event creation to payment webhook
When order is paid, automatically create Google Meet events for all consulting slots.
The meet_link is saved to consulting_slots table and included in notifications.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 16:41:22 +07:00
dwindown
7bf13b88d2 Add detailed debug info to edge function response
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 16:27:33 +07:00