183 lines
9.8 KiB
TypeScript
183 lines
9.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink } from 'lucide-react';
|
|
import { useAuth } from '../context/AuthContext';
|
|
import { EditProfileModal } from './EditProfileModal';
|
|
|
|
interface SettingsModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
theme: 'light' | 'dark';
|
|
onToggleTheme: () => void;
|
|
onNavigateToProfile?: (username: string) => void;
|
|
}
|
|
|
|
export const SettingsModal: React.FC<SettingsModalProps> = ({ isOpen, onClose, theme, onToggleTheme, onNavigateToProfile }) => {
|
|
const { user } = useAuth();
|
|
const [isEditProfileOpen, setIsEditProfileOpen] = useState(false);
|
|
|
|
if (!isOpen || !user) {
|
|
if (isEditProfileOpen && user) {
|
|
return (
|
|
<EditProfileModal
|
|
isOpen={isEditProfileOpen}
|
|
onClose={() => setIsEditProfileOpen(false)}
|
|
onSaved={() => setIsEditProfileOpen(false)}
|
|
/>
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4" onClick={onClose}>
|
|
<div
|
|
className="bg-white dark:bg-zinc-900 rounded-2xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-y-auto"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between p-6 border-b border-zinc-200 dark:border-white/5">
|
|
<h2 className="text-2xl font-bold text-zinc-900 dark:text-white">Settings</h2>
|
|
<button
|
|
onClick={onClose}
|
|
className="p-2 hover:bg-zinc-100 dark:hover:bg-white/5 rounded-full transition-colors"
|
|
>
|
|
<X size={20} className="text-zinc-500" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-6 space-y-8">
|
|
{/* User Profile Section */}
|
|
<div className="bg-zinc-50 dark:bg-zinc-800/50 rounded-xl p-6">
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-16 h-16 rounded-full bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-2xl font-bold text-white shadow-lg overflow-hidden">
|
|
{user.avatar_url ? (
|
|
<img src={user.avatar_url} alt={user.username} className="w-full h-full object-cover" />
|
|
) : (
|
|
user.username[0].toUpperCase()
|
|
)}
|
|
</div>
|
|
<div className="flex-1">
|
|
<h3 className="text-xl font-bold text-zinc-900 dark:text-white">@{user.username}</h3>
|
|
<p className="text-xs text-zinc-400 dark:text-zinc-500 mt-1">
|
|
Member since {new Date(user.createdAt).toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
|
|
</p>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<button
|
|
onClick={() => {
|
|
onClose();
|
|
setIsEditProfileOpen(true);
|
|
}}
|
|
className="flex items-center gap-2 px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium hover:bg-indigo-700 transition-colors"
|
|
>
|
|
<Edit3 size={16} />
|
|
Edit Profile
|
|
</button>
|
|
<button
|
|
onClick={() => {
|
|
onClose();
|
|
onNavigateToProfile?.(user.username);
|
|
}}
|
|
className="flex items-center gap-2 px-4 py-2 bg-zinc-200 dark:bg-zinc-700 text-zinc-900 dark:text-white rounded-lg text-sm font-medium hover:bg-zinc-300 dark:hover:bg-zinc-600 transition-colors"
|
|
>
|
|
<ExternalLink size={16} />
|
|
View Profile
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Account Section */}
|
|
<div className="space-y-4">
|
|
<div className="flex items-center gap-2 text-zinc-900 dark:text-white">
|
|
<UserIcon size={20} />
|
|
<h3 className="font-semibold">Account</h3>
|
|
</div>
|
|
<div className="pl-7 space-y-3">
|
|
<div>
|
|
<label className="text-sm text-zinc-500 dark:text-zinc-400">Username</label>
|
|
<p className="text-zinc-900 dark:text-white font-medium">@{user.username}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Theme Section */}
|
|
<div className="space-y-4">
|
|
<div className="flex items-center gap-2 text-zinc-900 dark:text-white">
|
|
<Palette size={20} />
|
|
<h3 className="font-semibold">Appearance</h3>
|
|
</div>
|
|
<div className="pl-7 space-y-3">
|
|
<div className="flex gap-3">
|
|
<button
|
|
onClick={theme === 'dark' ? onToggleTheme : undefined}
|
|
className={`flex-1 py-3 px-4 rounded-lg border-2 font-medium transition-colors ${theme === 'light'
|
|
? 'border-indigo-500 bg-indigo-50 text-indigo-700'
|
|
: 'border-zinc-300 dark:border-zinc-700 hover:border-zinc-400 dark:hover:border-zinc-600'
|
|
}`}
|
|
>
|
|
Light
|
|
</button>
|
|
<button
|
|
onClick={theme === 'light' ? onToggleTheme : undefined}
|
|
className={`flex-1 py-3 px-4 rounded-lg border-2 font-medium transition-colors ${theme === 'dark'
|
|
? 'border-indigo-500 bg-indigo-950 text-indigo-300'
|
|
: 'border-zinc-300 dark:border-zinc-700 hover:border-zinc-400 dark:hover:border-zinc-600'
|
|
}`}
|
|
>
|
|
Dark
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* About Section */}
|
|
<div className="space-y-4">
|
|
<div className="flex items-center gap-2 text-zinc-900 dark:text-white">
|
|
<Info size={20} />
|
|
<h3 className="font-semibold">About</h3>
|
|
</div>
|
|
<div className="pl-7 space-y-3 text-sm text-zinc-600 dark:text-zinc-400">
|
|
<p>Version 1.0.0</p>
|
|
<p>ACE-Step UI - Local AI Music Generator</p>
|
|
<p className="text-xs text-zinc-400 dark:text-zinc-500 mt-2">
|
|
Powered by ACE-Step 1.5. Open source and free to use.
|
|
</p>
|
|
<div className="pt-3 border-t border-zinc-200 dark:border-zinc-700/50 mt-4">
|
|
<p className="text-zinc-900 dark:text-white font-medium mb-2">Created by Ambsd</p>
|
|
<a
|
|
href="https://x.com/AmbsdOP"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="inline-flex items-center gap-2 px-4 py-2 bg-black dark:bg-white text-white dark:text-black rounded-lg text-sm font-medium hover:bg-zinc-800 dark:hover:bg-zinc-200 transition-colors"
|
|
>
|
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
|
|
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
|
|
</svg>
|
|
Follow @AmbsdOP
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="border-t border-zinc-200 dark:border-white/5 p-6 flex justify-end">
|
|
<button
|
|
onClick={onClose}
|
|
className="px-6 py-2 bg-zinc-900 dark:bg-white text-white dark:text-black font-semibold rounded-lg hover:bg-zinc-800 dark:hover:bg-zinc-200 transition-colors"
|
|
>
|
|
Done
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<EditProfileModal
|
|
isOpen={isEditProfileOpen}
|
|
onClose={() => setIsEditProfileOpen(false)}
|
|
onSaved={() => setIsEditProfileOpen(false)}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|