- 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>
- 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>
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>
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>
- 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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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
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.
- 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>
- 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>
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>
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>
- Add state-based lock (isTestRunning) to prevent duplicate API calls
- Update error handling in edge function for body consumption
- Add OAuth2 token generation helper tool (get-google-token-local.html)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Disable button while request is in progress
- Re-enable button after request completes (success or error)
- Prevents React Strict Mode from firing duplicate simultaneous requests
- Fixes 'Body already consumed' error from parallel edge function calls
- Replace JWT service account authentication with OAuth2 refresh token flow
- Service accounts cannot create Google Meet links for personal Gmail accounts
- Update edge function to use OAuth2 token exchange
- Change database column from google_service_account_json to google_oauth_config
- Add helper tool (get-google-refresh-token.html) to generate OAuth credentials
- Update IntegrasiTab UI to show OAuth config instead of service account
- Add SQL migration file for new google_oauth_config column
OAuth2 Config format:
{
"client_id": "...",
"client_secret": "...",
"refresh_token": "..."
}
This approach works with personal @gmail.com accounts without requiring
Google Workspace or Domain-Wide Delegation.
- Change integration_google_service_account_json to google_service_account_json
- Matches actual database column name
- Remove schema cache workaround since column name now matches
- Update all frontend references to use correct column name
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add fallback RPC method when PostgREST schema cache fails
- Save service account JSON separately via raw SQL
- Show warning message if manual save needed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 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>
- Add test/production toggle for n8n webhook URLs in IntegrasiTab
- Update create-meet-link function to use database test_mode setting
- Add send-email-v2 edge function for Mailketing API integration
- Update daily-reminders and send-consultation-reminder to use send-email-v2
- Remove deprecated branding field from BrandingTab
- Update domain references from hub.dwindi.com to with.dwindi.com
- Add environment variables for Coolify deployment
- Add comprehensive edge function test script
- Update payment flow redirect to order detail page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
🔄 Better UX Flow:
- After successful payment: redirect to /orders/{order_id} instead of /access
- This shows the specific order details where users can see their purchase
- Users can then proceed to payment if needed or access their content
📧 Updated Shortcodes:
- {thank_you_page} now uses dynamic URL pattern: /orders/{order_id}
- {order_id} will be replaced with actual order ID by ShortcodeProcessor
- Added {thank_you_page} to order_created and payment_reminder templates
🎯 User Journey:
1. User receives email with payment link
2. After successful payment → redirected to specific order detail page
3. If not logged in → redirects to login, then back to order detail
4. Order detail page shows payment status and access information
Much better user experience than generic dashboard redirect!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
✨ UI Improvements:
- Completely redesigned shortcode display with clean categorization
- Added collapsible section for all available shortcodes
- Used emoji icons for better visual organization
- Improved color coding and typography
- Added "Used in this template" section with visual distinction
➕ New Shortcodes:
- Added {payment_link} for direct payment links in emails
- Added {thank_you_page} for public thank you page access
- Updated relevant templates to include new payment shortcodes
🎯 Key Features:
- Shortcodes organized by category (User, Order, Product, Access, etc.)
- Visual hierarchy with proper spacing and borders
- Hover effects and smooth transitions
- Better readability with proper contrast
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix "nama is not defined" error by properly escaping shortcode text
- Wrap template literals with backticks in JSX to prevent variable interpretation
- This prevents shortcode braces from being treated as JavaScript variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace insert() with upsert() to handle existing templates
- Add onConflict: 'key' to update duplicates instead of failing
- This resolves "duplicate key value violates unique constraint" error
- Templates will now be properly updated/seeded on first visit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
🎯 **Shortcode Organization:**
- Replace overwhelming all-shortcodes display with per-template relevant shortcodes
- Each notification type now shows only shortcodes that make sense for that context
- Examples:
- Payment templates: order info, amounts, payment details
- Access templates: login credentials, access links
- Consulting templates: meeting details, consultation topics
- Event templates: event info, schedules, locations
🐛 **Template Content Debugging:**
- Auto-detect templates with empty content and force reseed
- Add "Reset Template Default" button for manual debugging
- Enhanced console logging for template loading issues
- Force reseed functionality to delete and recreate templates
✨ **UI Improvements:**
- Remove unused Textarea import
- Cleaner shortcode display within each template card
- Better user experience with focused, relevant information
🔧 **Debug Features:**
- Check for empty email_subject or email_body_html fields
- Automatic content repair when empty templates are detected
- Manual reset option for troubleshooting
- Detailed console logging for development
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
✨ Enhanced shortcode organization and display:
**NotifikasiTab improvements:**
- Organized shortcodes into 9 categories with color-coded badges
- User Info (blue), Order Info (green), Product Info (yellow), Access Info (purple)
- Consulting (orange), Event Info (pink), Bootcamp Info (indigo), Company Info (gray), Payment Info (red)
- Added scrollable container with max-height for better UX
- Better visual hierarchy with category headers
**EmailTemplatePreview improvements:**
- Scrollable shortcode list with grid layout (2-3 columns)
- Show only shortcodes used in current template
- Add "All Available Shortcodes" summary section
- Improved visual organization with consistent styling
🎨 UI/UX Benefits:
- Easier to find relevant shortcodes by category
- Visual distinction between different data types
- Better space utilization with scrollable areas
- More informative and scannable layout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Removed custom Tiptap table extensions that were causing import errors
- Kept EmailButton and OTPBox components working
- Table functionality will need proper Tiptap table extension setup later
- Build now completes successfully for deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Consolidated multiple preview canvases into single shared preview with "Simpan & Preview" button
- Fixed double scrollbar issue in preview box by using fixed height container and scrolling=no
- Added modular email components to Tiptap editor:
* EmailButton with URL, text, and full-width options
* OTPBox with monospace font and dashed border styling
* EmailTable with brutalist styling and proper header support
- Generated contextual initial email content for all template types:
* Payment success with professional details table
* Access granted with celebration styling and prominent CTA
* Order created with clear next steps and status information
* Payment reminder with urgent styling and warning alerts
* Consulting scheduled with session details and preparation tips
* Event reminder with high-energy countdown and call-to-action
* Bootcamp progress with motivational progress tracking
- Enhanced RichTextEditor toolbar with email component buttons and visual separators
- Improved NotifikasiTab with streamlined preview workflow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Create modular EmailTemplateRenderer with master shell and content separation
- Build reusable email components library (buttons, alerts, OTP boxes, etc.)
- Add EmailTemplatePreview component with master/content preview modes
- Implement test email functionality for each notification template
- Update NotifikasiTab to use new preview system with shortcode processing
- Add dummy shortcode data for testing (nama, email, order_id, etc.)
- Maintain design consistency between web and email
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Make email test inputs 50/50 with flex-1 classes
- Add save button back to Integrasi tab
- Improve button styling with border-top-2 for better separation
- Update save button text to 'Simpan Semua Pengaturan'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add Input import back to NotifikasiTab component
- Input components are used for email subject and webhook URL fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Move Mailketing API configuration from NotifikasiTab to IntegrasiTab
- Remove email provider settings from NotifikasiTab, add info card
- Update IntegrasiTab to save email settings to notification_settings table
- Add test email functionality to Integrasi tab
- Fix database schema compatibility with new email settings
- Remove GitHub remote, keep only Gitea remote
- Clean up unused imports and variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove SMTP host/port/username/TLS configuration
- Add Mailkening API token configuration
- Update email provider dropdown (Mailketing only)
- Update test email function to use Mailketing API
- Update help text and validation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>