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:
@@ -179,9 +179,16 @@ export function EmailTemplatePreview({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Shortcodes Used */}
|
{/* Shortcodes Used */}
|
||||||
<div className="p-3 bg-blue-50 border border-blue-200 rounded">
|
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
||||||
<h4 className="font-semibold text-sm mb-2">Shortcodes Used in This Template:</h4>
|
<h4 className="font-semibold text-sm mb-3 flex items-center gap-2">
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 text-sm max-h-32 overflow-y-auto">
|
<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
|
// User information
|
||||||
'{nama}', '{email}',
|
'{nama}', '{email}',
|
||||||
@@ -201,31 +208,164 @@ export function EmailTemplatePreview({
|
|||||||
// Company information
|
// Company information
|
||||||
'{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}',
|
'{nama_perusahaan}', '{website_perusahaan}', '{email_support}', '{telepon_support}',
|
||||||
// Payment information
|
// 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 =>
|
].filter(shortcode =>
|
||||||
(template.email_subject && template.email_subject.includes(shortcode)) ||
|
(template.email_subject && template.email_subject.includes(shortcode)) ||
|
||||||
(template.email_body_html && template.email_body_html.includes(shortcode))
|
(template.email_body_html && template.email_body_html.includes(shortcode))
|
||||||
).map(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}
|
{shortcode}
|
||||||
</code>
|
</code>
|
||||||
))}
|
))}
|
||||||
</div>
|
</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>
|
</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>
|
</div>
|
||||||
|
|
||||||
{/* Template Actions */}
|
{/* Template Actions */}
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ interface NotificationTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RELEVANT_SHORTCODES = {
|
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}'],
|
'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}'],
|
'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_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}'],
|
'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}'],
|
'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}'],
|
'bootcamp_progress': ['{nama}', '{email}', '{judul_bootcamp}', '{progres_bootcamp}', '{modul_selesai}', '{modul_selanjutnya}', '{link_progress}'],
|
||||||
|
|||||||
@@ -405,7 +405,9 @@ export class ShortcodeProcessor {
|
|||||||
nomor_rekening: '123-456-7890',
|
nomor_rekening: '123-456-7890',
|
||||||
atas_nama: 'PT Access Hub Indonesia',
|
atas_nama: 'PT Access Hub Indonesia',
|
||||||
jumlah_pembayaran: 'Rp 1.500.000',
|
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 {
|
static process(content: string, customData: Record<string, string> = {}): string {
|
||||||
|
|||||||
Reference in New Issue
Block a user