feat: add file upload support for custom profile pictures

This commit is contained in:
randomperson12344
2025-09-23 22:32:32 -07:00
parent 569d43ae7f
commit df0fb340ad

View File

@@ -257,8 +257,8 @@ export const ProfileForm = () => {
onValueChange={(e) => {
field.onChange(e);
}}
defaultValue={field.value}
value={field.value}
defaultValue={field.value?.startsWith('data:') ? 'upload' : field.value}
value={field.value?.startsWith('data:') ? 'upload' : field.value}
className="flex flex-row flex-wrap gap-2 max-xl:justify-center"
>
<FormItem key="no-avatar">
@@ -279,6 +279,54 @@ export const ProfileForm = () => {
</Avatar>
</FormLabel>
</FormItem>
<FormItem key="custom-upload">
<FormLabel className="[&:has([data-state=checked])>.upload-avatar]:border-primary [&:has([data-state=checked])>.upload-avatar]:border-1 [&:has([data-state=checked])>.upload-avatar]:p-px cursor-pointer">
<FormControl>
<RadioGroupItem
value="upload"
className="sr-only"
/>
</FormControl>
<div
className="upload-avatar h-12 w-12 rounded-full border border-dashed border-muted-foreground hover:border-primary transition-colors flex items-center justify-center bg-muted/50 hover:bg-muted overflow-hidden"
onClick={() => document.getElementById('avatar-upload')?.click()}
>
{field.value?.startsWith('data:') ? (
<img
src={field.value}
alt="Custom avatar"
className="h-full w-full object-cover rounded-full"
/>
) : (
<svg className="h-5 w-5 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
</svg>
)}
</div>
<input
id="avatar-upload"
type="file"
accept="image/*"
className="hidden"
onChange={async (e) => {
const file = e.target.files?.[0];
if (file) {
// max file size 5mb
if (file.size > 5 * 1024 * 1024) {
toast.error('Image size must be less than 5MB');
return;
}
const reader = new FileReader();
reader.onload = (event) => {
const result = event.target?.result as string;
field.onChange(result);
};
reader.readAsDataURL(file);
}
}}
/>
</FormLabel>
</FormItem>
{availableAvatars.map((image) => (
<FormItem key={image}>
<FormLabel className="[&:has([data-state=checked])>img]:border-primary [&:has([data-state=checked])>img]:border-1 [&:has([data-state=checked])>img]:p-px cursor-pointer">