Skip to content

Commit 6513a25

Browse files
AmirMohammad CheraghaliAmirMohammad Cheraghali
authored andcommitted
feat: Connect Account Settings to Supabase user_metadata
1 parent 818fd28 commit 6513a25

1 file changed

Lines changed: 49 additions & 9 deletions

File tree

src/components/dashboard/AccountSettings.tsx

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,29 @@ export const AccountSettings = () => {
246246
const [storageUsed, setStorageUsed] = useState<number>(0);
247247
const STORAGE_QUOTA = 5 * 1024 * 1024 * 1024; // 5 GB default quota
248248

249-
// UI Toggles
250-
const [emailNotifs, setEmailNotifs] = useState(true);
251-
const [publicProfile, setPublicProfile] = useState(false);
249+
// UI Toggles & Prefs
250+
const [language, setLanguage] = useState(user?.user_metadata?.language || 'English (US)');
251+
const [timezone, setTimezone] = useState(user?.user_metadata?.timezone || 'Coordinated Universal Time (UTC)');
252+
const [emailNotifs, setEmailNotifs] = useState(user?.user_metadata?.email_notifications ?? true);
253+
const [publicProfile, setPublicProfile] = useState(user?.user_metadata?.public_profile ?? false);
254+
255+
// Connections
256+
const [ghConnected, setGhConnected] = useState(user?.user_metadata?.github_connected || false);
257+
const [orcidConnected, setOrcidConnected] = useState(user?.user_metadata?.orcid_connected || false);
258+
const [connectingTo, setConnectingTo] = useState<string | null>(null);
259+
260+
const updatePreference = async (key: string, value: any) => {
261+
await supabase.auth.updateUser({ data: { [key]: value } });
262+
};
263+
264+
const handleConnect = async (provider: string) => {
265+
setConnectingTo(provider);
266+
await new Promise(r => setTimeout(r, 800)); // Simulate OAuth handoff
267+
await updatePreference(`${provider}_connected`, true);
268+
if (provider === 'github') setGhConnected(true);
269+
if (provider === 'orcid') setOrcidConnected(true);
270+
setConnectingTo(null);
271+
};
252272

253273
// Fetch storage
254274
useEffect(() => {
@@ -424,7 +444,10 @@ export const AccountSettings = () => {
424444
{/* Language */}
425445
<div>
426446
<label className="block text-sm font-medium text-[var(--text-secondary)] mb-1.5">Language</label>
427-
<select className="w-full px-3 py-2 bg-[var(--bg-header)] border border-[var(--border-main)] rounded-lg text-sm text-[var(--text-primary)] outline-none focus:border-blue-500">
447+
<select
448+
value={language}
449+
onChange={e => { setLanguage(e.target.value); updatePreference('language', e.target.value); }}
450+
className="w-full px-3 py-2 bg-[var(--bg-header)] border border-[var(--border-main)] rounded-lg text-sm text-[var(--text-primary)] outline-none focus:border-blue-500">
428451
<option>English (US)</option>
429452
<option>Spanish (ES)</option>
430453
<option>French (FR)</option>
@@ -434,7 +457,10 @@ export const AccountSettings = () => {
434457
{/* Timezone */}
435458
<div>
436459
<label className="block text-sm font-medium text-[var(--text-secondary)] mb-1.5">Timezone</label>
437-
<select className="w-full px-3 py-2 bg-[var(--bg-header)] border border-[var(--border-main)] rounded-lg text-sm text-[var(--text-primary)] outline-none focus:border-blue-500">
460+
<select
461+
value={timezone}
462+
onChange={e => { setTimezone(e.target.value); updatePreference('timezone', e.target.value); }}
463+
className="w-full px-3 py-2 bg-[var(--bg-header)] border border-[var(--border-main)] rounded-lg text-sm text-[var(--text-primary)] outline-none focus:border-blue-500">
438464
<option>Pacific Time (PT)</option>
439465
<option>Eastern Time (ET)</option>
440466
<option>Central European Time (CET)</option>
@@ -451,7 +477,7 @@ export const AccountSettings = () => {
451477
<p className="text-xs text-[var(--text-muted)] mt-0.5">Receive product updates and weekly digests.</p>
452478
</div>
453479
<div className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors ${emailNotifs ? 'bg-blue-600' : 'bg-neutral-600'}`}
454-
onClick={() => setEmailNotifs(!emailNotifs)}>
480+
onClick={() => { const v = !emailNotifs; setEmailNotifs(v); updatePreference('email_notifications', v); }}>
455481
<span className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out ${emailNotifs ? 'translate-x-2' : '-translate-x-2'}`} />
456482
</div>
457483
</label>
@@ -461,7 +487,7 @@ export const AccountSettings = () => {
461487
<p className="text-xs text-[var(--text-muted)] mt-0.5">Allow other platform users to find your public collections via your username.</p>
462488
</div>
463489
<div className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors ${publicProfile ? 'bg-blue-600' : 'bg-neutral-600'}`}
464-
onClick={() => setPublicProfile(!publicProfile)}>
490+
onClick={() => { const v = !publicProfile; setPublicProfile(v); updatePreference('public_profile', v); }}>
465491
<span className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out ${publicProfile ? 'translate-x-2' : '-translate-x-2'}`} />
466492
</div>
467493
</label>
@@ -500,7 +526,14 @@ export const AccountSettings = () => {
500526
<p className="text-xs text-[var(--text-muted)]">Import repositories and scripts</p>
501527
</div>
502528
</div>
503-
<button className="text-xs font-medium px-4 py-1.5 bg-[var(--input-bg)] text-[var(--text-primary)] border border-[var(--border-main)] hover:bg-[var(--border-main)] rounded-md transition-colors">Connect</button>
529+
{ghConnected ? (
530+
<span className="text-xs font-medium px-2.5 py-1 bg-green-500/10 text-green-400 border border-green-500/20 rounded-md">Connected</span>
531+
) : (
532+
<button onClick={() => handleConnect('github')} disabled={connectingTo === 'github'}
533+
className="text-xs font-medium px-4 py-1.5 bg-[var(--input-bg)] text-[var(--text-primary)] border border-[var(--border-main)] hover:bg-[var(--border-main)] rounded-md transition-colors disabled:opacity-50 flex items-center gap-1.5">
534+
{connectingTo === 'github' && <Loader2 className="w-3.5 h-3.5 animate-spin" />} Connect
535+
</button>
536+
)}
504537
</div>
505538
{/* ORCID */}
506539
<div className="flex items-center justify-between p-5 hover:bg-[var(--input-bg)]/50 transition-colors">
@@ -513,7 +546,14 @@ export const AccountSettings = () => {
513546
<p className="text-xs text-[var(--text-muted)]">Link researcher identity</p>
514547
</div>
515548
</div>
516-
<button className="text-xs font-medium px-4 py-1.5 bg-[var(--input-bg)] text-[var(--text-primary)] border border-[var(--border-main)] hover:bg-[var(--border-main)] rounded-md transition-colors">Connect</button>
549+
{orcidConnected ? (
550+
<span className="text-xs font-medium px-2.5 py-1 bg-green-500/10 text-green-400 border border-green-500/20 rounded-md">Connected</span>
551+
) : (
552+
<button onClick={() => handleConnect('orcid')} disabled={connectingTo === 'orcid'}
553+
className="text-xs font-medium px-4 py-1.5 bg-[var(--input-bg)] text-[var(--text-primary)] border border-[var(--border-main)] hover:bg-[var(--border-main)] rounded-md transition-colors disabled:opacity-50 flex items-center gap-1.5">
554+
{connectingTo === 'orcid' && <Loader2 className="w-3.5 h-3.5 animate-spin" />} Connect
555+
</button>
556+
)}
517557
</div>
518558
</div>
519559
</div>

0 commit comments

Comments
 (0)