Initial commit - Church Music Database
This commit is contained in:
236
new-site/frontend/src/pages/SettingsPage.jsx
Normal file
236
new-site/frontend/src/pages/SettingsPage.jsx
Normal file
@@ -0,0 +1,236 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user