Display Name
setDisplayName(e.target.value)}
/>
Location
setLocationInput(e.target.value)}
/>
Profile Image
{
const ensureBuckets = async () => {
try {
await fetch(
`${API_BASE}/api/storage/ensure-buckets`,
{
method: "POST",
},
);
} catch {}
};
const file = e.target.files?.[0];
if (!file || !user) return;
const storeDataUrl = () =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () =>
resolve(reader.result as string);
reader.onerror = () =>
reject(new Error("Failed to read file"));
reader.readAsDataURL(file);
});
try {
await ensureBuckets();
const path = `${user.id}/avatar-${Date.now()}-${file.name}`;
let { error } = await supabase.storage
.from("avatars")
.upload(path, file, { upsert: true });
if (
error &&
/bucket/i.test(error?.message || "")
) {
await ensureBuckets();
({ error } = await supabase.storage
.from("avatars")
.upload(path, file, { upsert: true }));
}
if (error) throw error;
const { data } = supabase.storage
.from("avatars")
.getPublicUrl(path);
await updateProfile({
avatar_url: data.publicUrl,
} as any);
computeProfileCompletion({
...(profile as any),
avatar_url: data.publicUrl,
});
aethexToast.success({
title: "Avatar updated",
});
} catch (err: any) {
try {
const dataUrl = await storeDataUrl();
await updateProfile({
avatar_url: dataUrl,
} as any);
computeProfileCompletion({
...(profile as any),
avatar_url: dataUrl,
});
aethexToast.success({
title: "Avatar saved (local)",
});
} catch (e: any) {
aethexToast.error({
title: "Upload failed",
description:
err?.message || "Unable to upload image",
});
}
}
}}
/>
Banner Image
{
const ensureBuckets = async () => {
try {
await fetch(
`${API_BASE}/api/storage/ensure-buckets`,
{
method: "POST",
},
);
} catch {}
};
const file = e.target.files?.[0];
if (!file || !user) return;
const storeDataUrl = () =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () =>
resolve(reader.result as string);
reader.onerror = () =>
reject(new Error("Failed to read file"));
reader.readAsDataURL(file);
});
try {
await ensureBuckets();
const path = `${user.id}/banner-${Date.now()}-${file.name}`;
let { error } = await supabase.storage
.from("banners")
.upload(path, file, { upsert: true });
if (
error &&
/bucket/i.test(error?.message || "")
) {
await ensureBuckets();
({ error } = await supabase.storage
.from("banners")
.upload(path, file, { upsert: true }));
}
if (error) throw error;
const { data } = supabase.storage
.from("banners")
.getPublicUrl(path);
await updateProfile({
banner_url: data.publicUrl,
} as any);
computeProfileCompletion({
...(profile as any),
banner_url: data.publicUrl,
});
aethexToast.success({
title: "Banner updated",
});
} catch (err: any) {
try {
const dataUrl = await storeDataUrl();
await updateProfile({
banner_url: dataUrl,
} as any);
computeProfileCompletion({
...(profile as any),
banner_url: dataUrl,
});
aethexToast.success({
title: "Banner saved (local)",
});
} catch (e: any) {
aethexToast.error({
title: "Upload failed",
description:
err?.message || "Unable to upload image",
});
}
}
}}
/>
Bio
Website
setWebsite(e.target.value)}
/>
LinkedIn URL
setLinkedin(e.target.value)}
/>
GitHub URL
setGithub(e.target.value)}
/>
Twitter URL
setTwitter(e.target.value)}
/>