diff --git a/src/app/api/user/settings/route.ts b/src/app/api/user/settings/route.ts new file mode 100644 index 0000000..b4f9812 --- /dev/null +++ b/src/app/api/user/settings/route.ts @@ -0,0 +1,113 @@ +import { NextRequest, NextResponse } from "next/server"; +import { verifyAccessToken } from "@/lib/auth/user-jwt"; +import connectToDatabase from "@/lib/db"; +import User from "@/lib/models/userSchema"; + +export async function PUT(request: NextRequest) { + try { + // Get access token from cookies + const accessToken = request.cookies.get("access_token")?.value; + + if (!accessToken) { + return NextResponse.json( + { error: "Access token not found" }, + { status: 401 } + ); + } + + // Verify the access token + let decoded; + try { + decoded = verifyAccessToken(accessToken); + } catch { + return NextResponse.json( + { error: "Invalid or expired access token" }, + { status: 401 } + ); + } + + const { emailNotifications, language } = await request.json(); + + await connectToDatabase(); + + // Find and update user settings + const user = await User.findById(decoded.userId); + if (!user) { + return NextResponse.json({ error: "User not found" }, { status: 404 }); + } + + // Update user preferences + const updatedUser = await User.findByIdAndUpdate( + decoded.userId, + { + $set: { + "preferences.emailNotifications": emailNotifications, + "preferences.language": language, + updatedAt: new Date(), + }, + }, + { new: true, runValidators: true } + ); + + return NextResponse.json({ + success: true, + message: "Settings updated successfully", + settings: { + emailNotifications: updatedUser.preferences?.emailNotifications ?? true, + language: updatedUser.preferences?.language ?? "en", + }, + }); + } catch (error) { + console.error("Error updating user settings:", error); + return NextResponse.json( + { error: "Internal server error" }, + { status: 500 } + ); + } +} + +export async function GET(request: NextRequest) { + try { + // Get access token from cookies + const accessToken = request.cookies.get("access_token")?.value; + + if (!accessToken) { + return NextResponse.json( + { error: "Access token not found" }, + { status: 401 } + ); + } + + // Verify the access token + let decoded; + try { + decoded = verifyAccessToken(accessToken); + } catch { + return NextResponse.json( + { error: "Invalid or expired access token" }, + { status: 401 } + ); + } + + await connectToDatabase(); + + const user = await User.findById(decoded.userId).select("preferences"); + if (!user) { + return NextResponse.json({ error: "User not found" }, { status: 404 }); + } + + return NextResponse.json({ + success: true, + settings: { + emailNotifications: user.preferences?.emailNotifications ?? true, + language: user.preferences?.language ?? "en", + }, + }); + } catch (error) { + console.error("Error fetching user settings:", error); + return NextResponse.json( + { error: "Internal server error" }, + { status: 500 } + ); + } +} diff --git a/src/app/user/help/page.tsx b/src/app/user/help/page.tsx new file mode 100644 index 0000000..3477216 --- /dev/null +++ b/src/app/user/help/page.tsx @@ -0,0 +1,566 @@ +"use client"; +import React, { useState } from "react"; +import UserDashboardLayout from "@/components/user/dashboard/UserDashboardLayout"; + +const UserHelpPage = () => { + const [language, setLanguage] = useState<"en" | "si" | "ta">("en"); + const [searchQuery, setSearchQuery] = useState(""); + const [activeCategory, setActiveCategory] = useState("getting-started"); + const [selectedArticle, setSelectedArticle] = useState(null); + + const translations = { + en: { + title: "Help & Support", + subtitle: "Find answers to your questions and get support", + searchPlaceholder: "Search for help...", + categories: "Categories", + gettingStarted: "Getting Started", + accountManagement: "Account Management", + services: "Government Services", + appointments: "Appointments", + documents: "Documents & Forms", + technical: "Technical Support", + contact: "Contact Support", + phone: "Phone", + email: "Email", + chat: "Live Chat", + faqs: "Frequently Asked Questions", + tutorials: "Video Tutorials", + }, + si: { + title: "උදව් සහ සහාය", + subtitle: "ඔබේ ප්‍රශ්නවලට පිළිතුරු සොයා ගන්න සහ සහාය ලබා ගන්න", + searchPlaceholder: "උදව් සඳහා සොයන්න...", + categories: "කාණ්ඩ", + gettingStarted: "ආරම්භ කිරීම", + accountManagement: "ගිණුම් කළමනාකරණය", + services: "රජයේ සේවාවන්", + appointments: "හමුවීම්", + documents: "ලේඛන සහ ෆෝම්", + technical: "තාක්ෂණික සහාය", + contact: "සහාය අමතන්න", + phone: "දුරකථනය", + email: "ඊමේල්", + chat: "සජීව කතාබස්", + faqs: "නිතර අසන ප්‍රශ්න", + tutorials: "වීඩියෝ නිබන්ධන", + }, + ta: { + title: "உதவி மற்றும் ஆதரவு", + subtitle: "உங்கள் கேள்விகளுக்கான பதில்களைக் கண்டறிந்து ஆதரவைப் பெறுங்கள்", + searchPlaceholder: "உதவிக்காக தேடுங்கள்...", + categories: "வகைகள்", + gettingStarted: "தொடங்குதல்", + accountManagement: "கணக்கு நிர்வாகம்", + services: "அரசாங்க சேவைகள்", + appointments: "சந்திப்புகள்", + documents: "ஆவணங்கள் மற்றும் படிவங்கள்", + technical: "தொழில்நுட்ப ஆதரவு", + contact: "ஆதரவைத் தொடர்பு கொள்ளவும்", + phone: "தொலைபேசி", + email: "மின்னஞ்சல்", + chat: "நேரடி அரட்டை", + faqs: "அடிக்கடி கேட்கப்படும் கேள்விகள்", + tutorials: "வீடியோ பயிற்சிகள்", + }, + }; + + const t = translations[language]; + + const helpCategories = [ + { + id: "getting-started", + icon: ( + + + + + + + ), + title: t.gettingStarted, + articles: [ + { + title: "How to register as a citizen", + content: + "To register as a citizen on GovLink:\n\n1. Click on 'Register' from the main page\n2. Fill in your personal details including your NIC number\n3. Provide a valid email address and mobile number\n4. Create a secure password\n5. Verify your email address by clicking the link sent to your inbox\n6. Complete your profile with additional information\n\nOnce registered, you'll have access to all government services available on the platform.", + }, + { + title: "First time login guide", + content: + "For your first login:\n\n1. Go to the citizen login page\n2. Enter your registered email and password\n3. If you forgot your password, use the 'Forgot Password' link\n4. After successful login, you'll be taken to your dashboard\n5. Complete your profile if prompted\n6. Explore the available services and features\n\nTip: Keep your login credentials secure and don't share them with anyone.", + }, + { + title: "Setting up your profile", + content: + "To complete your profile setup:\n\n1. Navigate to your profile page from the user menu\n2. Upload a clear profile picture\n3. Fill in all required personal information\n4. Add your address details\n5. Upload necessary verification documents\n6. Set your communication preferences\n7. Review and save your information\n\nA complete profile helps government agents serve you better and speeds up service delivery.", + }, + { + title: "Understanding the dashboard", + content: + "Your dashboard provides:\n\n1. **Quick Actions**: Apply for services, book appointments\n2. **Recent Activity**: View your recent applications and bookings\n3. **Notifications**: Important updates from government departments\n4. **Service Status**: Track your ongoing applications\n5. **Shortcuts**: Quick access to frequently used services\n6. **Help**: Access to support and guidance\n\nThe dashboard is your central hub for all government service interactions.", + }, + ], + }, + { + id: "account-management", + icon: ( + + + + + ), + title: t.accountManagement, + articles: [ + { + title: "Updating your personal information", + content: + "To update your personal information:\n\n1. Go to your profile page\n2. Click on 'Edit Profile'\n3. Update the necessary fields\n4. Upload new documents if required\n5. Save your changes\n\nNote: Some changes may require verification by government officials.", + }, + { + title: "Changing your password", + content: + "To change your password:\n\n1. Go to Settings from your profile menu\n2. Click on 'Change Password'\n3. Enter your current password\n4. Enter your new password (must be strong)\n5. Confirm your new password\n6. Save changes\n\nFor security, you'll be logged out of all devices after changing your password.", + }, + { + title: "Managing notification preferences", + content: + "To manage your notifications:\n\n1. Go to Settings\n2. Navigate to 'Notification Preferences'\n3. Choose your preferred notification methods (email, SMS)\n4. Select which types of notifications you want to receive\n5. Set your notification frequency\n6. Save your preferences\n\nYou can update these settings anytime.", + }, + { + title: "Account verification process", + content: + "Account verification steps:\n\n1. Upload required documents (NIC, proof of address)\n2. Wait for government verification (usually 2-3 business days)\n3. Check your email for verification status updates\n4. If additional documents are needed, you'll be notified\n5. Once verified, you'll have access to all services\n\nVerified accounts have higher service limits and faster processing.", + }, + ], + }, + { + id: "services", + icon: ( + + + + + ), + title: t.services, + articles: [ + { + title: "Available government services", + content: + "GovLink provides access to various government services:\n\n• **Identity Services**: NIC applications, passport renewals\n• **Business Services**: Business registration, licenses\n• **Health Services**: Medical certificates, health records\n• **Education Services**: Certificate verification, transcripts\n• **Social Services**: Welfare applications, pensions\n• **Property Services**: Land records, property transfers\n\nNew services are regularly added to the platform.", + }, + { + title: "How to apply for services", + content: + "To apply for government services:\n\n1. Browse available services from your dashboard\n2. Select the service you need\n3. Read the requirements and prepare documents\n4. Fill out the application form completely\n5. Upload required documents\n6. Review and submit your application\n7. Pay any applicable fees online\n8. Track your application status\n\nYou'll receive notifications about your application progress.", + }, + { + title: "Service status tracking", + content: + "Track your service applications:\n\n1. Go to your dashboard\n2. Click on 'My Applications'\n3. View the status of each application\n4. Click on any application for detailed information\n5. Check for updates and required actions\n6. Download completed documents when ready\n\nStatus updates include: Submitted, Under Review, Approved, Rejected, or Completed.", + }, + { + title: "Required documents checklist", + content: + "Common documents needed for services:\n\n**Identity Verification**:\n• Valid NIC (front and back)\n• Recent passport-size photograph\n\n**Address Verification**:\n• Utility bill (not older than 3 months)\n• Bank statement or rent agreement\n\n**Service-Specific Documents**:\n• Birth certificate (for passport applications)\n• Marriage certificate (for spouse-related services)\n• Educational certificates (for verification services)\n\nAlways check specific requirements for each service.", + }, + ], + }, + { + id: "appointments", + icon: ( + + + + + + + ), + title: t.appointments, + articles: [ + { + title: "Booking an appointment", + content: + "To book an appointment:\n\n1. Go to 'Book Appointment' from your dashboard\n2. Select the government department\n3. Choose the service you need\n4. Select an available agent\n5. Pick a convenient date and time\n6. Provide the purpose of your visit\n7. Confirm your appointment details\n8. Receive confirmation via email and SMS\n\nArrive 10 minutes early with all required documents.", + }, + { + title: "Rescheduling appointments", + content: + "To reschedule an appointment:\n\n1. Go to 'My Appointments' in your dashboard\n2. Find the appointment you want to reschedule\n3. Click 'Reschedule'\n4. Select a new available time slot\n5. Confirm the changes\n6. You'll receive updated confirmation\n\nNote: You can reschedule up to 24 hours before your appointment time.", + }, + { + title: "Canceling appointments", + content: + "To cancel an appointment:\n\n1. Navigate to 'My Appointments'\n2. Select the appointment to cancel\n3. Click 'Cancel Appointment'\n4. Provide a reason for cancellation (optional)\n5. Confirm the cancellation\n6. You'll receive cancellation confirmation\n\nCanceling early helps others book available slots.", + }, + { + title: "Appointment reminders", + content: + "Appointment reminder system:\n\n• **24 hours before**: Email and SMS reminder\n• **2 hours before**: Final SMS reminder\n• **Digital calendar**: Add appointment to your calendar\n• **Dashboard alerts**: Visual reminders when you log in\n\nYou can customize reminder preferences in your settings to receive notifications via your preferred method.", + }, + ], + }, + ]; + + const handleArticleClick = (articleTitle: string) => { + setSelectedArticle(selectedArticle === articleTitle ? null : articleTitle); + }; + + const getSelectedArticleContent = () => { + const currentCategory = helpCategories.find( + (cat) => cat.id === activeCategory + ); + if (!currentCategory || !selectedArticle) return null; + + const article = currentCategory.articles.find( + (art) => typeof art === "object" && art.title === selectedArticle + ); + return typeof article === "object" ? article.content : null; + }; + + const contactMethods = [ + { + icon: ( + + + + ), + title: t.phone, + value: "+94 11 234 5678", + description: "Available 24/7", + }, + { + icon: ( + + + + + ), + title: t.email, + value: "support@govlink.lk", + description: "Response within 24 hours", + }, + { + icon: ( + + + + ), + title: t.chat, + value: "Start Live Chat", + description: "Mon-Fri 8AM-6PM", + }, + ]; + + const faqs = [ + { + question: "How do I reset my password?", + answer: + 'You can reset your password by clicking the "Forgot Password" link on the login page and following the instructions sent to your email.', + }, + { + question: "How long does service processing take?", + answer: + "Processing times vary by service type. Most applications are processed within 5-10 business days. You can track the status in your dashboard.", + }, + { + question: "What documents do I need for verification?", + answer: + "You typically need a valid NIC, proof of address, and any service-specific documents. Check the requirements for each service.", + }, + { + question: "Can I cancel my application?", + answer: + "Yes, you can cancel applications that haven't been processed yet. Go to your dashboard and select the application to cancel.", + }, + ]; + + return ( + +
+ {/* Search Bar */} +
+
+ setSearchQuery(e.target.value)} + className="w-full px-4 py-3 pl-12 border border-border rounded-xl bg-card/50 backdrop-blur-md focus:outline-none focus:ring-2 focus:ring-[#FFC72C]/50 shadow-lg" + /> + + + + +
+
+ +
+ {/* Categories Sidebar */} +
+
+

{t.categories}

+ +
+
+ + {/* Main Content */} +
+ {/* Help Articles */} +
+

+ {helpCategories.find((cat) => cat.id === activeCategory)?.title} +

+
+ {helpCategories + .find((cat) => cat.id === activeCategory) + ?.articles.map((article, index) => ( +
+ + + {/* Article Content */} + {selectedArticle === + (typeof article === "object" + ? article.title + : article) && ( +
+
+ {typeof article === "object" ? ( +
+                                {article.content}
+                              
+ ) : ( +

+ Content for this article will be available soon. +

+ )} +
+
+ )} +
+ ))} +
+
+ + {/* FAQs */} +
+

+ + + + + + {t.faqs} +

+
+ {faqs.map((faq, index) => ( +
+ +
+ {faq.question} + + + +
+
+
+

{faq.answer}

+
+
+ ))} +
+
+ + {/* Contact Support */} +
+

+ + + + {t.contact} +

+
+ {contactMethods.map((method, index) => ( +
+
+ {method.icon} + {method.title} +
+
+ {method.value} +
+
+ {method.description} +
+
+ ))} +
+
+
+
+
+
+ ); +}; + +export default UserHelpPage; diff --git a/src/app/user/settings/page.tsx b/src/app/user/settings/page.tsx new file mode 100644 index 0000000..c80a40f --- /dev/null +++ b/src/app/user/settings/page.tsx @@ -0,0 +1,270 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { useAuth } from "@/lib/auth/AuthContext"; +import UserDashboardLayout from "@/components/user/dashboard/UserDashboardLayout"; + +const UserSettingsPage = () => { + const { user } = useAuth(); + const [language, setLanguage] = useState<"en" | "si" | "ta">("en"); + const [emailNotifications, setEmailNotifications] = useState(true); + const [isSaving, setIsSaving] = useState(false); + const [saveMessage, setSaveMessage] = useState(""); + + const translations = { + en: { + title: "Account Settings", + subtitle: "Manage your account preferences and notification settings", + profileSection: "Profile Information", + email: "Email Address", + phone: "Phone Number", + notificationSection: "Notification Preferences", + emailNotifications: "Email Notifications", + save: "Save Changes", + saving: "Saving...", + cancel: "Cancel", + saveSuccess: "Settings saved successfully!", + saveError: "Failed to save settings. Please try again.", + }, + si: { + title: "ගිණුම් සැකසුම්", + subtitle: "ඔබේ ගිණුම් මනාපයන් සහ දැනුම්දීම් සැකසුම් කළමනාකරණය කරන්න", + profileSection: "පැතිකඩ තොරතුරු", + email: "ඊමේල් ලිපිනය", + phone: "දුරකථන අංකය", + notificationSection: "දැනුම්දීම් මනාපයන්", + emailNotifications: "ඊමේල් දැනුම්දීම්", + save: "වෙනස්කම් සුරකින්න", + saving: "සුරකිමින්...", + cancel: "අවලංගු කරන්න", + saveSuccess: "සැකසුම් සාර්ථකව සුරකින ලදී!", + saveError: "සැකසුම් සුරැකීමට අසමත් විය. කරුණාකර නැවත උත්සාහ කරන්න.", + }, + ta: { + title: "கணக்கு அமைப்புகள்", + subtitle: + "உங்கள் கணக்கு விருப்பத்தேர்வுகள் மற்றும் அறிவிப்பு அமைப்புகளை நிர்வகிக்கவும்", + profileSection: "சுயவிவர தகவல்", + email: "மின்னஞ்சல் முகவரி", + phone: "தொலைபேசி எண்", + notificationSection: "அறிவிப்பு விருப்பத்தேர்வுகள்", + emailNotifications: "மின்னஞ்சல் அறிவிப்புகள்", + save: "மாற்றங்களை சேமி", + saving: "சேமிக்கிறது...", + cancel: "ரத்து செய்", + saveSuccess: "அமைப்புகள் வெற்றிகரமாக சேமிக்கப்பட்டன!", + saveError: + "அமைப்புகளை சேமிக்க முடியவில்லை. தயவுசெய்து மீண்டும் முயற்சிக்கவும்.", + }, + }; + + const t = translations[language]; + + // Load current settings when component mounts + useEffect(() => { + const loadSettings = async () => { + try { + const response = await fetch("/api/user/settings", { + credentials: "include", + }); + + if (response.ok) { + const data = await response.json(); + if (data.success) { + setEmailNotifications(data.settings.emailNotifications); + setLanguage(data.settings.language); + } + } + } catch (error) { + console.error("Error loading settings:", error); + } + }; + + loadSettings(); + }, []); + + const handleSave = async () => { + setIsSaving(true); + setSaveMessage(""); + + try { + // Create settings payload + const settingsData = { + emailNotifications, + language, + }; + + // Make API call to save settings + const response = await fetch("/api/user/settings", { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + credentials: "include", + body: JSON.stringify(settingsData), + }); + + if (response.ok) { + setSaveMessage(t.saveSuccess); + // Clear success message after 3 seconds + setTimeout(() => setSaveMessage(""), 3000); + } else { + throw new Error("Failed to save settings"); + } + } catch (error) { + console.error("Error saving settings:", error); + setSaveMessage(t.saveError); + // Clear error message after 5 seconds + setTimeout(() => setSaveMessage(""), 5000); + } finally { + setIsSaving(false); + } + }; + + return ( + +
+ {/* Profile Information */} +
+

+ + + + + {t.profileSection} +

+
+
+ + +
+
+ + +
+
+
+ + {/* Notification Preferences */} +
+

+ + + + + {t.notificationSection} +

+
+
+ + +
+
+
+ + {/* Action Buttons */} +
+ {/* Success/Error Message */} + {saveMessage && ( +
+ {saveMessage} +
+ )} + +
+ + +
+
+
+
+ ); +}; + +export default UserSettingsPage; diff --git a/src/components/user/dashboard/UserDashboardLayout.tsx b/src/components/user/dashboard/UserDashboardLayout.tsx index 2c14915..a30d92e 100644 --- a/src/components/user/dashboard/UserDashboardLayout.tsx +++ b/src/components/user/dashboard/UserDashboardLayout.tsx @@ -1,15 +1,15 @@ // src/components/user/dashboard/UserDashboardLayout.tsx "use client"; -import React, { useState } from 'react'; -import Link from 'next/link'; -import { useRouter } from 'next/navigation'; -import { ThemeToggle } from '@/components/ThemeToggle'; -import { useAuth } from '@/lib/auth/AuthContext'; -import { useLogout } from '@/lib/auth/useAuthUtils'; -import { LotusIcon } from '@/components/Icons/LotusIcon'; +import React, { useState } from "react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { ThemeToggle } from "@/components/ThemeToggle"; +import { useAuth } from "@/lib/auth/AuthContext"; +import { useLogout } from "@/lib/auth/useAuthUtils"; +import { LotusIcon } from "@/components/Icons/LotusIcon"; // Types for translations -type Language = 'en' | 'si' | 'ta'; +type Language = "en" | "si" | "ta"; interface Translation { dashboard: string; @@ -24,39 +24,39 @@ interface Translation { // Translation data const translations: Record = { en: { - dashboard: 'Dashboard', - citizenPortal: 'Citizen Portal', - logout: 'Logout', - profile: 'Profile', - settings: 'Settings', - help: 'Help', - notifications: 'Notifications' + dashboard: "Dashboard", + citizenPortal: "Citizen Portal", + logout: "Logout", + profile: "Profile", + settings: "Settings", + help: "Help", + notifications: "Notifications", }, si: { - dashboard: 'පාලනය', - citizenPortal: 'පුරවැසි පෝට්ලය', - logout: 'ඉවත්වන්න', - profile: 'පැතිකඩ', - settings: 'සැකසුම්', - help: 'උදව්', - notifications: 'දැනුම්දීම්' + dashboard: "පාලනය", + citizenPortal: "පුරවැසි පෝට්ලය", + logout: "ඉවත්වන්න", + profile: "පැතිකඩ", + settings: "සැකසුම්", + help: "උදව්", + notifications: "දැනුම්දීම්", }, ta: { - dashboard: 'டாஷ்போர்டு', - citizenPortal: 'குடிமக்கள் போர்டல்', - logout: 'வெளியேறு', - profile: 'சுயவிவரம்', - settings: 'அமைப்புகள்', - help: 'உதவி', - notifications: 'அறிவிப்புகள்' - } + dashboard: "டாஷ்போர்டு", + citizenPortal: "குடிமக்கள் போர்டல்", + logout: "வெளியேறு", + profile: "சுயவிவரம்", + settings: "அமைப்புகள்", + help: "உதவி", + notifications: "அறிவிப்புகள்", + }, }; // Language options const languageOptions = [ - { code: 'en', label: 'English', nativeLabel: 'English' }, - { code: 'si', label: 'Sinhala', nativeLabel: 'සිංහල' }, - { code: 'ta', label: 'Tamil', nativeLabel: 'தமிழ்' } + { code: "en", label: "English", nativeLabel: "English" }, + { code: "si", label: "Sinhala", nativeLabel: "සිංහල" }, + { code: "ta", label: "Tamil", nativeLabel: "தமிழ்" }, ]; // Lotus icon now imported from shared Icons @@ -67,26 +67,41 @@ const SriLankanBackground = () => {
{/* Main background image */}
-
{/* Overlay gradients for better text readability */}
- + {/* Enhanced lotus-inspired accent patterns */}
-
-
-
+
+
+
{/* Additional subtle accents */} -
-
+
+
); @@ -98,20 +113,20 @@ interface UserDashboardLayoutProps { subtitle?: string; language?: Language; onLanguageChange?: (language: Language) => void; - size?: 'default' | 'compact' | 'dense'; - contentMode?: 'normal' | 'fill'; + size?: "default" | "compact" | "dense"; + contentMode?: "normal" | "fill"; headerContent?: React.ReactNode; } -const UserDashboardLayout: React.FC = ({ - children, - title, +const UserDashboardLayout: React.FC = ({ + children, + title, subtitle, - language = 'en', + language = "en", onLanguageChange, - size = 'default', - contentMode = 'normal', - headerContent + size = "default", + contentMode = "normal", + headerContent, }) => { const router = useRouter(); const { user, isAuthenticated, isLoading } = useAuth(); @@ -121,18 +136,21 @@ const UserDashboardLayout: React.FC = ({ const t = translations[language]; // Get user display data - const userDisplayName = user?.firstName && user?.lastName - ? `${user.firstName} ${user.lastName}` - : user?.email?.split('@')[0] || 'User'; - - const userInitials = user?.firstName && user?.lastName - ? `${user.firstName[0]}${user.lastName[0]}`.toUpperCase() - : user?.email ? user.email[0].toUpperCase() - : 'U'; - - const userShortName = user?.firstName - ? `${user.firstName} ${user.lastName ? user.lastName[0] + '.' : ''}` - : user?.email?.split('@')[0] || 'User'; + const userDisplayName = + user?.firstName && user?.lastName + ? `${user.firstName} ${user.lastName}` + : user?.email?.split("@")[0] || "User"; + + const userInitials = + user?.firstName && user?.lastName + ? `${user.firstName[0]}${user.lastName[0]}`.toUpperCase() + : user?.email + ? user.email[0].toUpperCase() + : "U"; + + const userShortName = user?.firstName + ? `${user.firstName} ${user.lastName ? user.lastName[0] + "." : ""}` + : user?.email?.split("@")[0] || "User"; const handleLanguageChange = (newLanguage: Language) => { if (onLanguageChange) { @@ -142,7 +160,7 @@ const UserDashboardLayout: React.FC = ({ }; const handleLogout = () => { - logoutAndRedirect('/user/auth/login'); + logoutAndRedirect("/user/auth/login"); }; // Show loading state if user data is still loading @@ -156,7 +174,7 @@ const UserDashboardLayout: React.FC = ({ // Redirect to login if not authenticated (this shouldn't happen due to middleware) if (!isAuthenticated) { - router.push('/user/auth/login'); + router.push("/user/auth/login"); return null; } @@ -164,7 +182,7 @@ const UserDashboardLayout: React.FC = ({
{/* EXACT SAME Sri Lankan Background */} - + {/* Header - EXACT SAME styling as Agent Layout */}
- GovLink - {t.citizenPortal} + + GovLink + + + {t.citizenPortal} +
{/* Notification Bell */}
- {isDropdownOpen && ( <> -
setIsDropdownOpen(false)} />
{languageOptions.map((lang) => ( ))} @@ -236,7 +289,7 @@ const UserDashboardLayout: React.FC = ({ )}
- + {/* Profile Dropdown */}
{isProfileDropdownOpen && ( <> -
setIsProfileDropdownOpen(false)} />
-
{userDisplayName}
+
+ {userDisplayName} +
{user?.email}
- {user?.role === 'citizen' ? 'Citizen Account' : user?.role} + {user?.role === "citizen" + ? "Citizen Account" + : user?.role} {user?.accountStatus && ( - + {user.accountStatus} )}
- - + + {t.profile} - - +
-
- +
@@ -326,40 +442,64 @@ const UserDashboardLayout: React.FC = ({ {/* Main Content */} -
+
{headerContent ? ( -
+
{headerContent}
) : ( -
-

+
+

{title}

- + {subtitle && ( -

+

{subtitle}

)}
)} - {contentMode === 'fill' ? ( -
- {children} -
+ {contentMode === "fill" ? ( +
{children}
) : ( children )} @@ -368,4 +508,4 @@ const UserDashboardLayout: React.FC = ({ ); }; -export default UserDashboardLayout; \ No newline at end of file +export default UserDashboardLayout;