Improve shortcode UI and add payment link shortcodes

 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>
This commit is contained in:
dwindown
2025-12-22 22:17:51 +07:00
parent 3f8cd7937a
commit 7244433e12
3 changed files with 192 additions and 50 deletions

View File

@@ -179,9 +179,16 @@ export function EmailTemplatePreview({
</div>
{/* Shortcodes Used */}
<div className="p-3 bg-blue-50 border border-blue-200 rounded">
<h4 className="font-semibold text-sm mb-2">Shortcodes Used in This Template:</h4>
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 text-sm max-h-32 overflow-y-auto">
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<h4 className="font-semibold text-sm mb-3 flex items-center gap-2">
<span className="w-2 h-2 bg-blue-500 rounded-full"></span>
Shortcodes Available
</h4>
{/* Used in this template */}
<div className="mb-4">
<p className="text-xs font-medium text-blue-700 mb-2">Used in this template:</p>
<div className="flex flex-wrap gap-1">
{[
// User information
'{nama}', '{email}',
@@ -201,31 +208,164 @@ export function EmailTemplatePreview({
// Company information
'{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}',
// Payment information
'{bank_tujuan}', '{nomor_rekening}', '{atas_nama}', '{jumlah_pembayaran}', '{batas_pembayaran}'
'{bank_tujuan}', '{nomor_rekening}', '{atas_nama}', '{jumlah_pembayaran}', '{batas_pembayaran}',
'{payment_link}', '{thank_you_page}'
].filter(shortcode =>
(template.email_subject && template.email_subject.includes(shortcode)) ||
(template.email_body_html && template.email_body_html.includes(shortcode))
).map(shortcode => (
<code key={shortcode} className="bg-blue-100 px-2 py-1 rounded text-xs">
<code key={shortcode} className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs font-mono border border-blue-300">
{shortcode}
</code>
))}
{![
// User information
'{nama}', '{email}',
// Order information
'{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{status_pesanan}', '{invoice_url}',
// Product information
'{produk}', '{kategori_produk}', '{harga_produk}', '{deskripsi_produk}',
// Access information
'{link_akses}', '{username_akses}', '{password_akses}', '{kadaluarsa_akses}',
// Consulting information
'{tanggal_konsultasi}', '{jam_konsultasi}', '{durasi_konsultasi}', '{link_meet}',
'{jenis_konsultasi}', '{topik_konsultasi}',
// Event information
'{judul_event}', '{tanggal_event}', '{jam_event}', '{link_event}', '{lokasi_event}', '{kapasitas_event}',
// Bootcamp/Course information
'{judul_bootcamp}', '{progres_bootcamp}', '{modul_selesai}', '{modul_selanjutnya}', '{link_progress}',
// Company information
'{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}',
// Payment information
'{bank_tujuan}', '{nomor_rekening}', '{atas_nama}', '{jumlah_pembayaran}', '{batas_pembayaran}',
'{payment_link}', '{thank_you_page}'
].some(shortcode =>
(template.email_subject && template.email_subject.includes(shortcode)) ||
(template.email_body_html && template.email_body_html.includes(shortcode))
) && (
<span className="text-xs text-gray-500 italic">No shortcodes used yet</span>
)}
</div>
</div>
{/* All available shortcodes */}
<details className="group">
<summary className="cursor-pointer text-xs font-medium text-blue-700 hover:text-blue-900 transition-colors flex items-center gap-1">
<span className="group-open:rotate-90 transition-transform"></span>
View all available shortcodes
</summary>
<div className="mt-3 pt-3 border-t border-blue-200 space-y-3">
{/* User Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">👤 User Information</p>
<div className="flex flex-wrap gap-1">
{['{nama}', '{email}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
{((template.email_subject && template.email_subject.includes('{')) ||
(template.email_body_html && template.email_body_html.includes('{'))) && (
<div className="mt-3 pt-3 border-t border-blue-200">
<p className="text-xs text-blue-700">
<strong>All Available Shortcodes:</strong> User ({`{nama}`}, {`{email}`}), Orders ({`{order_id}`}, {`{tanggal_pesanan}`}, {`{total}`}, {`{metode_pembayaran}`}, {`{status_pesanan}`}, {`{invoice_url}`}),
Products ({`{produk}`}, {`{kategori_produk}`}, {`{harga_produk}`}),
Access ({`{link_akses}`}, {`{username_akses}`}, {`{password_akses}`}),
Consulting ({`{tanggal_konsultasi}`}, {`{jam_konsultasi}`}, {`{link_meet}`}),
Events ({`{judul_event}`}, {`{tanggal_event}`}, {`{link_event}`}),
Bootcamp ({`{judul_bootcamp}`}, {`{progres_bootcamp}`}, {`{modul_selesai}`}),
Payment ({`{bank_tujuan}`}, {`{nomor_rekening}`}, {`{jumlah_pembayaran}`}),
Company ({`{nama_perusahaan}`}, {`{email_support}`})
</p>
</div>
)}
{/* Order Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">📦 Order Information</p>
<div className="flex flex-wrap gap-1">
{['{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{status_pesanan}', '{invoice_url}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Product Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">🛍 Product Information</p>
<div className="flex flex-wrap gap-1">
{['{produk}', '{kategori_produk}', '{harga_produk}', '{deskripsi_produk}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Access Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">🔐 Access Information</p>
<div className="flex flex-wrap gap-1">
{['{link_akses}', '{username_akses}', '{password_akses}', '{kadaluarsa_akses}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Payment Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">💳 Payment Information</p>
<div className="flex flex-wrap gap-1">
{['{bank_tujuan}', '{nomor_rekening}', '{atas_nama}', '{jumlah_pembayaran}', '{batas_pembayaran}', '{payment_link}', '{thank_you_page}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Consulting Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">📅 Consulting Information</p>
<div className="flex flex-wrap gap-1">
{['{tanggal_konsultasi}', '{jam_konsultasi}', '{durasi_konsultasi}', '{link_meet}', '{jenis_konsultasi}', '{topik_konsultasi}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Event Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">🎪 Event Information</p>
<div className="flex flex-wrap gap-1">
{['{judul_event}', '{tanggal_event}', '{jam_event}', '{link_event}', '{lokasi_event}', '{kapasitas_event}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Bootcamp Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">🎓 Bootcamp Information</p>
<div className="flex flex-wrap gap-1">
{['{judul_bootcamp}', '{progres_bootcamp}', '{modul_selesai}', '{modul_selanjutnya}', '{link_progress}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
{/* Company Information */}
<div>
<p className="text-xs font-semibold text-gray-700 mb-1">🏢 Company Information</p>
<div className="flex flex-wrap gap-1">
{['{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}'].map(shortcode => (
<code key={shortcode} className="bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs font-mono border border-gray-300">
{shortcode}
</code>
))}
</div>
</div>
</div>
</details>
</div>
{/* Template Actions */}

View File

@@ -24,10 +24,10 @@ interface NotificationTemplate {
}
const RELEVANT_SHORTCODES = {
'payment_success': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{link_akses}'],
'payment_success': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{link_akses}', '{thank_you_page}'],
'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}'],
'order_created': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{payment_link}'],
'payment_reminder': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{batas_pembayaran}', '{jumlah_pembayaran}', '{bank_tujuan}', '{nomor_rekening}', '{payment_link}'],
'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}'],

View File

@@ -405,7 +405,9 @@ export class ShortcodeProcessor {
nomor_rekening: '123-456-7890',
atas_nama: 'PT Access Hub Indonesia',
jumlah_pembayaran: 'Rp 1.500.000',
batas_pembayaran: '22 Desember 2025 23:59'
batas_pembayaran: '22 Desember 2025 23:59',
payment_link: 'https://accesshub.example.com/payment/ORD-123456',
thank_you_page: 'https://accesshub.example.com/thank-you/ORD-123456'
};
static process(content: string, customData: Record<string, string> = {}): string {