deckhearth/pages/settings.js

669 lines
27 KiB
JavaScript
Raw Normal View History

🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import Layout from '../components/Layout';
export default function Settings() {
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
const router = useRouter();
// User state
const [user, setUser] = useState({
email: 'me@randallstillwell.com',
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
role: 'admin'
});
// Settings state
const [settings, setSettings] = useState({
// Account Settings
notifications_email: true,
notifications_marketing: false,
collection_visibility: 'private',
preferred_currency: 'USD',
cards_per_page: 50,
default_view: 'grid',
// Security Settings
two_factor_enabled: false,
// Display Settings
theme: 'system', // light, dark, system
language: 'en'
});
// Password change state
const [passwordForm, setPasswordForm] = useState({
current_password: '',
new_password: '',
confirm_password: ''
});
// UI state
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [changingPassword, setChangingPassword] = useState(false);
const [message, setMessage] = useState({ type: '', text: '' });
const [activeSection, setActiveSection] = useState('account');
useEffect(() => {
loadSettings();
}, []);
const loadSettings = async () => {
try {
const token = localStorage.getItem('auth_token');
if (!token) {
router.push('/login');
return;
}
const response = await fetch('/api/user/settings', {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const data = await response.json();
setUser(data.user);
setSettings(data.settings);
} else if (response.status === 401) {
router.push('/login');
}
} catch (error) {
console.error('Error loading settings:', error);
setMessage({ type: 'error', text: 'Failed to load settings' });
} finally {
setLoading(false);
}
};
const handleSettingChange = (key, value) => {
setSettings(prev => ({
...prev,
[key]: value
}));
};
const saveSettings = async () => {
setSaving(true);
setMessage({ type: '', text: '' });
try {
const token = localStorage.getItem('auth_token');
const response = await fetch('/api/user/settings', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(settings)
});
if (response.ok) {
setMessage({ type: 'success', text: 'Settings saved successfully!' });
} else {
const error = await response.json();
setMessage({ type: 'error', text: error.message || 'Failed to save settings' });
}
} catch (error) {
console.error('Error saving settings:', error);
setMessage({ type: 'error', text: 'Failed to save settings' });
} finally {
setSaving(false);
}
};
const handlePasswordChange = async (e) => {
e.preventDefault();
if (passwordForm.new_password !== passwordForm.confirm_password) {
setMessage({ type: 'error', text: 'New passwords do not match' });
return;
}
if (passwordForm.new_password.length < 8) {
setMessage({ type: 'error', text: 'Password must be at least 8 characters long' });
return;
}
setChangingPassword(true);
setMessage({ type: '', text: '' });
try {
const token = localStorage.getItem('auth_token');
const response = await fetch('/api/user/password', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
current_password: passwordForm.current_password,
new_password: passwordForm.new_password
})
});
if (response.ok) {
setPasswordForm({ current_password: '', new_password: '', confirm_password: '' });
setMessage({ type: 'success', text: 'Password changed successfully!' });
} else {
const error = await response.json();
setMessage({ type: 'error', text: error.message || 'Failed to change password' });
}
} catch (error) {
console.error('Error changing password:', error);
setMessage({ type: 'error', text: 'Failed to change password' });
} finally {
setChangingPassword(false);
}
};
const handleDeleteAccount = async () => {
const confirmed = window.confirm(
'Are you sure you want to delete your account? This action cannot be undone and will permanently delete all your cards, collections, and decks.'
);
if (!confirmed) return;
const doubleConfirmed = window.confirm(
'This is your final warning. Deleting your account will permanently remove all your data. Type "DELETE" to confirm.'
);
if (!doubleConfirmed) return;
try {
const token = localStorage.getItem('auth_token');
const response = await fetch('/api/user/delete', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
localStorage.removeItem('auth_token');
router.push('/login?message=Account deleted successfully');
} else {
const error = await response.json();
setMessage({ type: 'error', text: error.message || 'Failed to delete account' });
}
} catch (error) {
console.error('Error deleting account:', error);
setMessage({ type: 'error', text: 'Failed to delete account' });
}
};
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
const sections = [
{ id: 'account', name: 'Account', icon: '👤' },
{ id: 'security', name: 'Security', icon: '🔒' },
{ id: 'preferences', name: 'Preferences', icon: '⚙️' },
{ id: 'notifications', name: 'Notifications', icon: '🔔' },
{ id: 'display', name: 'Display', icon: '🎨' }
];
const currencyOptions = [
{ value: 'USD', label: 'US Dollar ($)' },
{ value: 'EUR', label: 'Euro (€)' },
{ value: 'GBP', label: 'British Pound (£)' },
{ value: 'CAD', label: 'Canadian Dollar (C$)' },
{ value: 'JPY', label: 'Japanese Yen (¥)' }
];
const cardsPerPageOptions = [
{ value: 25, label: '25 cards' },
{ value: 50, label: '50 cards' },
{ value: 100, label: '100 cards' }
];
const viewOptions = [
{ value: 'grid', label: 'Grid View' },
{ value: 'list', label: 'List View' }
];
const themeOptions = [
{ value: 'light', label: 'Light' },
{ value: 'dark', label: 'Dark' },
{ value: 'system', label: 'System' }
];
if (loading) {
return (
<Layout user={user}>
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-32 w-32 border-b-2" style={{ borderColor: 'var(--accent-ember)' }}></div>
</div>
</Layout>
);
}
return (
<Layout user={user}>
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
<div className="max-w-6xl mx-auto p-6">
{/* Header */}
<div className="mb-8">
<h1 className="text-3xl font-bold mb-2" style={{ color: 'var(--text-primary)' }}>
Settings
</h1>
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
<p className="text-lg" style={{ color: 'var(--text-secondary)' }}>
Manage your account preferences and security settings
</p>
</div>
🎯 Build Comprehensive User Profile & Settings System 👤 Profile Page Features: - Complete user profile with avatar, name, username, bio, and email - Avatar upload with file validation (5MB limit, image types only) - Avatar generation functionality for custom avatars - Favorite games selection (MTG, Pokemon, Lorcana) - Collection statistics display (total cards, collections, decks, value) - Profile editing with real-time validation - Member since date and role display ⚙️ Settings Page Features: - Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display) - Account settings: email (read-only), collection visibility, preferred currency - Security settings: password change with validation, 2FA toggle, account deletion - Preferences: cards per page (25/50/100), default view (grid/list) - Notifications: email notifications, marketing emails (toggle switches) - Display settings: theme (light/dark/system), language selection 🗄️ Database Schema Updates: - Added user profile fields: first_name, last_name, username, bio, avatar_url - Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view - Added notification settings: notifications_email, notifications_marketing, two_factor_enabled - Added display settings: theme, language - Created user_settings table for complex settings - Created user_avatars table for avatar management - Added performance indexes and data validation constraints 📡 API Endpoints Created: - GET/PUT /api/user/profile - Profile information management - GET/PUT /api/user/settings - Settings and preferences management - PUT /api/user/password - Secure password change with bcrypt validation - GET /api/user/stats - Collection statistics and analytics 🔒 Security & Validation: - Password change requires current password verification - Username uniqueness validation - Input validation for all enum fields (currency, theme, view mode, etc.) - Proper error handling and user feedback - Authentication required for all user endpoints 🎨 UI/UX Features: - Beautiful fire-themed design matching app branding - Responsive design for mobile and desktop - Loading states and success/error messages - Avatar placeholder with user initials - Tabbed settings interface with icons - Toggle switches for boolean settings - Form validation with helpful error messages ✨ Additional Features: - Collection stats with game/rarity breakdowns - Recent activity tracking - Danger zone for account deletion with double confirmation - Member since display with formatted dates - Currency formatting for collection values - Game icons and themed styling throughout The profile and settings system is now fully functional with comprehensive user management! 👨‍💻✨
2025-07-26 19:05:55 -04:00
{/* Message */}
{message.text && (
<div className={`mb-6 p-4 rounded-xl ${
message.type === 'success'
? 'bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-200 border border-green-200 dark:border-green-800'
: 'bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-200 border border-red-200 dark:border-red-800'
}`}>
{message.text}
</div>
)}
<div className="grid grid-cols-1 lg:grid-cols-4 gap-8">
{/* Sidebar Navigation */}
<div className="lg:col-span-1">
<div className="card p-4">
<nav className="space-y-2">
{sections.map(section => (
<button
key={section.id}
onClick={() => setActiveSection(section.id)}
className={`w-full flex items-center gap-3 px-4 py-3 rounded-xl font-medium transition-all duration-200 text-left ${
activeSection === section.id ? 'shadow-lg' : 'hover:shadow-md'
}`}
style={{
backgroundColor: activeSection === section.id ? 'var(--accent-ember)' : 'transparent',
color: activeSection === section.id ? 'white' : 'var(--text-primary)'
}}
>
<span>{section.icon}</span>
{section.name}
</button>
))}
</nav>
</div>
</div>
{/* Settings Content */}
<div className="lg:col-span-3">
<div className="card p-6">
{/* Account Settings */}
{activeSection === 'account' && (
<div>
<h2 className="text-2xl font-bold mb-6" style={{ color: 'var(--text-primary)' }}>
Account Settings
</h2>
<div className="space-y-6">
{/* Email */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Email Address
</label>
<div className="flex items-center gap-3">
<input
type="email"
value={user.email}
disabled
className="input-field flex-1 opacity-50 cursor-not-allowed"
/>
<span className="px-3 py-1 text-xs rounded-full bg-green-100 dark:bg-green-900/20 text-green-800 dark:text-green-200">
Verified
</span>
</div>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Contact support to change your email address
</p>
</div>
{/* Collection Visibility */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Default Collection Visibility
</label>
<select
value={settings.collection_visibility}
onChange={(e) => handleSettingChange('collection_visibility', e.target.value)}
className="input-field w-full"
>
<option value="private">Private</option>
<option value="public">Public</option>
<option value="unlisted">Unlisted</option>
</select>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Controls who can see your new collections by default
</p>
</div>
{/* Preferred Currency */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Preferred Currency
</label>
<select
value={settings.preferred_currency}
onChange={(e) => handleSettingChange('preferred_currency', e.target.value)}
className="input-field w-full"
>
{currencyOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Currency used for displaying card values
</p>
</div>
</div>
</div>
)}
{/* Security Settings */}
{activeSection === 'security' && (
<div>
<h2 className="text-2xl font-bold mb-6" style={{ color: 'var(--text-primary)' }}>
Security Settings
</h2>
<div className="space-y-8">
{/* Change Password */}
<div>
<h3 className="text-lg font-semibold mb-4" style={{ color: 'var(--text-primary)' }}>
Change Password
</h3>
<form onSubmit={handlePasswordChange} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Current Password
</label>
<input
type="password"
value={passwordForm.current_password}
onChange={(e) => setPasswordForm(prev => ({ ...prev, current_password: e.target.value }))}
className="input-field w-full"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
New Password
</label>
<input
type="password"
value={passwordForm.new_password}
onChange={(e) => setPasswordForm(prev => ({ ...prev, new_password: e.target.value }))}
className="input-field w-full"
minLength={8}
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Confirm New Password
</label>
<input
type="password"
value={passwordForm.confirm_password}
onChange={(e) => setPasswordForm(prev => ({ ...prev, confirm_password: e.target.value }))}
className="input-field w-full"
minLength={8}
required
/>
</div>
<button
type="submit"
disabled={changingPassword}
className="px-6 py-2 rounded-xl font-medium transition-all duration-200 hover:shadow-md"
style={{
backgroundColor: 'var(--accent-ember)',
color: 'white'
}}
>
{changingPassword ? 'Changing Password...' : 'Change Password'}
</button>
</form>
</div>
{/* Two-Factor Authentication */}
<div>
<h3 className="text-lg font-semibold mb-4" style={{ color: 'var(--text-primary)' }}>
Two-Factor Authentication
</h3>
<div className="flex items-center justify-between p-4 rounded-xl" style={{ backgroundColor: 'var(--bg-secondary)' }}>
<div>
<p className="font-medium" style={{ color: 'var(--text-primary)' }}>
Enable 2FA
</p>
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
Add an extra layer of security to your account
</p>
</div>
<button
onClick={() => handleSettingChange('two_factor_enabled', !settings.two_factor_enabled)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
settings.two_factor_enabled ? 'bg-green-600' : 'bg-gray-300 dark:bg-gray-600'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
settings.two_factor_enabled ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
{settings.two_factor_enabled && (
<p className="text-sm mt-2 p-3 rounded-lg bg-blue-50 dark:bg-blue-900/20 text-blue-800 dark:text-blue-200">
Two-factor authentication is enabled. Use your authenticator app to log in.
</p>
)}
</div>
{/* Danger Zone */}
<div className="border-t pt-8" style={{ borderColor: 'var(--border)' }}>
<h3 className="text-lg font-semibold mb-4 text-red-600 dark:text-red-400">
Danger Zone
</h3>
<div className="p-4 rounded-xl border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/20">
<div className="flex items-center justify-between">
<div>
<p className="font-medium text-red-800 dark:text-red-200">
Delete Account
</p>
<p className="text-sm text-red-600 dark:text-red-300">
Permanently delete your account and all associated data
</p>
</div>
<button
onClick={handleDeleteAccount}
className="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-xl font-medium transition-colors"
>
Delete Account
</button>
</div>
</div>
</div>
</div>
</div>
)}
{/* Preferences */}
{activeSection === 'preferences' && (
<div>
<h2 className="text-2xl font-bold mb-6" style={{ color: 'var(--text-primary)' }}>
Preferences
</h2>
<div className="space-y-6">
{/* Cards Per Page */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Cards Per Page
</label>
<select
value={settings.cards_per_page}
onChange={(e) => handleSettingChange('cards_per_page', parseInt(e.target.value))}
className="input-field w-full"
>
{cardsPerPageOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
{/* Default View */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Default View Mode
</label>
<select
value={settings.default_view}
onChange={(e) => handleSettingChange('default_view', e.target.value)}
className="input-field w-full"
>
{viewOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
</div>
</div>
)}
{/* Notifications */}
{activeSection === 'notifications' && (
<div>
<h2 className="text-2xl font-bold mb-6" style={{ color: 'var(--text-primary)' }}>
Notification Settings
</h2>
<div className="space-y-6">
{/* Email Notifications */}
<div className="flex items-center justify-between p-4 rounded-xl" style={{ backgroundColor: 'var(--bg-secondary)' }}>
<div>
<p className="font-medium" style={{ color: 'var(--text-primary)' }}>
Email Notifications
</p>
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
Receive notifications about your collections and cards
</p>
</div>
<button
onClick={() => handleSettingChange('notifications_email', !settings.notifications_email)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
settings.notifications_email ? 'bg-green-600' : 'bg-gray-300 dark:bg-gray-600'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
settings.notifications_email ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
{/* Marketing Emails */}
<div className="flex items-center justify-between p-4 rounded-xl" style={{ backgroundColor: 'var(--bg-secondary)' }}>
<div>
<p className="font-medium" style={{ color: 'var(--text-primary)' }}>
Marketing Emails
</p>
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
Receive updates about new features and promotions
</p>
</div>
<button
onClick={() => handleSettingChange('notifications_marketing', !settings.notifications_marketing)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
settings.notifications_marketing ? 'bg-green-600' : 'bg-gray-300 dark:bg-gray-600'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
settings.notifications_marketing ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
</div>
</div>
)}
{/* Display Settings */}
{activeSection === 'display' && (
<div>
<h2 className="text-2xl font-bold mb-6" style={{ color: 'var(--text-primary)' }}>
Display Settings
</h2>
<div className="space-y-6">
{/* Theme */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Theme
</label>
<select
value={settings.theme}
onChange={(e) => handleSettingChange('theme', e.target.value)}
className="input-field w-full"
>
{themeOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
System will follow your device's theme preference
</p>
</div>
{/* Language */}
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Language
</label>
<select
value={settings.language}
onChange={(e) => handleSettingChange('language', e.target.value)}
className="input-field w-full"
>
<option value="en">English</option>
<option value="es">Español</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
<option value="ja">日本語</option>
</select>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Interface language (coming soon)
</p>
</div>
</div>
</div>
)}
{/* Save Button */}
<div className="flex justify-end pt-8 border-t" style={{ borderColor: 'var(--border)' }}>
<button
onClick={saveSettings}
disabled={saving}
className="px-6 py-3 rounded-xl font-medium transition-all duration-200 hover:shadow-md"
style={{
backgroundColor: 'var(--accent-ember)',
color: 'white'
}}
>
{saving ? 'Saving...' : 'Save Settings'}
</button>
</div>
</div>
</div>
</div>
</div>
</Layout>
);
}