Commit Graph

20 Commits

Author SHA1 Message Date
dwindown
eee6339074 Fix email unconfirmed login flow with OTP resend and update email API field names 2026-01-02 19:33:51 +07:00
dwindown
08e56a22d8 Fix send-auth-otp: Remove notification_logs references
- Remove notification_logs table references (table doesn't exist)
- This was causing the function to crash after sending email
- Now the function should complete successfully
- Added better email payload logging
- Keep .env file for local development
2026-01-02 15:07:41 +07:00
dwindown
06d6845456 Fix API token mapping and add extensive debug logging
- Fixed api_token vs mailketing_api_token column mapping
- Added comprehensive debug logging to send-auth-otp
- Added fallback logic for missing settings fields
- Improved error messages for troubleshooting

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 14:31:23 +07:00
dwindown
c6250d2b47 Fix notification_templates table column names
Update auth email template migration and edge function to use correct column names:
- template_key → key
- subject → email_subject
- html_content → email_body_html

Matches existing notification_templates schema used in NotifikasiTab.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 13:41:30 +07:00
dwindown
0d29c953c1 Implement OTP-based email verification system
Add custom email verification using 6-digit OTP codes via Mailketing API:

Database:
- Create auth_otps table with 15-minute expiry
- Add indexes and RLS policies for security
- Add cleanup function for expired tokens
- Insert default auth_email_verification template

Edge Functions:
- send-auth-otp: Generate OTP, store in DB, send via Mailketing
- verify-auth-otp: Validate OTP, confirm email in Supabase Auth

Frontend:
- Add OTP input state to auth page
- Implement send/verify OTP in useAuth hook
- Add resend countdown timer (60 seconds)
- Update auth flow: signup → OTP verification → login

Features:
- Instant email delivery (no queue/cron)
- 6-digit OTP with 15-minute expiry
- Resend OTP with cooldown
- Admin-configurable email templates
- Indonesian UI text

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 13:27:46 +07:00
dwindown
60baf32f73 Display bootcamp lesson chapters on Product Detail page as marketing content
This commit implements displaying lesson chapters/timeline as marketing content
on the Product Detail page for bootcamp products, helping potential buyers
understand the detailed breakdown of what they'll learn.

## Changes

### Product Detail Page (src/pages/ProductDetail.tsx)
- Updated Lesson interface to include optional chapters property
- Modified fetchCurriculum to fetch chapters along with lessons
- Enhanced renderCurriculumPreview to display chapters as nested content under lessons
- Chapters shown with timestamps and titles, clickable to navigate to bootcamp access page
- Visual hierarchy: Module → Lesson → Chapters with proper indentation and styling

### Review System Fixes
- Fixed review prompt re-appearing after submission (before admin approval)
- Added hasSubmittedReview check to prevent showing prompt when review exists
- Fixed edit review functionality to pre-populate form with existing data
- ReviewModal now handles both INSERT (new) and UPDATE (edit) operations
- Edit resets is_approved to false requiring re-approval

### Video Player Enhancements
- Implemented Adilo/Video.js integration for M3U8/HLS playback
- Added video progress tracking with refs pattern for reliability
- Implemented chapter navigation for both Adilo and YouTube players
- Added keyboard shortcuts (Space, Arrows, F, M, J, L)
- Resume prompt for returning users with saved progress

### Database Migrations
- Added Adilo video support fields (m3u8_url, mp4_url, video_host)
- Created video_progress table for tracking user watch progress
- Fixed consulting slots user_id foreign key
- Added chapters support to products and bootcamp_lessons tables

### Documentation
- Added Adilo implementation plan and quick reference docs
- Cleaned up transcript analysis files

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 23:54:32 +07:00
dwindown
84de0a7efe Fix platform_settings table name and RLS policy
- Update migration to use correct table name (platform_settings, not site_settings)
- Fix WebinarRecording.tsx to query platform_settings table
- Fix Bootcamp.tsx to query platform_settings table
- This allows authenticated users to access brand_accent_color for theming

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 01:15:09 +07:00
dwindown
726250507a Fix Plyr controls and site_settings permissions
## Changes

### Video Player CSS Overlay Fix
- Moved overlay inside plyr__video-embed container
- Added check for plyr__control--overlaid (play button)
- Now only blocks YouTube iframe, not Plyr controls
- Preserves full functionality of play button, progress bar, etc.

### Site Settings Permissions
- Added RLS policy to make site_settings publicly readable
- All authenticated users can now access brand_accent_color
- Fixes 404 error when members try to fetch accent color

## Technical Details
- Overlay now properly allows clicks through to Plyr controls
- Site settings now accessible via public RLS policy for authenticated users

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 01:07:52 +07:00
dwindown
95fd4d3859 Add video chapter/timeline navigation feature
Implement timeline chapters for webinar and bootcamp videos with click-to-jump functionality:

**Components:**
- VideoPlayerWithChapters: Plyr.io-based player with chapter support
- TimelineChapters: Clickable chapter markers with active state
- ChaptersEditor: Admin UI for managing video chapters

**Features:**
- YouTube videos: Clickable timestamps that jump to specific time
- Embed videos: Static timeline display (non-clickable)
- Real-time chapter tracking during playback
- Admin-defined accent color for Plyr theme
- Auto-hides timeline when no chapters configured

**Database:**
- Add chapters JSONB column to products table (webinars)
- Add chapters JSONB column to bootcamp_lessons table
- Create indexes for faster queries

**Updated Pages:**
- WebinarRecording: Two-column layout (video + timeline)
- Bootcamp: Per-lesson chapter support
- AdminProducts: Chapter editor for webinars
- CurriculumEditor: Chapter editor for lessons

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 23:31:23 +07:00
dwindown
da71acb431 Enhance bootcamp with rich text editor, curriculum management, and video toggle
Phase 1: Rich Text Editor with Code Syntax Highlighting
- Add TipTap CodeBlock extension with lowlight for syntax highlighting
- Support multiple languages (JavaScript, TypeScript, Python, Java, C++, HTML, CSS, JSON)
- Add copy-to-clipboard button on code blocks
- Add line numbers display with CSS
- Replace textarea with RichTextEditor in CurriculumEditor
- Add DOMPurify sanitization in Bootcamp display
- Add dark theme syntax highlighting styles

Phase 2: Admin Curriculum Management Page
- Create dedicated ProductCurriculum page at /admin/products/:id/curriculum
- Three-column layout: Modules (3) | Lessons (5) | Editor (4)
- Full-page UX with drag-and-drop reordering
- Add "Manage Curriculum" button for bootcamp products in AdminProducts
- Breadcrumb navigation back to products

Phase 3: Product-Level Video Source Toggle
- Add youtube_url and embed_code columns to bootcamp_lessons table
- Add video_source and video_source_config columns to products table
- Update ProductCurriculum with separate YouTube URL and Embed Code fields
- Create smart VideoPlayer component in Bootcamp.tsx
- Support YouTube ↔ Embed switching with smart fallback
- Show "Konten tidak tersedia" warning when no video configured
- Maintain backward compatibility with existing video_url field

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 17:07:31 +07:00
dwindown
ac88e17856 Improve cancelled order display and add notes to order detail
- Add "Catatan" field display in consulting order detail page
- Add dedicated "Cancelled Order" section with rebooking option
- Update status alert to show proper message for cancelled orders
- Refactor edge function to focus on calendar cleanup only
- Set payment_status to 'failed' when auto-cancelling expired orders

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 21:36:01 +07:00
dwindown
5ab4e6b974 Add calendar event lifecycle management and "Add to Calendar" feature
- Migrate consulting_slots to consulting_sessions structure
- Add calendar_event_id to track Google Calendar events
- Create delete-calendar-event edge function for auto-cleanup
- Add "Tambah ke Kalender" button for members (OrderDetail, ConsultingHistory)
- Update create-google-meet-event to store calendar event ID
- Update handle-order-paid to use consulting_sessions table
- Remove deprecated create-meet-link function
- Add comprehensive documentation (CALENDAR_INTEGRATION.md, MIGRATION_GUIDE.md)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 13:54:16 +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
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
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
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
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
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
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
631dc9a083 Add Google Calendar integration via Supabase Edge Functions
- Create new create-google-meet-event edge function
- Use service account authentication (no OAuth needed)
- Add google_service_account_json field to platform_settings
- Add admin UI for service account JSON configuration
- Include test connection button in Integrasi tab
- Add comprehensive setup documentation
- Keep n8n workflows as alternative option

Features:
- Direct Google Calendar API integration
- JWT authentication with service account
- Auto-create Google Meet links
- No external dependencies needed
- Simple configuration via admin panel

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

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