diff --git a/manual/Manual_Pengguna_eCert_MBIP.docx b/manual/Manual_Pengguna_eCert_MBIP.docx new file mode 100644 index 0000000..d02d9bd Binary files /dev/null and b/manual/Manual_Pengguna_eCert_MBIP.docx differ diff --git a/manual/generate_manual.py b/manual/generate_manual.py new file mode 100644 index 0000000..5c340a9 --- /dev/null +++ b/manual/generate_manual.py @@ -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}") diff --git a/manual/~$nual_Pengguna_eCert_MBIP.docx b/manual/~$nual_Pengguna_eCert_MBIP.docx new file mode 100644 index 0000000..1a25f7e Binary files /dev/null and b/manual/~$nual_Pengguna_eCert_MBIP.docx differ diff --git a/src/resources/views/admin/programs/_form.blade.php b/src/resources/views/admin/programs/_form.blade.php index 6fe660f..2e5ec33 100644 --- a/src/resources/views/admin/programs/_form.blade.php +++ b/src/resources/views/admin/programs/_form.blade.php @@ -39,7 +39,7 @@ + placeholder="Contoh: Dewan Utama MBIP"> @error('location')
{{ $message }}
@enderror diff --git a/src/resources/views/admin/programs/_form.blade.php.bak b/src/resources/views/admin/programs/_form.blade.php.bak new file mode 100644 index 0000000..6fe660f --- /dev/null +++ b/src/resources/views/admin/programs/_form.blade.php.bak @@ -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) +--}} +
+ @csrf + @isset($method) @method($method) @endisset + +
+ + {{-- ── Maklumat Asas ── --}} +
+
+
+ Maklumat Asas +
+
+
+
+ + + @error('title')
{{ $message }}
@enderror +
+ +
+ + + @error('organizer')
{{ $message }}
@enderror +
+ +
+ + + @error('location')
{{ $message }}
@enderror +
+ +
+ + + @error('description')
{{ $message }}
@enderror +
+
+
+
+
+ + {{-- ── Tarikh & Masa ── --}} +
+
+
+ Tarikh & Masa +
+
+
+
+ + + @error('start_date')
{{ $message }}
@enderror +
+
+ + + @error('end_date')
{{ $message }}
@enderror +
+ +

Tempoh Check-In (kosongkan jika tidak ditetapkan)

+ +
+ + + @error('checkin_start_at')
{{ $message }}
@enderror +
+
+ + + @error('checkin_end_at')
{{ $message }}
@enderror +
+ +

Tempoh Download eCert (kosongkan jika tidak ditetapkan)

+ +
+ + + @error('ecert_download_start_at')
{{ $message }}
@enderror +
+
+ + + @error('ecert_download_end_at')
{{ $message }}
@enderror +
+
+
+
+
+ + {{-- ── Tetapan Kehadiran ── --}} +
+
+
+ Tetapan Kehadiran +
+
+
+
+
+ + allow_walk_in ?? true) ? 'checked' : '' }}> + +
+
Orang luar boleh daftar sendiri semasa program.
+
+ +
+ + + @error('default_staff_session')
{{ $message }}
@enderror +
+ +
+ + + @error('default_external_session')
{{ $message }}
@enderror +
+
+
+
+
+ + {{-- ── Butang Submit ── --}} +
+ + Batal + + +
+
+
diff --git a/src/resources/views/auth/forgot-password.blade.php b/src/resources/views/auth/forgot-password.blade.php index e6d9898..b1c84c3 100644 --- a/src/resources/views/auth/forgot-password.blade.php +++ b/src/resources/views/auth/forgot-password.blade.php @@ -3,7 +3,7 @@ - Terlupa Kata Laluan — eCert MBIP + Terlupa Kata Laluan — mySijil@MBIP @vite(['resources/css/app.css', 'resources/js/app.js'])