Files

3124 lines
125 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
definePageMeta({
title: "Mobile Kitchen Sink",
breadcrumb: [
{
name: "Kitchen Sink",
path: "/kitchen-sink",
},
{
name: "Mobile Kitchen Sink",
type: "current",
},
],
});
// Demo data for Asnaf Zakat users (recipients)
const exampleData = ref({
headerTitle: "Dashboard Zakat",
profileExpanded: false,
showNotifications: false,
currentSection: 'dashboard',
previousSection: null,
showBackButton: false,
subSection: null,
// Data untuk metrik utama dashboard
keyMetrics: [
{
title: "Jumlah Agihan Zakat",
value: "RM 284.5 J",
icon: "ic:baseline-volunteer-activism",
change: "positive",
description: "+18.3% berbanding tahun lepas"
},
{
title: "Jumlah Penerima",
value: "412,674",
icon: "ic:baseline-people",
change: "positive",
description: "+12.4% berbanding tahun lepas"
},
{
title: "Kadar Pengagihan",
value: "92.4%",
icon: "ic:baseline-donut-large",
change: "positive",
description: "+3.2% berbanding sasaran"
},
{
title: "Permohonan Diluluskan",
value: "38,245",
icon: "ic:baseline-fact-check",
change: "neutral",
description: "+5.8% berbanding suku tahun"
}
],
// Data untuk kategori agihan zakat mengikut asnaf
asnafDistribution: [
{ category: "Fakir", percentage: 28.5, amount: 81.1 },
{ category: "Miskin", percentage: 32.7, amount: 93.1 },
{ category: "Amil", percentage: 12.5, amount: 35.6 },
{ category: "Muallaf", percentage: 5.8, amount: 16.5 },
{ category: "Gharimin", percentage: 6.2, amount: 17.6 },
{ category: "Fisabilillah", percentage: 10.2, amount: 29.0 },
{ category: "Ibnu Sabil", percentage: 2.4, amount: 6.8 },
{ category: "Riqab", percentage: 1.7, amount: 4.8 }
],
// Data agihan bulanan
monthlyDistribution: [
{
name: "Agihan 2023",
data: [18.5, 19.2, 22.4, 24.8, 26.5, 28.2, 29.4, 31.6, 28.8, 25.4, 16.2, 13.5]
},
{
name: "Agihan 2022",
data: [15.8, 16.4, 19.2, 20.6, 21.8, 23.5, 24.8, 26.3, 24.5, 22.1, 14.6, 11.8]
}
],
// Data program agihan zakat
zakatPrograms: [
{ program: "Bantuan Pendidikan", beneficiaries: 98450, amount: 62.8, disbursed: 93.5 },
{ program: "Bantuan Kesihatan", beneficiaries: 74280, amount: 48.5, disbursed: 87.2 },
{ program: "Bantuan Sara Hidup", beneficiaries: 85640, amount: 52.4, disbursed: 95.8 },
{ program: "Bantuan Perumahan", beneficiaries: 28450, amount: 36.2, disbursed: 82.4 }
],
// Data prestasi KPI
kpiData: [
{ metric: "Kadar Pengagihan Dana Zakat", actual: 92.4, target: 85, status: "Cemerlang" },
{ metric: "Masa Pemprosesan Permohonan", actual: 12, target: 14, status: "Cemerlang" },
{ metric: "Kepuasan Asnaf", actual: 94.2, target: 90, status: "Cemerlang" }
],
demoPages: [
{
id: 'dashboard',
title: 'Utama',
icon: 'ic:outline-home'
},
{
id: 'permohonan',
title: 'Permohonan',
icon: 'ic:outline-article'
},
{
id: 'bantuan',
title: 'Bantuan',
icon: 'ic:outline-volunteer-activism'
},
{
id: 'notifikasi',
title: 'Notifikasi',
icon: 'ic:outline-notifications'
},
{
id: 'profile',
title: 'Profil',
icon: 'ic:outline-person'
}
],
permohonanTabs: [
{ id: 'active', title: 'Aktif' },
{ id: 'draft', title: 'Draf' },
{ id: 'history', title: 'Sejarah' }
],
activeTab: 'active',
showMenu: false,
searchQuery: "",
showEmptyState: false,
isLoading: false,
showFabMenu: false,
// User profile data
userProfile: {
name: "Muhammad bin Daud",
id: "860215-14-5732",
email: "muhammad.daud@example.com",
phone: "019-8765432",
address: "No. 45, Jalan Gemilang, Taman Bahagia, 40100 Shah Alam, Selangor",
position: "Penerima Bantuan",
department: "Asnaf Fakir",
joinDate: "10 Jan 2018",
avatar: "M",
actions: [
{ name: "Tetapan Akaun", icon: "ic:baseline-settings", action: "settings" },
{ name: "Bantuan", icon: "ic:baseline-help-outline", action: "help" },
{ name: "Log Aktiviti", icon: "ic:baseline-history", action: "activity" }
]
},
// Dashboard data
dashboardData: {
totalBantuan: "RM 3,450",
nextPayment: "15 Jun 2023",
bantuanBulan: "RM 700",
totalPendidikan: "RM 200",
announcements: [
{
id: 1,
title: "Program Bantuan Sekolah 2023",
content: "Permohonan bantuan persekolahan untuk anak-anak asnaf kini dibuka sehingga 30 Jun 2023.",
date: "10 Jun 2023",
image: "school-aid.jpg"
},
{
id: 2,
title: "Kursus Kemahiran Digital",
content: "Kursus percuma untuk asnaf yang berminat dalam kemahiran digital. Tempat terhad!",
date: "08 Jun 2023",
image: "digital-course.jpg"
}
],
upcomingEvents: [
{
id: 1,
title: "Agihan Bantuan Ramadan",
date: "20 Jun 2023",
time: "9:00 pagi",
location: "Kompleks Zakat Selangor"
},
{
id: 2,
title: "Sesi Kaunseling Kewangan",
date: "25 Jun 2023",
time: "10:00 pagi",
location: "Pusat Komuniti Petaling Jaya"
}
]
},
// Permohonan (application) data
permohonanData: {
activeApplications: [
{
id: "APP-2023-1234",
pemohon: "Ahmad bin Hassan",
noIC: "901122-14-5523",
alamat: "No. 12, Jalan Maju, 40000 Shah Alam",
telefon: "019-1234567",
type: "Bantuan Pendidikan",
amount: "RM 2,500",
submissionDate: "12 Mei 2023",
status: "DALAM PROSES"
},
{
id: "APP-2023-2345",
pemohon: "Siti Aminah",
noIC: "891215-14-5123",
alamat: "No. 45, Jalan Berjaya, 40100 Shah Alam",
telefon: "012-3456789",
type: "Bantuan Sara Hidup",
amount: "RM 1,200",
submissionDate: "18 Mei 2023",
status: "DALAM PROSES"
},
{
id: "APP-2023-3456",
pemohon: "Kamal bin Johari",
noIC: "850430-14-7851",
alamat: "No. 78, Jalan Harmoni, 40200 Shah Alam",
telefon: "017-9876543",
type: "Bantuan Perniagaan",
amount: "RM 5,000",
submissionDate: "25 Mei 2023",
status: "MENUNGGU"
}
],
draftApplications: [
{
id: "DRAFT-2023-5678",
pemohon: "Zahir bin Omar",
noIC: "880517-14-5123",
type: "Bantuan Pendidikan",
lastUpdated: "15 Mei 2023"
}
],
historicalApplications: [
{
id: "APP-2022-9012",
pemohon: "Farid bin Razali",
noIC: "790222-14-5123",
type: "Bantuan Perniagaan",
amount: "RM 7,500",
submissionDate: "10 Jan 2023",
status: "LULUS"
},
{
id: "APP-2022-3456",
pemohon: "Noraini binti Aziz",
noIC: "881115-14-5553",
type: "Bantuan Perubatan",
amount: "RM 3,200",
submissionDate: "15 Mar 2023",
status: "DITOLAK",
reason: "Dokumen tidak lengkap"
},
{
id: "APP-2022-7890",
pemohon: "Zulkifli bin Hasan",
noIC: "751020-14-7123",
type: "Bantuan Pendidikan",
amount: "RM 1,800",
submissionDate: "22 Feb 2023",
status: "LULUS"
}
],
applicationTypes: [
{ id: "BSH", name: "Bantuan Sara Hidup" },
{ id: "PEND", name: "Bantuan Pendidikan" },
{ id: "PERU", name: "Bantuan Perubatan" },
{ id: "PERNI", name: "Bantuan Perniagaan" },
{ id: "RURUN", name: "Bantuan Rumah" }
]
},
// Bantuan Saya (My Aid) data
bantuanData: {
activeBantuan: [
{
id: "BAN-2023-1234",
type: "Bantuan Sara Hidup",
amount: "RM 500/bulan",
startDate: "Jan 2023",
endDate: "Dis 2023",
nextPayment: "15 Jun 2023"
},
{
id: "BAN-2023-5678",
type: "Bantuan Pendidikan Anak",
amount: "RM 200/bulan",
startDate: "Feb 2023",
endDate: "Nov 2023",
nextPayment: "15 Jun 2023"
}
],
paymentHistory: [
{ id: "PMT-0012", date: "15 Mei 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai" },
{ id: "PMT-0011", date: "15 Apr 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai" },
{ id: "PMT-0010", date: "15 Mac 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai" }
],
timeline: [
{ step: 'Permohonan Dihantar', date: '10/05/2023', time: '09:30', completed: true },
{ step: 'Verifikasi Dokumen', date: '11/05/2023', time: '14:45', completed: true },
{ step: 'Semakan Pegawai', date: '12/05/2023', time: '11:20', completed: true },
{ step: 'Kelulusan', date: '20/05/2023', time: '10:15', completed: true },
{ step: 'Agihan Bantuan', date: '01/06/2023', time: '09:00', completed: true }
]
},
// Notification data
notificationData: {
unread: 3,
items: [
{ id: 1, title: "Pembayaran Bantuan", content: "Bantuan bulanan sebanyak RM 700 telah dikreditkan ke akaun anda", time: "2 jam lalu", unread: true, type: "success" },
{ id: 2, title: "Dokumen Tambahan Diperlukan", content: "Sila kemukakan salinan surat pengesahan pendapatan untuk permohonan #APP-2023-1234", time: "5 jam lalu", unread: true, type: "warning" },
{ id: 3, title: "Peringatan Temuduga", content: "Temuduga untuk permohonan bantuan akan diadakan pada 18 Jun 2023, 10:00 pagi", time: "1 hari lalu", unread: true, type: "info" },
{ id: 4, title: "Program Asnaf", content: "Program Latihan Kemahiran untuk Asnaf akan bermula pada 20 Jun 2023", time: "2 hari lalu", unread: false, type: "info" },
{ id: 5, title: "Status Permohonan", content: "Permohonan #APP-2022-3456 telah ditolak. Sila semak maklumat lanjut dalam sistem.", time: "3 hari lalu", unread: false, type: "error" }
]
},
// Form data for application
newApplicationForm: {
type: "",
fullName: "",
idNumber: "",
phone: "",
email: "",
address: "",
reason: "",
dependents: 0,
monthlyIncome: "",
documents: []
},
formErrors: {
type: false,
fullName: false,
idNumber: false,
phone: false,
email: false,
monthlyIncome: false
},
// Form validation states
formIsValid: false,
formSubmitted: false,
formSubmitting: false,
// Active detail views
activeApplicationDetail: null,
activeBantuanDetail: null,
editApplicationId: null
});
// Animation states
const animationStates = ref({
menuExpanded: false,
profileExpanded: false,
fabExpanded: false,
pageTransition: false
});
// Toggle functions for demo
const toggleMenu = () => {
exampleData.value.showMenu = !exampleData.value.showMenu;
animationStates.value.menuExpanded = exampleData.value.showMenu;
// Add/remove body-locked class to disable scrolling when menu is open
// Only affect the mobile-content element, not the entire document
const mobileContent = document.querySelector('.mobile-content');
if (exampleData.value.showMenu && mobileContent) {
mobileContent.classList.add('body-locked');
} else if (mobileContent) {
mobileContent.classList.remove('body-locked');
}
};
const toggleProfileDropdown = () => {
exampleData.value.profileExpanded = !exampleData.value.profileExpanded;
animationStates.value.profileExpanded = exampleData.value.profileExpanded;
// Close notifications panel if open
if (exampleData.value.showNotifications) {
exampleData.value.showNotifications = false;
}
};
const toggleNotifications = () => {
exampleData.value.showNotifications = !exampleData.value.showNotifications;
// Close profile dropdown if open
if (exampleData.value.profileExpanded) {
exampleData.value.profileExpanded = false;
animationStates.value.profileExpanded = false;
}
};
const toggleFabMenu = () => {
exampleData.value.showFabMenu = !exampleData.value.showFabMenu;
animationStates.value.fabExpanded = exampleData.value.showFabMenu;
};
const toggleLoading = () => {
exampleData.value.isLoading = true;
setTimeout(() => {
exampleData.value.isLoading = false;
}, 2000);
};
const toggleEmptyState = () => {
exampleData.value.showEmptyState = !exampleData.value.showEmptyState;
};
const simulateError = (field) => {
exampleData.value.formErrors[field] = true;
setTimeout(() => {
exampleData.value.formErrors[field] = false;
}, 3000);
};
// Navigate to a different section
const navigateTo = (sectionId, subsection = null) => {
exampleData.value.previousSection = exampleData.value.currentSection;
exampleData.value.currentSection = sectionId;
exampleData.value.subSection = subsection;
// Show back button if navigating to a subsection or if navigating to components section
exampleData.value.showBackButton = subsection !== null || sectionId === 'components';
// Reset scroll position
setTimeout(() => {
const mobileContent = document.querySelector('.mobile-content');
if (mobileContent) {
mobileContent.scrollTop = 0;
}
}, 10);
// Close any open UI elements
closeAllOverlays();
};
// Navigate back
const navigateBack = () => {
if (exampleData.value.subSection) {
// If in a subsection, go back to main section
exampleData.value.subSection = null;
exampleData.value.showBackButton = exampleData.value.currentSection === 'components';
} else if (exampleData.value.currentSection === 'components') {
// If on components page, go back to dashboard
exampleData.value.currentSection = 'dashboard';
exampleData.value.previousSection = null;
exampleData.value.showBackButton = false;
} else if (exampleData.value.previousSection) {
// If have a previous main section, go back to it
exampleData.value.currentSection = exampleData.value.previousSection;
exampleData.value.previousSection = null;
exampleData.value.showBackButton = false;
}
// Reset scroll position
if (document.querySelector('.mobile-content')) {
document.querySelector('.mobile-content').scrollTop = 0;
}
// Close any open UI elements
closeAllOverlays();
};
// Close all overlays
const closeAllOverlays = () => {
exampleData.value.showMenu = false;
exampleData.value.profileExpanded = false;
exampleData.value.showNotifications = false;
exampleData.value.showFabMenu = false;
// Reset animation states
animationStates.value.menuExpanded = false;
animationStates.value.profileExpanded = false;
animationStates.value.fabExpanded = false;
// Remove body lock only from the mobile content
const mobileContent = document.querySelector('.mobile-content');
if (mobileContent) {
mobileContent.classList.remove('body-locked');
}
};
// Change tab
const changeTab = (tabId) => {
exampleData.value.activeTab = tabId;
};
// Create new application draft function
const createNewApplication = (type) => {
// Navigate to the new application form
navigateTo('permohonan', 'new');
// Set initial form values
exampleData.value.newApplicationForm = {
type: type,
fullName: exampleData.value.userProfile.name,
idNumber: exampleData.value.userProfile.id,
phone: exampleData.value.userProfile.phone,
email: exampleData.value.userProfile.email,
address: exampleData.value.userProfile.address,
reason: "",
dependents: exampleData.value.userProfile.dependents || 0,
monthlyIncome: "",
documents: []
};
// Close FAB menu
exampleData.value.showFabMenu = false;
animationStates.value.fabExpanded = false;
};
// Edit application function
const editApplication = (application) => {
// Navigate to the edit form
navigateTo('permohonan', 'edit');
// Set form values from the application
exampleData.value.newApplicationForm = {
type: application.type,
fullName: application.pemohon,
idNumber: application.noIC,
phone: application.telefon,
email: exampleData.value.userProfile.email, // Assuming email is not in the application object
address: application.alamat,
reason: "",
dependents: 0,
monthlyIncome: application.amount.replace("RM ", ""),
documents: []
};
// Store the application ID for update
exampleData.value.editApplicationId = application.id;
};
// Approve application function
const approveApplication = (application) => {
// Show confirmation dialog (in a real app)
if (confirm(`Adakah anda pasti untuk meluluskan permohonan ${application.id}?`)) {
// Update application status
const index = exampleData.value.permohonanData.activeApplications.findIndex(app => app.id === application.id);
if (index !== -1) {
exampleData.value.permohonanData.activeApplications[index].status = 'LULUS';
// Show success notification
addNotification({
title: "Permohonan Diluluskan",
content: `Permohonan ${application.id} telah berjaya diluluskan.`,
type: "success"
});
}
}
};
// Delete application function
const deleteApplication = (application) => {
// Show confirmation dialog (in a real app)
if (confirm(`Adakah anda pasti untuk memadamkan permohonan ${application.id}?`)) {
// Remove application from the list
const index = exampleData.value.permohonanData.activeApplications.findIndex(app => app.id === application.id);
if (index !== -1) {
exampleData.value.permohonanData.activeApplications.splice(index, 1);
// Show success notification
addNotification({
title: "Permohonan Dipadam",
content: `Permohonan ${application.id} telah berjaya dipadam.`,
type: "success"
});
}
}
};
// Submit application form
const submitApplicationForm = () => {
// Validate form first
validateForm();
if (exampleData.value.formIsValid) {
exampleData.value.formSubmitting = true;
// Simulate form submission
setTimeout(() => {
// Add to draft applications
exampleData.value.permohonanData.draftApplications.unshift({
id: `DRAFT-2023-${Math.floor(1000 + Math.random() * 9000)}`,
type: exampleData.value.newApplicationForm.type,
lastUpdated: new Date().toLocaleDateString('ms-MY', {day: '2-digit', month: 'short', year: 'numeric'})
});
exampleData.value.formSubmitting = false;
exampleData.value.formSubmitted = true;
// Show success notification
addNotification({
title: "Draf Permohonan Dibuat",
content: `Draf permohonan untuk ${exampleData.value.newApplicationForm.type} telah berjaya dibuat.`,
type: "success"
});
// Navigate back to permohonan list after delay
setTimeout(() => {
navigateTo('permohonan');
exampleData.value.formSubmitted = false;
changeTab('draft');
}, 1500);
}, 2000);
}
};
// View application details
const viewApplicationDetails = (applicationId, tab) => {
const applications = tab === 'active'
? exampleData.value.permohonanData.activeApplications
: tab === 'history'
? exampleData.value.permohonanData.historicalApplications
: exampleData.value.permohonanData.draftApplications;
const application = applications.find(app => app.id === applicationId);
if (application) {
exampleData.value.activeApplicationDetail = application;
navigateTo('permohonan', 'details');
}
};
// View bantuan details
const viewBantuanDetails = (bantuanId) => {
const bantuan = exampleData.value.bantuanData.activeBantuan.find(b => b.id === bantuanId);
if (bantuan) {
exampleData.value.activeBantuanDetail = bantuan;
navigateTo('bantuan', 'details');
}
};
// Form validation
const validateForm = () => {
// Reset errors
Object.keys(exampleData.value.formErrors).forEach(key => {
exampleData.value.formErrors[key] = false;
});
// Check required fields
let isValid = true;
// Required fields validation
const requiredFields = ['type', 'fullName', 'idNumber', 'phone', 'email', 'monthlyIncome'];
requiredFields.forEach(field => {
if (!exampleData.value.newApplicationForm[field]) {
exampleData.value.formErrors[field] = true;
isValid = false;
}
});
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (exampleData.value.newApplicationForm.email && !emailRegex.test(exampleData.value.newApplicationForm.email)) {
exampleData.value.formErrors.email = true;
isValid = false;
}
// Phone validation
const phoneRegex = /^01\d-\d{7,8}$/;
if (exampleData.value.newApplicationForm.phone && !phoneRegex.test(exampleData.value.newApplicationForm.phone)) {
exampleData.value.formErrors.phone = true;
isValid = false;
}
exampleData.value.formIsValid = isValid;
return isValid;
};
// For notification actions
const markAsRead = (id) => {
const notification = exampleData.value.notificationData.items.find(n => n.id === id);
if (notification && notification.unread) {
notification.unread = false;
exampleData.value.notificationData.unread -= 1;
}
};
const markAllAsRead = () => {
exampleData.value.notificationData.items.forEach(notification => {
notification.unread = false;
});
exampleData.value.notificationData.unread = 0;
};
const deleteNotification = (id) => {
const index = exampleData.value.notificationData.items.findIndex(n => n.id === id);
if (index !== -1) {
const isUnread = exampleData.value.notificationData.items[index].unread;
if (isUnread) {
exampleData.value.notificationData.unread -= 1;
}
exampleData.value.notificationData.items.splice(index, 1);
}
};
// Add new notification
const addNotification = (notification) => {
const newNotification = {
id: exampleData.value.notificationData.items.length + 1,
title: notification.title,
content: notification.content,
time: "Baru sahaja",
unread: true,
type: notification.type || "info"
};
exampleData.value.notificationData.items.unshift(newNotification);
exampleData.value.notificationData.unread += 1;
};
// Set page title based on current section
const updatePageTitle = () => {
const currentSection = exampleData.value.currentSection;
const page = exampleData.value.demoPages.find(p => p.id === currentSection);
if (exampleData.value.subSection) {
switch (exampleData.value.subSection) {
case 'new':
exampleData.value.headerTitle = 'Permohonan Baru';
break;
case 'details':
exampleData.value.headerTitle = 'Butiran';
break;
default:
exampleData.value.headerTitle = page?.title || 'Portal Asnaf';
}
} else {
exampleData.value.headerTitle = page?.title || 'Portal Asnaf';
}
};
// Watch for section changes
watch(() => [exampleData.value.currentSection, exampleData.value.subSection], () => {
updatePageTitle();
// Implement page transition animation
animationStates.value.pageTransition = true;
setTimeout(() => {
animationStates.value.pageTransition = false;
}, 300);
});
// Initialize page title
onMounted(() => {
updatePageTitle();
});
// Profile Section
const viewProfile = () => {
navigateTo('profile');
exampleData.value.profileExpanded = false;
};
// Mobile Components Showcase
const viewMobileComponents = () => {
navigateTo('components');
};
// For notification actions
const handleNotificationAction = (notification) => {
// Navigate to appropriate section based on notification
if (notification.action === 'view_bantuan') {
navigateTo('bantuan', 'details');
if (notification.bantuanId) {
viewBantuanDetails(notification.bantuanId);
}
} else if (notification.action === 'view_permohonan') {
navigateTo('permohonan', 'details');
if (notification.permohonanId) {
viewApplicationDetails(notification.permohonanId, 'active');
}
} else if (notification.action === 'rsvp_program') {
// Show RSVP confirmation dialog - simplified for demo
alert('Anda telah mendaftar untuk program ini.');
markAsRead(notification.id);
}
};
// Update Bantuan Data with more comprehensive info
exampleData.value.bantuanData = {
activeBantuan: [
{
id: "BAN-2023-1234",
type: "Bantuan Sara Hidup",
category: "Fakir",
amount: "RM 500/bulan",
startDate: "Jan 2023",
endDate: "Dis 2023",
nextPayment: "15 Jun 2023",
referenceNo: "BSH-23/1234",
status: "AKTIF",
details: {
approvedBy: "Pegawai Zakat Daerah Shah Alam",
approvalDate: "15 Dis 2022",
disbursementMethod: "Akaun Bank",
bankName: "Bank Islam",
accountNo: "xxxx-xxx-xxxxx",
totalAmountApproved: "RM 6,000 (RM 500 × 12 bulan)",
totalDisbursed: "RM 2,500 (5 bulan)",
remainingAmount: "RM 3,500 (7 bulan)"
}
},
{
id: "BAN-2023-5678",
type: "Bantuan Pendidikan Anak",
category: "Miskin",
amount: "RM 200/bulan",
startDate: "Feb 2023",
endDate: "Nov 2023",
nextPayment: "15 Jun 2023",
referenceNo: "BPA-23/5678",
status: "AKTIF",
details: {
approvedBy: "Pegawai Zakat Daerah Shah Alam",
approvalDate: "20 Jan 2023",
disbursementMethod: "Akaun Bank",
bankName: "Bank Islam",
accountNo: "xxxx-xxx-xxxxx",
totalAmountApproved: "RM 2,000 (RM 200 × 10 bulan)",
totalDisbursed: "RM 800 (4 bulan)",
remainingAmount: "RM 1,200 (6 bulan)",
children: [
{ name: "Ahmad bin Muhammad", age: 12, school: "SK Taman Sri Muda", level: "Darjah 6" },
{ name: "Nur Aisyah binti Muhammad", age: 15, school: "SMK Taman Sri Muda", level: "Tingkatan 3" }
]
}
},
{
id: "BAN-2023-9012",
type: "Bantuan Perubatan",
category: "Fakir",
amount: "RM 350/bulan",
startDate: "Apr 2023",
endDate: "Apr 2024",
nextPayment: "15 Jun 2023",
referenceNo: "BPR-23/9012",
status: "AKTIF",
details: {
approvedBy: "Pegawai Zakat Daerah Shah Alam",
approvalDate: "25 Mar 2023",
disbursementMethod: "Akaun Bank",
bankName: "Bank Islam",
accountNo: "xxxx-xxx-xxxxx",
totalAmountApproved: "RM 4,200 (RM 350 × 12 bulan)",
totalDisbursed: "RM 700 (2 bulan)",
remainingAmount: "RM 3,500 (10 bulan)",
medicalCondition: "Diabetes & Tekanan Darah Tinggi",
medicalFacility: "Klinik Kesihatan Seksyen 7"
}
}
],
paymentHistory: [
{ id: "PMT-0012", date: "15 Mei 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai", details: "Bantuan Sara Hidup (RM 500) & Pendidikan (RM 200)" },
{ id: "PMT-0011", date: "15 Apr 2023", amount: "RM 1,050", type: "Bantuan Bulanan", status: "Selesai", details: "Bantuan Sara Hidup (RM 500), Pendidikan (RM 200) & Perubatan (RM 350)" },
{ id: "PMT-0010", date: "15 Mac 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai", details: "Bantuan Sara Hidup (RM 500) & Pendidikan (RM 200)" },
{ id: "PMT-0009", date: "15 Feb 2023", amount: "RM 700", type: "Bantuan Bulanan", status: "Selesai", details: "Bantuan Sara Hidup (RM 500) & Pendidikan (RM 200)" },
{ id: "PMT-0008", date: "15 Jan 2023", amount: "RM 500", type: "Bantuan Bulanan", status: "Selesai", details: "Bantuan Sara Hidup (RM 500)" }
],
timeline: [
{ step: 'Permohonan Dihantar', date: '10/05/2023', time: '09:30', completed: true },
{ step: 'Verifikasi Dokumen', date: '11/05/2023', time: '14:45', completed: true },
{ step: 'Semakan Pegawai', date: '12/05/2023', time: '11:20', completed: true },
{ step: 'Kelulusan', date: '20/05/2023', time: '10:15', completed: true },
{ step: 'Agihan Bantuan', date: '01/06/2023', time: '09:00', completed: true }
],
bantuanCategories: [
{ id: "BSH", name: "Bantuan Sara Hidup", description: "Bantuan kewangan bulanan untuk memenuhi keperluan asas", eligibility: "Asnaf fakir, miskin" },
{ id: "BPD", name: "Bantuan Pendidikan", description: "Bantuan untuk yuran dan keperluan sekolah", eligibility: "Asnaf fakir, miskin dengan anak bersekolah" },
{ id: "BPR", name: "Bantuan Perubatan", description: "Bantuan untuk rawatan dan ubat-ubatan", eligibility: "Asnaf fakir, miskin yang sakit kronik" },
{ id: "BPK", name: "Bantuan Perniagaan Kecil", description: "Modal untuk memulakan perniagaan kecil", eligibility: "Asnaf fakir, miskin yang berkelayakan" },
{ id: "BRM", name: "Bantuan Rumah", description: "Bantuan untuk sewaan atau baik pulih rumah", eligibility: "Asnaf fakir, miskin tanpa rumah tetap" }
],
nearbyFacilities: [
{ name: "Pejabat Zakat Daerah Shah Alam", type: "Pejabat Zakat", distance: "2.5 KM", address: "Kompleks PKNS, Seksyen 14, 40000 Shah Alam", phone: "03-1234 5678" },
{ name: "Pusat Agihan Zakat Seksyen 7", type: "Pusat Agihan", distance: "1.8 KM", address: "Jalan Plumbum 7/101B, Seksyen 7, 40000 Shah Alam", phone: "03-2345 6789" },
{ name: "Klinik Kesihatan Seksyen 7", type: "Klinik Kesihatan", distance: "2.0 KM", address: "Jalan Plumbum 7/102, Seksyen 7, 40000 Shah Alam", phone: "03-3456 7890" }
],
notifications: [
{
id: 1,
title: "Pengagihan Bantuan Jun 2023",
content: "Bantuan bulanan anda berjumlah RM 700 akan dikreditkan pada 15 Jun 2023.",
date: "08/06/2023"
},
{
id: 2,
title: "Peringatan Kemaskini Maklumat",
content: "Sila kemaskini maklumat akaun bank anda sebelum 30 Jun 2023.",
date: "05/06/2023"
}
],
bantuanForm: {
type: "",
fullName: "",
idNumber: "",
category: "",
address: "",
phone: "",
email: "",
bankName: "",
accountNumber: "",
reason: "",
documents: []
}
};
// Add some example notification data with actions
exampleData.value.notificationData.items = [
{
id: 1,
title: "Pembayaran Bantuan",
content: "Bantuan bulanan sebanyak RM 700 telah dikreditkan ke akaun anda",
time: "2 jam lalu",
unread: true,
type: "success",
action: "view_bantuan",
actionText: "Lihat Detail"
},
{
id: 2,
title: "Dokumen Tambahan Diperlukan",
content: "Sila kemukakan salinan surat pengesahan pendapatan untuk permohonan #APP-2023-1234",
time: "5 jam lalu",
unread: true,
type: "warning",
action: "view_permohonan",
permohonanId: "APP-2023-1234",
actionText: "Kemaskini"
},
{
id: 3,
title: "Program Kemahiran Digital",
content: "Tempat masih dibuka untuk Program Kemahiran Digital pada 25 Jun 2023, 10:00 pagi",
time: "1 hari lalu",
unread: true,
type: "info",
action: "rsvp_program",
actionText: "Daftar"
},
{
id: 4,
title: "Program Asnaf",
content: "Program Latihan Kemahiran untuk Asnaf akan bermula pada 20 Jun 2023",
time: "2 hari lalu",
unread: false,
type: "info"
},
{
id: 5,
title: "Status Permohonan",
content: "Permohonan #APP-2022-3456 telah ditolak. Sila semak maklumat lanjut dalam sistem.",
time: "3 hari lalu",
unread: false,
type: "error"
}
];
// ... more existing code ...
// New methods for Bantuan page
const editBantuan = (bantuan) => {
// Navigate to edit form
exampleData.value.bantuanForm = {
type: bantuan.type,
fullName: exampleData.value.userProfile.name,
idNumber: exampleData.value.userProfile.id,
category: bantuan.category,
address: exampleData.value.userProfile.address,
phone: exampleData.value.userProfile.phone,
email: exampleData.value.userProfile.email,
bankName: bantuan.details.bankName,
accountNumber: bantuan.details.accountNo,
reason: "Kemaskini maklumat akaun bank",
documents: []
};
navigateTo('bantuan', 'edit');
};
const createNewBantuan = (type) => {
// Reset form and navigate to new form
exampleData.value.bantuanForm = {
type: type || "",
fullName: exampleData.value.userProfile.name,
idNumber: exampleData.value.userProfile.id,
category: "",
address: exampleData.value.userProfile.address,
phone: exampleData.value.userProfile.phone,
email: exampleData.value.userProfile.email,
bankName: "",
accountNumber: "",
reason: "",
documents: []
};
// Reset form errors
exampleData.value.formErrors = {
type: false,
fullName: false,
idNumber: false,
phone: false,
email: false,
address: false,
bankName: false,
accountNumber: false,
category: false,
reason: false,
monthlyIncome: false
};
navigateTo('bantuan', 'new');
};
const submitBantuanForm = () => {
// Validate form first
validateBantuanForm();
if (exampleData.value.formIsValid) {
// Simulate form submission
exampleData.value.formSubmitting = true;
setTimeout(() => {
exampleData.value.formSubmitting = false;
exampleData.value.formSubmitted = true;
// Add notification
addNotification({
title: "Permohonan Dihantar",
content: `Permohonan bantuan ${exampleData.value.bantuanForm.type || "Bantuan Sara Hidup"} telah berjaya dihantar.`,
type: "success"
});
// Navigate to success page
navigateTo('bantuan', 'success');
}, 2000);
}
};
// Validate Bantuan Form
const validateBantuanForm = () => {
// Reset errors
Object.keys(exampleData.value.formErrors).forEach(key => {
exampleData.value.formErrors[key] = false;
});
// Check required fields
let isValid = true;
// Required fields for personal info
if (exampleData.value.currentSection === 'bantuan' && exampleData.value.subSection === 'new') {
const requiredFields = ['type', 'fullName', 'idNumber', 'phone', 'address', 'category'];
requiredFields.forEach(field => {
if (!exampleData.value.bantuanForm[field]) {
exampleData.value.formErrors[field] = true;
isValid = false;
}
});
// Email validation if provided
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (exampleData.value.bantuanForm.email && !emailRegex.test(exampleData.value.bantuanForm.email)) {
exampleData.value.formErrors.email = true;
isValid = false;
}
// Phone validation
const phoneRegex = /^01\d-\d{7,8}$/;
if (exampleData.value.bantuanForm.phone && !phoneRegex.test(exampleData.value.bantuanForm.phone)) {
exampleData.value.formErrors.phone = true;
isValid = false;
}
}
// Required fields for bank info in the review step
if (exampleData.value.currentSection === 'bantuan' && exampleData.value.subSection === 'review') {
const requiredBankFields = ['bankName', 'accountNumber'];
requiredBankFields.forEach(field => {
if (!exampleData.value.bantuanForm[field]) {
exampleData.value.formErrors[field] = true;
isValid = false;
}
});
// Bank account number validation
if (exampleData.value.bantuanForm.accountNumber && exampleData.value.bantuanForm.accountNumber.length < 8) {
exampleData.value.formErrors.accountNumber = true;
isValid = false;
}
// Reason is required
if (!exampleData.value.bantuanForm.reason) {
exampleData.value.formErrors.reason = true;
isValid = false;
}
}
exampleData.value.formIsValid = isValid;
return isValid;
};
// ... existing code ...
// Set theme to LZS theme on component mount
onMounted(() => {
document.documentElement.setAttribute("data-theme", "LZS");
});
</script>
<template>
<div>
<div class="wrapper">
<div class="phone-container">
<!-- Phone Frame -->
<div class="mobile-frame">
<!-- Status Bar -->
<div class="h-5 bg-black flex items-center justify-between px-5">
<span class="text-white text-xs">12:45</span>
<div class="flex space-x-1">
<Icon name="ic:baseline-signal-cellular-alt" class="text-white" size="14" />
<Icon name="ic:baseline-wifi" class="text-white" size="14" />
<Icon name="ic:baseline-battery-full" class="text-white" size="14" />
</div>
</div>
<!-- Mobile App -->
<div class="mobile-content overflow-hidden">
<!-- Mobile Header -->
<div class="mobile-header bg-primary shadow-md">
<div class="flex items-center justify-between px-4 py-3">
<div class="flex items-center">
<button @click="toggleMenu" class="mr-3 text-header-text">
<Icon name="ic:baseline-menu" size="24" />
</button>
<h1 class="text-header-text font-medium">{{ exampleData.headerTitle }}</h1>
</div>
<div class="flex items-center space-x-4">
<button @click="toggleNotifications" class="relative text-header-text">
<Icon name="ic:baseline-notifications" size="24" />
<span
v-if="exampleData.notificationData.unread > 0"
class="absolute -top-1 -right-1 w-4 h-4 bg-accent rounded-full text-primary text-[8px] font-bold flex items-center justify-center"
>
{{ exampleData.notificationData.unread }}
</span>
</button>
<button @click="toggleProfileDropdown" class="text-header-text w-8 h-8 rounded-full bg-white/20 flex items-center justify-center font-bold">
{{ exampleData.userProfile.avatar }}
</button>
</div>
</div>
<!-- Notifications Panel -->
<div
v-if="exampleData.showNotifications"
class="absolute top-12 right-0 w-full max-w-xs bg-white z-20 rounded-b-lg shadow-lg transition-all border border-t-0 border-gray-100 overflow-hidden"
>
<div class="p-3 border-b border-gray-100 flex justify-between items-center">
<h2 class="text-sm font-medium">Notifikasi <span class="text-xs ml-1">({{ exampleData.notificationData.unread }} baru)</span></h2>
<button class="text-xs text-primary">Tandakan semua dibaca</button>
</div>
<div class="max-h-[400px] overflow-y-auto">
<div
v-for="notification in exampleData.notificationData.items"
:key="notification.id"
class="p-3 border-b border-gray-100 last:border-0 relative hover:bg-gray-50"
:class="{ 'bg-blue-50/30': notification.unread }"
>
<div class="flex">
<div class="flex-shrink-0 mr-3">
<div class="w-8 h-8 rounded-full flex items-center justify-center"
:class="{
'bg-green-100 text-green-600': notification.type === 'success',
'bg-yellow-100 text-yellow-600': notification.type === 'warning',
'bg-blue-100 text-blue-600': notification.type === 'info',
'bg-red-100 text-red-600': notification.type === 'error',
}"
>
<Icon
:name="{
'success': 'ic:baseline-check-circle',
'warning': 'ic:baseline-warning',
'info': 'ic:baseline-info',
'error': 'ic:baseline-error',
}[notification.type]"
size="16"
/>
</div>
</div>
<div>
<div class="flex items-start">
<p class="font-medium text-sm">{{ notification.title }}</p>
<span v-if="notification.unread" class="ml-2 w-2 h-2 rounded-full bg-primary"></span>
</div>
<p class="text-xs text-gray-600 my-1">{{ notification.content }}</p>
<p class="text-xs text-gray-400">{{ notification.time }}</p>
</div>
</div>
</div>
</div>
<div class="p-2 border-t border-gray-100 text-center">
<button class="text-sm text-primary font-medium">Lihat Semua Notifikasi</button>
</div>
</div>
<!-- Profile Dropdown -->
<div
v-if="exampleData.profileExpanded"
class="absolute top-12 right-0 w-full max-w-xs bg-white z-20 rounded-b-lg shadow-lg transition-all border border-t-0 border-gray-100 overflow-hidden"
:class="{ 'expanded': animationStates.profileExpanded }"
>
<div class="p-4 border-b border-gray-100">
<div class="flex items-center space-x-3 mb-3">
<div class="w-12 h-12 rounded-full bg-primary/10 text-primary flex items-center justify-center font-bold text-xl">
{{ exampleData.userProfile.avatar }}
</div>
<div class="flex-1">
<h3 class="font-medium">{{ exampleData.userProfile.name }}</h3>
<p class="text-xs text-gray-500">{{ exampleData.userProfile.email }}</p>
</div>
</div>
<!-- Profile Details (enhanced) -->
<div class="border border-gray-100 rounded-lg p-3 bg-gray-50 mb-3">
<div class="text-xs">
<div class="flex items-center mb-2">
<Icon name="ic:baseline-badge" size="14" class="text-primary mr-2" />
<span class="text-gray-600">No. ID:</span>
<span class="ml-1 font-medium">{{ exampleData.userProfile.id }}</span>
</div>
<div class="flex items-center mb-2">
<Icon name="ic:baseline-phone" size="14" class="text-primary mr-2" />
<span class="text-gray-600">Telefon:</span>
<span class="ml-1 font-medium">{{ exampleData.userProfile.phone }}</span>
</div>
<div class="flex items-start mb-2">
<Icon name="ic:baseline-home" size="14" class="text-primary mr-2 mt-0.5" />
<div>
<span class="text-gray-600">Alamat:</span>
<div class="font-medium">{{ exampleData.userProfile.address }}</div>
</div>
</div>
<div class="flex items-center">
<Icon name="ic:baseline-category" size="14" class="text-primary mr-2" />
<span class="text-gray-600">Status:</span>
<span class="ml-1 font-medium">{{ exampleData.userProfile.department }}</span>
</div>
</div>
</div>
<!-- Asnaf Status Badge (new) -->
<div class="mb-3 py-2 px-3 bg-secondary/10 rounded-lg border border-secondary/20 flex items-center">
<Icon name="ic:baseline-verified-user" class="text-secondary mr-2" size="18" />
<div>
<p class="text-xs font-medium text-gray-700">Status Asnaf:</p>
<p class="text-sm font-medium text-secondary">{{ exampleData.userProfile.department }} <span class="text-xs">(sejak {{ exampleData.userProfile.joinDate }})</span></p>
</div>
</div>
</div>
<div class="divide-y divide-gray-100">
<button
v-for="action in exampleData.userProfile.actions"
:key="action.name"
class="flex items-center w-full p-3 hover:bg-gray-50 transition-colors"
>
<Icon :name="action.icon" size="18" class="text-gray-500 mr-3" />
<span class="text-sm">{{ action.name }}</span>
</button>
<button class="flex items-center w-full p-3 hover:bg-gray-50 transition-colors text-red-600">
<Icon name="ic:baseline-logout" size="18" class="mr-3" />
<span class="text-sm">Log Keluar</span>
</button>
</div>
</div>
</div>
<!-- Mobile Content -->
<div class="relative min-h-[calc(100%-56px)]">
<transition name="fade">
<div :key="exampleData.currentSection" class="content-wrapper">
<!-- Dashboard Section - Enhanced with LZS theming -->
<div v-if="exampleData.currentSection === 'dashboard'" class="p-4 pb-24">
<!-- Asnaf Profile Summary Card - Modernized -->
<div class="mb-4 bg-white rounded-xl shadow-md overflow-hidden border border-gray-100">
<div class="bg-primary/5 p-4 border-b border-gray-100">
<div class="flex items-center">
<div class="w-14 h-14 rounded-lg bg-primary/10 text-primary flex items-center justify-center font-bold text-xl shadow-sm border border-primary/20">
{{ exampleData.userProfile.avatar }}
</div>
<div class="ml-3">
<h3 class="font-medium text-gray-800">{{ exampleData.userProfile.name }}</h3>
<div class="flex items-center mt-1">
<span class="text-xs bg-secondary/15 text-secondary py-1 px-2 rounded-full font-medium border border-secondary/20">
{{ exampleData.userProfile.department }}
</span>
</div>
</div>
</div>
</div>
<!-- Bantuan Summary -->
<div class="p-4">
<div class="grid grid-cols-2 gap-4 mb-4">
<div class="rounded-lg bg-primary/5 p-3 border border-primary/10">
<p class="text-xs text-gray-600 mb-1">Jumlah Bantuan</p>
<p class="text-lg font-semibold text-primary">{{ exampleData.dashboardData.totalBantuan }}</p>
</div>
<div class="rounded-lg bg-secondary/5 p-3 border border-secondary/10">
<p class="text-xs text-gray-600 mb-1">Bantuan Bulan Ini</p>
<p class="text-lg font-semibold text-secondary">{{ exampleData.dashboardData.bantuanBulan }}</p>
</div>
</div>
<div class="flex items-center justify-between p-3 rounded-lg bg-accent/5 border border-accent/10 mb-4">
<div>
<p class="text-xs text-gray-600 mb-1">Pembayaran Seterusnya</p>
<p class="font-medium">{{ exampleData.dashboardData.nextPayment }}</p>
</div>
<Icon name="ic:baseline-calendar-today" class="text-accent" size="20" />
</div>
<button class="w-full py-2.5 px-4 bg-primary text-white font-medium rounded-lg shadow-sm hover:bg-primary-dark transition flex items-center justify-center">
<Icon name="ic:baseline-receipt-long" class="mr-2" size="18" />
Lihat Semua Bantuan
</button>
</div>
</div>
<!-- Dashboard Metrics Cards - Enhanced with LZS theming -->
<h3 class="text-base font-medium mb-3 text-gray-800">Metrik Zakat</h3>
<div class="grid grid-cols-2 gap-3 mb-6">
<div v-for="(metric, index) in exampleData.keyMetrics" :key="index"
class="bg-white rounded-xl p-3 shadow-sm border border-gray-100 flex flex-col justify-between">
<div class="flex justify-between items-start mb-2">
<div class="w-9 h-9 rounded-md flex items-center justify-center"
:class="{
'bg-secondary/15 text-secondary': index === 1 || index === 2,
'bg-primary/15 text-primary': index === 0 || index === 3
}">
<Icon :name="metric.icon" size="20" />
</div>
<div class="text-xs px-1.5 py-0.5 rounded font-medium"
:class="{
'bg-secondary/15 text-secondary': metric.change === 'positive',
'bg-gray-100 text-gray-600': metric.change === 'neutral',
'bg-danger/15 text-danger': metric.change === 'negative'
}">
{{ metric.description }}
</div>
</div>
<div>
<p class="text-sm text-gray-600 mb-1">{{ metric.title }}</p>
<p class="text-base font-bold"
:class="{
'text-secondary': index === 1 || index === 2,
'text-primary': index === 0 || index === 3
}">
{{ metric.value }}
</p>
</div>
</div>
</div>
<!-- Announcements - Enhanced -->
<h3 class="text-base font-medium mb-3 text-gray-800">Pengumuman</h3>
<div class="space-y-3 mb-6">
<div v-for="announcement in exampleData.dashboardData.announcements" :key="announcement.id"
class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-100">
<div class="h-32 bg-gray-200">
<!-- We would use actual images here -->
<div class="h-full w-full flex items-center justify-center bg-primary/10 text-primary">
<Icon name="ic:baseline-image" size="36" />
</div>
</div>
<div class="p-3">
<p class="font-medium mb-1.5">{{ announcement.title }}</p>
<p class="text-sm text-gray-600 mb-2">{{ announcement.content }}</p>
<div class="flex justify-between items-center">
<span class="text-xs text-gray-500">{{ announcement.date }}</span>
<button class="text-primary text-sm font-medium">Baca Lagi</button>
</div>
</div>
</div>
</div>
<!-- Upcoming Events - Enhanced -->
<h3 class="text-base font-medium mb-3 text-gray-800">Acara Akan Datang</h3>
<div class="space-y-3 mb-6">
<div v-for="event in exampleData.dashboardData.upcomingEvents" :key="event.id"
class="bg-white rounded-xl p-3.5 shadow-sm border border-gray-100 flex items-start">
<div class="w-12 h-12 rounded-lg bg-primary/10 flex flex-col items-center justify-center mr-3 border border-primary/20">
<span class="text-xs font-medium text-gray-600">{{ event.date.split(' ')[1] }}</span>
<span class="text-base font-bold text-primary">{{ event.date.split(' ')[0] }}</span>
</div>
<div class="flex-1">
<p class="font-medium mb-1">{{ event.title }}</p>
<div class="flex items-center text-xs text-gray-500 mb-1">
<Icon name="ic:baseline-access-time" size="14" class="mr-1" />
<span>{{ event.time }}</span>
</div>
<div class="flex items-center text-xs text-gray-500">
<Icon name="ic:baseline-location-on" size="14" class="mr-1" />
<span>{{ event.location }}</span>
</div>
</div>
<button class="ml-2 w-7 h-7 rounded-full flex items-center justify-center bg-primary/10 text-primary">
<Icon name="ic:baseline-arrow-forward" size="16" />
</button>
</div>
</div>
</div>
<!-- Permohonan (Applications) Section - Enhanced with LZS theming -->
<div v-if="exampleData.currentSection === 'permohonan' && !exampleData.subSection" class="p-4 pb-24">
<!-- Tabs - Enhanced -->
<div class="flex mb-4 bg-gray-100 p-1 rounded-lg">
<button
v-for="tab in exampleData.permohonanTabs"
:key="tab.id"
@click="changeTab(tab.id)"
class="flex-1 py-2 px-3 rounded-md text-sm font-medium transition-all duration-200"
:class="exampleData.activeTab === tab.id ? 'bg-white text-primary shadow-sm' : 'text-gray-600'"
>
{{ tab.title }}
</button>
</div>
<!-- Active Applications Tab -->
<div v-if="exampleData.activeTab === 'active'" class="space-y-4">
<div
v-for="app in exampleData.permohonanData.activeApplications"
:key="app.id"
class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"
>
<div class="border-b border-gray-100 p-3 flex justify-between items-center">
<div>
<h4 class="font-medium">{{ app.id }}</h4>
<p class="text-xs text-gray-600">{{ app.submissionDate }}</p>
</div>
<div class="py-1 px-2.5 rounded-full text-xs font-medium"
:class="{
'badge-lulus': app.status === 'LULUS',
'badge-menunggu': app.status === 'MENUNGGU',
'badge-dalam-proses': app.status === 'DALAM PROSES',
'badge-ditolak': app.status === 'DITOLAK'
}">
{{ app.status }}
</div>
</div>
<div class="p-3">
<div class="mb-3">
<h3 class="font-medium text-gray-800">{{ app.type }}</h3>
<p class="text-sm text-gray-600">{{ app.amount }}</p>
</div>
<div class="space-y-2 mb-3">
<div class="flex text-sm">
<div class="w-24 text-gray-500">Pemohon</div>
<div class="font-medium">{{ app.pemohon }}</div>
</div>
<div class="flex text-sm">
<div class="w-24 text-gray-500">No. IC</div>
<div class="font-medium">{{ app.noIC }}</div>
</div>
<div class="flex text-sm">
<div class="w-24 text-gray-500">Telefon</div>
<div class="font-medium">{{ app.telefon }}</div>
</div>
</div>
<div class="flex justify-end space-x-2">
<button class="p-2 rounded-full bg-primary/10 text-primary">
<Icon name="ic:baseline-edit" size="18" />
</button>
<button class="p-2 rounded-full bg-secondary/10 text-secondary" @click="viewApplicationDetails(app.id, 'active')">
<Icon name="ic:baseline-visibility" size="18" />
</button>
<button class="p-2 rounded-full bg-danger/10 text-danger">
<Icon name="ic:baseline-delete" size="18" />
</button>
</div>
</div>
</div>
<!-- Empty state for active applications -->
<div v-if="exampleData.permohonanData.activeApplications.length === 0" class="text-center py-10">
<div class="w-16 h-16 mx-auto bg-gray-100 rounded-full flex items-center justify-center mb-3">
<Icon name="ic:baseline-article" size="28" class="text-gray-400" />
</div>
<h3 class="font-medium text-gray-700 mb-1">Tiada Permohonan Aktif</h3>
<p class="text-sm text-gray-500 mb-4">Anda tidak mempunyai sebarang permohonan aktif buat masa ini.</p>
<button class="px-4 py-2 bg-primary text-white rounded-lg font-medium shadow-sm">
Buat Permohonan Baru
</button>
</div>
</div>
<!-- Draft Applications Tab -->
<div v-if="exampleData.activeTab === 'draft'" class="space-y-4">
<div
v-for="app in exampleData.permohonanData.draftApplications"
:key="app.id"
class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"
>
<div class="border-b border-gray-100 p-3 flex justify-between items-center">
<div>
<h4 class="font-medium">{{ app.id }}</h4>
<p class="text-xs text-gray-600">Dikemaskini: {{ app.lastUpdated }}</p>
</div>
<div class="badge-deraf px-2.5 py-1 rounded-full text-xs font-medium">
DRAF
</div>
</div>
<div class="p-3">
<h3 class="font-medium text-gray-800 mb-3">{{ app.type }}</h3>
<div class="flex justify-end space-x-2">
<button class="px-3 py-1.5 rounded-md bg-primary text-white text-sm font-medium shadow-sm">
Teruskan
</button>
<button class="px-3 py-1.5 rounded-md bg-danger/10 text-danger text-sm font-medium">
Padam
</button>
</div>
</div>
</div>
<!-- Empty state for draft applications -->
<div v-if="exampleData.permohonanData.draftApplications.length === 0" class="text-center py-10">
<div class="w-16 h-16 mx-auto bg-gray-100 rounded-full flex items-center justify-center mb-3">
<Icon name="ic:baseline-draft" size="28" class="text-gray-400" />
</div>
<h3 class="font-medium text-gray-700 mb-1">Tiada Draf</h3>
<p class="text-sm text-gray-500 mb-4">Anda tidak mempunyai sebarang draf permohonan buat masa ini.</p>
</div>
</div>
<!-- History Applications Tab -->
<div v-if="exampleData.activeTab === 'history'" class="space-y-4">
<div
v-for="app in exampleData.permohonanData.historicalApplications"
:key="app.id"
class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"
>
<div class="border-b border-gray-100 p-3 flex justify-between items-center">
<div>
<h4 class="font-medium">{{ app.id }}</h4>
<p class="text-xs text-gray-600">{{ app.submissionDate }}</p>
</div>
<div class="py-1 px-2.5 rounded-full text-xs font-medium"
:class="{
'badge-lulus': app.status === 'LULUS',
'badge-menunggu': app.status === 'MENUNGGU',
'badge-dalam-proses': app.status === 'DALAM PROSES',
'badge-ditolak': app.status === 'DITOLAK'
}">
{{ app.status }}
</div>
</div>
<div class="p-3">
<div class="mb-3">
<h3 class="font-medium text-gray-800">{{ app.type }}</h3>
<p class="text-sm text-gray-600">{{ app.amount }}</p>
</div>
<div v-if="app.reason" class="p-2 bg-danger/5 rounded-md mb-3 border border-danger/10">
<p class="text-sm text-danger">{{ app.reason }}</p>
</div>
<div class="flex justify-end">
<button class="px-3 py-1.5 rounded-md bg-primary/10 text-primary text-sm font-medium">
Lihat Butiran
</button>
</div>
</div>
</div>
<!-- Empty state for history applications -->
<div v-if="exampleData.permohonanData.historicalApplications.length === 0" class="text-center py-10">
<div class="w-16 h-16 mx-auto bg-gray-100 rounded-full flex items-center justify-center mb-3">
<Icon name="ic:baseline-history" size="28" class="text-gray-400" />
</div>
<h3 class="font-medium text-gray-700 mb-1">Tiada Sejarah</h3>
<p class="text-sm text-gray-500">Anda belum mempunyai sebarang sejarah permohonan.</p>
</div>
</div>
</div>
<!-- Bantuan (Aid) Section - Enhanced with LZS theming -->
<div v-if="exampleData.currentSection === 'bantuan' && !exampleData.subSection" class="p-4 pb-24">
<div class="flex justify-between items-center mb-4">
<h3 class="text-base font-medium text-gray-800">Bantuan Aktif</h3>
<button
@click="createNewBantuan()"
class="px-3 py-1.5 rounded-md bg-primary text-white text-sm font-medium shadow-sm flex items-center"
>
<Icon name="ic:baseline-add" size="18" class="mr-1" />
Bantuan Baru
</button>
</div>
<!-- Active Aid Cards -->
<div class="space-y-4 mb-6">
<div
v-for="bantuan in exampleData.bantuanData.activeBantuan"
:key="bantuan.id"
class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"
>
<div class="border-b border-gray-100 p-3 flex justify-between items-center">
<div>
<h4 class="font-medium">{{ bantuan.type }}</h4>
<p class="text-xs text-gray-600">{{ bantuan.referenceNo }}</p>
</div>
<div class="badge-aktif py-1 px-2.5 rounded-full text-xs font-medium">
{{ bantuan.status }}
</div>
</div>
<div class="p-3">
<div class="mb-3">
<div class="grid grid-cols-2 gap-3">
<div>
<p class="text-xs text-gray-500 mb-1">Jumlah</p>
<p class="font-medium text-secondary">{{ bantuan.amount }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Kategori</p>
<p class="font-medium">{{ bantuan.category }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Tarikh Mula</p>
<p class="font-medium">{{ bantuan.startDate }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Tarikh Tamat</p>
<p class="font-medium">{{ bantuan.endDate }}</p>
</div>
</div>
</div>
<div class="flex items-center p-2 bg-accent/5 rounded-lg border border-accent/20 mb-3">
<Icon name="ic:baseline-calendar-today" class="text-accent mr-2" size="18" />
<div>
<p class="text-xs text-gray-600 mb-0.5">Pembayaran Seterusnya</p>
<p class="font-medium">{{ bantuan.nextPayment }}</p>
</div>
</div>
<div class="flex justify-end space-x-2">
<button class="px-3 py-1.5 rounded-md bg-primary/10 text-primary text-sm font-medium" @click="viewBantuanDetails(bantuan.id)">
Lihat Butiran
</button>
<button class="px-3 py-1.5 rounded-md bg-secondary text-white text-sm font-medium shadow-sm">
Semak Status
</button>
</div>
</div>
</div>
</div>
<!-- Payment History Section -->
<h3 class="text-base font-medium mb-3 text-gray-800">Sejarah Pembayaran</h3>
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden mb-6">
<div class="divide-y divide-gray-100">
<div
v-for="payment in exampleData.bantuanData.paymentHistory.slice(0, 3)"
:key="payment.id"
class="p-3"
>
<div class="flex justify-between items-center">
<div>
<p class="font-medium">{{ payment.amount }}</p>
<p class="text-xs text-gray-600">{{ payment.date }}</p>
</div>
<div class="text-right">
<p class="text-sm">{{ payment.type }}</p>
<span class="text-xs px-1.5 py-0.5 bg-secondary/10 text-secondary rounded-full">
{{ payment.status }}
</span>
</div>
</div>
</div>
</div>
<div class="p-2 border-t border-gray-100 text-center">
<button class="text-sm text-primary font-medium">
Lihat Semua Pembayaran
</button>
</div>
</div>
<!-- Nearby Facilities Section -->
<h3 class="text-base font-medium mb-3 text-gray-800">Kemudahan Berdekatan</h3>
<div class="space-y-3 mb-6">
<div
v-for="facility in exampleData.bantuanData.nearbyFacilities"
:key="facility.name"
class="bg-white rounded-xl p-3 shadow-sm border border-gray-100"
>
<div class="flex items-start">
<div class="bg-primary/10 rounded-md p-2 mr-3">
<Icon
:name="facility.type.includes('Pejabat') ? 'ic:baseline-apartment' :
facility.type.includes('Agihan') ? 'ic:baseline-store' :
'ic:baseline-local-hospital'"
size="20"
class="text-primary"
/>
</div>
<div class="flex-1">
<div class="flex justify-between">
<h4 class="font-medium text-gray-800">{{ facility.name }}</h4>
<span class="text-xs bg-primary/5 py-0.5 px-1.5 rounded text-primary">{{ facility.distance }}</span>
</div>
<p class="text-xs text-gray-600 mt-1">{{ facility.address }}</p>
<div class="flex justify-between items-center mt-2">
<p class="text-xs text-gray-500">{{ facility.type }}</p>
<button class="text-xs text-primary flex items-center">
<Icon name="ic:baseline-call" size="14" class="mr-1" />
Hubungi
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Notifications Page - Enhanced with LZS theming -->
<div v-if="exampleData.currentSection === 'notifikasi'" class="p-4 pb-24">
<div class="flex justify-between items-center mb-4">
<h3 class="text-base font-medium text-gray-800">Notifikasi ({{ exampleData.notificationData.items.length }})</h3>
<button v-if="exampleData.notificationData.unread > 0" class="text-xs text-primary font-medium" @click="markAllAsRead">
Tandakan Semua Dibaca
</button>
</div>
<div class="space-y-3">
<div
v-for="notification in exampleData.notificationData.items"
:key="notification.id"
class="bg-white rounded-xl shadow-sm border overflow-hidden transition-all"
:class="notification.unread ? 'border-l-4 border-l-primary border-gray-100' : 'border-gray-100'"
>
<div class="p-3.5">
<div class="flex items-start">
<div class="flex-shrink-0 mr-3">
<div class="w-10 h-10 rounded-full flex items-center justify-center"
:class="{
'bg-secondary/15 text-secondary': notification.type === 'success',
'bg-warning/15 text-warning': notification.type === 'warning',
'bg-primary/15 text-primary': notification.type === 'info',
'bg-danger/15 text-danger': notification.type === 'error'
}"
>
<Icon
:name="{
'success': 'ic:baseline-check-circle',
'warning': 'ic:baseline-warning',
'info': 'ic:baseline-info',
'error': 'ic:baseline-error'
}[notification.type]"
size="20"
/>
</div>
</div>
<div class="flex-1">
<div class="flex justify-between items-start">
<h4 class="font-medium mb-1">{{ notification.title }}</h4>
<div class="flex items-center">
<span v-if="notification.unread" class="w-2.5 h-2.5 bg-primary rounded-full mr-2"></span>
<button @click="deleteNotification(notification.id)" class="text-gray-400">
<Icon name="ic:baseline-close" size="18" />
</button>
</div>
</div>
<p class="text-sm text-gray-600 mb-2">{{ notification.content }}</p>
<div class="flex justify-between items-center">
<span class="text-xs text-gray-500">{{ notification.time }}</span>
<button
v-if="notification.action"
class="text-xs bg-primary/10 text-primary py-1 px-2 rounded-md font-medium"
@click="handleNotificationAction(notification)"
>
{{ notification.actionText || 'Lihat' }}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Empty state for notifications -->
<div v-if="exampleData.notificationData.items.length === 0" class="text-center py-10">
<div class="w-16 h-16 mx-auto bg-gray-100 rounded-full flex items-center justify-center mb-3">
<Icon name="ic:baseline-notifications-off" size="28" class="text-gray-400" />
</div>
<h3 class="font-medium text-gray-700 mb-1">Tiada Notifikasi</h3>
<p class="text-sm text-gray-500">Anda tidak mempunyai sebarang notifikasi buat masa ini.</p>
</div>
</div>
</div>
<!-- Profile Page - Enhanced with LZS theming -->
<div v-if="exampleData.currentSection === 'profile'" class="pb-24">
<!-- Profile Header with background -->
<div class="bg-primary pb-20 pt-6 px-4 rounded-b-[40px] shadow-md relative">
<div class="flex flex-col items-center">
<div class="w-20 h-20 rounded-xl bg-white/20 text-white flex items-center justify-center font-bold text-3xl shadow-md border border-white/30">
{{ exampleData.userProfile.avatar }}
</div>
<h2 class="mt-3 text-white font-semibold text-lg">{{ exampleData.userProfile.name }}</h2>
<p class="text-white/80 text-sm">{{ exampleData.userProfile.email }}</p>
<div class="mt-2 bg-secondary/20 py-1 px-3 rounded-full text-white/90 text-sm flex items-center shadow-sm">
<Icon name="ic:baseline-verified-user" class="mr-1.5" size="16" />
{{ exampleData.userProfile.department }}
</div>
</div>
</div>
<!-- Profile Content -->
<div class="px-4 -mt-16">
<!-- Personal Information Card -->
<div class="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h3 class="font-medium flex items-center text-gray-800">
<Icon name="ic:baseline-person" class="mr-2 text-primary" size="20" />
Maklumat Peribadi
</h3>
</div>
<div class="p-4 space-y-4">
<div>
<p class="text-xs text-gray-500 mb-1">No. Kad Pengenalan</p>
<p class="font-medium">{{ exampleData.userProfile.id }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Nombor Telefon</p>
<p class="font-medium">{{ exampleData.userProfile.phone }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Alamat</p>
<p class="font-medium">{{ exampleData.userProfile.address }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Jawatan</p>
<p class="font-medium">{{ exampleData.userProfile.position }}</p>
</div>
<div>
<p class="text-xs text-gray-500 mb-1">Tarikh Kelulusan</p>
<p class="font-medium">{{ exampleData.userProfile.joinDate }}</p>
</div>
</div>
<div class="border-t border-gray-100 p-3 flex justify-end">
<button class="text-sm bg-primary/10 text-primary py-1.5 px-3 rounded-lg font-medium">
Kemaskini Maklumat
</button>
</div>
</div>
<!-- Account Settings Card -->
<div class="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h3 class="font-medium flex items-center text-gray-800">
<Icon name="ic:baseline-settings" class="mr-2 text-primary" size="20" />
Tetapan Akaun
</h3>
</div>
<div class="divide-y divide-gray-100">
<button
v-for="action in exampleData.userProfile.actions"
:key="action.name"
class="w-full flex justify-between items-center p-4 hover:bg-gray-50 transition-colors"
>
<div class="flex items-center">
<Icon :name="action.icon" size="20" class="text-gray-500 mr-3" />
<span>{{ action.name }}</span>
</div>
<Icon name="ic:baseline-arrow-forward-ios" size="16" class="text-gray-400" />
</button>
</div>
</div>
<!-- Support Card -->
<div class="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h3 class="font-medium flex items-center text-gray-800">
<Icon name="ic:baseline-support-agent" class="mr-2 text-primary" size="20" />
Sokongan
</h3>
</div>
<div class="p-4">
<div class="bg-primary/5 rounded-lg p-3 border border-primary/10 flex items-start mb-3">
<Icon name="ic:baseline-info" class="text-primary mr-2 mt-0.5" size="18" />
<div>
<p class="text-sm font-medium mb-1">Pusat Bantuan</p>
<p class="text-xs text-gray-600">Dapatkan jawapan untuk soalan lazim dan bantuan menggunakan aplikasi ini.</p>
</div>
</div>
<div class="bg-gray-100 rounded-lg p-4 flex items-center justify-between">
<div>
<p class="text-sm font-medium">Hubungi Kami</p>
<p class="text-xs text-gray-600">603-9235 5678</p>
</div>
<button class="w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center">
<Icon name="ic:baseline-call" size="20" />
</button>
</div>
</div>
</div>
<!-- Logout Button -->
<button class="w-full py-3 bg-danger/10 text-danger rounded-lg font-medium mb-6 flex items-center justify-center">
<Icon name="ic:baseline-logout" class="mr-2" size="20" />
Log Keluar
</button>
</div>
</div>
</div>
</transition>
<!-- Floating Action Button (FAB) -->
<div
class="fab bg-primary text-white shadow-lg hover:bg-primary-dark transition-transform"
@click="toggleFabMenu"
:class="{ 'rotate-45': exampleData.showFabMenu }"
>
<Icon name="ic:baseline-add" size="24" />
</div>
<!-- FAB Menu -->
<div class="fab-menu" v-if="exampleData.showFabMenu">
<div
v-for="(type, index) in exampleData.permohonanData.applicationTypes.slice(0, 3)"
:key="type.id"
class="fab-item"
:class="{ 'expanded': animationStates.fabExpanded }"
:style="{ 'transition-delay': `${0.05 * (exampleData.permohonanData.applicationTypes.slice(0, 3).length - index)}s` }"
>
<div class="fab-item-text shadow-md bg-white">{{ type.name }}</div>
<button
class="fab-item-button bg-primary text-white shadow-lg hover:bg-primary-dark transition-all"
@click="createNewApplication(type.name)"
>
<Icon name="ic:baseline-add" size="20" />
</button>
</div>
</div>
</div>
<!-- Drawer Menu - Move outside mobile-content to ensure it's above the header -->
<div v-if="exampleData.showMenu" class="mobile-drawer">
<!-- Overlay -->
<div
class="absolute inset-0 bg-black transition-opacity w-full h-full"
:class="animationStates.menuExpanded ? 'bg-opacity-50' : 'bg-opacity-0'"
@click="toggleMenu"
></div>
<!-- Drawer Content -->
<div
class="drawer-content absolute left-0 top-0 bottom-0 w-4/5 max-w-[260px] bg-white flex flex-col shadow-2xl"
:class="{ 'expanded': animationStates.menuExpanded }"
>
<!-- User Profile Section - Enhanced -->
<div class="bg-sidebar p-4 text-white">
<div class="flex items-center space-x-3">
<div class="w-12 h-12 rounded-full bg-white text-primary flex items-center justify-center font-bold text-xl shadow-md">
{{ exampleData.userProfile.avatar }}
</div>
<div>
<p class="font-medium">{{ exampleData.userProfile.name }}</p>
<p class="text-xs opacity-80">{{ exampleData.userProfile.email }}</p>
<div class="mt-2 bg-accent/20 py-1 px-2 rounded-full inline-flex items-center shadow-sm">
<span class="text-xs font-medium text-accent">{{ exampleData.userProfile.department }}</span>
</div>
</div>
</div>
</div>
<!-- Menu Items -->
<div class="overflow-y-auto flex-1">
<div class="py-2">
<button
v-for="(page, index) in exampleData.demoPages"
:key="index"
@click="exampleData.currentSection = page.id; toggleMenu()"
class="w-full flex items-center px-4 py-3 hover:bg-gray-50 transition-colors"
:class="{ 'border-l-4 border-accent bg-primary/5': exampleData.currentSection === page.id }"
>
<Icon :name="page.icon" class="mr-3" size="20" :class="exampleData.currentSection === page.id ? 'text-primary' : 'text-gray-600'" />
<span :class="exampleData.currentSection === page.id ? 'text-primary font-medium' : ''">{{ page.title }}</span>
<span
v-if="page.id === 'permohonan' && exampleData.permohonanData.activeApplications.length > 0"
class="ml-2 bg-accent text-primary text-xs px-2 py-0.5 rounded-full font-bold"
>
{{ exampleData.permohonanData.activeApplications.length }}
</span>
</button>
<div class="border-t border-gray-200 my-2"></div>
<button class="w-full flex items-center px-4 py-3 hover:bg-gray-50 transition-colors">
<Icon name="ic:baseline-help" class="mr-3 text-gray-600" size="20" />
<span>Bantuan</span>
</button>
<button class="w-full flex items-center px-4 py-3 hover:bg-gray-50 transition-colors">
<Icon name="ic:baseline-info" class="mr-3 text-gray-600" size="20" />
<span>Tentang Kami</span>
</button>
</div>
</div>
<!-- Logout Button -->
<div class="border-t border-gray-200 p-4">
<button class="flex items-center text-red-600">
<Icon name="ic:baseline-logout" class="mr-2" size="20" />
<span>Log Keluar</span>
</button>
</div>
</div>
</div>
<!-- Bottom Navigation - Fixed at bottom -->
<div class="bottom-nav-container">
<div class="bottom-nav bg-white shadow-lg border-t flex justify-around py-2">
<button
v-for="page in exampleData.demoPages"
:key="page.id"
@click="navigateTo(page.id)"
class="flex flex-col items-center p-2 relative"
:class="exampleData.currentSection === page.id ? 'text-primary' : 'text-gray-500'"
>
<div class="w-6 h-6 flex items-center justify-center" :class="exampleData.currentSection === page.id ? 'bg-primary/10 rounded-full' : ''">
<Icon :name="page.icon" size="20" />
</div>
<span class="text-xs mt-1" :class="exampleData.currentSection === page.id ? 'font-medium' : ''">{{ page.title }}</span>
<!-- Notification badge for permohonan -->
<span
v-if="page.id === 'permohonan' && exampleData.permohonanData.activeApplications.length > 0"
class="absolute -top-1 -right-1 w-4 h-4 bg-accent rounded-full text-primary text-[8px] font-bold flex items-center justify-center shadow-sm"
>
{{ exampleData.permohonanData.activeApplications.length }}
</span>
<!-- Notification badge for notifikasi -->
<span
v-if="page.id === 'notifikasi' && exampleData.notificationData.unread > 0"
class="absolute -top-1 -right-1 w-4 h-4 bg-accent rounded-full text-primary text-[8px] font-bold flex items-center justify-center shadow-sm"
>
{{ exampleData.notificationData.unread }}
</span>
</button>
</div>
</div>
</div>
<!-- Phone Bottom Bar -->
<div class="h-4 bg-black pixel-nav-bar flex justify-center items-center">
<div class="w-1/3 h-1 bg-white rounded-full"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Bantuan Form Page (New) -->
<div v-if="exampleData.currentSection === 'bantuan' && exampleData.subSection === 'new'" class="p-4 pb-24">
<h3 class="h3 mb-4 text-gray-800">Permohonan Bantuan Baru</h3>
<!-- Stepper / Progress indicator -->
<div class="mb-6">
<div class="flex items-center justify-between">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-primary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">1</div>
<span class="text-xs font-medium mt-1 text-primary">Maklumat</span>
</div>
<div class="flex-1 h-1 mx-2 bg-primary"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-200 text-gray-600 rounded-full flex items-center justify-center font-medium text-sm">2</div>
<span class="text-xs font-medium mt-1 text-gray-500">Dokumen</span>
</div>
<div class="flex-1 h-1 mx-2 bg-gray-200"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-200 text-gray-600 rounded-full flex items-center justify-center font-medium text-sm">3</div>
<span class="text-xs font-medium mt-1 text-gray-500">Pengesahan</span>
</div>
</div>
</div>
<!-- Form Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-person" class="mr-2 text-primary" size="20" />
Maklumat Peribadi
</h4>
</div>
<div class="p-4 space-y-4">
<!-- Type of Aid -->
<div>
<label class="form-label mb-1.5 block">Jenis Bantuan <span class="text-danger">*</span></label>
<select
v-model="exampleData.bantuanForm.type"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.type }"
>
<option value="" disabled selected>-- Pilih Jenis Bantuan --</option>
<option v-for="type in exampleData.bantuanData.bantuanCategories" :key="type.id" :value="type.name">
{{ type.name }}
</option>
</select>
<p v-if="exampleData.formErrors.type" class="text-danger text-xs mt-1">Sila pilih jenis bantuan</p>
<!-- Type description if selected -->
<div v-if="exampleData.bantuanForm.type" class="mt-2 p-2 bg-primary/5 rounded-md text-xs">
<p class="font-medium mb-1">{{ exampleData.bantuanForm.type }}</p>
<p class="text-gray-600">
{{ exampleData.bantuanData.bantuanCategories.find(t => t.name === exampleData.bantuanForm.type)?.description || '' }}
</p>
</div>
</div>
<!-- Asnaf Category -->
<div>
<label class="form-label mb-1.5 block">Kategori Asnaf <span class="text-danger">*</span></label>
<select
v-model="exampleData.bantuanForm.category"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.category }"
>
<option value="" disabled selected>-- Pilih Kategori Asnaf --</option>
<option value="Fakir">Fakir</option>
<option value="Miskin">Miskin</option>
<option value="Amil">Amil</option>
<option value="Muallaf">Muallaf</option>
<option value="Gharimin">Gharimin</option>
<option value="Fisabilillah">Fisabilillah</option>
<option value="Ibnu Sabil">Ibnu Sabil</option>
</select>
<p v-if="exampleData.formErrors.category" class="text-danger text-xs mt-1">Sila pilih kategori asnaf</p>
</div>
<!-- Full Name -->
<div>
<label class="form-label mb-1.5 block">Nama Penuh <span class="text-danger">*</span></label>
<input
type="text"
v-model="exampleData.bantuanForm.fullName"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.fullName }"
placeholder="Masukkan nama penuh"
/>
<p v-if="exampleData.formErrors.fullName" class="text-danger text-xs mt-1">Sila masukkan nama penuh</p>
</div>
<!-- ID Number -->
<div>
<label class="form-label mb-1.5 block">No. Kad Pengenalan <span class="text-danger">*</span></label>
<input
type="text"
v-model="exampleData.bantuanForm.idNumber"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.idNumber }"
placeholder="Cth: 860215-14-5732"
/>
<p v-if="exampleData.formErrors.idNumber" class="text-danger text-xs mt-1">Sila masukkan nombor kad pengenalan yang sah</p>
</div>
</div>
</div>
<!-- Contact Information Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-contact-phone" class="mr-2 text-primary" size="20" />
Maklumat Perhubungan
</h4>
</div>
<div class="p-4 space-y-4">
<!-- Phone Number -->
<div>
<label class="form-label mb-1.5 block">No. Telefon <span class="text-danger">*</span></label>
<input
type="tel"
v-model="exampleData.bantuanForm.phone"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.phone }"
placeholder="Cth: 019-8765432"
/>
<p v-if="exampleData.formErrors.phone" class="text-danger text-xs mt-1">Sila masukkan nombor telefon yang sah</p>
</div>
<!-- Email -->
<div>
<label class="form-label mb-1.5 block">Alamat E-mel</label>
<input
type="email"
v-model="exampleData.bantuanForm.email"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.email }"
placeholder="Cth: nama@contoh.com"
/>
<p v-if="exampleData.formErrors.email" class="text-danger text-xs mt-1">Sila masukkan alamat e-mel yang sah</p>
</div>
<!-- Address -->
<div>
<label class="form-label mb-1.5 block">Alamat <span class="text-danger">*</span></label>
<textarea
v-model="exampleData.bantuanForm.address"
class="form-input w-full min-h-[80px]"
:class="{ 'border-danger': exampleData.formErrors.address }"
placeholder="Masukkan alamat penuh"
></textarea>
<p v-if="exampleData.formErrors.address" class="text-danger text-xs mt-1">Sila masukkan alamat</p>
</div>
</div>
</div>
<!-- Bank Information Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-account-balance" class="mr-2 text-primary" size="20" />
Maklumat Bank
</h4>
</div>
<div class="p-4 space-y-4">
<!-- Bank Name -->
<div>
<label class="form-label mb-1.5 block">Nama Bank <span class="text-danger">*</span></label>
<select
v-model="exampleData.bantuanForm.bankName"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.bankName }"
>
<option value="" disabled selected>-- Pilih Bank --</option>
<option value="Bank Islam">Bank Islam</option>
<option value="Maybank">Maybank</option>
<option value="CIMB Bank">CIMB Bank</option>
<option value="Bank Rakyat">Bank Rakyat</option>
<option value="RHB Bank">RHB Bank</option>
</select>
<p v-if="exampleData.formErrors.bankName" class="text-danger text-xs mt-1">Sila pilih bank</p>
</div>
<!-- Account Number -->
<div>
<label class="form-label mb-1.5 block">No. Akaun Bank <span class="text-danger">*</span></label>
<input
type="text"
v-model="exampleData.bantuanForm.accountNumber"
class="form-input w-full"
:class="{ 'border-danger': exampleData.formErrors.accountNumber }"
placeholder="Masukkan nombor akaun bank"
/>
<p v-if="exampleData.formErrors.accountNumber" class="text-danger text-xs mt-1">Sila masukkan nombor akaun yang sah</p>
</div>
</div>
</div>
<!-- Reason Section -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-info" class="mr-2 text-primary" size="20" />
Sebab Permohonan
</h4>
</div>
<div class="p-4 space-y-4">
<div>
<label class="form-label mb-1.5 block">Alasan Memohon <span class="text-danger">*</span></label>
<textarea
v-model="exampleData.bantuanForm.reason"
class="form-input w-full min-h-[100px]"
:class="{ 'border-danger': exampleData.formErrors.reason }"
placeholder="Sila nyatakan sebab keperluan bantuan dengan terperinci"
></textarea>
<p v-if="exampleData.formErrors.reason" class="text-danger text-xs mt-1">Sila nyatakan alasan permohonan</p>
</div>
</div>
</div>
<!-- Form Action Buttons -->
<div class="flex justify-between items-center mt-6 mb-4">
<button class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg flex items-center">
<Icon name="ic:baseline-save" class="mr-2" size="18" />
Simpan Draf
</button>
<button @click="navigateTo('bantuan', 'documents')" class="px-4 py-2 bg-primary text-white rounded-lg shadow-sm flex items-center">
Langkah Seterusnya
<Icon name="ic:baseline-arrow-forward" class="ml-2" size="18" />
</button>
</div>
<!-- Help tip -->
<div class="bg-primary/5 p-3 rounded-lg border border-primary/10 mb-4 flex items-start">
<Icon name="ic:baseline-info" class="text-primary mr-2 mt-0.5" size="18" />
<div class="text-xs">
<p class="font-medium mb-1">Bantuan untuk pengisian</p>
<p class="text-gray-600">Sila isi semua maklumat yang diperlukan dengan tepat. Medan bertanda <span class="text-danger">*</span> adalah wajib.</p>
</div>
</div>
</div>
<!-- Bantuan Documents Upload Page -->
<div v-if="exampleData.currentSection === 'bantuan' && exampleData.subSection === 'documents'" class="p-4 pb-24">
<h3 class="h3 mb-4 text-gray-800">Muat Naik Dokumen</h3>
<!-- Stepper / Progress indicator -->
<div class="mb-6">
<div class="flex items-center justify-between">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-secondary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">
<Icon name="ic:baseline-check" size="16" />
</div>
<span class="text-xs font-medium mt-1 text-secondary">Maklumat</span>
</div>
<div class="flex-1 h-1 mx-2 bg-primary"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-primary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">2</div>
<span class="text-xs font-medium mt-1 text-primary">Dokumen</span>
</div>
<div class="flex-1 h-1 mx-2 bg-gray-200"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-200 text-gray-600 rounded-full flex items-center justify-center font-medium text-sm">3</div>
<span class="text-xs font-medium mt-1 text-gray-500">Pengesahan</span>
</div>
</div>
</div>
<!-- Required Documents Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-description" class="mr-2 text-primary" size="20" />
Dokumen Wajib
</h4>
</div>
<div class="p-4">
<!-- ID Card Document -->
<div class="mb-4 border border-gray-100 rounded-lg p-3">
<div class="flex justify-between items-start mb-2">
<div>
<h5 class="h5 text-gray-800">Kad Pengenalan</h5>
<p class="text-xs text-gray-500">Salinan depan dan belakang</p>
</div>
<span class="text-xs bg-warning/15 text-warning py-0.5 px-2 rounded-full font-medium">Diperlukan</span>
</div>
<button class="w-full border border-dashed border-gray-300 rounded-lg p-4 flex flex-col items-center justify-center bg-gray-50">
<Icon name="ic:baseline-cloud-upload" size="24" class="text-primary mb-2" />
<span class="text-sm font-medium text-gray-700">Klik untuk muat naik</span>
<span class="text-xs text-gray-500 mt-1">Format: JPG, PNG, PDF</span>
</button>
</div>
<!-- Income Proof Document -->
<div class="mb-4 border border-gray-100 rounded-lg p-3">
<div class="flex justify-between items-start mb-2">
<div>
<h5 class="h5 text-gray-800">Bukti Pendapatan</h5>
<p class="text-xs text-gray-500">Slip gaji / Penyata pencen / Penyata Pendapatan</p>
</div>
<span class="text-xs bg-warning/15 text-warning py-0.5 px-2 rounded-full font-medium">Diperlukan</span>
</div>
<button class="w-full border border-dashed border-gray-300 rounded-lg p-4 flex flex-col items-center justify-center bg-gray-50">
<Icon name="ic:baseline-cloud-upload" size="24" class="text-primary mb-2" />
<span class="text-sm font-medium text-gray-700">Klik untuk muat naik</span>
<span class="text-xs text-gray-500 mt-1">Format: JPG, PNG, PDF</span>
</button>
</div>
<!-- Bank Statement Document -->
<div class="mb-4 border border-gray-100 rounded-lg p-3">
<div class="flex justify-between items-start mb-2">
<div>
<h5 class="h5 text-gray-800">Penyata Bank</h5>
<p class="text-xs text-gray-500">Penyata bank 3 bulan terkini</p>
</div>
<span class="text-xs bg-warning/15 text-warning py-0.5 px-2 rounded-full font-medium">Diperlukan</span>
</div>
<button class="w-full border border-dashed border-gray-300 rounded-lg p-4 flex flex-col items-center justify-center bg-gray-50">
<Icon name="ic:baseline-cloud-upload" size="24" class="text-primary mb-2" />
<span class="text-sm font-medium text-gray-700">Klik untuk muat naik</span>
<span class="text-xs text-gray-500 mt-1">Format: JPG, PNG, PDF</span>
</button>
</div>
</div>
</div>
<!-- Supporting Documents Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-backup" class="mr-2 text-primary" size="20" />
Dokumen Sokongan
</h4>
</div>
<div class="p-4">
<!-- Medical Document -->
<div class="mb-4 border border-gray-100 rounded-lg p-3">
<div class="flex justify-between items-start mb-2">
<div>
<h5 class="h5 text-gray-800">Laporan Perubatan</h5>
<p class="text-xs text-gray-500">Jika berkenaan</p>
</div>
<span class="text-xs bg-gray-100 text-gray-600 py-0.5 px-2 rounded-full font-medium">Pilihan</span>
</div>
<button class="w-full border border-dashed border-gray-300 rounded-lg p-4 flex flex-col items-center justify-center bg-gray-50">
<Icon name="ic:baseline-cloud-upload" size="24" class="text-primary mb-2" />
<span class="text-sm font-medium text-gray-700">Klik untuk muat naik</span>
<span class="text-xs text-gray-500 mt-1">Format: JPG, PNG, PDF</span>
</button>
</div>
<!-- Add Document Button -->
<button class="w-full py-2.5 text-sm text-primary flex items-center justify-center">
<Icon name="ic:baseline-add" size="18" class="mr-1" />
Tambah Dokumen Lain
</button>
</div>
</div>
<!-- Form Action Buttons -->
<div class="flex justify-between items-center mt-6 mb-4">
<button @click="navigateTo('bantuan', 'new')" class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg flex items-center">
<Icon name="ic:baseline-arrow-back" class="mr-2" size="18" />
Kembali
</button>
<button @click="navigateTo('bantuan', 'review')" class="px-4 py-2 bg-primary text-white rounded-lg shadow-sm flex items-center">
Langkah Seterusnya
<Icon name="ic:baseline-arrow-forward" class="ml-2" size="18" />
</button>
</div>
</div>
<!-- Bantuan Review & Submit Page -->
<div v-if="exampleData.currentSection === 'bantuan' && exampleData.subSection === 'review'" class="p-4 pb-24">
<h3 class="h3 mb-4 text-gray-800">Semak & Hantar</h3>
<!-- Stepper / Progress indicator -->
<div class="mb-6">
<div class="flex items-center justify-between">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-secondary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">
<Icon name="ic:baseline-check" size="16" />
</div>
<span class="text-xs font-medium mt-1 text-secondary">Maklumat</span>
</div>
<div class="flex-1 h-1 mx-2 bg-secondary"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-secondary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">
<Icon name="ic:baseline-check" size="16" />
</div>
<span class="text-xs font-medium mt-1 text-secondary">Dokumen</span>
</div>
<div class="flex-1 h-1 mx-2 bg-primary"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-primary text-white rounded-full flex items-center justify-center font-medium text-sm shadow-sm">3</div>
<span class="text-xs font-medium mt-1 text-primary">Pengesahan</span>
</div>
</div>
</div>
<!-- Summary Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-summarize" class="mr-2 text-primary" size="20" />
Ringkasan Permohonan
</h4>
</div>
<div class="p-4">
<!-- Bantuan Details -->
<div class="mb-4">
<h5 class="h5 mb-2 text-gray-800">Maklumat Bantuan</h5>
<div class="bg-gray-50 rounded-lg p-3 space-y-2">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Jenis Bantuan:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.type || "Bantuan Sara Hidup" }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Kategori Asnaf:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.category || "Fakir" }}</span>
</div>
</div>
</div>
<!-- Personal Details -->
<div class="mb-4">
<h5 class="h5 mb-2 text-gray-800">Maklumat Peribadi</h5>
<div class="bg-gray-50 rounded-lg p-3 space-y-2">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Nama Penuh:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.fullName || exampleData.userProfile.name }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">No. Kad Pengenalan:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.idNumber || exampleData.userProfile.id }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">No. Telefon:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.phone || exampleData.userProfile.phone }}</span>
</div>
<div class="flex justify-between items-start">
<span class="text-sm text-gray-600">Alamat:</span>
<span class="text-sm font-medium text-right max-w-[60%]">{{ exampleData.bantuanForm.address || exampleData.userProfile.address }}</span>
</div>
</div>
</div>
<!-- Bank Details -->
<div class="mb-4">
<h5 class="h5 mb-2 text-gray-800">Maklumat Bank</h5>
<div class="bg-gray-50 rounded-lg p-3 space-y-2">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Nama Bank:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.bankName || "Bank Islam" }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">No. Akaun:</span>
<span class="text-sm font-medium">{{ exampleData.bantuanForm.accountNumber || "xxxx-xxx-xxxxx" }}</span>
</div>
</div>
</div>
<!-- Documents -->
<div>
<h5 class="h5 mb-2 text-gray-800">Dokumen</h5>
<div class="bg-gray-50 rounded-lg p-3">
<div class="flex items-center mb-2">
<Icon name="ic:baseline-check-circle" class="text-secondary mr-2" size="16" />
<span class="text-sm">Kad Pengenalan (dimuat naik)</span>
</div>
<div class="flex items-center mb-2">
<Icon name="ic:baseline-check-circle" class="text-secondary mr-2" size="16" />
<span class="text-sm">Bukti Pendapatan (dimuat naik)</span>
</div>
<div class="flex items-center">
<Icon name="ic:baseline-check-circle" class="text-secondary mr-2" size="16" />
<span class="text-sm">Penyata Bank (dimuat naik)</span>
</div>
</div>
</div>
</div>
</div>
<!-- Declaration Section -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 mb-5">
<div class="border-b border-gray-100 p-4">
<h4 class="h4 flex items-center text-gray-800">
<Icon name="ic:baseline-gavel" class="mr-2 text-primary" size="20" />
Pengakuan
</h4>
</div>
<div class="p-4">
<div class="bg-gray-50 p-3 rounded-lg mb-3 text-sm text-gray-700">
<p>Saya mengaku bahawa segala maklumat yang diberikan dalam permohonan ini adalah benar dan tepat. Saya faham bahawa sebarang maklumat palsu boleh menyebabkan permohonan ditolak dan tindakan undang-undang diambil.</p>
</div>
<div class="flex items-center mb-3">
<input type="checkbox" id="agreement" class="mr-2 h-4 w-4 text-primary focus:ring-primary">
<label for="agreement" class="text-sm">Saya bersetuju dengan syarat-syarat yang dinyatakan di atas</label>
</div>
</div>
</div>
<!-- Form Action Buttons -->
<div class="flex justify-between items-center mt-6 mb-4">
<button @click="navigateTo('bantuan', 'documents')" class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg flex items-center">
<Icon name="ic:baseline-arrow-back" class="mr-2" size="18" />
Kembali
</button>
<button @click="submitBantuanForm" class="px-5 py-2.5 bg-primary text-white rounded-lg shadow-sm flex items-center font-medium">
<Icon name="ic:baseline-send" class="mr-2" size="18" />
Hantar Permohonan
</button>
</div>
<!-- Help tip -->
<div class="bg-warning/5 p-3 rounded-lg border border-warning/10 mb-4 flex items-start">
<Icon name="ic:baseline-info" class="text-warning mr-2 mt-0.5" size="18" />
<div class="text-xs">
<p class="font-medium mb-1">Peringatan Penting</p>
<p class="text-gray-600">Sila semak semua maklumat dengan teliti sebelum menghantar. Permohonan yang telah dihantar tidak boleh diedit.</p>
</div>
</div>
</div>
<!-- Bantuan Application Success Page -->
<div v-if="exampleData.currentSection === 'bantuan' && exampleData.subSection === 'success'" class="p-4 pb-24">
<div class="text-center py-8">
<div class="w-20 h-20 bg-secondary/15 rounded-full flex items-center justify-center mx-auto mb-6">
<Icon name="ic:baseline-check-circle" class="text-secondary" size="48" />
</div>
<h3 class="h3 mb-2 text-gray-800">Permohonan Berjaya Dihantar!</h3>
<p class="text-gray-600 mb-6">Terima kasih. Permohonan anda telah berjaya dihantar dan kini dalam proses semakan.</p>
<div class="bg-white rounded-xl shadow-md border border-gray-100 p-4 mb-6 text-left">
<div class="flex justify-between items-center mb-3">
<span class="text-sm text-gray-600">Nombor Rujukan:</span>
<span class="font-bold text-primary">BSH-23/5789</span>
</div>
<div class="flex justify-between items-center mb-3">
<span class="text-sm text-gray-600">Tarikh Permohonan:</span>
<span class="font-medium">10 Jun 2023</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Status:</span>
<span class="badge-menunggu py-1 px-2.5 rounded-full text-xs font-medium">MENUNGGU</span>
</div>
</div>
<div class="bg-primary/5 p-4 rounded-lg border border-primary/10 mb-6 text-left">
<h5 class="h5 mb-2 text-primary">Langkah Seterusnya</h5>
<ul class="text-sm space-y-2">
<li class="flex items-start">
<Icon name="ic:baseline-circle" class="text-primary mr-2 mt-1" size="8" />
<span>Permohonan anda akan disemak dalam tempoh 7-14 hari bekerja.</span>
</li>
<li class="flex items-start">
<Icon name="ic:baseline-circle" class="text-primary mr-2 mt-1" size="8" />
<span>Anda akan menerima notifikasi sebarang kemajuan melalui SMS atau sistem ini.</span>
</li>
<li class="flex items-start">
<Icon name="ic:baseline-circle" class="text-primary mr-2 mt-1" size="8" />
<span>Pegawai kami mungkin akan menghubungi anda jika maklumat tambahan diperlukan.</span>
</li>
</ul>
</div>
<div class="flex flex-col space-y-3">
<button @click="navigateTo('bantuan')" class="w-full py-3 bg-primary text-white rounded-lg shadow-sm font-medium">
Kembali ke Halaman Bantuan
</button>
<button class="w-full py-3 bg-primary/10 text-primary rounded-lg font-medium">
Semak Status Permohonan
</button>
</div>
</div>
</div>
</template>
<style scoped>
/* Add LZS theme-specific styling */
.bg-primary {
background-color: rgb(var(--color-primary));
}
.text-primary {
color: rgb(var(--color-primary));
}
.text-header-text {
color: rgb(var(--header-text));
}
.bg-primary-dark {
background-color: rgba(var(--color-primary), 0.9);
}
.bg-accent {
background-color: rgb(var(--color-accent));
}
.text-accent {
color: rgb(var(--color-accent));
}
.bg-secondary {
background-color: rgb(var(--color-secondary));
}
.text-secondary {
color: rgb(var(--color-secondary));
}
.bg-sidebar {
background-color: rgb(var(--sidebar));
}
/* Standardized Font Hierarchy */
h1, .h1 {
font-size: 20px;
font-weight: 700;
line-height: 1.4;
}
h2, .h2 {
font-size: 18px;
font-weight: 700;
line-height: 1.4;
}
h3, .h3 {
font-size: 16px;
font-weight: 600;
line-height: 1.4;
}
h4, .h4 {
font-size: 15px;
font-weight: 600;
line-height: 1.4;
}
h5, .h5 {
font-size: 14px;
font-weight: 600;
line-height: 1.4;
}
.body-text {
font-size: 14px;
line-height: 1.5;
}
.small-text {
font-size: 12px;
line-height: 1.5;
}
.label-text {
font-size: 12px;
font-weight: 500;
line-height: 1.4;
}
/* Enhance existing styles with LZS theme */
.mobile-frame {
width: 360px;
height: 720px;
background-color: #000;
border-radius: 30px;
overflow: hidden;
position: relative;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 0 40px rgba(0, 0, 0, 0.1) inset;
border: 10px solid #111;
}
.mobile-content {
width: 100%;
height: calc(100% - 39px); /* Account for status bar (24px) and bottom bar (15px) */
background-color: rgb(var(--bg-1));
position: relative;
overflow-y: auto;
}
.mobile-header {
position: sticky;
top: 0;
width: 100%;
z-index: 10;
}
/* FAB and its components with fixed positioning within mobile-content */
.fab {
position: absolute;
bottom: 80px;
right: 20px;
width: 56px;
height: 56px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 11;
transition: transform 0.3s ease;
box-shadow: 0 4px 12px rgba(var(--color-primary), 0.25);
}
.fab-menu {
position: absolute;
bottom: 80px;
right: 20px;
z-index: 10;
}
.fab-item {
display: flex;
align-items: center;
margin-bottom: 16px;
opacity: 0;
transform: translateY(20px);
transition: all 0.3s ease;
}
.fab-item.expanded {
opacity: 1;
transform: translateY(0);
}
.fab-item-text {
padding: 8px 16px;
background-color: #fff;
color: #333;
border-radius: 18px;
margin-right: 8px;
font-size: 14px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.fab-item-button {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 10px rgba(var(--color-primary), 0.25);
}
/* Drawer menu with enhanced styling - now positioned within mobile-frame */
.mobile-drawer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
}
.drawer-content {
transform: translateX(-100%);
transition: transform 0.3s ease-out;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.drawer-content.expanded {
transform: translateX(0%);
}
/* Bottom navigation - fixed to the bottom of mobile-content */
.bottom-nav-container {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
z-index: 10;
}
.bottom-nav {
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}
/* Pixel-style navigation bar */
.pixel-nav-bar {
position: absolute;
bottom: 0;
width: 100%;
}
.wrapper {
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f5f5f8;
}
.phone-container {
display: flex;
flex-direction: column;
align-items: center;
}
/* For notification badges */
.badge {
position: absolute;
top: 0;
right: 0;
min-width: 16px;
height: 16px;
border-radius: 8px;
padding: 0 4px;
font-size: 10px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
}
/* Card styles enhancement */
.card {
background-color: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
margin-bottom: 16px;
}
/* Transition effects */
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
/* Prevent scrolling when menu is open */
.body-locked {
overflow: hidden;
}
/* LZS-themed badges/status styles */
.badge-lulus, .badge-aktif, .status-lulus, .status-aktif {
background-color: rgba(var(--color-secondary), 0.15);
color: rgb(var(--color-secondary));
border: 1px solid rgba(var(--color-secondary), 0.3);
}
.badge-menunggu, .status-menunggu {
background-color: rgba(var(--color-warning), 0.15);
color: rgb(87, 65, 16); /* Darker shade for contrast */
border: 1px solid rgba(var(--color-warning), 0.3);
}
.badge-dalam-proses, .status-dalam-proses {
background-color: rgba(var(--color-info), 0.15);
color: rgb(var(--color-info));
border: 1px solid rgba(var(--color-info), 0.3);
}
.badge-ditolak, .status-ditolak {
background-color: rgba(var(--color-danger), 0.15);
color: rgb(var(--color-danger));
border: 1px solid rgba(var(--color-danger), 0.3);
}
.badge-deraf, .status-deraf {
background-color: rgba(100, 100, 100, 0.15);
color: rgb(100, 100, 100);
border: 1px solid rgba(100, 100, 100, 0.3);
}
.badge-baru, .status-baru {
background-color: rgba(var(--color-primary), 0.15);
color: rgb(var(--color-primary));
border: 1px solid rgba(var(--color-primary), 0.3);
}
/* Enhanced button styles */
.btn-primary {
background-color: rgb(var(--color-primary));
color: white;
font-weight: 500;
padding: 0.625rem 1.25rem;
border-radius: 0.5rem;
transition: all 0.2s ease;
box-shadow: 0 2px 6px rgba(var(--color-primary), 0.25);
}
.btn-primary:hover, .btn-primary:focus {
background-color: rgba(var(--color-primary), 0.9);
box-shadow: 0 4px 8px rgba(var(--color-primary), 0.35);
}
.btn-secondary {
background-color: rgb(var(--color-secondary));
color: white;
font-weight: 500;
padding: 0.625rem 1.25rem;
border-radius: 0.5rem;
transition: all 0.2s ease;
box-shadow: 0 2px 6px rgba(var(--color-secondary), 0.25);
}
.btn-outline {
background-color: transparent;
color: rgb(var(--color-primary));
border: 1px solid rgb(var(--color-primary));
font-weight: 500;
padding: 0.625rem 1.25rem;
border-radius: 0.5rem;
transition: all 0.2s ease;
}
.btn-outline:hover, .btn-outline:focus {
background-color: rgba(var(--color-primary), 0.05);
}
/* Enhanced form input styles */
.form-input {
border: 1px solid rgba(var(--border-color), 1);
border-radius: 0.5rem;
padding: 0.625rem 0.875rem;
transition: all 0.2s ease;
font-size: 0.875rem;
background-color: rgb(var(--bg-2));
}
.form-input:focus {
border-color: rgb(var(--color-primary));
box-shadow: 0 0 0 3px rgba(var(--color-primary), 0.15);
outline: none;
}
.form-label {
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 0.375rem;
color: rgba(var(--text-color), 0.8);
}
/* Card with enhanced styling */
.card-lzs {
background-color: white;
border-radius: 0.75rem;
overflow: hidden;
box-shadow: rgba(var(--color-primary), 0.08) 0px 2px 8px, rgba(var(--color-primary), 0.05) 0px 0px 1px;
margin-bottom: 1rem;
border: 1px solid rgba(var(--border-color), 0.3);
}
.card-lzs-header {
padding: 1rem;
border-bottom: 1px solid rgba(var(--border-color), 0.5);
background-color: rgba(var(--bg-1), 0.5);
}
.card-lzs-content {
padding: 1rem;
}
.card-lzs-footer {
padding: 0.75rem 1rem;
background-color: rgba(var(--bg-1), 0.5);
border-top: 1px solid rgba(var(--border-color), 0.5);
}
/* Timeline styling */
.timeline-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: rgb(var(--color-primary));
border: 2px solid white;
box-shadow: 0 0 0 2px rgba(var(--color-primary), 0.2);
}
.timeline-line {
width: 2px;
background-color: rgba(var(--color-primary), 0.3);
}
.timeline-dot-active {
background-color: rgb(var(--color-secondary));
box-shadow: 0 0 0 2px rgba(var(--color-secondary), 0.2);
}
.timeline-dot-pending {
background-color: rgb(var(--border-color));
box-shadow: 0 0 0 2px rgba(var(--border-color), 0.2);
}
/* Enhanced asnaf profile card */
.asnaf-profile-card {
background: linear-gradient(to bottom right, rgba(var(--color-primary), 0.05), rgba(var(--color-primary), 0.02));
border-radius: 0.75rem;
border: 1px solid rgba(var(--color-primary), 0.1);
padding: 1rem;
margin-bottom: 1rem;
}
.asnaf-status-badge {
background-color: rgba(var(--color-secondary), 0.15);
color: rgb(var(--color-secondary));
font-weight: 500;
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
border-radius: 999px;
display: inline-flex;
align-items: center;
}
.asnaf-status-badge .icon {
margin-right: 0.25rem;
}
/* Add fixed padding at the bottom to accommodate the navigation bar */
.pb-24 {
padding-bottom: 76px !important; /* Adjusted to ensure content doesn't get hidden behind navbar */
}
/* Ensure content area accommodates bottom nav */
.content-wrapper {
padding-bottom: 60px;
}
</style>