From 78e7b946ac4fd80c0e912cba12f052353a1b0f95 Mon Sep 17 00:00:00 2001 From: dwindown Date: Mon, 22 Dec 2025 21:38:47 +0700 Subject: [PATCH] Fix shortcode organization and add template debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎯 **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 --- .../admin/settings/NotifikasiTab.tsx | 155 +++++++----------- 1 file changed, 60 insertions(+), 95 deletions(-) diff --git a/src/components/admin/settings/NotifikasiTab.tsx b/src/components/admin/settings/NotifikasiTab.tsx index f1c07c0..7a8a81b 100644 --- a/src/components/admin/settings/NotifikasiTab.tsx +++ b/src/components/admin/settings/NotifikasiTab.tsx @@ -5,7 +5,6 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; -import { Textarea } from '@/components/ui/textarea'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { RichTextEditor } from '@/components/RichTextEditor'; import { toast } from '@/hooks/use-toast'; @@ -24,25 +23,14 @@ interface NotificationTemplate { last_payload_example: Record | null; } -const SHORTCODES_HELP = { - // User information - common: ['{nama}', '{email}'], - // Order information - orders: ['{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{status_pesanan}', '{invoice_url}'], - // Product information - products: ['{produk}', '{kategori_produk}', '{harga_produk}', '{deskripsi_produk}'], - // Access information - access: ['{link_akses}', '{username_akses}', '{password_akses}', '{kadaluarsa_akses}'], - // Consulting information - consulting: ['{tanggal_konsultasi}', '{jam_konsultasi}', '{durasi_konsultasi}', '{link_meet}', '{jenis_konsultasi}', '{topik_konsultasi}'], - // Event information - event: ['{judul_event}', '{tanggal_event}', '{jam_event}', '{link_event}', '{lokasi_event}', '{kapasitas_event}'], - // Bootcamp/Course information - bootcamp: ['{judul_bootcamp}', '{progres_bootcamp}', '{modul_selesai}', '{modul_selanjutnya}', '{link_progress}'], - // Company information - company: ['{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}'], - // Payment information - payment: ['{bank_tujuan}', '{nomor_rekening}', '{atas_nama}', '{jumlah_pembayaran}', '{batas_pembayaran}'], +const RELEVANT_SHORTCODES = { + 'payment_success': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{link_akses}'], + 'access_granted': ['{nama}', '{email}', '{produk}', '{link_akses}', '{username_akses}', '{password_akses}', '{kadaluarsa_akses}'], + 'order_created': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}'], + 'payment_reminder': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{batas_pembayaran}', '{jumlah_pembayaran}', '{bank_tujuan}', '{nomor_rekening}'], + 'consulting_scheduled': ['{nama}', '{email}', '{tanggal_konsultasi}', '{jam_konsultasi}', '{durasi_konsultasi}', '{link_meet}', '{jenis_konsultasi}', '{topik_konsultasi}'], + 'event_reminder': ['{nama}', '{email}', '{judul_event}', '{tanggal_event}', '{jam_event}', '{link_event}', '{lokasi_event}', '{kapasitas_event}'], + 'bootcamp_progress': ['{nama}', '{email}', '{judul_bootcamp}', '{progres_bootcamp}', '{modul_selesai}', '{modul_selanjutnya}', '{link_progress}'], }; const DEFAULT_TEMPLATES: { key: string; name: string; defaultSubject: string; defaultBody: string }[] = [ @@ -385,10 +373,19 @@ export function NotifikasiTab() { } console.log('Templates data:', templatesData); + console.log('Template count:', templatesData?.length); if (templatesData && templatesData.length > 0) { console.log('Setting templates from database:', templatesData.length); - setTemplates(templatesData); + // Check if any templates have empty content + const emptyTemplates = templatesData.filter(t => !t.email_subject || !t.email_body_html); + if (emptyTemplates.length > 0) { + console.log('Found templates with empty content:', emptyTemplates.map(t => ({ key: t.key, name: t.name }))); + console.log('Reseeding templates with empty content...'); + await forceSeedTemplates(); + } else { + setTemplates(templatesData); + } } else { console.log('No templates found, seeding default templates...'); // Seed default templates if none exist @@ -406,6 +403,22 @@ export function NotifikasiTab() { } }; + const forceSeedTemplates = async () => { + try { + console.log('Force reseed: Deleting existing templates...'); + // Delete existing templates + const { error: deleteError } = await supabase.from('notification_templates').delete().neq('id', ''); + if (deleteError) { + console.error('Error deleting templates:', deleteError); + } + + console.log('Force reseed: Inserting default templates...'); + await seedTemplates(); + } catch (error) { + console.error('Error in forceSeedTemplates:', error); + } + }; + const seedTemplates = async () => { try { console.log('Seeding default templates...'); @@ -550,6 +563,19 @@ export function NotifikasiTab() { Gunakan Mailketing API untuk pengiriman email yang andal. +
+ + + Gunakan jika template kosong atau bermasalah + +
@@ -564,80 +590,7 @@ export function NotifikasiTab() {

Shortcode yang tersedia:

-
-
- User Info: -
- {SHORTCODES_HELP.common.map(code => ( - {code} - ))} -
-
-
- Order Info: -
- {SHORTCODES_HELP.orders.map(code => ( - {code} - ))} -
-
-
- Product Info: -
- {SHORTCODES_HELP.products.map(code => ( - {code} - ))} -
-
-
- Access Info: -
- {SHORTCODES_HELP.access.map(code => ( - {code} - ))} -
-
-
- Consulting: -
- {SHORTCODES_HELP.consulting.map(code => ( - {code} - ))} -
-
-
- Event Info: -
- {SHORTCODES_HELP.event.map(code => ( - {code} - ))} -
-
-
- Bootcamp Info: -
- {SHORTCODES_HELP.bootcamp.map(code => ( - {code} - ))} -
-
-
- Company Info: -
- {SHORTCODES_HELP.company.map(code => ( - {code} - ))} -
-
-
- Payment Info: -
- {SHORTCODES_HELP.payment.map(code => ( - {code} - ))} -
-
-
+

Setiap template memiliki shortcode yang relevan dengan jenis notifikasinya. Lihat detail template untuk shortcode yang tersedia.

Penting: Email dikirim melalui Mailketing API yang dikonfigurasi di tab Integrasi. Pastikan API token valid dan domain pengirim sudah terdaftar di Mailketing. @@ -724,6 +677,18 @@ export function NotifikasiTab() { className="border-2" />

+ + {/* Relevant Shortcodes for this Template */} +
+

Shortcodes untuk template ini:

+
+ {RELEVANT_SHORTCODES[template.key as keyof typeof RELEVANT_SHORTCODES]?.map(shortcode => ( + + {shortcode} + + )) || Tidak ada shortcode khusus untuk template ini} +
+