237 lines
9.1 KiB
JavaScript
237 lines
9.1 KiB
JavaScript
import { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { useTheme } from "@context/ThemeContext";
|
|
import { useAuth } from "@context/AuthContext";
|
|
import { Sun, Moon, Palette, Bell, Lock, Database, ChevronRight, LogOut, User } from "lucide-react";
|
|
import toast from "react-hot-toast";
|
|
|
|
export default function SettingsPage() {
|
|
const { theme, toggleTheme, isDark, accentColor, setAccentColor } = useTheme();
|
|
const { user, logout } = useAuth();
|
|
const navigate = useNavigate();
|
|
const [notifications, setNotifications] = useState(true);
|
|
|
|
const handleLogout = async () => {
|
|
try {
|
|
await logout();
|
|
toast.success("Logged out successfully");
|
|
navigate("/login");
|
|
} catch (error) {
|
|
toast.error("Logout failed");
|
|
}
|
|
};
|
|
|
|
const accentColors = [
|
|
{ name: 'violet', color: 'bg-violet-500', value: 'violet' },
|
|
{ name: 'blue', color: 'bg-blue-500', value: 'blue' },
|
|
{ name: 'cyan', color: 'bg-cyan-500', value: 'cyan' },
|
|
{ name: 'emerald', color: 'bg-emerald-500', value: 'emerald' },
|
|
{ name: 'amber', color: 'bg-amber-500', value: 'amber' },
|
|
{ name: 'rose', color: 'bg-rose-500', value: 'rose' },
|
|
];
|
|
|
|
const cardClasses = `rounded-2xl p-6 border backdrop-blur-lg transition-colors ${
|
|
isDark
|
|
? 'bg-white/10 border-white/20'
|
|
: 'bg-white border-gray-200 shadow-sm'
|
|
}`;
|
|
|
|
const labelClasses = `font-medium ${isDark ? 'text-white' : 'text-gray-900'}`;
|
|
const subLabelClasses = `text-sm ${isDark ? 'text-white/60' : 'text-gray-500'}`;
|
|
|
|
return (
|
|
<div className="max-w-2xl mx-auto space-y-6 pb-10">
|
|
<div>
|
|
<h1 className={`text-3xl font-bold ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
Settings
|
|
</h1>
|
|
<p className={subLabelClasses}>Customize your experience</p>
|
|
</div>
|
|
|
|
{/* Appearance */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-5 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
<Palette size={22} className="text-violet-500" />
|
|
Appearance
|
|
</h2>
|
|
|
|
{/* Theme Toggle */}
|
|
<div className="flex items-center justify-between py-4 border-b border-white/10">
|
|
<div>
|
|
<p className={labelClasses}>Theme</p>
|
|
<p className={subLabelClasses}>Toggle between light and dark mode</p>
|
|
</div>
|
|
<button
|
|
onClick={toggleTheme}
|
|
className={`flex items-center gap-3 px-5 py-2.5 rounded-xl font-medium transition-all ${
|
|
isDark
|
|
? 'bg-amber-500/20 text-amber-300 hover:bg-amber-500/30'
|
|
: 'bg-slate-800 text-slate-100 hover:bg-slate-700'
|
|
}`}
|
|
>
|
|
{isDark ? (
|
|
<>
|
|
<Sun size={18} />
|
|
Light Mode
|
|
</>
|
|
) : (
|
|
<>
|
|
<Moon size={18} />
|
|
Dark Mode
|
|
</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Accent Color */}
|
|
<div className="py-4">
|
|
<div className="mb-3">
|
|
<p className={labelClasses}>Accent Color</p>
|
|
<p className={subLabelClasses}>Choose your preferred accent color</p>
|
|
</div>
|
|
<div className="flex flex-wrap gap-3">
|
|
{accentColors.map(({ name, color, value }) => (
|
|
<button
|
|
key={value}
|
|
onClick={() => setAccentColor(value)}
|
|
className={`w-10 h-10 rounded-xl ${color} transition-transform hover:scale-110
|
|
${accentColor === value ? 'ring-2 ring-offset-2 ring-offset-slate-900 ring-white' : ''}`}
|
|
title={name}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Notifications */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-5 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
<Bell size={22} className="text-cyan-500" />
|
|
Notifications
|
|
</h2>
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className={labelClasses}>Push Notifications</p>
|
|
<p className={subLabelClasses}>Get notified about worship list updates</p>
|
|
</div>
|
|
<button
|
|
onClick={() => setNotifications(!notifications)}
|
|
className={`relative w-14 h-8 rounded-full transition-colors ${
|
|
notifications ? 'bg-emerald-500' : 'bg-white/20'
|
|
}`}
|
|
>
|
|
<div
|
|
className={`absolute top-1 w-6 h-6 bg-white rounded-full shadow-md transition-transform ${
|
|
notifications ? 'left-7' : 'left-1'
|
|
}`}
|
|
/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Security */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-5 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
<Lock size={22} className="text-rose-500" />
|
|
Security
|
|
</h2>
|
|
<div className="space-y-3">
|
|
<button className={`w-full flex items-center justify-between p-4 rounded-xl transition-colors ${
|
|
isDark ? 'hover:bg-white/5' : 'hover:bg-gray-50'
|
|
}`}>
|
|
<div className="text-left">
|
|
<p className={labelClasses}>Change Password</p>
|
|
<p className={subLabelClasses}>Update your account password</p>
|
|
</div>
|
|
<ChevronRight size={20} className={isDark ? 'text-white/40' : 'text-gray-400'} />
|
|
</button>
|
|
<button className={`w-full flex items-center justify-between p-4 rounded-xl transition-colors ${
|
|
isDark ? 'hover:bg-white/5' : 'hover:bg-gray-50'
|
|
}`}>
|
|
<div className="text-left">
|
|
<p className={labelClasses}>Biometric Login</p>
|
|
<p className={subLabelClasses}>Use Face ID or fingerprint</p>
|
|
</div>
|
|
<ChevronRight size={20} className={isDark ? 'text-white/40' : 'text-gray-400'} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Data */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-5 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
<Database size={22} className="text-amber-500" />
|
|
Data
|
|
</h2>
|
|
<div className="space-y-3">
|
|
<button className={`w-full flex items-center justify-between p-4 rounded-xl transition-colors ${
|
|
isDark ? 'hover:bg-white/5' : 'hover:bg-gray-50'
|
|
}`}>
|
|
<div className="text-left">
|
|
<p className={labelClasses}>Export Songs</p>
|
|
<p className={subLabelClasses}>Download all songs as JSON</p>
|
|
</div>
|
|
<ChevronRight size={20} className={isDark ? 'text-white/40' : 'text-gray-400'} />
|
|
</button>
|
|
<button className={`w-full flex items-center justify-between p-4 rounded-xl transition-colors ${
|
|
isDark ? 'hover:bg-white/5' : 'hover:bg-gray-50'
|
|
}`}>
|
|
<div className="text-left">
|
|
<p className={labelClasses}>Clear Cache</p>
|
|
<p className={subLabelClasses}>Free up storage space</p>
|
|
</div>
|
|
<ChevronRight size={20} className={isDark ? 'text-white/40' : 'text-gray-400'} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* About */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-4 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
About
|
|
</h2>
|
|
<div className={`space-y-2 ${isDark ? 'text-white/70' : 'text-gray-600'}`}>
|
|
<p className="font-semibold">HOP Worship Platform</p>
|
|
<p>Version 2.0.0</p>
|
|
<p>House of Praise Music Ministry</p>
|
|
<p className="text-sm mt-4 opacity-70">
|
|
© 2026 House of Praise. All rights reserved.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Account Section */}
|
|
<div className={cardClasses}>
|
|
<h2 className={`text-xl font-semibold mb-5 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
|
|
<User size={22} className="text-blue-500" />
|
|
Account
|
|
</h2>
|
|
|
|
{/* User Info */}
|
|
<div className={`p-4 rounded-xl mb-4 ${isDark ? 'bg-white/5' : 'bg-gray-50'}`}>
|
|
<p className={`text-sm ${subLabelClasses}`}>Logged in as</p>
|
|
<p className={`font-semibold ${labelClasses}`}>
|
|
{user?.name || user?.username || 'User'}
|
|
</p>
|
|
<p className={`text-xs ${subLabelClasses}`}>
|
|
{user?.role === 'admin' ? 'Administrator' : 'User'}
|
|
</p>
|
|
</div>
|
|
|
|
{/* Logout Button */}
|
|
<button
|
|
onClick={handleLogout}
|
|
className={`w-full flex items-center justify-center gap-3 p-4 rounded-xl font-medium transition-all transform active:scale-[0.98] ${
|
|
isDark
|
|
? 'bg-red-500/20 hover:bg-red-500/30 text-red-400 border border-red-500/30'
|
|
: 'bg-red-50 hover:bg-red-100 text-red-600 border border-red-200'
|
|
}`}
|
|
>
|
|
<LogOut size={20} />
|
|
<span>Sign Out</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|