tukar nama MB Ipoh Perak kepada MBIP
This commit is contained in:
BIN
manual/Manual_Pengguna_eCert_MBIP.docx
Normal file
BIN
manual/Manual_Pengguna_eCert_MBIP.docx
Normal file
Binary file not shown.
722
manual/generate_manual.py
Normal file
722
manual/generate_manual.py
Normal file
@@ -0,0 +1,722 @@
|
|||||||
|
"""
|
||||||
|
Penjana Manual Pengguna eCert MBIP
|
||||||
|
Format: Microsoft Word (.docx)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from docx import Document
|
||||||
|
from docx.shared import Pt, Cm, RGBColor, Inches
|
||||||
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||||||
|
from docx.enum.table import WD_TABLE_ALIGNMENT
|
||||||
|
from docx.oxml.ns import qn
|
||||||
|
from docx.oxml import OxmlElement
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
BASE_URL = "https://mysijil.mbip.my"
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
|
||||||
|
# ── Margin halaman ────────────────────────────────────────────────────────────
|
||||||
|
for section in doc.sections:
|
||||||
|
section.top_margin = Cm(2.5)
|
||||||
|
section.bottom_margin = Cm(2.5)
|
||||||
|
section.left_margin = Cm(3.0)
|
||||||
|
section.right_margin = Cm(2.5)
|
||||||
|
|
||||||
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||||
|
def add_heading(text, level=1):
|
||||||
|
h = doc.add_heading(text, level=level)
|
||||||
|
h.runs[0].font.color.rgb = RGBColor(0x1a, 0x3a, 0x6b)
|
||||||
|
return h
|
||||||
|
|
||||||
|
def add_body(text):
|
||||||
|
p = doc.add_paragraph(text)
|
||||||
|
p.runs[0].font.size = Pt(11)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def add_bullet(text):
|
||||||
|
p = doc.add_paragraph(text, style='List Bullet')
|
||||||
|
p.runs[0].font.size = Pt(11)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def add_screenshot_box(caption, url, height_cm=7):
|
||||||
|
"""Kotak placeholder untuk tangkapan skrin."""
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
# Jadual satu sel sebagai kotak
|
||||||
|
tbl = doc.add_table(rows=1, cols=1)
|
||||||
|
tbl.alignment = WD_TABLE_ALIGNMENT.CENTER
|
||||||
|
cell = tbl.cell(0, 0)
|
||||||
|
|
||||||
|
# Warna latar
|
||||||
|
tc = cell._tc
|
||||||
|
tcPr = tc.get_or_add_tcPr()
|
||||||
|
shd = OxmlElement('w:shd')
|
||||||
|
shd.set(qn('w:val'), 'clear')
|
||||||
|
shd.set(qn('w:color'), 'auto')
|
||||||
|
shd.set(qn('w:fill'), 'EEF2FF')
|
||||||
|
tcPr.append(shd)
|
||||||
|
|
||||||
|
# Tinggi sel
|
||||||
|
trPr = tbl.rows[0]._tr.get_or_add_trPr()
|
||||||
|
trHeight = OxmlElement('w:trHeight')
|
||||||
|
trHeight.set(qn('w:val'), str(int(height_cm * 567)))
|
||||||
|
trHeight.set(qn('w:hRule'), 'exact')
|
||||||
|
trPr.append(trHeight)
|
||||||
|
|
||||||
|
# Teks dalam kotak
|
||||||
|
p = cell.paragraphs[0]
|
||||||
|
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
run = p.add_run(f"\n\n[ TANGKAPAN SKRIN ]\n\n{caption}")
|
||||||
|
run.font.size = Pt(10)
|
||||||
|
run.font.color.rgb = RGBColor(0x64, 0x74, 0x8B)
|
||||||
|
run.font.italic = True
|
||||||
|
|
||||||
|
# Label URL
|
||||||
|
p2 = doc.add_paragraph()
|
||||||
|
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
run2 = p2.add_run(f"URL: {url}")
|
||||||
|
run2.font.size = Pt(9)
|
||||||
|
run2.font.color.rgb = RGBColor(0x1a, 0x56, 0xa0)
|
||||||
|
run2.font.italic = True
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
def add_note(text):
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.add_run("Nota: ").bold = True
|
||||||
|
run = p.add_run(text)
|
||||||
|
run.font.size = Pt(10)
|
||||||
|
run.font.italic = True
|
||||||
|
p.paragraph_format.left_indent = Cm(0.5)
|
||||||
|
|
||||||
|
def page_break():
|
||||||
|
doc.add_page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# HALAMAN TAJUK
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
doc.add_paragraph()
|
||||||
|
doc.add_paragraph()
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
t = doc.add_paragraph("eCert MBIP")
|
||||||
|
t.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
r = t.runs[0]
|
||||||
|
r.font.size = Pt(32)
|
||||||
|
r.font.bold = True
|
||||||
|
r.font.color.rgb = RGBColor(0x1a, 0x3a, 0x6b)
|
||||||
|
|
||||||
|
t2 = doc.add_paragraph("Sistem Pengurusan Sijil Digital")
|
||||||
|
t2.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
r2 = t2.runs[0]
|
||||||
|
r2.font.size = Pt(18)
|
||||||
|
r2.font.color.rgb = RGBColor(0x1a, 0x3a, 0x6b)
|
||||||
|
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
t3 = doc.add_paragraph("MANUAL PENGGUNA — PENTADBIR")
|
||||||
|
t3.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
r3 = t3.runs[0]
|
||||||
|
r3.font.size = Pt(16)
|
||||||
|
r3.font.bold = True
|
||||||
|
r3.font.color.rgb = RGBColor(0x55, 0x55, 0x55)
|
||||||
|
|
||||||
|
doc.add_paragraph()
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
t4 = doc.add_paragraph("Majlis Bandaraya Ipoh Perak (MBIP)")
|
||||||
|
t4.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
t4.runs[0].font.size = Pt(12)
|
||||||
|
|
||||||
|
t5 = doc.add_paragraph(f"Versi 1.0 · {datetime.date.today().strftime('%B %Y')}")
|
||||||
|
t5.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||||
|
t5.runs[0].font.size = Pt(11)
|
||||||
|
t5.runs[0].font.color.rgb = RGBColor(0x88, 0x88, 0x88)
|
||||||
|
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# ISI KANDUNGAN (placeholder manual)
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("Isi Kandungan", level=1)
|
||||||
|
|
||||||
|
toc_items = [
|
||||||
|
("1", "Pengenalan"),
|
||||||
|
("2", "Log Masuk ke Sistem"),
|
||||||
|
("3", "Dashboard Utama"),
|
||||||
|
("4", "Pengurusan Program"),
|
||||||
|
(" 4.1", "Cipta Program Baru"),
|
||||||
|
(" 4.2", "Kemaskini Maklumat Program"),
|
||||||
|
(" 4.3", "Tetapan Check-in dan Muat Turun"),
|
||||||
|
(" 4.4", "Publish dan Tutup Program"),
|
||||||
|
("5", "Pengurusan Peserta"),
|
||||||
|
(" 5.1", "Lihat Senarai Peserta"),
|
||||||
|
(" 5.2", "Tambah Peserta Satu-Satu"),
|
||||||
|
(" 5.3", "Import Peserta dari Excel"),
|
||||||
|
(" 5.4", "Export Senarai Peserta"),
|
||||||
|
("6", "Kod QR Check-in"),
|
||||||
|
("7", "Template Sijil"),
|
||||||
|
(" 7.1", "Muat Naik Template"),
|
||||||
|
(" 7.2", "Konfigurasi Kedudukan Teks"),
|
||||||
|
(" 7.3", "Jana Pratonton Sijil"),
|
||||||
|
("8", "Soalselidik Program"),
|
||||||
|
("9", "Pengurusan Sijil"),
|
||||||
|
("10", "Statistik Program"),
|
||||||
|
("11", "Set Soalselidik"),
|
||||||
|
(" 11.1", "Cipta Set Soalselidik"),
|
||||||
|
(" 11.2", "Tambah dan Urus Soalan"),
|
||||||
|
("12", "Pengurusan Pengguna (Super Admin)"),
|
||||||
|
("13", "Profil Pengguna"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for num, title in toc_items:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(0.5) if num.startswith(" ") else Cm(0)
|
||||||
|
r = p.add_run(f"{num.strip()} {title}")
|
||||||
|
r.font.size = Pt(11)
|
||||||
|
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 1: PENGENALAN
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("1. Pengenalan")
|
||||||
|
add_body(
|
||||||
|
"eCert MBIP ialah sistem pengurusan sijil digital yang dibangunkan untuk Majlis Bandaraya Ipoh Perak (MBIP). "
|
||||||
|
"Sistem ini membolehkan pentadbir mengurus program, menguruskan peserta, menjana sijil digital secara automatik, "
|
||||||
|
"dan mengumpul maklum balas peserta melalui soalselidik dalam talian."
|
||||||
|
)
|
||||||
|
doc.add_paragraph()
|
||||||
|
add_body("Fungsi utama sistem:")
|
||||||
|
add_bullet("Pengurusan program dan peserta")
|
||||||
|
add_bullet("Check-in peserta melalui kod QR")
|
||||||
|
add_bullet("Jana dan hantar sijil digital secara automatik")
|
||||||
|
add_bullet("Pengurusan template sijil")
|
||||||
|
add_bullet("Kutipan maklum balas melalui soalselidik")
|
||||||
|
add_bullet("Laporan statistik kehadiran dan penyertaan")
|
||||||
|
doc.add_paragraph()
|
||||||
|
add_body("Manual ini ditujukan kepada pentadbir sistem (Admin dan Super Admin) untuk menggunakan semua fungsi yang tersedia.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 2: LOG MASUK
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("2. Log Masuk ke Sistem")
|
||||||
|
add_body("Untuk mengakses sistem eCert MBIP, pentadbir perlu log masuk menggunakan alamat emel dan kata laluan yang telah diberikan.")
|
||||||
|
doc.add_paragraph()
|
||||||
|
add_body("Langkah-langkah log masuk:")
|
||||||
|
add_bullet(f"Buka pelayar web dan pergi ke: {BASE_URL}/login")
|
||||||
|
add_bullet("Masukkan Alamat Emel yang berdaftar.")
|
||||||
|
add_bullet("Masukkan Kata Laluan.")
|
||||||
|
add_bullet("Klik butang Log Masuk.")
|
||||||
|
doc.add_paragraph()
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Log Masuk — Borang emel dan kata laluan",
|
||||||
|
f"{BASE_URL}/login"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_note(
|
||||||
|
"Jika terlupa kata laluan, klik pautan 'Terlupa Kata Laluan?' di bawah borang log masuk. "
|
||||||
|
"Pautan set semula kata laluan akan dihantar ke alamat emel yang didaftarkan."
|
||||||
|
)
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 3: DASHBOARD
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("3. Dashboard Utama")
|
||||||
|
add_body(
|
||||||
|
"Selepas log masuk, pentadbir akan dibawa ke halaman Dashboard. Dashboard memaparkan ringkasan aktiviti sistem "
|
||||||
|
"termasuk jumlah program aktif, jumlah peserta, dan sijil yang dijana."
|
||||||
|
)
|
||||||
|
doc.add_paragraph()
|
||||||
|
add_body("Elemen pada Dashboard:")
|
||||||
|
add_bullet("Jumlah program yang sedang aktif")
|
||||||
|
add_bullet("Senarai program terkini")
|
||||||
|
add_bullet("Pautan pantas ke fungsi utama")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Dashboard Utama — Ringkasan statistik dan senarai program",
|
||||||
|
f"{BASE_URL}/admin/dashboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_body("Bar navigasi di sebelah kiri (sidebar) menyediakan akses pantas ke semua modul sistem.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 4: PENGURUSAN PROGRAM
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("4. Pengurusan Program")
|
||||||
|
add_body(
|
||||||
|
"Modul Program adalah teras sistem eCert MBIP. Setiap program mewakili satu acara atau kursus yang dianjurkan. "
|
||||||
|
"Pentadbir boleh mencipta, mengemaskini, dan mengurus status program dari modul ini."
|
||||||
|
)
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Senarai Program — Semua program yang telah dicipta",
|
||||||
|
f"{BASE_URL}/admin/programs"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4.1
|
||||||
|
add_heading("4.1 Cipta Program Baru", level=2)
|
||||||
|
add_body("Langkah-langkah mencipta program baru:")
|
||||||
|
add_bullet("Klik butang + Cipta Program di halaman Senarai Program.")
|
||||||
|
add_bullet("Isi maklumat program:")
|
||||||
|
|
||||||
|
fields_program = [
|
||||||
|
("Tajuk Program", "Nama program atau acara (wajib)"),
|
||||||
|
("Penerangan", "Huraian ringkas program"),
|
||||||
|
("Tarikh Mula / Tamat", "Tarikh pelaksanaan program"),
|
||||||
|
("Lokasi", "Tempat program diadakan"),
|
||||||
|
("Benarkan Walk-in", "Aktifkan jika peserta luar dibenarkan daftar semasa check-in"),
|
||||||
|
]
|
||||||
|
for field, desc in fields_program:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(1)
|
||||||
|
r1 = p.add_run(f"{field}: ")
|
||||||
|
r1.bold = True
|
||||||
|
r1.font.size = Pt(11)
|
||||||
|
p.add_run(desc).font.size = Pt(11)
|
||||||
|
|
||||||
|
add_bullet("Klik Simpan untuk menyimpan program.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Borang Cipta Program Baru — Isi maklumat program",
|
||||||
|
f"{BASE_URL}/admin/programs/create"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4.2
|
||||||
|
add_heading("4.2 Kemaskini Maklumat Program", level=2)
|
||||||
|
add_body(
|
||||||
|
"Untuk mengedit program sedia ada, klik ikon Edit (pensel) pada senarai program atau klik nama program "
|
||||||
|
"kemudian pilih tab Butiran."
|
||||||
|
)
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Butiran Program — Tab maklumat, peserta, template, soalselidik, sijil",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4.3
|
||||||
|
add_heading("4.3 Tetapan Check-in dan Muat Turun", level=2)
|
||||||
|
add_body("Pentadbir perlu menetapkan waktu check-in dan tempoh muat turun sijil dalam tetapan program:")
|
||||||
|
|
||||||
|
settings_table = [
|
||||||
|
("Mula Check-in", "Tarikh dan masa check-in dibuka untuk peserta"),
|
||||||
|
("Tamat Check-in", "Tarikh dan masa check-in ditutup"),
|
||||||
|
("Mula Muat Turun Sijil", "Peserta boleh muat turun sijil selepas tempoh ini"),
|
||||||
|
("Tamat Muat Turun Sijil", "Tempoh muat turun sijil tamat"),
|
||||||
|
]
|
||||||
|
for field, desc in settings_table:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(1)
|
||||||
|
r1 = p.add_run(f"{field}: ")
|
||||||
|
r1.bold = True
|
||||||
|
r1.font.size = Pt(11)
|
||||||
|
p.add_run(desc).font.size = Pt(11)
|
||||||
|
|
||||||
|
add_note("Semua masa menggunakan waktu Malaysia (MYT, UTC+8).")
|
||||||
|
|
||||||
|
# 4.4
|
||||||
|
add_heading("4.4 Publish dan Tutup Program", level=2)
|
||||||
|
add_body("Program perlu di-publish sebelum peserta dapat menggunakan pautan check-in QR.")
|
||||||
|
add_bullet("Klik butang Publish untuk mengaktifkan program. Status bertukar kepada Aktif.")
|
||||||
|
add_bullet("Klik butang Tutup untuk menamatkan program. Peserta tidak lagi dapat check-in.")
|
||||||
|
add_note("Program yang telah ditutup tidak boleh dibuka semula secara automatik.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 5: PENGURUSAN PESERTA
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("5. Pengurusan Peserta")
|
||||||
|
add_body("Modul Peserta membolehkan pentadbir mengurus senarai peserta bagi setiap program.")
|
||||||
|
|
||||||
|
# 5.1
|
||||||
|
add_heading("5.1 Lihat Senarai Peserta", level=2)
|
||||||
|
add_body("Klik tab Peserta dalam halaman butiran program untuk melihat semua peserta berdaftar.")
|
||||||
|
add_body("Maklumat yang dipaparkan:")
|
||||||
|
add_bullet("Nama peserta")
|
||||||
|
add_bullet("No. Kad Pengenalan")
|
||||||
|
add_bullet("Status check-in (Hadir / Belum Hadir)")
|
||||||
|
add_bullet("Status sijil (Belum Jana / Dijana / Dihantar)")
|
||||||
|
add_bullet("Sumber pendaftaran (Pra-daftar / Walk-in)")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Senarai Peserta — Status kehadiran dan sijil setiap peserta",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/participants"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5.2
|
||||||
|
add_heading("5.2 Tambah Peserta Satu-Satu", level=2)
|
||||||
|
add_body("Untuk menambah peserta secara manual:")
|
||||||
|
add_bullet("Klik butang + Tambah Peserta.")
|
||||||
|
add_bullet("Isi Nama Penuh dan No. Kad Pengenalan (12 digit).")
|
||||||
|
add_bullet("Isi maklumat tambahan jika perlu (emel, telefon, agensi).")
|
||||||
|
add_bullet("Klik Simpan.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Borang Tambah Peserta — Isi maklumat peserta",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/participants/create"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5.3
|
||||||
|
add_heading("5.3 Import Peserta dari Excel", level=2)
|
||||||
|
add_body("Untuk mendaftar ramai peserta sekaligus:")
|
||||||
|
add_bullet("Klik butang Import Excel.")
|
||||||
|
add_bullet("Muat turun templat Excel yang disediakan.")
|
||||||
|
add_bullet("Isi maklumat peserta dalam templat (Nama, No. KP, Emel, Telefon, Agensi).")
|
||||||
|
add_bullet("Muat naik semula fail Excel yang telah diisi.")
|
||||||
|
add_bullet("Semak ringkasan import dan klik Sahkan.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Import Peserta — Muat naik fail Excel",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/participants/import"
|
||||||
|
)
|
||||||
|
add_note("Sistem akan abaikan baris yang No. KP-nya sudah wujud dalam program yang sama.")
|
||||||
|
|
||||||
|
# 5.4
|
||||||
|
add_heading("5.4 Export Senarai Peserta", level=2)
|
||||||
|
add_body("Klik butang Export Excel untuk memuat turun senarai lengkap peserta beserta status check-in dan sijil ke dalam fail Excel.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 6: KOD QR CHECK-IN
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("6. Kod QR Check-in")
|
||||||
|
add_body(
|
||||||
|
"Setiap program mempunyai Kod QR unik yang digunakan peserta untuk check-in. "
|
||||||
|
"Peserta mengimbas kod ini menggunakan telefon pintar untuk mendaftarkan kehadiran."
|
||||||
|
)
|
||||||
|
add_body("Cara menjana dan menggunakan Kod QR:")
|
||||||
|
add_bullet("Klik tab Kod QR dalam halaman butiran program.")
|
||||||
|
add_bullet("Klik Jana QR Code jika belum dijana.")
|
||||||
|
add_bullet("Paparkan Kod QR pada skrin besar atau cetak untuk peserta mengimbas.")
|
||||||
|
add_bullet("Klik Muat Turun untuk menyimpan imej Kod QR.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Kod QR — Jana, papar, dan muat turun QR Code",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/qr"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_note(
|
||||||
|
"Kod QR boleh dinyahaktifkan (Deactivate) dan dijana semula jika diperlukan. "
|
||||||
|
"Kod lama tidak akan berfungsi selepas dinyahaktifkan."
|
||||||
|
)
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 7: TEMPLATE SIJIL
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("7. Template Sijil")
|
||||||
|
add_body(
|
||||||
|
"Modul Template Sijil membolehkan pentadbir menyediakan reka bentuk sijil yang akan digunakan "
|
||||||
|
"untuk menjana sijil digital peserta."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 7.1
|
||||||
|
add_heading("7.1 Muat Naik Template", level=2)
|
||||||
|
add_body("Langkah-langkah muat naik template sijil:")
|
||||||
|
add_bullet("Klik tab Template Sijil dalam halaman butiran program.")
|
||||||
|
add_bullet("Klik butang Pilih Fail dan pilih imej template (format JPG atau PNG, maksimum 10MB).")
|
||||||
|
add_bullet("Resolusi disyorkan: 1754 × 1240 piksel (A4 landscape) atau 1240 × 1754 piksel (portrait).")
|
||||||
|
add_bullet("Klik Muat Naik.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Muat Naik Template — Pilih fail imej sijil",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 7.2
|
||||||
|
add_heading("7.2 Konfigurasi Kedudukan Teks", level=2)
|
||||||
|
add_body(
|
||||||
|
"Selepas template dimuat naik, pentadbir perlu menetapkan kedudukan teks pada sijil. "
|
||||||
|
"Koordinat dikira dari sudut kiri atas imej (piksel)."
|
||||||
|
)
|
||||||
|
add_body("Medan yang boleh dikonfigurasi:")
|
||||||
|
|
||||||
|
config_fields = [
|
||||||
|
("Nama Peserta", "Kedudukan X, Y, saiz font, warna, dan penjajaran (kiri/tengah/kanan)"),
|
||||||
|
("No. IC", "Saiz font No. IC yang dipaparkan di bawah nama"),
|
||||||
|
("No. Sijil (Pilihan)", "Aktifkan togol 'Papar' untuk menambah No. Sijil pada sijil. Tetapkan kedudukan X, Y."),
|
||||||
|
]
|
||||||
|
for field, desc in config_fields:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(1)
|
||||||
|
r1 = p.add_run(f"{field}: ")
|
||||||
|
r1.bold = True
|
||||||
|
r1.font.size = Pt(11)
|
||||||
|
p.add_run(desc).font.size = Pt(11)
|
||||||
|
|
||||||
|
add_bullet("Klik Simpan Konfigurasi untuk menyimpan tetapan.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Konfigurasi Template — Tetapkan kedudukan teks nama dan No. Sijil",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 7.3
|
||||||
|
add_heading("7.3 Jana Pratonton Sijil", level=2)
|
||||||
|
add_body("Untuk menyemak kedudukan teks sebelum menjana sijil sebenar:")
|
||||||
|
add_bullet("Masukkan nama contoh dalam kotak Jana Pratonton.")
|
||||||
|
add_bullet("Klik butang Pratonton.")
|
||||||
|
add_bullet("Imej pratonton akan dipaparkan dengan teks pada koordinat yang ditetapkan.")
|
||||||
|
add_note("Pratonton menggunakan nilai koordinat terkini walaupun belum disimpan.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 8: SOALSELIDIK PROGRAM
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("8. Soalselidik Program")
|
||||||
|
add_body(
|
||||||
|
"Pentadbir boleh mengaitkan set soalselidik dengan program. Peserta akan diminta mengisi soalselidik "
|
||||||
|
"selepas check-in sebelum sijil boleh dimuat turun."
|
||||||
|
)
|
||||||
|
add_body("Cara mengaitkan soalselidik dengan program:")
|
||||||
|
add_bullet("Klik tab Soalselidik dalam halaman butiran program.")
|
||||||
|
add_bullet("Pilih Set Soalselidik yang ingin digunakan daripada senarai tersedia.")
|
||||||
|
add_bullet("Klik Lampirkan Soalselidik.")
|
||||||
|
add_bullet("Klik Sahkan untuk mengesahkan penggunaan soalselidik ini.")
|
||||||
|
add_bullet("Klik Pratonton untuk melihat soalan yang akan dijawab peserta.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Soalselidik Program — Lampirkan dan pratonton soalselidik",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/questionnaire"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_note("Soalselidik yang telah disahkan tidak boleh ditukar. Sah kan hanya apabila sudah pasti.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 9: PENGURUSAN SIJIL
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("9. Pengurusan Sijil")
|
||||||
|
add_body(
|
||||||
|
"Modul Sijil membolehkan pentadbir menjana dan menghantar sijil digital kepada semua peserta yang hadir."
|
||||||
|
)
|
||||||
|
add_body("Fungsi yang tersedia:")
|
||||||
|
add_bullet("Jana Semua Sijil — Menjana sijil untuk semua peserta yang telah check-in.")
|
||||||
|
add_bullet("Hantar Emel Semua — Menghantar sijil kepada peserta melalui emel secara pukal.")
|
||||||
|
add_body("Status sijil setiap peserta:")
|
||||||
|
|
||||||
|
status_sijil = [
|
||||||
|
("Belum Jana", "Sijil belum dijana untuk peserta ini"),
|
||||||
|
("Dijana", "Sijil sudah dijana dan sedia untuk dihantar"),
|
||||||
|
("Dihantar", "Sijil telah dihantar melalui emel"),
|
||||||
|
("Dimuat Turun", "Peserta telah memuat turun sijil mereka"),
|
||||||
|
]
|
||||||
|
for status, desc in status_sijil:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(1)
|
||||||
|
r1 = p.add_run(f"{status}: ")
|
||||||
|
r1.bold = True
|
||||||
|
r1.font.size = Pt(11)
|
||||||
|
p.add_run(desc).font.size = Pt(11)
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Sijil — Senarai sijil dan fungsi jana/hantar pukal",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/certificates"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_note("Pastikan template sijil telah dikonfigurasi terlebih dahulu sebelum menjana sijil.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 10: STATISTIK PROGRAM
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("10. Statistik Program")
|
||||||
|
add_body(
|
||||||
|
"Halaman Statistik memaparkan data analitik terperinci bagi setiap program. "
|
||||||
|
"Pentadbir boleh memantau prestasi program melalui laporan yang disediakan."
|
||||||
|
)
|
||||||
|
add_body("Data yang dipaparkan:")
|
||||||
|
add_bullet("Jumlah peserta berdaftar vs. jumlah yang hadir")
|
||||||
|
add_bullet("Pecahan mengikut sesi (Slot masa check-in)")
|
||||||
|
add_bullet("Pecahan mengikut sumber pendaftaran (Pra-daftar / Walk-in)")
|
||||||
|
add_bullet("Status sijil (Dijana, Dihantar, Dimuat Turun)")
|
||||||
|
add_bullet("Keputusan soalselidik (jika soalselidik dikaitkan)")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Statistik — Graf dan data analitik program",
|
||||||
|
f"{BASE_URL}/admin/programs/{{uuid}}/statistics"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_body("Klik butang Export Excel untuk memuat turun laporan statistik dalam format Excel.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 11: SET SOALSELIDIK
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("11. Set Soalselidik")
|
||||||
|
add_body(
|
||||||
|
"Modul Set Soalselidik membolehkan pentadbir membina borang soalan yang boleh digunakan semula "
|
||||||
|
"merentasi pelbagai program."
|
||||||
|
)
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Senarai Set Soalselidik — Semua set yang telah dicipta",
|
||||||
|
f"{BASE_URL}/admin/questionnaires"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 11.1
|
||||||
|
add_heading("11.1 Cipta Set Soalselidik", level=2)
|
||||||
|
add_body("Langkah-langkah mencipta set soalselidik baru:")
|
||||||
|
add_bullet("Klik butang + Cipta Set Soalselidik.")
|
||||||
|
add_bullet("Masukkan Nama Set dan Penerangan (pilihan).")
|
||||||
|
add_bullet("Klik Simpan.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Borang Cipta Set Soalselidik — Nama dan penerangan",
|
||||||
|
f"{BASE_URL}/admin/questionnaires/create"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 11.2
|
||||||
|
add_heading("11.2 Tambah dan Urus Soalan", level=2)
|
||||||
|
add_body("Selepas set dicipta, tambah soalan melalui halaman butiran set soalselidik.")
|
||||||
|
add_body("Jenis soalan yang tersedia:")
|
||||||
|
|
||||||
|
jenis_soalan = [
|
||||||
|
("Tajuk (Seksyen)", "Pengepala bahagian — boleh menjadi parent kepada soalan Rating"),
|
||||||
|
("Rating (1-5)", "Penilaian skala 1 hingga 5 — mesti diletakkan di bawah Tajuk"),
|
||||||
|
("Pilihan Tunggal", "Peserta pilih satu jawapan sahaja"),
|
||||||
|
("Pilihan Berganda", "Peserta boleh pilih lebih dari satu jawapan"),
|
||||||
|
("Teks Pendek", "Jawapan dalam satu baris"),
|
||||||
|
("Teks Panjang", "Jawapan berbilang baris"),
|
||||||
|
]
|
||||||
|
for jenis, desc in jenis_soalan:
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
p.paragraph_format.left_indent = Cm(1)
|
||||||
|
r1 = p.add_run(f"{jenis}: ")
|
||||||
|
r1.bold = True
|
||||||
|
r1.font.size = Pt(11)
|
||||||
|
p.add_run(desc).font.size = Pt(11)
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Set Soalselidik — Senarai soalan dan borang tambah soalan",
|
||||||
|
f"{BASE_URL}/admin/questionnaires/{{id}}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_body("Ciri-ciri tambahan:")
|
||||||
|
add_bullet("Soalan Rating: Pentadbir boleh tetapkan label teks untuk setiap nilai (1-5) pada peringkat Tajuk.")
|
||||||
|
add_bullet("Susunan soalan boleh diubah dengan seret-dan-lepas (drag-and-drop).")
|
||||||
|
add_bullet("Soalan Rating tidak boleh dipindahkan keluar dari Tajuk induknya.")
|
||||||
|
add_bullet("Tetapkan soalan sebagai Wajib atau tidak wajib.")
|
||||||
|
|
||||||
|
add_note(
|
||||||
|
"Set soalselidik perlu di-Publish sebelum boleh dikaitkan dengan program. "
|
||||||
|
"Selepas di-Publish, soalan tidak boleh diubah."
|
||||||
|
)
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 12: PENGURUSAN PENGGUNA (SUPER ADMIN)
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("12. Pengurusan Pengguna")
|
||||||
|
add_body(
|
||||||
|
"Modul ini hanya boleh diakses oleh Super Admin. "
|
||||||
|
"Super Admin boleh mencipta dan mengurus akaun pentadbir lain dalam sistem."
|
||||||
|
)
|
||||||
|
add_body("Fungsi yang tersedia:")
|
||||||
|
add_bullet("Lihat senarai semua pentadbir")
|
||||||
|
add_bullet("Cipta akaun pentadbir baru")
|
||||||
|
add_bullet("Kemaskini maklumat pentadbir")
|
||||||
|
add_bullet("Padam akaun pentadbir")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Pengurusan Pengguna — Senarai pentadbir (Super Admin sahaja)",
|
||||||
|
f"{BASE_URL}/admin/users"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_body("Jenis peranan pengguna:")
|
||||||
|
add_bullet("Super Admin — Akses penuh termasuk Pengurusan Pengguna")
|
||||||
|
add_bullet("Admin Program — Akses kepada semua program dan soalselidik, kecuali Pengurusan Pengguna")
|
||||||
|
|
||||||
|
add_note("Setiap sistem perlu sekurang-kurangnya satu akaun Super Admin yang aktif.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BAB 13: PROFIL PENGGUNA
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("13. Profil Pengguna")
|
||||||
|
add_body(
|
||||||
|
"Setiap pentadbir boleh mengurus maklumat akaun peribadi mereka melalui halaman Profil. "
|
||||||
|
"Klik nama pengguna atau butang Profil di bar navigasi kiri untuk mengakses halaman ini."
|
||||||
|
)
|
||||||
|
add_body("Fungsi yang tersedia:")
|
||||||
|
|
||||||
|
add_heading("Tukar Alamat Emel", level=2)
|
||||||
|
add_bullet("Masukkan Kata Laluan Semasa untuk pengesahan.")
|
||||||
|
add_bullet("Masukkan Emel Baru.")
|
||||||
|
add_bullet("Klik Kemaskini Emel.")
|
||||||
|
|
||||||
|
add_heading("Tukar Kata Laluan", level=2)
|
||||||
|
add_bullet("Masukkan Kata Laluan Semasa.")
|
||||||
|
add_bullet("Masukkan Kata Laluan Baru (minimum 8 aksara).")
|
||||||
|
add_bullet("Masukkan semula Kata Laluan Baru untuk pengesahan.")
|
||||||
|
add_bullet("Klik Tukar Kata Laluan.")
|
||||||
|
|
||||||
|
add_screenshot_box(
|
||||||
|
"Halaman Profil — Tukar emel dan kata laluan",
|
||||||
|
f"{BASE_URL}/admin/profile"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_note("Kata laluan baru mestilah sekurang-kurangnya 8 aksara. Simpan kata laluan di tempat yang selamat.")
|
||||||
|
page_break()
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# LAMPIRAN: ALIRAN KERJA SISTEM
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
add_heading("Lampiran: Aliran Kerja Tipikal")
|
||||||
|
add_body("Berikut adalah urutan langkah yang disyorkan untuk menjalankan sebuah program dari mula hingga selesai:")
|
||||||
|
|
||||||
|
workflow = [
|
||||||
|
("1", "Cipta Set Soalselidik", "Bina soalan maklum balas di Modul Set Soalselidik dan publish."),
|
||||||
|
("2", "Cipta Program", "Isi maklumat program, tarikh, dan tetapan check-in."),
|
||||||
|
("3", "Import Peserta", "Muat naik senarai peserta melalui Excel."),
|
||||||
|
("4", "Muat Naik Template Sijil", "Upload reka bentuk sijil dan konfigurasi kedudukan teks."),
|
||||||
|
("5", "Lampirkan Soalselidik", "Kaitkan set soalselidik dengan program dan sahkan."),
|
||||||
|
("6", "Publish Program", "Aktifkan program supaya peserta boleh check-in."),
|
||||||
|
("7", "Jana & Papar Kod QR", "Paparkan QR Code semasa acara untuk peserta mengimbas."),
|
||||||
|
("8", "Pantau Statistik", "Semak kehadiran dan maklum balas dalam masa nyata."),
|
||||||
|
("9", "Jana dan Hantar Sijil", "Selepas program tamat, jana sijil dan hantar melalui emel."),
|
||||||
|
]
|
||||||
|
|
||||||
|
tbl = doc.add_table(rows=1, cols=3)
|
||||||
|
tbl.style = 'Table Grid'
|
||||||
|
hdr = tbl.rows[0].cells
|
||||||
|
hdr[0].text = "Langkah"
|
||||||
|
hdr[1].text = "Tindakan"
|
||||||
|
hdr[2].text = "Penerangan"
|
||||||
|
for cell in hdr:
|
||||||
|
cell.paragraphs[0].runs[0].bold = True
|
||||||
|
cell.paragraphs[0].runs[0].font.size = Pt(10)
|
||||||
|
|
||||||
|
for step, action, desc in workflow:
|
||||||
|
row = tbl.add_row().cells
|
||||||
|
row[0].text = step
|
||||||
|
row[1].text = action
|
||||||
|
row[2].text = desc
|
||||||
|
for cell in row:
|
||||||
|
cell.paragraphs[0].runs[0].font.size = Pt(10)
|
||||||
|
|
||||||
|
doc.add_paragraph()
|
||||||
|
add_body(f"Untuk sokongan teknikal, hubungi pentadbir sistem atau lawati: {BASE_URL}")
|
||||||
|
|
||||||
|
# ── Simpan dokumen ─────────────────────────────────────────────────────────────
|
||||||
|
output_path = r"C:\Users\User\Aplikasi\ecert\manual\Manual_Pengguna_eCert_MBIP.docx"
|
||||||
|
doc.save(output_path)
|
||||||
|
print(f"Manual berjaya dijana: {output_path}")
|
||||||
BIN
manual/~$nual_Pengguna_eCert_MBIP.docx
Normal file
BIN
manual/~$nual_Pengguna_eCert_MBIP.docx
Normal file
Binary file not shown.
@@ -39,7 +39,7 @@
|
|||||||
<label class="form-label fw-medium">Lokasi <span class="text-danger">*</span></label>
|
<label class="form-label fw-medium">Lokasi <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="location" class="form-control @error('location') is-invalid @enderror"
|
<input type="text" name="location" class="form-control @error('location') is-invalid @enderror"
|
||||||
value="{{ old('location', $program->location ?? '') }}"
|
value="{{ old('location', $program->location ?? '') }}"
|
||||||
placeholder="Contoh: Dewan Bandaraya Ipoh">
|
placeholder="Contoh: Dewan Utama MBIP">
|
||||||
@error('location')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
@error('location')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
174
src/resources/views/admin/programs/_form.blade.php.bak
Normal file
174
src/resources/views/admin/programs/_form.blade.php.bak
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
{{--
|
||||||
|
Shared form partial.
|
||||||
|
Variables expected:
|
||||||
|
$program — Program model (or null for create)
|
||||||
|
$action — form action URL
|
||||||
|
$method — PUT for edit, omit for create (POST)
|
||||||
|
--}}
|
||||||
|
<form method="POST" action="{{ $action }}">
|
||||||
|
@csrf
|
||||||
|
@isset($method) @method($method) @endisset
|
||||||
|
|
||||||
|
<div class="row g-4">
|
||||||
|
|
||||||
|
{{-- ── Maklumat Asas ── --}}
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom py-3">
|
||||||
|
<span class="fw-semibold"><i class="bi bi-info-circle me-2 text-primary"></i>Maklumat Asas</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-12">
|
||||||
|
<label class="form-label fw-medium">Nama Program <span class="text-danger">*</span></label>
|
||||||
|
<input type="text" name="title" class="form-control @error('title') is-invalid @enderror"
|
||||||
|
value="{{ old('title', $program->title ?? '') }}"
|
||||||
|
placeholder="Contoh: Kursus Pengurusan Projek 2025">
|
||||||
|
@error('title')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Penganjur <span class="text-danger">*</span></label>
|
||||||
|
<input type="text" name="organizer" class="form-control @error('organizer') is-invalid @enderror"
|
||||||
|
value="{{ old('organizer', $program->organizer ?? 'MBIP') }}"
|
||||||
|
placeholder="Contoh: Jabatan Sumber Manusia">
|
||||||
|
@error('organizer')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Lokasi <span class="text-danger">*</span></label>
|
||||||
|
<input type="text" name="location" class="form-control @error('location') is-invalid @enderror"
|
||||||
|
value="{{ old('location', $program->location ?? '') }}"
|
||||||
|
placeholder="Contoh: Dewan Bandaraya Ipoh">
|
||||||
|
@error('location')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<label class="form-label fw-medium">Deskripsi</label>
|
||||||
|
<textarea name="description" rows="3"
|
||||||
|
class="form-control @error('description') is-invalid @enderror"
|
||||||
|
placeholder="Huraian ringkas tentang program...">{{ old('description', $program->description ?? '') }}</textarea>
|
||||||
|
@error('description')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- ── Tarikh & Masa ── --}}
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom py-3">
|
||||||
|
<span class="fw-semibold"><i class="bi bi-calendar-range me-2 text-primary"></i>Tarikh & Masa</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Tarikh Mula <span class="text-danger">*</span></label>
|
||||||
|
<input type="date" name="start_date" class="form-control @error('start_date') is-invalid @enderror"
|
||||||
|
value="{{ old('start_date', isset($program->start_date) ? $program->start_date->format('Y-m-d') : '') }}">
|
||||||
|
@error('start_date')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Tarikh Tamat <span class="text-danger">*</span></label>
|
||||||
|
<input type="date" name="end_date" class="form-control @error('end_date') is-invalid @enderror"
|
||||||
|
value="{{ old('end_date', isset($program->end_date) ? $program->end_date->format('Y-m-d') : '') }}">
|
||||||
|
@error('end_date')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12"><hr class="my-1"><p class="text-muted small mb-2">Tempoh Check-In (kosongkan jika tidak ditetapkan)</p></div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Mula Check-In</label>
|
||||||
|
<input type="datetime-local" name="checkin_start_at"
|
||||||
|
class="form-control @error('checkin_start_at') is-invalid @enderror"
|
||||||
|
value="{{ old('checkin_start_at', isset($program->checkin_start_at) ? $program->checkin_start_at->format('Y-m-d\TH:i') : '') }}">
|
||||||
|
@error('checkin_start_at')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Tamat Check-In</label>
|
||||||
|
<input type="datetime-local" name="checkin_end_at"
|
||||||
|
class="form-control @error('checkin_end_at') is-invalid @enderror"
|
||||||
|
value="{{ old('checkin_end_at', isset($program->checkin_end_at) ? $program->checkin_end_at->format('Y-m-d\TH:i') : '') }}">
|
||||||
|
@error('checkin_end_at')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12"><hr class="my-1"><p class="text-muted small mb-2">Tempoh Download eCert (kosongkan jika tidak ditetapkan)</p></div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Mula Download Sijil</label>
|
||||||
|
<input type="datetime-local" name="ecert_download_start_at"
|
||||||
|
class="form-control @error('ecert_download_start_at') is-invalid @enderror"
|
||||||
|
value="{{ old('ecert_download_start_at', isset($program->ecert_download_start_at) ? $program->ecert_download_start_at->format('Y-m-d\TH:i') : '') }}">
|
||||||
|
@error('ecert_download_start_at')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Tamat Download Sijil</label>
|
||||||
|
<input type="datetime-local" name="ecert_download_end_at"
|
||||||
|
class="form-control @error('ecert_download_end_at') is-invalid @enderror"
|
||||||
|
value="{{ old('ecert_download_end_at', isset($program->ecert_download_end_at) ? $program->ecert_download_end_at->format('Y-m-d\TH:i') : '') }}">
|
||||||
|
@error('ecert_download_end_at')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- ── Tetapan Kehadiran ── --}}
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom py-3">
|
||||||
|
<span class="fw-semibold"><i class="bi bi-person-check me-2 text-primary"></i>Tetapan Kehadiran</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="form-check form-switch mt-2">
|
||||||
|
<input type="hidden" name="allow_walk_in" value="0">
|
||||||
|
<input class="form-check-input" type="checkbox" id="allow_walk_in" name="allow_walk_in" value="1"
|
||||||
|
{{ old('allow_walk_in', $program->allow_walk_in ?? true) ? 'checked' : '' }}>
|
||||||
|
<label class="form-check-label fw-medium" for="allow_walk_in">
|
||||||
|
Benarkan Daftar Walk-in
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="text-muted small mt-1">Orang luar boleh daftar sendiri semasa program.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-medium">Sesi Default (Kakitangan)</label>
|
||||||
|
<select name="default_staff_session" class="form-select @error('default_staff_session') is-invalid @enderror">
|
||||||
|
<option value="">— Pilih Sesi —</option>
|
||||||
|
<option value="pagi" {{ old('default_staff_session', $program->default_staff_session ?? '') === 'pagi' ? 'selected' : '' }}>Pagi</option>
|
||||||
|
<option value="petang" {{ old('default_staff_session', $program->default_staff_session ?? '') === 'petang' ? 'selected' : '' }}>Petang</option>
|
||||||
|
<option value="full_day" {{ old('default_staff_session', $program->default_staff_session ?? '') === 'full_day' ? 'selected' : '' }}>Sehari Penuh</option>
|
||||||
|
</select>
|
||||||
|
@error('default_staff_session')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-medium">Sesi Default (Peserta Luar)</label>
|
||||||
|
<select name="default_external_session" class="form-select @error('default_external_session') is-invalid @enderror">
|
||||||
|
<option value="">— Pilih Sesi —</option>
|
||||||
|
<option value="pagi" {{ old('default_external_session', $program->default_external_session ?? '') === 'pagi' ? 'selected' : '' }}>Pagi</option>
|
||||||
|
<option value="petang" {{ old('default_external_session', $program->default_external_session ?? '') === 'petang' ? 'selected' : '' }}>Petang</option>
|
||||||
|
<option value="full_day" {{ old('default_external_session', $program->default_external_session ?? '') === 'full_day' ? 'selected' : '' }}>Sehari Penuh</option>
|
||||||
|
</select>
|
||||||
|
@error('default_external_session')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- ── Butang Submit ── --}}
|
||||||
|
<div class="col-12 d-flex justify-content-end gap-2">
|
||||||
|
<a href="{{ route('admin.programs.index') }}" class="btn btn-outline-secondary">
|
||||||
|
<i class="bi bi-x-lg me-1"></i> Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary px-4">
|
||||||
|
<i class="bi bi-check-lg me-1"></i>
|
||||||
|
{{ isset($program) ? 'Simpan Perubahan' : 'Tambah Program' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Terlupa Kata Laluan — eCert MBIP</title>
|
<title>Terlupa Kata Laluan — mySijil@MBIP</title>
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="w-100 px-3">
|
<div class="w-100 px-3">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
||||||
<h4 class="text-white fw-bold mt-2 mb-0">eCert MBIP</h4>
|
<h4 class="text-white fw-bold mt-2 mb-0">mySijil@MBIP</h4>
|
||||||
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
<small class="text-white opacity-60">Majlis Bandaraya Ipoh Perak © {{ date('Y') }}</small>
|
<small class="text-white opacity-60">Majlis Bandaraya Iskandar Puteri © {{ date('Y') }}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Log Masuk — eCert MBIP</title>
|
<title>Log Masuk — mySijil@MBIP</title>
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="w-100 px-3">
|
<div class="w-100 px-3">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
||||||
<h4 class="text-white fw-bold mt-2 mb-0">eCert MBIP</h4>
|
<h4 class="text-white fw-bold mt-2 mb-0">mySijil@MBIP</h4>
|
||||||
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
<small class="text-white opacity-60">Majlis Bandaraya Ipoh Perak © {{ date('Y') }}</small>
|
<small class="text-white opacity-60">Majlis Bandaraya Iskandar Puteri © {{ date('Y') }}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Tetapkan Semula Kata Laluan — eCert MBIP</title>
|
<title>Tetapkan Semula Kata Laluan — mySijil@MBIP</title>
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="w-100 px-3">
|
<div class="w-100 px-3">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
<i class="bi bi-award-fill text-white" style="font-size: 3rem;"></i>
|
||||||
<h4 class="text-white fw-bold mt-2 mb-0">eCert MBIP</h4>
|
<h4 class="text-white fw-bold mt-2 mb-0">mySijil@MBIP</h4>
|
||||||
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
<small class="text-white opacity-75">Sistem Pengurusan Sijil Digital</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
<small class="text-white opacity-60">Majlis Bandaraya Ipoh Perak © {{ date('Y') }}</small>
|
<small class="text-white opacity-60">Majlis Bandaraya Iskandar Puteri © {{ date('Y') }}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<button class="btn btn-outline-success w-100 py-3 h-100 type-btn {{ session('show_external_option') ? 'active' : '' }}"
|
<button class="btn btn-outline-success w-100 py-3 h-100 type-btn {{ session('show_external_option') ? 'active' : '' }}"
|
||||||
data-target="external-form" style="border-radius:.75rem;">
|
data-target="external-form" style="border-radius:.75rem;">
|
||||||
<i class="bi bi-person-plus fs-3 d-block mb-2"></i>
|
<i class="bi bi-person-plus fs-3 d-block mb-2"></i>
|
||||||
<div class="fw-semibold">Orang Luar</div>
|
<div class="fw-semibold">Orang Awam</div>
|
||||||
<small class="text-muted d-none d-sm-block">Daftar sekarang</small>
|
<small class="text-muted d-none d-sm-block">Daftar sekarang</small>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user