i18n (Phase C batch 12): residu empty-state/hint di 24 file admin ID/EN
This commit is contained in:
1 parent
e70bc23651
commit
60ef8bafab
26 files changed
+209
-97
No files matched your search
+77
-21
@@ -927,7 +927,12 @@
|
|||||||
"th_pppoe": "PPPoE / ONU Tag",
|
"th_pppoe": "PPPoE / ONU Tag",
|
||||||
"th_pkg_odp": "Package & ODP",
|
"th_pkg_odp": "Package & ODP",
|
||||||
"th_gps": "GPS Coordinates",
|
"th_gps": "GPS Coordinates",
|
||||||
"ph_odp": "Search ODP (name / description)..."
|
"ph_odp": "Search ODP (name / description)...",
|
||||||
|
"pon_port": "PON Port (optional)",
|
||||||
|
"empty_cust": "No customer data yet.",
|
||||||
|
"empty_odp": "No ODP data yet.",
|
||||||
|
"view_port": "Click to view port visual",
|
||||||
|
"port_err": "Failed to load port data."
|
||||||
},
|
},
|
||||||
"print_invoice": {
|
"print_invoice": {
|
||||||
"title": "Print Invoice Receipt",
|
"title": "Print Invoice Receipt",
|
||||||
@@ -1109,7 +1114,9 @@
|
|||||||
"wifi_pass": "Wi-Fi Password (WPA2)",
|
"wifi_pass": "Wi-Fi Password (WPA2)",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"run_prov": "Run Provisioning",
|
"run_prov": "Run Provisioning",
|
||||||
"add_server": "Add ACS Server"
|
"add_server": "Add ACS Server",
|
||||||
|
"bind_lan": "Select the LAN Ports to bind:",
|
||||||
|
"bind_ssid": "Select the WLAN (SSID) to bind:"
|
||||||
},
|
},
|
||||||
"vd": {
|
"vd": {
|
||||||
"action": "Action",
|
"action": "Action",
|
||||||
@@ -1138,7 +1145,8 @@
|
|||||||
"tab_broadcast": "Broadcast & Reminder",
|
"tab_broadcast": "Broadcast & Reminder",
|
||||||
"tab_templates": "Message Templates",
|
"tab_templates": "Message Templates",
|
||||||
"tab_livechat": "Live Chat",
|
"tab_livechat": "Live Chat",
|
||||||
"tab_preview": "Message Preview"
|
"tab_preview": "Message Preview",
|
||||||
|
"ph_deviceid": "Device ID (optional)"
|
||||||
},
|
},
|
||||||
"automation": {
|
"automation": {
|
||||||
"title": "Automation",
|
"title": "Automation",
|
||||||
@@ -1630,7 +1638,9 @@
|
|||||||
"disconnect_mt": "Disconnect MikroTik Session",
|
"disconnect_mt": "Disconnect MikroTik Session",
|
||||||
"calc_reg": "Prorata Calculator — Approve Registrant",
|
"calc_reg": "Prorata Calculator — Approve Registrant",
|
||||||
"start_use": "Start Using",
|
"start_use": "Start Using",
|
||||||
"approve_invoice": "Approve & Create Invoice"
|
"approve_invoice": "Approve & Create Invoice",
|
||||||
|
"modem_hint": "Customer modem login credentials for RADIUS & PPPoE.",
|
||||||
|
"reg_hint": "Automatically calculated on install/payment. Can be adjusted manually if needed."
|
||||||
},
|
},
|
||||||
"bill": {
|
"bill": {
|
||||||
"ph_note": "e.g. service credit for downtime",
|
"ph_note": "e.g. service credit for downtime",
|
||||||
@@ -1684,12 +1694,17 @@
|
|||||||
"general_task": "-- General / Non-Customer Task (Maintenance) --",
|
"general_task": "-- General / Non-Customer Task (Maintenance) --",
|
||||||
"unassigned": "-- Unassigned (Open) --",
|
"unassigned": "-- Unassigned (Open) --",
|
||||||
"st_open": "Not Handled (Open)",
|
"st_open": "Not Handled (Open)",
|
||||||
"st_progress": "In Progress"
|
"st_progress": "In Progress",
|
||||||
|
"no_photo": "No photo"
|
||||||
},
|
},
|
||||||
"onu": {
|
"onu": {
|
||||||
"select_vendor": "Select Vendor",
|
"select_vendor": "Select Vendor",
|
||||||
"hint_rescan": "Click \"Rescan\" to find unconfigured ONUs",
|
"hint_rescan": "Click \"Rescan\" to find unconfigured ONUs",
|
||||||
"hint_reload": "Click \"Reload / Scan\" to monitor configured ONU status via SNMP"
|
"hint_reload": "Click \"Reload / Scan\" to monitor configured ONU status via SNMP",
|
||||||
|
"ssid_hint": "Set the ONU WiFi SSID and password",
|
||||||
|
"wan_mode_hint": "Bridge (MikroTik dials) or Router (ONU dials)",
|
||||||
|
"ph_url": "Format: http://host:port or https://host:port",
|
||||||
|
"empty": "No unconfigured ONU found"
|
||||||
},
|
},
|
||||||
"rds": {
|
"rds": {
|
||||||
"card_status": "RADIUS Server Status",
|
"card_status": "RADIUS Server Status",
|
||||||
@@ -1897,13 +1912,19 @@
|
|||||||
"no_data": "No data yet.",
|
"no_data": "No data yet.",
|
||||||
"ew_not_tx": "Not a transaction",
|
"ew_not_tx": "Not a transaction",
|
||||||
"ew_paid": "Paid",
|
"ew_paid": "Paid",
|
||||||
"ew_unmatched": "Not matched"
|
"ew_unmatched": "Not matched",
|
||||||
|
"speedtest_hint": "The preset only auto-fills — adjust the URL if needed.",
|
||||||
|
"qris_dyn_hint": "If filled, the system creates a dynamic QRIS per transaction (amount auto-filled on scan). If empty, the system uses the image URL as usual.",
|
||||||
|
"qris_upload_hint": "If uploaded, the system saves the file and auto-fills the QRIS URL.",
|
||||||
|
"bank_hint": "The amount & unique code are the same as QRIS; verification is automatic (webhook forwarder) + manual (upload proof)."
|
||||||
},
|
},
|
||||||
"mt": {
|
"mt": {
|
||||||
"updating": "Updating...",
|
"updating": "Updating...",
|
||||||
"online_list": "Online PPPoE Users",
|
"online_list": "Online PPPoE Users",
|
||||||
"offline_list": "Offline PPPoE Users",
|
"offline_list": "Offline PPPoE Users",
|
||||||
"limit_uptime": "Uptime Limit (e.g. 1h)"
|
"limit_uptime": "Uptime Limit (e.g. 1h)",
|
||||||
|
"empty_pppoe": "No PPPoE profile data.",
|
||||||
|
"empty_hs": "No Hotspot profile data."
|
||||||
},
|
},
|
||||||
"disc": {
|
"disc": {
|
||||||
"title": "Invoice Discount",
|
"title": "Invoice Discount",
|
||||||
@@ -1927,7 +1948,8 @@
|
|||||||
"apply": "Apply Discount",
|
"apply": "Apply Discount",
|
||||||
"selected": "selected",
|
"selected": "selected",
|
||||||
"history": "Discount History (last 100)",
|
"history": "Discount History (last 100)",
|
||||||
"th_note": "Note"
|
"th_note": "Note",
|
||||||
|
"empty_cust": "No customers."
|
||||||
},
|
},
|
||||||
"cpay": {
|
"cpay": {
|
||||||
"title": "Collector Payment Approval",
|
"title": "Collector Payment Approval",
|
||||||
@@ -1942,7 +1964,8 @@
|
|||||||
"th_invoice": "Invoice",
|
"th_invoice": "Invoice",
|
||||||
"th_process": "Process",
|
"th_process": "Process",
|
||||||
"approve": "Approve",
|
"approve": "Approve",
|
||||||
"reject": "Reject"
|
"reject": "Reject",
|
||||||
|
"wait_approval": "Waiting for admin or cashier"
|
||||||
},
|
},
|
||||||
"att": {
|
"att": {
|
||||||
"late_checkin": "Late Check-in",
|
"late_checkin": "Late Check-in",
|
||||||
@@ -1959,7 +1982,9 @@
|
|||||||
"checkin_time": "Check-in Time",
|
"checkin_time": "Check-in Time",
|
||||||
"duration": "Duration",
|
"duration": "Duration",
|
||||||
"location": "Location",
|
"location": "Location",
|
||||||
"photo": "Photo"
|
"photo": "Photo",
|
||||||
|
"empty": "No attendance data",
|
||||||
|
"empty_sub": "No employee has checked in on this date."
|
||||||
},
|
},
|
||||||
"olt": {
|
"olt": {
|
||||||
"all_summary": "All OLTs (Total Summary)",
|
"all_summary": "All OLTs (Total Summary)",
|
||||||
@@ -2015,7 +2040,12 @@
|
|||||||
"ph_isolir_profile": "— use global/customer default —",
|
"ph_isolir_profile": "— use global/customer default —",
|
||||||
"night_profile": "Night Profile Name (MikroTik)",
|
"night_profile": "Night Profile Name (MikroTik)",
|
||||||
"ph_night_profile": "-- Select Profile --",
|
"ph_night_profile": "-- Select Profile --",
|
||||||
"night_down": "Night Download (Mbps)"
|
"night_down": "Night Download (Mbps)",
|
||||||
|
"promo_prorata": "Invoice promo & proration",
|
||||||
|
"prorata_first": "First invoice proration (install date = billing month)",
|
||||||
|
"night_hint": "The system switches customers to this PPP profile between 00:00 - 06:00.",
|
||||||
|
"kalong_hint": "Check to configure (fields open automatically if this package uses Jam Kalong).",
|
||||||
|
"fup_hint": "Check to configure (fields open automatically if this package uses FUP)."
|
||||||
},
|
},
|
||||||
"col": {
|
"col": {
|
||||||
"title": "Collector Management",
|
"title": "Collector Management",
|
||||||
@@ -2032,7 +2062,8 @@
|
|||||||
"del": "Delete Collector",
|
"del": "Delete Collector",
|
||||||
"full_name": "Full Name",
|
"full_name": "Full Name",
|
||||||
"area_region": "Area / Assignment Region",
|
"area_region": "Area / Assignment Region",
|
||||||
"opt_all_area": "-- All Areas / Unrestricted --"
|
"opt_all_area": "-- All Areas / Unrestricted --",
|
||||||
|
"empty": "No collector data yet."
|
||||||
},
|
},
|
||||||
"mon": {
|
"mon": {
|
||||||
"title": "System Monitoring",
|
"title": "System Monitoring",
|
||||||
@@ -2079,7 +2110,9 @@
|
|||||||
"total_hours": "Total Hours",
|
"total_hours": "Total Hours",
|
||||||
"work_hours": "Work hours",
|
"work_hours": "Work hours",
|
||||||
"avg": "Average",
|
"avg": "Average",
|
||||||
"hours_per_day": "Hours/day"
|
"hours_per_day": "Hours/day",
|
||||||
|
"preview": "Preview of the final photo to be sent:",
|
||||||
|
"checkin_hint": "Please check in to start your workday."
|
||||||
},
|
},
|
||||||
"gis": {
|
"gis": {
|
||||||
"ph_search": "Search ODP, ODC, HTB, Customer...",
|
"ph_search": "Search ODP, ODC, HTB, Customer...",
|
||||||
@@ -2132,7 +2165,10 @@
|
|||||||
"th_validity": "Validity",
|
"th_validity": "Validity",
|
||||||
"th_prefix": "Prefix",
|
"th_prefix": "Prefix",
|
||||||
"th_len": "Code Length",
|
"th_len": "Code Length",
|
||||||
"th_chars": "Characters"
|
"th_chars": "Characters",
|
||||||
|
"opt_active": "Active (Shown in customer portal)",
|
||||||
|
"empty": "No real-time hotspot voucher package registered yet. Click the Add button above to start!",
|
||||||
|
"no_meta": "The profile has no Mikhmon metadata. Fill in the price and validity manually."
|
||||||
},
|
},
|
||||||
"cashin": {
|
"cashin": {
|
||||||
"heading": "Cash In (Others)",
|
"heading": "Cash In (Others)",
|
||||||
@@ -2157,7 +2193,8 @@
|
|||||||
"ph_ref": "Can be left blank",
|
"ph_ref": "Can be left blank",
|
||||||
"save": "Save Income",
|
"save": "Save Income",
|
||||||
"title": "Cash In",
|
"title": "Cash In",
|
||||||
"th_method": "Method"
|
"th_method": "Method",
|
||||||
|
"empty": "No cash-in data yet."
|
||||||
},
|
},
|
||||||
"exp": {
|
"exp": {
|
||||||
"heading": "Expenses (Cash Out)",
|
"heading": "Expenses (Cash Out)",
|
||||||
@@ -2182,7 +2219,8 @@
|
|||||||
"pay_credit": "Credit / Paylater",
|
"pay_credit": "Credit / Paylater",
|
||||||
"save": "Save Expense",
|
"save": "Save Expense",
|
||||||
"title": "Expenses",
|
"title": "Expenses",
|
||||||
"th_method": "Method"
|
"th_method": "Method",
|
||||||
|
"empty": "No expense data yet."
|
||||||
},
|
},
|
||||||
"ar": {
|
"ar": {
|
||||||
"heading": "Area / Region Management",
|
"heading": "Area / Region Management",
|
||||||
@@ -2211,7 +2249,8 @@
|
|||||||
"setup_fw": "Isolir Firewall Setup",
|
"setup_fw": "Isolir Firewall Setup",
|
||||||
"edit": "Edit Router",
|
"edit": "Edit Router",
|
||||||
"del": "Delete Router",
|
"del": "Delete Router",
|
||||||
"live_title": "Router Live Detail"
|
"live_title": "Router Live Detail",
|
||||||
|
"script_hint": "This script is auto-generated from the server IP & billing URL (app_url). You can copy and paste it into the MikroTik Winbox Terminal."
|
||||||
},
|
},
|
||||||
"bc": {
|
"bc": {
|
||||||
"send_title": "Send Invoices Now (Manual — if Auto is OFF)",
|
"send_title": "Send Invoices Now (Manual — if Auto is OFF)",
|
||||||
@@ -2245,7 +2284,9 @@
|
|||||||
"auto_clean": "Automatic Cleanup",
|
"auto_clean": "Automatic Cleanup",
|
||||||
"retention": "Retention (Days)",
|
"retention": "Retention (Days)",
|
||||||
"history": "Backup History",
|
"history": "Backup History",
|
||||||
"empty": "No backup files available"
|
"empty": "No backup files available",
|
||||||
|
"file_hint": ".db (database) or .json (settings) file",
|
||||||
|
"retention_hint": "Backups older than this period will be deleted"
|
||||||
},
|
},
|
||||||
"wt": {
|
"wt": {
|
||||||
"title": "WhatsApp Notification Template Settings",
|
"title": "WhatsApp Notification Template Settings",
|
||||||
@@ -2265,12 +2306,27 @@
|
|||||||
"opt_qris": "QRIS Invoice Template",
|
"opt_qris": "QRIS Invoice Template",
|
||||||
"opt_success": "Payment Success Template",
|
"opt_success": "Payment Success Template",
|
||||||
"opt_isolir": "Isolir Notice Template",
|
"opt_isolir": "Isolir Notice Template",
|
||||||
"vars": "Parameter Order Variables (Components Payload):"
|
"vars": "Parameter Order Variables (Components Payload):",
|
||||||
|
"ph_user": "(PPPoE Username, optional)",
|
||||||
|
"warn_custid": "must include the Customer ID variable"
|
||||||
},
|
},
|
||||||
"md": {
|
"md": {
|
||||||
"connecting": "Connecting to MikroTik...",
|
"connecting": "Connecting to MikroTik...",
|
||||||
"fullscreen": "Fullscreen",
|
"fullscreen": "Fullscreen",
|
||||||
"exit": "Exit"
|
"exit": "Exit",
|
||||||
|
"reconnect_hint": "Make sure the IP/port is correct and the API service is active. Retrying..."
|
||||||
|
},
|
||||||
|
"payroll": {
|
||||||
|
"empty_staff": "No active employees",
|
||||||
|
"empty_slip": "No payslip for this period",
|
||||||
|
"gen_hint": "Click \"Generate All\" to create payslips automatically"
|
||||||
|
},
|
||||||
|
"rep": {
|
||||||
|
"ppn_incl": "Yes — VAT already included",
|
||||||
|
"tax_hint": "Corporate income tax, VAT, USO & BHP are calculated automatically from this value."
|
||||||
|
},
|
||||||
|
"wlc": {
|
||||||
|
"empty": "No messages with this customer yet. Type a message below and press Enter to start."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tech": {
|
"tech": {
|
||||||
|
|||||||
+77
-21
@@ -927,7 +927,12 @@
|
|||||||
"th_pppoe": "PPPoE / Tag ONU",
|
"th_pppoe": "PPPoE / Tag ONU",
|
||||||
"th_pkg_odp": "Paket & ODP",
|
"th_pkg_odp": "Paket & ODP",
|
||||||
"th_gps": "Koordinat GPS",
|
"th_gps": "Koordinat GPS",
|
||||||
"ph_odp": "Cari ODP (nama / deskripsi)..."
|
"ph_odp": "Cari ODP (nama / deskripsi)...",
|
||||||
|
"pon_port": "PON Port (opsional)",
|
||||||
|
"empty_cust": "Belum ada data pelanggan.",
|
||||||
|
"empty_odp": "Belum ada data ODP.",
|
||||||
|
"view_port": "Klik untuk lihat visual port",
|
||||||
|
"port_err": "Gagal memuat data port."
|
||||||
},
|
},
|
||||||
"print_invoice": {
|
"print_invoice": {
|
||||||
"title": "Cetak Struk Tagihan",
|
"title": "Cetak Struk Tagihan",
|
||||||
@@ -1109,7 +1114,9 @@
|
|||||||
"wifi_pass": "Sandi Wi-Fi (WPA2)",
|
"wifi_pass": "Sandi Wi-Fi (WPA2)",
|
||||||
"loading": "Mengunduh...",
|
"loading": "Mengunduh...",
|
||||||
"run_prov": "Jalankan Provisioning",
|
"run_prov": "Jalankan Provisioning",
|
||||||
"add_server": "Tambah Server ACS"
|
"add_server": "Tambah Server ACS",
|
||||||
|
"bind_lan": "Pilih LAN Port yang akan di-bind:",
|
||||||
|
"bind_ssid": "Pilih WLAN (SSID) yang akan di-bind:"
|
||||||
},
|
},
|
||||||
"vd": {
|
"vd": {
|
||||||
"action": "Aksi",
|
"action": "Aksi",
|
||||||
@@ -1138,7 +1145,8 @@
|
|||||||
"tab_broadcast": "Broadcast & Pengingat",
|
"tab_broadcast": "Broadcast & Pengingat",
|
||||||
"tab_templates": "Template Pesan",
|
"tab_templates": "Template Pesan",
|
||||||
"tab_livechat": "Live Chat",
|
"tab_livechat": "Live Chat",
|
||||||
"tab_preview": "Preview Pesan"
|
"tab_preview": "Preview Pesan",
|
||||||
|
"ph_deviceid": "Device ID (opsional)"
|
||||||
},
|
},
|
||||||
"automation": {
|
"automation": {
|
||||||
"title": "Otomatisasi",
|
"title": "Otomatisasi",
|
||||||
@@ -1631,7 +1639,9 @@
|
|||||||
"disconnect_mt": "Putus Sesi MikroTik",
|
"disconnect_mt": "Putus Sesi MikroTik",
|
||||||
"calc_reg": "Kalkulator Prorata — Setujui Pendaftar",
|
"calc_reg": "Kalkulator Prorata — Setujui Pendaftar",
|
||||||
"start_use": "Mulai Pakai",
|
"start_use": "Mulai Pakai",
|
||||||
"approve_invoice": "Setujui & Buat Tagihan"
|
"approve_invoice": "Setujui & Buat Tagihan",
|
||||||
|
"modem_hint": "Kredensial login modem pelanggan untuk RADIUS & PPPoE.",
|
||||||
|
"reg_hint": "Otomatis dihitung saat pasang/bayar. Bisa disesuaikan manual jika perlu."
|
||||||
},
|
},
|
||||||
"bill": {
|
"bill": {
|
||||||
"ph_note": "mis. kompensasi gangguan",
|
"ph_note": "mis. kompensasi gangguan",
|
||||||
@@ -1685,12 +1695,17 @@
|
|||||||
"general_task": "-- Tugas Umum / Non-Pelanggan (Maintenance) --",
|
"general_task": "-- Tugas Umum / Non-Pelanggan (Maintenance) --",
|
||||||
"unassigned": "-- Belum Ditugaskan (Bebas) --",
|
"unassigned": "-- Belum Ditugaskan (Bebas) --",
|
||||||
"st_open": "Belum Ditangani (Open)",
|
"st_open": "Belum Ditangani (Open)",
|
||||||
"st_progress": "Sedang Dikerjakan (In Progress)"
|
"st_progress": "Sedang Dikerjakan (In Progress)",
|
||||||
|
"no_photo": "Tidak ada foto"
|
||||||
},
|
},
|
||||||
"onu": {
|
"onu": {
|
||||||
"select_vendor": "Pilih Vendor",
|
"select_vendor": "Pilih Vendor",
|
||||||
"hint_rescan": "Klik \"Scan Ulang\" untuk mencari ONU yang belum terkonfigurasi",
|
"hint_rescan": "Klik \"Scan Ulang\" untuk mencari ONU yang belum terkonfigurasi",
|
||||||
"hint_reload": "Klik \"Muat Ulang / Scan\" untuk memantau status ONU terkonfigurasi via SNMP"
|
"hint_reload": "Klik \"Muat Ulang / Scan\" untuk memantau status ONU terkonfigurasi via SNMP",
|
||||||
|
"ssid_hint": "Set SSID dan password WiFi ONU",
|
||||||
|
"wan_mode_hint": "Bridge (MikroTik dial) atau Router (ONU dial)",
|
||||||
|
"ph_url": "Format: http://host:port atau https://host:port",
|
||||||
|
"empty": "Tidak ada ONU yang belum terkonfigurasi"
|
||||||
},
|
},
|
||||||
"rds": {
|
"rds": {
|
||||||
"card_status": "Status RADIUS Server",
|
"card_status": "Status RADIUS Server",
|
||||||
@@ -1898,13 +1913,19 @@
|
|||||||
"no_data": "Belum ada data.",
|
"no_data": "Belum ada data.",
|
||||||
"ew_not_tx": "Bukan transaksi",
|
"ew_not_tx": "Bukan transaksi",
|
||||||
"ew_paid": "Lunas",
|
"ew_paid": "Lunas",
|
||||||
"ew_unmatched": "Belum cocok"
|
"ew_unmatched": "Belum cocok",
|
||||||
|
"speedtest_hint": "Preset hanya mengisi otomatis — sesuaikan URL bila perlu.",
|
||||||
|
"qris_dyn_hint": "Jika diisi, sistem akan membuat QRIS dinamis per transaksi (nominal langsung terisi saat scan). Jika kosong, sistem pakai URL gambar seperti biasa.",
|
||||||
|
"qris_upload_hint": "Jika di-upload, sistem akan menyimpan file dan otomatis mengisi URL QRIS.",
|
||||||
|
"bank_hint": "Nominal & kode unik sama seperti QRIS; verifikasi otomatis (webhook forwarder) + manual (upload bukti)."
|
||||||
},
|
},
|
||||||
"mt": {
|
"mt": {
|
||||||
"updating": "Memperbarui...",
|
"updating": "Memperbarui...",
|
||||||
"online_list": "Daftar User PPPoE Online",
|
"online_list": "Daftar User PPPoE Online",
|
||||||
"offline_list": "Daftar User PPPoE Offline",
|
"offline_list": "Daftar User PPPoE Offline",
|
||||||
"limit_uptime": "Limit Uptime (e.g. 1h)"
|
"limit_uptime": "Limit Uptime (e.g. 1h)",
|
||||||
|
"empty_pppoe": "Tidak ada data profile PPPoE.",
|
||||||
|
"empty_hs": "Tidak ada data profile Hotspot."
|
||||||
},
|
},
|
||||||
"disc": {
|
"disc": {
|
||||||
"title": "Diskon Tagihan",
|
"title": "Diskon Tagihan",
|
||||||
@@ -1928,7 +1949,8 @@
|
|||||||
"apply": "Terapkan Diskon",
|
"apply": "Terapkan Diskon",
|
||||||
"selected": "dipilih",
|
"selected": "dipilih",
|
||||||
"history": "Riwayat Diskon (100 terakhir)",
|
"history": "Riwayat Diskon (100 terakhir)",
|
||||||
"th_note": "Catatan"
|
"th_note": "Catatan",
|
||||||
|
"empty_cust": "Tidak ada pelanggan."
|
||||||
},
|
},
|
||||||
"cpay": {
|
"cpay": {
|
||||||
"title": "Approval Pembayaran Kolektor",
|
"title": "Approval Pembayaran Kolektor",
|
||||||
@@ -1943,7 +1965,8 @@
|
|||||||
"th_invoice": "Tagihan",
|
"th_invoice": "Tagihan",
|
||||||
"th_process": "Proses",
|
"th_process": "Proses",
|
||||||
"approve": "Setujui",
|
"approve": "Setujui",
|
||||||
"reject": "Tolak"
|
"reject": "Tolak",
|
||||||
|
"wait_approval": "Menunggu admin atau kasir"
|
||||||
},
|
},
|
||||||
"att": {
|
"att": {
|
||||||
"late_checkin": "Terlambat Check-in",
|
"late_checkin": "Terlambat Check-in",
|
||||||
@@ -1960,7 +1983,9 @@
|
|||||||
"checkin_time": "Waktu Check-in",
|
"checkin_time": "Waktu Check-in",
|
||||||
"duration": "Durasi",
|
"duration": "Durasi",
|
||||||
"location": "Lokasi",
|
"location": "Lokasi",
|
||||||
"photo": "Foto"
|
"photo": "Foto",
|
||||||
|
"empty": "Tidak ada data absensi",
|
||||||
|
"empty_sub": "Belum ada karyawan yang melakukan absensi pada tanggal ini."
|
||||||
},
|
},
|
||||||
"olt": {
|
"olt": {
|
||||||
"all_summary": "Semua OLT (Ringkasan Total)",
|
"all_summary": "Semua OLT (Ringkasan Total)",
|
||||||
@@ -2016,7 +2041,12 @@
|
|||||||
"ph_isolir_profile": "— pakai default global/customer —",
|
"ph_isolir_profile": "— pakai default global/customer —",
|
||||||
"night_profile": "Nama Profile Malam (MikroTik)",
|
"night_profile": "Nama Profile Malam (MikroTik)",
|
||||||
"ph_night_profile": "-- Pilih Profile --",
|
"ph_night_profile": "-- Pilih Profile --",
|
||||||
"night_down": "Download Malam (Mbps)"
|
"night_down": "Download Malam (Mbps)",
|
||||||
|
"promo_prorata": "Promo & prorata tagihan",
|
||||||
|
"prorata_first": "Prorata tagihan pertama (tanggal pasang = bulan tagihan)",
|
||||||
|
"night_hint": "Sistem akan ganti profile ppp pelanggan ke profile ini pada jam 00:00 - 06:00.",
|
||||||
|
"kalong_hint": "Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai Jam Kalong).",
|
||||||
|
"fup_hint": "Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai FUP)."
|
||||||
},
|
},
|
||||||
"col": {
|
"col": {
|
||||||
"title": "Manajemen Kolektor",
|
"title": "Manajemen Kolektor",
|
||||||
@@ -2033,7 +2063,8 @@
|
|||||||
"del": "Hapus Kolektor",
|
"del": "Hapus Kolektor",
|
||||||
"full_name": "Nama Lengkap",
|
"full_name": "Nama Lengkap",
|
||||||
"area_region": "Area / Wilayah Tugas",
|
"area_region": "Area / Wilayah Tugas",
|
||||||
"opt_all_area": "-- Semua Area / Bebas --"
|
"opt_all_area": "-- Semua Area / Bebas --",
|
||||||
|
"empty": "Belum ada data kolektor."
|
||||||
},
|
},
|
||||||
"mon": {
|
"mon": {
|
||||||
"title": "Monitoring Sistem",
|
"title": "Monitoring Sistem",
|
||||||
@@ -2080,7 +2111,9 @@
|
|||||||
"total_hours": "Total Jam",
|
"total_hours": "Total Jam",
|
||||||
"work_hours": "Jam kerja",
|
"work_hours": "Jam kerja",
|
||||||
"avg": "Rata-rata",
|
"avg": "Rata-rata",
|
||||||
"hours_per_day": "Jam/hari"
|
"hours_per_day": "Jam/hari",
|
||||||
|
"preview": "Preview foto final yang akan dikirim:",
|
||||||
|
"checkin_hint": "Silakan lakukan check-in untuk memulai hari kerja Anda."
|
||||||
},
|
},
|
||||||
"gis": {
|
"gis": {
|
||||||
"ph_search": "Cari ODP, ODC, HTB, Pelanggan...",
|
"ph_search": "Cari ODP, ODC, HTB, Pelanggan...",
|
||||||
@@ -2133,7 +2166,10 @@
|
|||||||
"th_validity": "Masa Aktif",
|
"th_validity": "Masa Aktif",
|
||||||
"th_prefix": "Prefix",
|
"th_prefix": "Prefix",
|
||||||
"th_len": "Panjang Kode",
|
"th_len": "Panjang Kode",
|
||||||
"th_chars": "Karakter"
|
"th_chars": "Karakter",
|
||||||
|
"opt_active": "Aktif (Tampil di portal pelanggan)",
|
||||||
|
"empty": "Belum ada paket voucher hotspot real-time terdaftar. Klik tombol Tambah diatas untuk memulai!",
|
||||||
|
"no_meta": "Profil tidak memiliki metadata Mikhmon. Isi harga dan masa aktif manual."
|
||||||
},
|
},
|
||||||
"cashin": {
|
"cashin": {
|
||||||
"heading": "Kas Masuk (Lain-lain)",
|
"heading": "Kas Masuk (Lain-lain)",
|
||||||
@@ -2158,7 +2194,8 @@
|
|||||||
"ph_ref": "Bisa dikosongkan",
|
"ph_ref": "Bisa dikosongkan",
|
||||||
"save": "Simpan Pemasukan",
|
"save": "Simpan Pemasukan",
|
||||||
"title": "Kas Masuk",
|
"title": "Kas Masuk",
|
||||||
"th_method": "Metode"
|
"th_method": "Metode",
|
||||||
|
"empty": "Belum ada data kas masuk."
|
||||||
},
|
},
|
||||||
"exp": {
|
"exp": {
|
||||||
"heading": "Pengeluaran (Cash Out)",
|
"heading": "Pengeluaran (Cash Out)",
|
||||||
@@ -2183,7 +2220,8 @@
|
|||||||
"pay_credit": "Kredit / Paylater",
|
"pay_credit": "Kredit / Paylater",
|
||||||
"save": "Simpan Pengeluaran",
|
"save": "Simpan Pengeluaran",
|
||||||
"title": "Pengeluaran",
|
"title": "Pengeluaran",
|
||||||
"th_method": "Metode"
|
"th_method": "Metode",
|
||||||
|
"empty": "Belum ada data pengeluaran."
|
||||||
},
|
},
|
||||||
"ar": {
|
"ar": {
|
||||||
"heading": "Manajemen Area / Wilayah",
|
"heading": "Manajemen Area / Wilayah",
|
||||||
@@ -2212,7 +2250,8 @@
|
|||||||
"setup_fw": "Setup Firewall Isolir",
|
"setup_fw": "Setup Firewall Isolir",
|
||||||
"edit": "Edit Router",
|
"edit": "Edit Router",
|
||||||
"del": "Hapus Router",
|
"del": "Hapus Router",
|
||||||
"live_title": "Detail Live Router"
|
"live_title": "Detail Live Router",
|
||||||
|
"script_hint": "Script ini di-generate otomatis berdasarkan IP server & URL billing (app_url). Anda dapat menyalin dan menempelkannya di Winbox Terminal MikroTik."
|
||||||
},
|
},
|
||||||
"bc": {
|
"bc": {
|
||||||
"send_title": "Kirim Tagihan Sekarang (Manual — bila Auto OFF)",
|
"send_title": "Kirim Tagihan Sekarang (Manual — bila Auto OFF)",
|
||||||
@@ -2246,7 +2285,9 @@
|
|||||||
"auto_clean": "Pembersihan Otomatis",
|
"auto_clean": "Pembersihan Otomatis",
|
||||||
"retention": "Retensi (Hari)",
|
"retention": "Retensi (Hari)",
|
||||||
"history": "Riwayat Backup",
|
"history": "Riwayat Backup",
|
||||||
"empty": "Belum ada file backup tersedia"
|
"empty": "Belum ada file backup tersedia",
|
||||||
|
"file_hint": "File .db (database) atau .json (settings)",
|
||||||
|
"retention_hint": "Backup lebih lama dari periode ini akan dihapus"
|
||||||
},
|
},
|
||||||
"wt": {
|
"wt": {
|
||||||
"title": "Pengaturan Template Notifikasi WhatsApp",
|
"title": "Pengaturan Template Notifikasi WhatsApp",
|
||||||
@@ -2266,12 +2307,27 @@
|
|||||||
"opt_qris": "Template Tagihan QRIS",
|
"opt_qris": "Template Tagihan QRIS",
|
||||||
"opt_success": "Template Pembayaran Sukses",
|
"opt_success": "Template Pembayaran Sukses",
|
||||||
"opt_isolir": "Template Pemberitahuan Isolir",
|
"opt_isolir": "Template Pemberitahuan Isolir",
|
||||||
"vars": "Daftar Variabel Urutan Parameter (Components Payload):"
|
"vars": "Daftar Variabel Urutan Parameter (Components Payload):",
|
||||||
|
"ph_user": "(Username PPPoE, opsional)",
|
||||||
|
"warn_custid": "wajib menyertakan variabel ID Pelanggan"
|
||||||
},
|
},
|
||||||
"md": {
|
"md": {
|
||||||
"connecting": "Menghubungkan ke MikroTik...",
|
"connecting": "Menghubungkan ke MikroTik...",
|
||||||
"fullscreen": "Layar Penuh",
|
"fullscreen": "Layar Penuh",
|
||||||
"exit": "Keluar"
|
"exit": "Keluar",
|
||||||
|
"reconnect_hint": "Pastikan IP/port benar dan API service aktif. Mencoba kembali..."
|
||||||
|
},
|
||||||
|
"payroll": {
|
||||||
|
"empty_staff": "Belum ada karyawan aktif",
|
||||||
|
"empty_slip": "Belum ada slip gaji untuk periode ini",
|
||||||
|
"gen_hint": "Klik \"Generate Semua\" untuk membuat slip gaji otomatis"
|
||||||
|
},
|
||||||
|
"rep": {
|
||||||
|
"ppn_incl": "Ya — PPN sudah termasuk",
|
||||||
|
"tax_hint": "PPh Badan, PPN, USO & BHP dihitung otomatis dari nilai ini."
|
||||||
|
},
|
||||||
|
"wlc": {
|
||||||
|
"empty": "Belum ada pesan dengan pelanggan ini. Ketik pesan di bawah dan tekan Enter untuk memulai."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tech": {
|
"tech": {
|
||||||
|
|||||||
+2
-2
@@ -396,7 +396,7 @@
|
|||||||
<div style="background: var(--sub-bg); border: 1px solid var(--border); padding: 18px; border-radius: 16px; margin-bottom: 5px;">
|
<div style="background: var(--sub-bg); border: 1px solid var(--border); padding: 18px; border-radius: 16px; margin-bottom: 5px;">
|
||||||
<h4 style="margin: 0 0 12px 0; font-size: 13px; color: var(--text); font-weight: 700;"><i class="bi bi-bezier2 text-primary"></i> LAN / WLAN Port Binding</h4>
|
<h4 style="margin: 0 0 12px 0; font-size: 13px; color: var(--text); font-weight: 700;"><i class="bi bi-bezier2 text-primary"></i> LAN / WLAN Port Binding</h4>
|
||||||
|
|
||||||
<label class="fl" style="margin-bottom: 8px;">Pilih LAN Port yang akan di-bind:</label>
|
<label class="fl" style="margin-bottom: 8px;"><%= t('admin.acs.bind_lan','Pilih LAN Port yang akan di-bind:') %></label>
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 15px;">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 15px;">
|
||||||
<label class="bind-tag active" id="lblLan1">
|
<label class="bind-tag active" id="lblLan1">
|
||||||
<input type="checkbox" name="lanPorts" value="LAN1" checked style="display: none;" onchange="syncTagClass(this, 'lblLan1')"> LAN 1
|
<input type="checkbox" name="lanPorts" value="LAN1" checked style="display: none;" onchange="syncTagClass(this, 'lblLan1')"> LAN 1
|
||||||
@@ -412,7 +412,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="fl" style="margin-bottom: 8px;">Pilih WLAN (SSID) yang akan di-bind:</label>
|
<label class="fl" style="margin-bottom: 8px;"><%= t('admin.acs.bind_ssid','Pilih WLAN (SSID) yang akan di-bind:') %></label>
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;">
|
||||||
<label class="bind-tag active" id="lblWlan1">
|
<label class="bind-tag active" id="lblWlan1">
|
||||||
<input type="checkbox" name="wlanSsids" value="SSID1" checked style="display: none;" onchange="syncTagClass(this, 'lblWlan1')"> SSID 1
|
<input type="checkbox" name="wlanSsids" value="SSID1" checked style="display: none;" onchange="syncTagClass(this, 'lblWlan1')"> SSID 1
|
||||||
|
|||||||
@@ -372,8 +372,8 @@
|
|||||||
<% } else { %>
|
<% } else { %>
|
||||||
<div class="card-bd" style="text-align:center;padding:60px 20px">
|
<div class="card-bd" style="text-align:center;padding:60px 20px">
|
||||||
<div style="font-size:64px;margin-bottom:16px;opacity:0.3"><i class="bi bi-inbox"></i></div>
|
<div style="font-size:64px;margin-bottom:16px;opacity:0.3"><i class="bi bi-inbox"></i></div>
|
||||||
<h3 style="color:var(--muted);font-weight:500">Tidak ada data absensi</h3>
|
<h3 style="color:var(--muted);font-weight:500"><%= t('admin.att.empty','Tidak ada data absensi') %></h3>
|
||||||
<p style="color:var(--muted);font-size:14px">Belum ada karyawan yang melakukan absensi pada tanggal ini.</p>
|
<p style="color:var(--muted);font-size:14px"><%= t('admin.att.empty_sub','Belum ada karyawan yang melakukan absensi pada tanggal ini.') %></p>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><%= t('admin.bk.pick_file','Pilih File Backup (.db / .json)') %></label>
|
<label class="fl"><%= t('admin.bk.pick_file','Pilih File Backup (.db / .json)') %></label>
|
||||||
<input type="file" class="fc" name="backupFile" accept=".db,.sqlite,.json" required style="padding: 6px 10px;">
|
<input type="file" class="fc" name="backupFile" accept=".db,.sqlite,.json" required style="padding: 6px 10px;">
|
||||||
<small class="text-muted" style="font-size: 10px; display: block; margin-top: 4px;">File .db (database) atau .json (settings)</small>
|
<small class="text-muted" style="font-size: 10px; display: block; margin-top: 4px;"><%= t('admin.bk.file_hint','File .db (database) atau .json (settings)') %></small>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-s w-100">
|
<button type="submit" class="btn btn-s w-100">
|
||||||
<i class="bi bi-cloud-arrow-up"></i> Upload & Restore
|
<i class="bi bi-cloud-arrow-up"></i> Upload & Restore
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><%= t('admin.bk.retention','Retensi (Hari)') %></label>
|
<label class="fl"><%= t('admin.bk.retention','Retensi (Hari)') %></label>
|
||||||
<input type="number" class="fc" name="retentionDays" value="30" min="1" max="365">
|
<input type="number" class="fc" name="retentionDays" value="30" min="1" max="365">
|
||||||
<small class="text-muted" style="font-size: 10px; display: block; margin-top: 4px;">Backup lebih lama dari periode ini akan dihapus</small>
|
<small class="text-muted" style="font-size: 10px; display: block; margin-top: 4px;"><%= t('admin.bk.retention_hint','Backup lebih lama dari periode ini akan dihapus') %></small>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-w w-100">
|
<button type="submit" class="btn btn-w w-100">
|
||||||
<i class="bi bi-stars"></i> Bersihkan Sekarang
|
<i class="bi bi-stars"></i> Bersihkan Sekarang
|
||||||
|
|||||||
@@ -186,7 +186,7 @@
|
|||||||
<button type="button" onclick="clearSelectedPhoto('checkoutPhoto')" class="btn btn-d btn-sm" id="checkoutPhotoClearBtn" style="display: none; border-radius: 8px; font-size: 11px;"><%= t('collector.delete_photo','Hapus Foto') %></button>
|
<button type="button" onclick="clearSelectedPhoto('checkoutPhoto')" class="btn btn-d btn-sm" id="checkoutPhotoClearBtn" style="display: none; border-radius: 8px; font-size: 11px;"><%= t('collector.delete_photo','Hapus Foto') %></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="checkoutPhotoPreviewWrap" style="display:none;margin-top:8px">
|
<div id="checkoutPhotoPreviewWrap" style="display:none;margin-top:8px">
|
||||||
<div class="photo-help" style="margin-bottom:6px">Preview foto final yang akan dikirim:</div>
|
<div class="photo-help" style="margin-bottom:6px"><%= t('admin.ca.preview','Preview foto final yang akan dikirim:') %></div>
|
||||||
<img id="checkoutPhotoPreview" alt="Preview foto check-out" style="width:100%;max-width:240px;border-radius:12px;border:1px solid var(--border);object-fit:cover">
|
<img id="checkoutPhotoPreview" alt="Preview foto check-out" style="width:100%;max-width:240px;border-radius:12px;border:1px solid var(--border);object-fit:cover">
|
||||||
</div>
|
</div>
|
||||||
<button id="checkoutSubmitBtn" class="btn btn-d btn-sm" style="width:100%;margin-top:12px;opacity:0.55;cursor:not-allowed" onclick="checkout(event)" disabled>
|
<button id="checkoutSubmitBtn" class="btn btn-d btn-sm" style="width:100%;margin-top:12px;opacity:0.55;cursor:not-allowed" onclick="checkout(event)" disabled>
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
|
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<span class="status-badge status-not-checked-in"><i class="bi bi-x-lg"></i> <%= t('admin.ca.not_checked_in','Belum Check-in') %></span>
|
<span class="status-badge status-not-checked-in"><i class="bi bi-x-lg"></i> <%= t('admin.ca.not_checked_in','Belum Check-in') %></span>
|
||||||
<p style="color: var(--muted); margin: 16px 0;">Silakan lakukan check-in untuk memulai hari kerja Anda.</p>
|
<p style="color: var(--muted); margin: 16px 0;"><%= t('admin.ca.checkin_hint','Silakan lakukan check-in untuk memulai hari kerja Anda.') %></p>
|
||||||
|
|
||||||
<textarea id="checkinNote" class="note-input" placeholder="<%= t('admin.ca.ph_note_in','Catatan check-in (opsional)') %>"></textarea>
|
<textarea id="checkinNote" class="note-input" placeholder="<%= t('admin.ca.ph_note_in','Catatan check-in (opsional)') %>"></textarea>
|
||||||
<input id="checkinPhoto" type="file" accept="image/*" capture="user" style="display: none;" onchange="updatePhotoInfo('checkinPhoto', 'checkinPhotoInfo', 'checkinPhotoPreviewWrap', 'checkinPhotoPreview')">
|
<input id="checkinPhoto" type="file" accept="image/*" capture="user" style="display: none;" onchange="updatePhotoInfo('checkinPhoto', 'checkinPhotoInfo', 'checkinPhotoPreviewWrap', 'checkinPhotoPreview')">
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
<button type="button" onclick="clearSelectedPhoto('checkinPhoto')" class="btn btn-d btn-sm" id="checkinPhotoClearBtn" style="display: none; border-radius: 8px; font-size: 11px;"><%= t('collector.delete_photo','Hapus Foto') %></button>
|
<button type="button" onclick="clearSelectedPhoto('checkinPhoto')" class="btn btn-d btn-sm" id="checkinPhotoClearBtn" style="display: none; border-radius: 8px; font-size: 11px;"><%= t('collector.delete_photo','Hapus Foto') %></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="checkinPhotoPreviewWrap" style="display:none;margin-top:8px">
|
<div id="checkinPhotoPreviewWrap" style="display:none;margin-top:8px">
|
||||||
<div class="photo-help" style="margin-bottom:6px">Preview foto final yang akan dikirim:</div>
|
<div class="photo-help" style="margin-bottom:6px"><%= t('admin.ca.preview','Preview foto final yang akan dikirim:') %></div>
|
||||||
<img id="checkinPhotoPreview" alt="Preview foto check-in" style="width:100%;max-width:240px;border-radius:12px;border:1px solid var(--border);object-fit:cover">
|
<img id="checkinPhotoPreview" alt="Preview foto check-in" style="width:100%;max-width:240px;border-radius:12px;border:1px solid var(--border);object-fit:cover">
|
||||||
</div>
|
</div>
|
||||||
<button id="checkinSubmitBtn" class="btn btn-s btn-sm" style="width:100%;margin-top:12px;opacity:0.55;cursor:not-allowed" onclick="checkin(event)" disabled>
|
<button id="checkinSubmitBtn" class="btn btn-s btn-sm" style="width:100%;margin-top:12px;opacity:0.55;cursor:not-allowed" onclick="checkin(event)" disabled>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
<% if (decidedRole === 'system') { %>
|
<% if (decidedRole === 'system') { %>
|
||||||
<div style="font-size:10px;color:var(--muted)">Kolektor auto-approve aktif</div>
|
<div style="font-size:10px;color:var(--muted)">Kolektor auto-approve aktif</div>
|
||||||
<% } else if (r.status === 'pending') { %>
|
<% } else if (r.status === 'pending') { %>
|
||||||
<div style="font-size:10px;color:var(--muted)">Menunggu admin atau kasir</div>
|
<div style="font-size:10px;color:var(--muted)"><%= t('admin.cpay.wait_approval','Menunggu admin atau kasir') %></div>
|
||||||
<% } else if (r.decided_by_name) { %>
|
<% } else if (r.decided_by_name) { %>
|
||||||
<div style="font-size:10px;color:var(--muted)">Oleh: <%= r.decided_by_name %></div>
|
<div style="font-size:10px;color:var(--muted)">Oleh: <%= r.decided_by_name %></div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% if (!collectors || collectors.length === 0) { %>
|
<% if (!collectors || collectors.length === 0) { %>
|
||||||
<tr><td colspan="8" class="text-center text-muted" style="padding:20px">Belum ada data kolektor.</td></tr>
|
<tr><td colspan="8" class="text-center text-muted" style="padding:20px"><%= t('admin.col.empty','Belum ada data kolektor.') %></td></tr>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<% collectors.forEach(c => { %>
|
<% collectors.forEach(c => { %>
|
||||||
<tr data-mode="<%= c.auto_approve ? 'direct' : 'approval' %>" data-status="<%= c.is_active ? 'active' : 'inactive' %>">
|
<tr data-mode="<%= c.auto_approve ? 'direct' : 'approval' %>" data-status="<%= c.is_active ? 'active' : 'inactive' %>">
|
||||||
|
|||||||
@@ -819,7 +819,7 @@
|
|||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl" style="font-weight:700; color:var(--warning);"><i class="bi bi-key-fill"></i> Password PPPoE / RADIUS *</label>
|
<label class="fl" style="font-weight:700; color:var(--warning);"><i class="bi bi-key-fill"></i> Password PPPoE / RADIUS *</label>
|
||||||
<input class="fc" name="pppoe_password" id="e_pppoe_password" placeholder="<%= t('admin.cust.ph_pppoe_pass','Masukkan password PPPoE') %>" required>
|
<input class="fc" name="pppoe_password" id="e_pppoe_password" placeholder="<%= t('admin.cust.ph_pppoe_pass','Masukkan password PPPoE') %>" required>
|
||||||
<small class="text-muted" style="font-size:10px;display:block;margin-top:4px">Kredensial login modem pelanggan untuk RADIUS & PPPoE.</small>
|
<small class="text-muted" style="font-size:10px;display:block;margin-top:4px"><%= t('admin.cust.modem_hint','Kredensial login modem pelanggan untuk RADIUS & PPPoE.') %></small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -886,7 +886,7 @@
|
|||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><i class="bi bi-hourglass-split text-warning me-1"></i> <%= t('admin.cust.validity_prepaid','Masa Aktif / Expired Date (Khusus Prabayar)') %></label>
|
<label class="fl"><i class="bi bi-hourglass-split text-warning me-1"></i> <%= t('admin.cust.validity_prepaid','Masa Aktif / Expired Date (Khusus Prabayar)') %></label>
|
||||||
<input class="fc" type="date" name="expired_at" id="e_expired_at">
|
<input class="fc" type="date" name="expired_at" id="e_expired_at">
|
||||||
<small class="text-muted" style="font-size:10px;display:block;margin-top:2px;">Otomatis dihitung saat pasang/bayar. Bisa disesuaikan manual jika perlu.</small>
|
<small class="text-muted" style="font-size:10px;display:block;margin-top:2px;"><%= t('admin.cust.reg_hint','Otomatis dihitung saat pasang/bayar. Bisa disesuaikan manual jika perlu.') %></small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% if (customers.length===0) { %>
|
<% if (customers.length===0) { %>
|
||||||
<tr><td colspan="7" class="text-center text-muted" style="padding:24px">Tidak ada pelanggan.</td></tr>
|
<tr><td colspan="7" class="text-center text-muted" style="padding:24px"><%= t('admin.disc.empty_cust','Tidak ada pelanggan.') %></td></tr>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% customers.forEach(function(c){ %>
|
<% customers.forEach(function(c){ %>
|
||||||
<tr class="cust-row <%= c.status==='suspended'?'suspended':'' %>">
|
<tr class="cust-row <%= c.status==='suspended'?'suspended':'' %>">
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% if (cashIn.length===0) { %>
|
<% if (cashIn.length===0) { %>
|
||||||
<tr><td colspan="7" class="text-center text-muted" style="padding:32px">Belum ada data kas masuk.</td></tr>
|
<tr><td colspan="7" class="text-center text-muted" style="padding:32px"><%= t('admin.cashin.empty','Belum ada data kas masuk.') %></td></tr>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% cashIn.forEach((item)=>{ %>
|
<% cashIn.forEach((item)=>{ %>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% if (expenses.length===0) { %>
|
<% if (expenses.length===0) { %>
|
||||||
<tr><td colspan="8" class="text-center text-muted" style="padding:32px">Belum ada data pengeluaran.</td></tr>
|
<tr><td colspan="8" class="text-center text-muted" style="padding:32px"><%= t('admin.exp.empty','Belum ada data pengeluaran.') %></td></tr>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% expenses.forEach((item)=>{ %>
|
<% expenses.forEach((item)=>{ %>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
+6
-6
@@ -847,7 +847,7 @@
|
|||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="fg"><label class="fl">Jumlah Port (Kapasitas)</label><input type="number" name="port_capacity" class="fc" min="1" step="1" value="16" required></div>
|
<div class="fg"><label class="fl">Jumlah Port (Kapasitas)</label><input type="number" name="port_capacity" class="fc" min="1" step="1" value="16" required></div>
|
||||||
<div class="fg"><label class="fl">PON Port (opsional)</label><input type="text" name="pon_port" class="fc" placeholder="Contoh: 1/2/7"></div>
|
<div class="fg"><label class="fl"><%= t('admin.map.pon_port','PON Port (opsional)') %></label><input type="text" name="pon_port" class="fc" placeholder="Contoh: 1/2/7"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="fl"><%= t('admin.map.form.pick_location', 'Pilih Lokasi di Peta') %></label>
|
<label class="fl"><%= t('admin.map.form.pick_location', 'Pilih Lokasi di Peta') %></label>
|
||||||
@@ -878,7 +878,7 @@
|
|||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="fg"><label class="fl">Jumlah Port (Kapasitas)</label><input type="number" name="port_capacity" id="e_odp_capacity" class="fc" min="1" step="1" required></div>
|
<div class="fg"><label class="fl">Jumlah Port (Kapasitas)</label><input type="number" name="port_capacity" id="e_odp_capacity" class="fc" min="1" step="1" required></div>
|
||||||
<div class="fg"><label class="fl">PON Port (opsional)</label><input type="text" name="pon_port" id="e_odp_pon" class="fc" placeholder="Contoh: 1/2/7"></div>
|
<div class="fg"><label class="fl"><%= t('admin.map.pon_port','PON Port (opsional)') %></label><input type="text" name="pon_port" id="e_odp_pon" class="fc" placeholder="Contoh: 1/2/7"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="fl"><%= t('admin.map.form.adjust_location', 'Sesuaikan Lokasi di Peta') %></label>
|
<label class="fl"><%= t('admin.map.form.adjust_location', 'Sesuaikan Lokasi di Peta') %></label>
|
||||||
@@ -1121,7 +1121,7 @@
|
|||||||
function renderCustomerTable() {
|
function renderCustomerTable() {
|
||||||
var tb = document.getElementById('customersTableBody');
|
var tb = document.getElementById('customersTableBody');
|
||||||
if (!tb) return;
|
if (!tb) return;
|
||||||
if (!customers.length) { tb.innerHTML = '<tr><td colspan="6" style="padding:16px;text-align:center;color:#64748b;">Belum ada data pelanggan.</td></tr>'; return; }
|
if (!customers.length) { tb.innerHTML = '<tr><td colspan="6" style="padding:16px;text-align:center;color:#64748b;"><%= t('admin.map.empty_cust','Belum ada data pelanggan.') %></td></tr>'; return; }
|
||||||
tb.innerHTML = customers.map(function (c) {
|
tb.innerHTML = customers.map(function (c) {
|
||||||
var hasGps = Boolean(c.lat && c.lng);
|
var hasGps = Boolean(c.lat && c.lng);
|
||||||
var isActive = c.status === 'active';
|
var isActive = c.status === 'active';
|
||||||
@@ -1149,7 +1149,7 @@
|
|||||||
function renderOdpTable() {
|
function renderOdpTable() {
|
||||||
var tb = document.getElementById('odpsTbody');
|
var tb = document.getElementById('odpsTbody');
|
||||||
if (!tb) return;
|
if (!tb) return;
|
||||||
if (!odps.length) { tb.innerHTML = '<tr><td colspan="5" style="padding:16px;text-align:center;color:#64748b;">Belum ada data ODP.</td></tr>'; return; }
|
if (!odps.length) { tb.innerHTML = '<tr><td colspan="5" style="padding:16px;text-align:center;color:#64748b;"><%= t('admin.map.empty_odp','Belum ada data ODP.') %></td></tr>'; return; }
|
||||||
tb.innerHTML = odps.map(function (o) {
|
tb.innerHTML = odps.map(function (o) {
|
||||||
var pu = o.port_usage || { capacity: Number(o.port_capacity || 16) || 16, usedCount: 0, remaining: Number(o.port_capacity || 16) || 16 };
|
var pu = o.port_usage || { capacity: Number(o.port_capacity || 16) || 16, usedCount: 0, remaining: Number(o.port_capacity || 16) || 16 };
|
||||||
return '<tr data-name="' + escapeHtml(String(o.name || '').toLowerCase()) + '" data-desc="' + escapeHtml(String(o.description || '').toLowerCase()) + '">' +
|
return '<tr data-name="' + escapeHtml(String(o.name || '').toLowerCase()) + '" data-desc="' + escapeHtml(String(o.description || '').toLowerCase()) + '">' +
|
||||||
@@ -1158,7 +1158,7 @@
|
|||||||
'<td><div style="font-weight:800;font-size:12px;">' +
|
'<td><div style="font-weight:800;font-size:12px;">' +
|
||||||
'<button type="button" class="btn btn-sm btn-g" style="font-weight:800;padding:2px 8px" onclick="showOdpPorts(' + Number(o.id) + ')" title="Lihat visual port terpakai"><i class="bi bi-diagram-2"></i> ' + pu.usedCount + '/' + pu.capacity + '</button>' +
|
'<button type="button" class="btn btn-sm btn-g" style="font-weight:800;padding:2px 8px" onclick="showOdpPorts(' + Number(o.id) + ')" title="Lihat visual port terpakai"><i class="bi bi-diagram-2"></i> ' + pu.usedCount + '/' + pu.capacity + '</button>' +
|
||||||
(pu.remaining === 0 ? ' <span class="cp-chip" style="background:#fee2e2;color:#991b1b;border-color:#fecaca"><i class="bi bi-exclamation-triangle-fill"></i> PENUH</span>' : ' <span style="font-size:11px;color:var(--muted)">sisa ' + pu.remaining + '</span>') +
|
(pu.remaining === 0 ? ' <span class="cp-chip" style="background:#fee2e2;color:#991b1b;border-color:#fecaca"><i class="bi bi-exclamation-triangle-fill"></i> PENUH</span>' : ' <span style="font-size:11px;color:var(--muted)">sisa ' + pu.remaining + '</span>') +
|
||||||
'</div><div style="font-size:11px;color:var(--muted);margin-top:2px">Klik untuk lihat visual port</div></td>' +
|
'</div><div style="font-size:11px;color:var(--muted);margin-top:2px"><%= t('admin.map.view_port','Klik untuk lihat visual port') %></div></td>' +
|
||||||
'<td><div style="font-size:11.5px;font-family:monospace;color:#334155;font-weight:700;">' + (Number(o.lat) || 0).toFixed(6) + ', ' + (Number(o.lng) || 0).toFixed(6) + '</div></td>' +
|
'<td><div style="font-size:11.5px;font-family:monospace;color:#334155;font-weight:700;">' + (Number(o.lat) || 0).toFixed(6) + ', ' + (Number(o.lng) || 0).toFixed(6) + '</div></td>' +
|
||||||
'<td style="white-space:nowrap"><div class="act">' +
|
'<td style="white-space:nowrap"><div class="act">' +
|
||||||
'<button type="button" class="act-btn" title="Aksi" onclick="actToggle(event, this)"><i class="bi bi-three-dots-vertical"></i></button>' +
|
'<button type="button" class="act-btn" title="Aksi" onclick="actToggle(event, this)"><i class="bi bi-three-dots-vertical"></i></button>' +
|
||||||
@@ -2268,7 +2268,7 @@
|
|||||||
if (legend) legend.textContent = 'Hijau = terhubung (online), Merah = offline, tanpa warna = belum terhubung. Terpakai ' + (u.usedCount || 0) + '/' + cap + '.';
|
if (legend) legend.textContent = 'Hijau = terhubung (online), Merah = offline, tanpa warna = belum terhubung. Terpakai ' + (u.usedCount || 0) + '/' + cap + '.';
|
||||||
if (title) title.textContent = 'Port ODP (' + (u.usedCount || 0) + '/' + cap + ')';
|
if (title) title.textContent = 'Port ODP (' + (u.usedCount || 0) + '/' + cap + ')';
|
||||||
})
|
})
|
||||||
.catch(function () { grid.innerHTML = '<span class="text-muted">Gagal memuat data port.</span>'; });
|
.catch(function () { grid.innerHTML = '<span class="text-muted"><%= t('admin.map.port_err','Gagal memuat data port.') %></span>'; });
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildWaLink(phone, name) {
|
function buildWaLink(phone, name) {
|
||||||
|
|||||||
@@ -850,7 +850,7 @@
|
|||||||
}
|
}
|
||||||
pppoeProfilesData = await res.json();
|
pppoeProfilesData = await res.json();
|
||||||
if (!Array.isArray(pppoeProfilesData) || pppoeProfilesData.length === 0) {
|
if (!Array.isArray(pppoeProfilesData) || pppoeProfilesData.length === 0) {
|
||||||
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-muted">Tidak ada data profile PPPoE.</td></tr>`;
|
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-muted"><%= t('admin.mt.empty_pppoe','Tidak ada data profile PPPoE.') %></td></tr>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tbody.innerHTML = pppoeProfilesData.map((p, i) => `
|
tbody.innerHTML = pppoeProfilesData.map((p, i) => `
|
||||||
@@ -886,7 +886,7 @@
|
|||||||
}
|
}
|
||||||
hotspotProfilesData = await res.json();
|
hotspotProfilesData = await res.json();
|
||||||
if (!Array.isArray(hotspotProfilesData) || hotspotProfilesData.length === 0) {
|
if (!Array.isArray(hotspotProfilesData) || hotspotProfilesData.length === 0) {
|
||||||
tbody.innerHTML = `<tr><td colspan="7" class="text-center text-muted">Tidak ada data profile Hotspot.</td></tr>`;
|
tbody.innerHTML = `<tr><td colspan="7" class="text-center text-muted"><%= t('admin.mt.empty_hs','Tidak ada data profile Hotspot.') %></td></tr>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tbody.innerHTML = hotspotProfilesData.map((p, i) => {
|
tbody.innerHTML = hotspotProfilesData.map((p, i) => {
|
||||||
|
|||||||
@@ -1386,7 +1386,7 @@
|
|||||||
overlay.style.pointerEvents = 'auto';
|
overlay.style.pointerEvents = 'auto';
|
||||||
const overlayText = overlay.querySelector('.overlay-text');
|
const overlayText = overlay.querySelector('.overlay-text');
|
||||||
if (overlayText) {
|
if (overlayText) {
|
||||||
overlayText.innerHTML = `<span style="color:var(--danger);font-weight:700">Koneksi MikroTik Gagal</span><br><span style="font-size:11px;text-transform:none;margin-top:4px;display:block;color:var(--text-muted)">Pastikan IP/port benar dan API service aktif. Mencoba kembali...</span>`;
|
overlayText.innerHTML = `<span style="color:var(--danger);font-weight:700">Koneksi MikroTik Gagal</span><br><span style="font-size:11px;text-transform:none;margin-top:4px;display:block;color:var(--text-muted)"><%= t('admin.md.reconnect_hint','Pastikan IP/port benar dan API service aktif. Mencoba kembali...') %></span>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,7 +358,7 @@
|
|||||||
<i class="bi bi-wifi" style="font-size:20px;color:#3b82f6"></i>
|
<i class="bi bi-wifi" style="font-size:20px;color:#3b82f6"></i>
|
||||||
<div>
|
<div>
|
||||||
<div style="font-weight:700;color:#e2e8f0">Konfigurasi WiFi</div>
|
<div style="font-weight:700;color:#e2e8f0">Konfigurasi WiFi</div>
|
||||||
<div class="hint" style="font-size:12px;margin-top:2px">Set SSID dan password WiFi ONU</div>
|
<div class="hint" style="font-size:12px;margin-top:2px"><%= t('admin.onu.ssid_hint','Set SSID dan password WiFi ONU') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="checkbox" id="enableWifi" onchange="toggleWifiFields()" style="width:20px;height:20px;cursor:pointer">
|
<input type="checkbox" id="enableWifi" onchange="toggleWifiFields()" style="width:20px;height:20px;cursor:pointer">
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
<i class="bi bi-ethernet" style="font-size:20px;color:#10b981"></i>
|
<i class="bi bi-ethernet" style="font-size:20px;color:#10b981"></i>
|
||||||
<div>
|
<div>
|
||||||
<div style="font-weight:700;color:#e2e8f0">Mode LAN</div>
|
<div style="font-weight:700;color:#e2e8f0">Mode LAN</div>
|
||||||
<div class="hint" style="font-size:12px;margin-top:2px">Bridge (MikroTik dial) atau Router (ONU dial)</div>
|
<div class="hint" style="font-size:12px;margin-top:2px"><%= t('admin.onu.wan_mode_hint','Bridge (MikroTik dial) atau Router (ONU dial)') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="checkbox" id="enableLanMode" onchange="toggleLanModeFields()" style="width:20px;height:20px;cursor:pointer">
|
<input type="checkbox" id="enableLanMode" onchange="toggleLanModeFields()" style="width:20px;height:20px;cursor:pointer">
|
||||||
@@ -460,7 +460,7 @@
|
|||||||
<div class="fg" style="margin:0">
|
<div class="fg" style="margin:0">
|
||||||
<label class="fl">ACS URL <span style="color:#ef4444">*</span></label>
|
<label class="fl">ACS URL <span style="color:#ef4444">*</span></label>
|
||||||
<input type="text" class="fc" name="tr069AcsUrl" placeholder="http://acs.example.com:7547">
|
<input type="text" class="fc" name="tr069AcsUrl" placeholder="http://acs.example.com:7547">
|
||||||
<div class="hint" style="font-size:11px;margin-top:4px">Format: http://host:port atau https://host:port</div>
|
<div class="hint" style="font-size:11px;margin-top:4px"><%= t('admin.onu.ph_url','Format: http://host:port atau https://host:port') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row2">
|
<div class="form-row2">
|
||||||
<div class="fg" style="margin:0">
|
<div class="fg" style="margin:0">
|
||||||
@@ -585,7 +585,7 @@ async function scanUnconfiguredONUs() {
|
|||||||
});
|
});
|
||||||
listDiv.innerHTML = html;
|
listDiv.innerHTML = html;
|
||||||
} else {
|
} else {
|
||||||
listDiv.innerHTML = '<div class="hint" style="text-align:center;padding:40px"><i class="bi bi-check-circle" style="font-size:32px;color:#22c55e"></i><p>Tidak ada ONU yang belum terkonfigurasi</p></div>';
|
listDiv.innerHTML = '<div class="hint" style="text-align:center;padding:40px"><i class="bi bi-check-circle" style="font-size:32px;color:#22c55e"></i><p><%= t('admin.onu.empty','Tidak ada ONU yang belum terkonfigurasi') %></p></div>';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
listDiv.innerHTML = '<div class="alert alert-d"><i class="bi bi-exclamation-circle"></i> Error: ' + error.message + '</div>';
|
listDiv.innerHTML = '<div class="alert alert-d"><i class="bi bi-exclamation-circle"></i> Error: ' + error.message + '</div>';
|
||||||
|
|||||||
@@ -253,7 +253,7 @@
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<div style="background: rgba(34,197,94,0.06); padding: 12px 14px; border-radius: 10px; margin-top: 10px;">
|
<div style="background: rgba(34,197,94,0.06); padding: 12px 14px; border-radius: 10px; margin-top: 10px;">
|
||||||
<div class="fw6" style="font-size:12px;margin-bottom:8px;color:var(--success)"><i class="bi bi-percent"></i> Promo & prorata tagihan</div>
|
<div class="fw6" style="font-size:12px;margin-bottom:8px;color:var(--success)"><i class="bi bi-percent"></i> <%= t('admin.pkg.promo_prorata','Promo & prorata tagihan') %></div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_price','Harga promo (Rp / siklus)') %></label><input class="fc" name="promo_price" type="number" min="0" placeholder="<%= t('admin.pkg.ph_promo_price','Opsional, mis. 99000') %>"></div>
|
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_price','Harga promo (Rp / siklus)') %></label><input class="fc" name="promo_price" type="number" min="0" placeholder="<%= t('admin.pkg.ph_promo_price','Opsional, mis. 99000') %>"></div>
|
||||||
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_cycles','Jumlah bulan promo') %></label><input class="fc" name="promo_cycles" type="number" min="0" value="0" placeholder="<%= t('admin.pkg.ph_promo_cycles','0 = tanpa promo') %>"></div>
|
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_cycles','Jumlah bulan promo') %></label><input class="fc" name="promo_cycles" type="number" min="0" value="0" placeholder="<%= t('admin.pkg.ph_promo_cycles','0 = tanpa promo') %>"></div>
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
<div class="fg"><label class="fl"><%= t('admin.pkg.night_down','Download Malam (Mbps)') %></label><input class="fc" name="night_speed_down" type="number" step="any" min="0" placeholder="20"></div>
|
<div class="fg"><label class="fl"><%= t('admin.pkg.night_down','Download Malam (Mbps)') %></label><input class="fc" name="night_speed_down" type="number" step="any" min="0" placeholder="20"></div>
|
||||||
<div class="fg"><label class="fl">Upload Malam (Mbps)</label><input class="fc" name="night_speed_up" type="number" step="any" min="0" placeholder="10"></div>
|
<div class="fg"><label class="fl">Upload Malam (Mbps)</label><input class="fc" name="night_speed_up" type="number" step="any" min="0" placeholder="10"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size: 10px; color: var(--muted); margin-top: 4px;">Sistem akan ganti profile ppp pelanggan ke profile ini pada jam 00:00 - 06:00.</div>
|
<div style="font-size: 10px; color: var(--muted); margin-top: 4px;"><%= t('admin.pkg.night_hint','Sistem akan ganti profile ppp pelanggan ke profile ini pada jam 00:00 - 06:00.') %></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr style="opacity:0.1; margin: 15px 0;">
|
<hr style="opacity:0.1; margin: 15px 0;">
|
||||||
@@ -454,14 +454,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background: rgba(34,197,94,0.06); padding: 12px 14px; border-radius: 10px; margin-top: 10px;">
|
<div style="background: rgba(34,197,94,0.06); padding: 12px 14px; border-radius: 10px; margin-top: 10px;">
|
||||||
<div class="fw6" style="font-size:12px;margin-bottom:8px;color:var(--success)"><i class="bi bi-percent"></i> Promo & prorata tagihan</div>
|
<div class="fw6" style="font-size:12px;margin-bottom:8px;color:var(--success)"><i class="bi bi-percent"></i> <%= t('admin.pkg.promo_prorata','Promo & prorata tagihan') %></div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_price','Harga promo (Rp / siklus)') %></label><input class="fc" name="promo_price" id="e_promo_price" type="number" min="0" placeholder="Kosong = tanpa harga promo"></div>
|
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_price','Harga promo (Rp / siklus)') %></label><input class="fc" name="promo_price" id="e_promo_price" type="number" min="0" placeholder="Kosong = tanpa harga promo"></div>
|
||||||
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_cycles','Jumlah bulan promo') %></label><input class="fc" name="promo_cycles" id="e_promo_cycles" type="number" min="0" value="0"></div>
|
<div class="fg"><label class="fl"><%= t('admin.pkg.promo_cycles','Jumlah bulan promo') %></label><input class="fc" name="promo_cycles" id="e_promo_cycles" type="number" min="0" value="0"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex ai-c" style="gap:8px;margin-top:4px">
|
<div class="flex ai-c" style="gap:8px;margin-top:4px">
|
||||||
<input type="checkbox" name="prorate_first_invoice" id="e_prorate" value="1">
|
<input type="checkbox" name="prorate_first_invoice" id="e_prorate" value="1">
|
||||||
<label for="e_prorate" style="margin:0;font-size:12px">Prorata tagihan pertama (tanggal pasang = bulan tagihan)</label>
|
<label for="e_prorate" style="margin:0;font-size:12px"><%= t('admin.pkg.prorata_first','Prorata tagihan pertama (tanggal pasang = bulan tagihan)') %></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@
|
|||||||
<input type="checkbox" name="use_night_speed" id="e_use_night" value="1" onchange="toggleEditNight()">
|
<input type="checkbox" name="use_night_speed" id="e_use_night" value="1" onchange="toggleEditNight()">
|
||||||
<h6 style="font-size:12px; margin: 0; color: var(--primary); text-transform: uppercase; letter-spacing: 0.5px;"><i class="bi bi-clock"></i> Aktifkan Jam Kalong</h6>
|
<h6 style="font-size:12px; margin: 0; color: var(--primary); text-transform: uppercase; letter-spacing: 0.5px;"><i class="bi bi-clock"></i> Aktifkan Jam Kalong</h6>
|
||||||
</div>
|
</div>
|
||||||
<small class="text-muted" style="font-size:11px;display:block;margin:-6px 0 8px 26px">Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai Jam Kalong).</small>
|
<small class="text-muted" style="font-size:11px;display:block;margin:-6px 0 8px 26px"><%= t('admin.pkg.kalong_hint','Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai Jam Kalong).') %></small>
|
||||||
<div id="e_night_fields" style="display:none">
|
<div id="e_night_fields" style="display:none">
|
||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><%= t('admin.pkg.prof_name','Nama Profil') %>e Malam (MikroTik)</label>
|
<label class="fl"><%= t('admin.pkg.prof_name','Nama Profil') %>e Malam (MikroTik)</label>
|
||||||
@@ -559,7 +559,7 @@
|
|||||||
<input type="checkbox" name="use_fup" id="e_use_fup" value="1" onchange="toggleEditFup()">
|
<input type="checkbox" name="use_fup" id="e_use_fup" value="1" onchange="toggleEditFup()">
|
||||||
<h6 style="font-size:12px; margin: 0; color: var(--danger); text-transform: uppercase; letter-spacing: 0.5px;"><i class="bi bi-speedometer2"></i> Aktifkan FUP</h6>
|
<h6 style="font-size:12px; margin: 0; color: var(--danger); text-transform: uppercase; letter-spacing: 0.5px;"><i class="bi bi-speedometer2"></i> Aktifkan FUP</h6>
|
||||||
</div>
|
</div>
|
||||||
<small class="text-muted" style="font-size:11px;display:block;margin:-6px 0 8px 26px">Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai FUP).</small>
|
<small class="text-muted" style="font-size:11px;display:block;margin:-6px 0 8px 26px"><%= t('admin.pkg.fup_hint','Centang untuk mengatur (kolom terbuka otomatis bila paket ini memakai FUP).') %></small>
|
||||||
<div id="e_fup_fields" style="display:none">
|
<div id="e_fup_fields" style="display:none">
|
||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><%= t('admin.pkg.prof_name','Nama Profil') %>e FUP (MikroTik)</label>
|
<label class="fl"><%= t('admin.pkg.prof_name','Nama Profil') %>e FUP (MikroTik)</label>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-bd">
|
<div class="card-bd">
|
||||||
<% if (employees.length === 0) { %>
|
<% if (employees.length === 0) { %>
|
||||||
<div style="text-align:center;padding:40px"><div style="font-size:48px;opacity:.3"><i class="bi bi-person-fill"></i></div><p style="color:var(--muted)">Belum ada karyawan aktif</p></div>
|
<div style="text-align:center;padding:40px"><div style="font-size:48px;opacity:.3"><i class="bi bi-person-fill"></i></div><p style="color:var(--muted)"><%= t('admin.payroll.empty_staff','Belum ada karyawan aktif') %></p></div>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<% employees.forEach(emp => { %>
|
<% employees.forEach(emp => { %>
|
||||||
<div class="emp-card type-<%= emp.employee_type %>">
|
<div class="emp-card type-<%= emp.employee_type %>">
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-bd">
|
<div class="card-bd">
|
||||||
<% if (slips.length === 0) { %>
|
<% if (slips.length === 0) { %>
|
||||||
<div style="text-align:center;padding:40px"><div style="font-size:48px;opacity:.3"><i class="bi bi-inbox"></i></div><p style="color:var(--muted)">Belum ada slip gaji untuk periode ini</p><p style="color:var(--muted);font-size:12px">Klik "Generate Semua" untuk membuat slip gaji otomatis</p></div>
|
<div style="text-align:center;padding:40px"><div style="font-size:48px;opacity:.3"><i class="bi bi-inbox"></i></div><p style="color:var(--muted)"><%= t('admin.payroll.empty_slip','Belum ada slip gaji untuk periode ini') %></p><p style="color:var(--muted);font-size:12px"><%= t('admin.payroll.gen_hint','Klik "Generate Semua" untuk membuat slip gaji otomatis') %></p></div>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
|
|
||||||
<!-- Bulk Actions -->
|
<!-- Bulk Actions -->
|
||||||
|
|||||||
@@ -226,12 +226,12 @@
|
|||||||
<div class="fg"><label class="fl">PPN di dalam harga?</label>
|
<div class="fg"><label class="fl">PPN di dalam harga?</label>
|
||||||
<select class="fs" name="finance_revenue_includes_ppn">
|
<select class="fs" name="finance_revenue_includes_ppn">
|
||||||
<option value="0" <%= finance.inclPpn ? '' : 'selected' %>>Tidak — PPN ditambahkan</option>
|
<option value="0" <%= finance.inclPpn ? '' : 'selected' %>>Tidak — PPN ditambahkan</option>
|
||||||
<option value="1" <%= finance.inclPpn ? 'selected' : '' %>>Ya — PPN sudah termasuk</option>
|
<option value="1" <%= finance.inclPpn ? 'selected' : '' %>><%= t('admin.rep.ppn_incl','Ya — PPN sudah termasuk') %></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-p btn-sm"><i class="bi bi-save"></i> Simpan Pengaturan</button>
|
<button type="submit" class="btn btn-p btn-sm"><i class="bi bi-save"></i> Simpan Pengaturan</button>
|
||||||
<span class="hint" style="margin-left:10px">PPh Badan, PPN, USO & BHP dihitung otomatis dari nilai ini.</span>
|
<span class="hint" style="margin-left:10px"><%- t('admin.rep.tax_hint','PPh Badan, PPN, USO & BHP dihitung otomatis dari nilai ini.') %></span>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -556,7 +556,7 @@
|
|||||||
|
|
||||||
<!-- TAB 2: RouterOS Manual Script (.rsc) -->
|
<!-- TAB 2: RouterOS Manual Script (.rsc) -->
|
||||||
<div id="isolir-tab-script" style="display:none;">
|
<div id="isolir-tab-script" style="display:none;">
|
||||||
<p class="small text-muted mb-2">Script ini di-generate otomatis berdasarkan IP server & URL billing (app_url). Anda dapat menyalin dan menempelkannya di Winbox Terminal MikroTik.</p>
|
<p class="small text-muted mb-2"><%= t('admin.rt.script_hint','Script ini di-generate otomatis berdasarkan IP server & URL billing (app_url). Anda dapat menyalin dan menempelkannya di Winbox Terminal MikroTik.') %></p>
|
||||||
<div id="isolir-script-meta" class="small text-muted mb-2 fw-bold" style="color:#a5b4fc !important;"></div>
|
<div id="isolir-script-meta" class="small text-muted mb-2 fw-bold" style="color:#a5b4fc !important;"></div>
|
||||||
<textarea id="isolir-script-body" class="fc" readonly rows="14" style="width:100%;font-family:ui-monospace,monospace;font-size:12px;background:rgba(15,23,42,0.9);color:#818cf8;border-radius:8px;"></textarea>
|
<textarea id="isolir-script-body" class="fc" readonly rows="14" style="width:100%;font-family:ui-monospace,monospace;font-size:12px;background:rgba(15,23,42,0.9);color:#818cf8;border-radius:8px;"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -543,7 +543,7 @@
|
|||||||
<option value="googlefiber"><%= t('admin.set.sp_googlefiber','Google Fiber Speed Test (eksternal, buka tab)') %></option>
|
<option value="googlefiber"><%= t('admin.set.sp_googlefiber','Google Fiber Speed Test (eksternal, buka tab)') %></option>
|
||||||
<option value="speedtestnet"><%= t('admin.set.sp_speedtestnet','Speedtest.net / Ookla (eksternal, buka tab)') %></option>
|
<option value="speedtestnet"><%= t('admin.set.sp_speedtestnet','Speedtest.net / Ookla (eksternal, buka tab)') %></option>
|
||||||
</select>
|
</select>
|
||||||
<div style="font-size:10px; color:var(--muted); margin-top:4px">Preset hanya mengisi otomatis — sesuaikan URL bila perlu.</div>
|
<div style="font-size:10px; color:var(--muted); margin-top:4px"><%= t('admin.set.speedtest_hint','Preset hanya mengisi otomatis — sesuaikan URL bila perlu.') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl"><%= t('admin.set.speed_link','Link Speed Test') %></label>
|
<label class="fl"><%= t('admin.set.speed_link','Link Speed Test') %></label>
|
||||||
@@ -615,14 +615,14 @@
|
|||||||
<div class="fg" style="margin-top:10px">
|
<div class="fg" style="margin-top:10px">
|
||||||
<label class="fl"><%= t('admin.set.qris_payload','QRIS Static Payload (String)') %></label>
|
<label class="fl"><%= t('admin.set.qris_payload','QRIS Static Payload (String)') %></label>
|
||||||
<textarea class="fc" name="qris_static_payload" rows="3" placeholder="000201010211...6304XXXX"><%= settings.qris_static_payload || '' %></textarea>
|
<textarea class="fc" name="qris_static_payload" rows="3" placeholder="000201010211...6304XXXX"><%= settings.qris_static_payload || '' %></textarea>
|
||||||
<div style="font-size:10px; color:var(--muted); margin-top:4px">Jika diisi, sistem akan membuat QRIS dinamis per transaksi (nominal langsung terisi saat scan). Jika kosong, sistem pakai URL gambar seperti biasa.</div>
|
<div style="font-size:10px; color:var(--muted); margin-top:4px"><%= t('admin.set.qris_dyn_hint','Jika diisi, sistem akan membuat QRIS dinamis per transaksi (nominal langsung terisi saat scan). Jika kosong, sistem pakai URL gambar seperti biasa.') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top:10px">
|
<div style="margin-top:10px">
|
||||||
<div style="display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap">
|
<div style="display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap">
|
||||||
<div class="fg" style="min-width:260px; flex: 1 1 260px">
|
<div class="fg" style="min-width:260px; flex: 1 1 260px">
|
||||||
<label class="fl"><%= t('admin.set.qris_upload','Upload Gambar QRIS (opsional)') %></label>
|
<label class="fl"><%= t('admin.set.qris_upload','Upload Gambar QRIS (opsional)') %></label>
|
||||||
<input class="fc" type="file" id="qris_upload_file" name="qris_file" accept="image/png,image/jpeg,image/jpg,image/webp">
|
<input class="fc" type="file" id="qris_upload_file" name="qris_file" accept="image/png,image/jpeg,image/jpg,image/webp">
|
||||||
<div style="font-size:10px; color:var(--muted); margin-top:4px">Jika di-upload, sistem akan menyimpan file dan otomatis mengisi URL QRIS.</div>
|
<div style="font-size:10px; color:var(--muted); margin-top:4px"><%= t('admin.set.qris_upload_hint','Jika di-upload, sistem akan menyimpan file dan otomatis mengisi URL QRIS.') %></div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-s" type="button" id="qris_upload_btn" style="height:38px"><i class="bi bi-upload"></i> Upload</button>
|
<button class="btn btn-s" type="button" id="qris_upload_btn" style="height:38px"><i class="bi bi-upload"></i> Upload</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -727,7 +727,7 @@
|
|||||||
<label class="fl"><%= t('admin.set.ewallet_list','E-Wallet (1 per baris: Nama|Nomor|Atas Nama)') %></label>
|
<label class="fl"><%= t('admin.set.ewallet_list','E-Wallet (1 per baris: Nama|Nomor|Atas Nama)') %></label>
|
||||||
<textarea class="fc" name="payment_ewallet_accounts" rows="3" placeholder="DANA|08123456789|Admin OPEN-ISP"><%= settings.payment_ewallet_accounts || '' %></textarea>
|
<textarea class="fc" name="payment_ewallet_accounts" rows="3" placeholder="DANA|08123456789|Admin OPEN-ISP"><%= settings.payment_ewallet_accounts || '' %></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size:10px; color:var(--muted); margin-top:4px">Nominal & kode unik sama seperti QRIS; verifikasi otomatis (webhook forwarder) + manual (upload bukti).</div>
|
<div style="font-size:10px; color:var(--muted); margin-top:4px"><%- t('admin.set.bank_hint','Nominal & kode unik sama seperti QRIS; verifikasi otomatis (webhook forwarder) + manual (upload bukti).') %></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Hubungkan Webhook Notifikasi E-Wallet (Mode 2) -->
|
<!-- Hubungkan Webhook Notifikasi E-Wallet (Mode 2) -->
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ document.addEventListener('click', function(e) {
|
|||||||
const allPhotos = [...customerPhotos, ...techPhotos];
|
const allPhotos = [...customerPhotos, ...techPhotos];
|
||||||
|
|
||||||
if (allPhotos.length === 0) {
|
if (allPhotos.length === 0) {
|
||||||
gallery.innerHTML = '<div class="col-12 text-center text-muted">Tidak ada foto</div>';
|
gallery.innerHTML = '<div class="col-12 text-center text-muted"><%= t('admin.tk.no_photo','Tidak ada foto') %></div>';
|
||||||
} else {
|
} else {
|
||||||
// Customer photos first
|
// Customer photos first
|
||||||
if (customerPhotos.length > 0) {
|
if (customerPhotos.length > 0) {
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
<div class="fg">
|
<div class="fg">
|
||||||
<label class="fl">Status Paket *</label>
|
<label class="fl">Status Paket *</label>
|
||||||
<select class="fc" id="form_is_active" required>
|
<select class="fc" id="form_is_active" required>
|
||||||
<option value="1">Aktif (Tampil di portal pelanggan)</option>
|
<option value="1"><%= t('admin.vp.opt_active','Aktif (Tampil di portal pelanggan)') %></option>
|
||||||
<option value="0">Nonaktif (Sembunyikan)</option>
|
<option value="0">Nonaktif (Sembunyikan)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
|
|
||||||
const list = document.getElementById('packages-list');
|
const list = document.getElementById('packages-list');
|
||||||
if (currentPackages.length === 0) {
|
if (currentPackages.length === 0) {
|
||||||
list.innerHTML = '<tr><td colspan="9" class="text-center text-muted" style="padding: 24px;">Belum ada paket voucher hotspot real-time terdaftar. Klik tombol Tambah diatas untuk memulai!</td></tr>';
|
list.innerHTML = '<tr><td colspan="9" class="text-center text-muted" style="padding: 24px;"><%= t('admin.vp.empty','Belum ada paket voucher hotspot real-time terdaftar. Klik tombol Tambah diatas untuk memulai!') %></td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
document.getElementById('form_validity').value = meta.validity;
|
document.getElementById('form_validity').value = meta.validity;
|
||||||
hintEl.innerHTML = `<span style="color:var(--success)"><b>Terdeteksi:</b> Harga Rp ${meta.price.toLocaleString('id-ID')} • Durasi ${meta.validity}</span>`;
|
hintEl.innerHTML = `<span style="color:var(--success)"><b>Terdeteksi:</b> Harga Rp ${meta.price.toLocaleString('id-ID')} • Durasi ${meta.validity}</span>`;
|
||||||
} else {
|
} else {
|
||||||
hintEl.innerHTML = '<span class="text-muted">Profil tidak memiliki metadata Mikhmon. Isi harga dan masa aktif manual.</span>';
|
hintEl.innerHTML = '<span class="text-muted"><%= t('admin.vp.no_meta','Profil tidak memiliki metadata Mikhmon. Isi harga dan masa aktif manual.') %></span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@
|
|||||||
<div style="font-size:11px;color:var(--muted);margin-top:4px">Default REST GOWA port <code>3000</code>. Jalankan: <code>whatsapp rest</code>.</div>
|
<div style="font-size:11px;color:var(--muted);margin-top:4px">Default REST GOWA port <code>3000</code>. Jalankan: <code>whatsapp rest</code>.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fg" style="flex:1;">
|
<div class="fg" style="flex:1;">
|
||||||
<label class="fl">Device ID (opsional)</label>
|
<label class="fl"><%= t('admin.wa.ph_deviceid','Device ID (opsional)') %></label>
|
||||||
<input class="fc" name="gowa_device_id" value="<%= gowaSettings.gowa_device_id %>" placeholder="multi-device (mis. device1)">
|
<input class="fc" name="gowa_device_id" value="<%= gowaSettings.gowa_device_id %>" placeholder="multi-device (mis. device1)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ async function loadChatMessages(phone, showSpinner = false) {
|
|||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
const messages = data.messages || [];
|
const messages = data.messages || [];
|
||||||
if (messages.length === 0) {
|
if (messages.length === 0) {
|
||||||
container.innerHTML = `<div class="text-center text-muted" style="margin:auto;">Belum ada pesan dengan pelanggan ini. Ketik pesan di bawah dan tekan Enter untuk memulai.</div>`;
|
container.innerHTML = `<div class="text-center text-muted" style="margin:auto;"><%= t('admin.wlc.empty','Belum ada pesan dengan pelanggan ini. Ketik pesan di bawah dan tekan Enter untuk memulai.') %></div>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<label class="fl"><%= t('admin.wt.lbl_reminder','Template Pengingat Tagihan (Bulanan / Manual)') %></label>
|
<label class="fl"><%= t('admin.wt.lbl_reminder','Template Pengingat Tagihan (Bulanan / Manual)') %></label>
|
||||||
<textarea class="fc" id="tmpl_auto_billing" name="whatsapp_auto_billing_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_auto_billing_message %></textarea>
|
<textarea class="fc" id="tmpl_auto_billing" name="whatsapp_auto_billing_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_auto_billing_message %></textarea>
|
||||||
<div style="font-size: 11px; color: var(--muted); margin-top: 6px; display:flex; justify-between; align-items:center;">
|
<div style="font-size: 11px; color: var(--muted); margin-top: 6px; display:flex; justify-between; align-items:center;">
|
||||||
<span><i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)">(Username PPPoE, opsional)</span>, <b>{{nama}}</b>, <b>{{tagihan}}</b>, <b>{{rincian}}</b>, <b>{{paket}}</b>, <b>{{link}}</b>.</span>
|
<span><i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)"><%= t('admin.wt.ph_user','(Username PPPoE, opsional)') %></span>, <b>{{nama}}</b>, <b>{{tagihan}}</b>, <b>{{rincian}}</b>, <b>{{paket}}</b>, <b>{{link}}</b>.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<label class="fl"><%= t('admin.wt.lbl_qris','Template Tagihan QRIS (Manual)') %></label>
|
<label class="fl"><%= t('admin.wt.lbl_qris','Template Tagihan QRIS (Manual)') %></label>
|
||||||
<textarea class="fc" id="tmpl_billing_qris" name="whatsapp_billing_qris_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_billing_qris_message %></textarea>
|
<textarea class="fc" id="tmpl_billing_qris" name="whatsapp_billing_qris_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_billing_qris_message %></textarea>
|
||||||
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
||||||
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)">(Username PPPoE, opsional)</span>, <b>{{nama}}</b>, <b>{{periode}}</b>, <b>{{paket}}</b>, <b>{{qris_nominal}}</b>, <b>{{qris_kode}}</b>, <b>{{qris_qr}}</b>.
|
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)"><%= t('admin.wt.ph_user','(Username PPPoE, opsional)') %></span>, <b>{{nama}}</b>, <b>{{periode}}</b>, <b>{{paket}}</b>, <b>{{qris_nominal}}</b>, <b>{{qris_kode}}</b>, <b>{{qris_qr}}</b>.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<label class="fl"><%= t('admin.wt.lbl_success','Template Pembayaran Sukses (Lunas)') %></label>
|
<label class="fl"><%= t('admin.wt.lbl_success','Template Pembayaran Sukses (Lunas)') %></label>
|
||||||
<textarea class="fc" id="tmpl_payment_success" name="whatsapp_payment_success_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_payment_success_message %></textarea>
|
<textarea class="fc" id="tmpl_payment_success" name="whatsapp_payment_success_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_payment_success_message %></textarea>
|
||||||
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
||||||
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)">(Username PPPoE, opsional)</span>, <b>{{nama}}</b>, <b>{{no_invoice}}</b>, <b>{{paket}}</b>, <b>{{periode}}</b>, <b>{{waktu}}</b>, <b>{{metode}}</b>, <b>{{total}}</b>, <b>{{company}}</b>, <b>{{company_phone}}</b>, <b>{{link_portal}}</b>, <b>{{link_pdf}}</b> (link PDF invoice).
|
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)"><%= t('admin.wt.ph_user','(Username PPPoE, opsional)') %></span>, <b>{{nama}}</b>, <b>{{no_invoice}}</b>, <b>{{paket}}</b>, <b>{{periode}}</b>, <b>{{waktu}}</b>, <b>{{metode}}</b>, <b>{{total}}</b>, <b>{{company}}</b>, <b>{{company_phone}}</b>, <b>{{link_portal}}</b>, <b>{{link_pdf}}</b> (link PDF invoice).
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<label class="fl"><%= t('admin.wt.lbl_isolir','Template Pemberitahuan Isolir (Otomatis / Manual)') %></label>
|
<label class="fl"><%= t('admin.wt.lbl_isolir','Template Pemberitahuan Isolir (Otomatis / Manual)') %></label>
|
||||||
<textarea class="fc" id="tmpl_isolir" name="whatsapp_isolir_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_isolir_message %></textarea>
|
<textarea class="fc" id="tmpl_isolir" name="whatsapp_isolir_message" rows="8" required style="width: 100%;"><%= templates.whatsapp_isolir_message %></textarea>
|
||||||
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
<div style="font-size: 11px; color: var(--muted); margin-top: 6px;">
|
||||||
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)">(Username PPPoE, opsional)</span>, <b>{{nama}}</b>, <b>{{paket}}</b>, <b>{{tagihan}}</b>, <b>{{link}}</b>.
|
<i class="bi bi-info-circle"></i> Variabel: <b style="color:var(--primary)">{{id_pelanggan}}</b> <span style="color:var(--primary)"><%= t('common.required','(wajib)') %></span>, <b style="color:var(--primary)">{{pppoe}}</b> <span style="color:var(--muted)"><%= t('admin.wt.ph_user','(Username PPPoE, opsional)') %></span>, <b>{{nama}}</b>, <b>{{paket}}</b>, <b>{{tagihan}}</b>, <b>{{link}}</b>.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
<button type="button" class="btn btn-primary btn-sm" onclick="fillOfficialReceiptPreset()"><i class="bi bi-receipt-cutoff"></i> Muat Template Struk Resmi Lengkap</button>
|
<button type="button" class="btn btn-primary btn-sm" onclick="fillOfficialReceiptPreset()"><i class="bi bi-receipt-cutoff"></i> Muat Template Struk Resmi Lengkap</button>
|
||||||
<button type="button" class="btn btn-g btn-sm" onclick="fillSpintaxPreset()"><i class="bi bi-magic"></i> Muat Template Ringkas (Spintax Anti-Ban)</button>
|
<button type="button" class="btn btn-g btn-sm" onclick="fillSpintaxPreset()"><i class="bi bi-magic"></i> Muat Template Ringkas (Spintax Anti-Ban)</button>
|
||||||
<button type="button" class="btn btn-w btn-sm" onclick="showMetaConverter()"><i class="bi bi-meta"></i> <i class="bi bi-magic"></i> <%= t('admin.wt.convert','Konversi Format Meta Cloud API') %></button>
|
<button type="button" class="btn btn-w btn-sm" onclick="showMetaConverter()"><i class="bi bi-meta"></i> <i class="bi bi-magic"></i> <%= t('admin.wt.convert','Konversi Format Meta Cloud API') %></button>
|
||||||
<div style="flex-basis:100%; font-size:11.5px; color:var(--muted); margin-top:4px"><i class="bi bi-exclamation-circle" style="color:var(--primary)"></i> Setiap template <b>wajib menyertakan variabel ID Pelanggan</b> <b style="color:var(--primary)">{{id_pelanggan}}</b>.</div>
|
<div style="flex-basis:100%; font-size:11.5px; color:var(--muted); margin-top:4px"><i class="bi bi-exclamation-circle" style="color:var(--primary)"></i> Setiap template <b><%= t('admin.wt.warn_custid','wajib menyertakan variabel ID Pelanggan') %></b> <b style="color:var(--primary)">{{id_pelanggan}}</b>.</div>
|
||||||
<div id="presetStatus" style="flex-basis:100%; font-size:12px; display:none"></div>
|
<div id="presetStatus" style="flex-basis:100%; font-size:12px; display:none"></div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-p"><i class="bi bi-save"></i> <%= t('admin.wt.save','Simpan Template') %></button>
|
<button type="submit" class="btn btn-p"><i class="bi bi-save"></i> <%= t('admin.wt.save','Simpan Template') %></button>
|
||||||
|
|||||||
Reference in new issue
Block a user