All checks were successful
Deploy Brew Application / deploy (push) Successful in 11s
142 lines
7.8 KiB
JavaScript
142 lines
7.8 KiB
JavaScript
/* global __APP_VERSION__ */
|
|
import { useContext } from "react";
|
|
import { AuthContext } from "../AuthContext";
|
|
import { useTheme } from "../ThemeContext";
|
|
import { User, Mail, Contrast, Coffee, Database, MessageSquare } from "lucide-react";
|
|
|
|
export default function ProfilePage({ user, isOnline, syncing, showSyncedStatus }) {
|
|
const { logout } = useContext(AuthContext);
|
|
const { theme, setTheme } = useTheme();
|
|
|
|
const themeOptions = [
|
|
{ value: "light", label: "Light" },
|
|
{ value: "dark", label: "Dark" },
|
|
{ value: "system", label: "System" }
|
|
];
|
|
|
|
return (
|
|
<div className="transition-colors duration-200">
|
|
{/* Avatar & Name */}
|
|
<div className="flex flex-col items-center pt-6 pb-8">
|
|
<div className="w-20 h-20 rounded-full bg-[#2C1810] dark:bg-[#D4A325] flex items-center justify-center text-3xl text-[#FAF6F1] dark:text-[#2C1810] font-serif font-bold mb-3 shadow-sm">
|
|
{user?.username?.[0]?.toUpperCase() || <User size={32} strokeWidth={2} />}
|
|
</div>
|
|
<div className="font-serif text-xl font-semibold text-[#2C1810] dark:text-[#FAF6F1]">{user?.username}</div>
|
|
<div className="text-sm text-[#9C8B7A] dark:text-[#C8B9A6] mt-0.5">{user?.email}</div>
|
|
<div className={`flex items-center gap-1.5 text-[11px] font-medium px-3 py-1.5 rounded-full mt-3 transition-all ${isOnline ? "text-[#4A7C59] bg-[rgba(74,124,89,0.1)] dark:text-[#6CB281] dark:bg-[rgba(108,178,129,0.15)]" : "text-[#B44040] bg-[rgba(180,64,64,0.1)] dark:text-[#E55B5B] dark:bg-[rgba(229,91,91,0.15)]"}`}>
|
|
<span className={`text-[10px] ${syncing ? "animate-sync-pulse" : ""}`}>●</span>
|
|
<span>{isOnline ? (syncing ? "Syncing…" : "All data synced") : "Offline — saved locally"}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Account section */}
|
|
<div className="mb-6">
|
|
<div className="text-[11px] font-semibold uppercase tracking-widest text-[#9C8B7A] dark:text-[#C8B9A6] mb-2 px-1">Account</div>
|
|
<div className="bg-white dark:bg-[#22120B] rounded-2xl border border-[#E8DFD3] dark:border-[#3B2217] overflow-hidden shadow-sm transition-colors duration-200">
|
|
<div className="flex items-center gap-3 px-4 py-3.5 border-b border-[#F3EDE4] dark:border-[#3B2217]">
|
|
<User size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6]">Username</div>
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">{user?.username}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3 px-4 py-3.5">
|
|
<Mail size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6]">Email</div>
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">{user?.email}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Sign out */}
|
|
<div className="mb-6">
|
|
<button
|
|
onClick={() => logout()}
|
|
className="w-full py-3.5 border border-[#B44040] dark:border-[#E55B5B] rounded-2xl text-sm font-semibold text-[#B44040] dark:text-[#E55B5B] bg-transparent cursor-pointer hover:bg-[rgba(180,64,64,0.05)] dark:hover:bg-[rgba(229,91,91,0.05)] transition-all">
|
|
Sign Out
|
|
</button>
|
|
</div>
|
|
|
|
{/* Appearance Settings section */}
|
|
<div className="mb-6">
|
|
<div className="text-[11px] font-semibold uppercase tracking-widest text-[#9C8B7A] dark:text-[#C8B9A6] mb-2 px-1">Appearance</div>
|
|
<div className="bg-white dark:bg-[#22120B] rounded-2xl border border-[#E8DFD3] dark:border-[#3B2217] p-4 flex flex-col gap-3 shadow-sm transition-colors duration-200">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<Contrast size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div>
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">Theme</div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6]">Customize your viewing experience</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-3 gap-1 bg-[#F3EDE4] dark:bg-[#2C1810] p-1 rounded-xl transition-colors duration-200">
|
|
{themeOptions.map((opt) => {
|
|
const active = theme === opt.value;
|
|
return (
|
|
<button
|
|
key={opt.value}
|
|
onClick={() => setTheme(opt.value)}
|
|
className={`py-2 px-3 rounded-xl text-xs font-semibold transition-all cursor-pointer ${
|
|
active
|
|
? "bg-[#2C1810] text-[#FAF6F1] dark:bg-[#FAF6F1] dark:text-[#2C1810] shadow-sm"
|
|
: "text-[#6B5744] hover:text-[#2C1810] dark:text-[#C8B9A6] dark:hover:text-[#FAF6F1]"
|
|
}`}
|
|
>
|
|
{opt.label}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* App info */}
|
|
<div className="mb-6">
|
|
<div className="text-[11px] font-semibold uppercase tracking-widest text-[#9C8B7A] dark:text-[#C8B9A6] mb-2 px-1">App</div>
|
|
<div className="bg-white dark:bg-[#22120B] rounded-2xl border border-[#E8DFD3] dark:border-[#3B2217] overflow-hidden shadow-sm transition-colors duration-200">
|
|
<div className="flex items-center justify-between px-4 py-3.5 border-b border-[#F3EDE4] dark:border-[#3B2217]">
|
|
<div className="flex items-center gap-3">
|
|
<Coffee size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">Brew Journal</div>
|
|
</div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6] font-mono">{__APP_VERSION__}</div>
|
|
</div>
|
|
<div className="flex items-center gap-3 px-4 py-3.5">
|
|
<Database size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6]">Storage</div>
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">Local + PostgreSQL</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Support section */}
|
|
<div className="mb-6">
|
|
<div className="text-[11px] font-semibold uppercase tracking-widest text-[#9C8B7A] dark:text-[#C8B9A6] mb-2 px-1">Support</div>
|
|
<div className="bg-white dark:bg-[#22120B] rounded-2xl border border-[#E8DFD3] dark:border-[#3B2217] overflow-hidden shadow-sm transition-colors duration-200">
|
|
<a
|
|
href="https://git.adityagupta.dev/sortedcord/brew/issues/new"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-center justify-between px-4 py-3.5 hover:bg-[#F3EDE4]/50 dark:hover:bg-[#2C1810]/50 transition-colors cursor-pointer no-underline group"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<MessageSquare size={18} strokeWidth={2} className="text-[#9C8B7A] dark:text-[#C8B9A6] flex-shrink-0" />
|
|
<div>
|
|
<div className="text-xs text-[#9C8B7A] dark:text-[#C8B9A6]">Feedback</div>
|
|
<div className="text-sm font-medium text-[#2C1810] dark:text-[#FAF6F1]">Report an issue or request a feature</div>
|
|
</div>
|
|
</div>
|
|
<span className="text-[#9C8B7A] dark:text-[#C8B9A6] text-sm group-hover:translate-x-0.5 transition-transform duration-200">→</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|