From a02f784c990cf719c1fa379b186903282312c58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20LAGACHE?= Date: Tue, 16 Jun 2026 16:58:07 +0200 Subject: [PATCH] fix(onboarding): validate avatar upload size/type and handle FileReader errors --- src/features/onboarding/steps/step-preferences.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/features/onboarding/steps/step-preferences.tsx b/src/features/onboarding/steps/step-preferences.tsx index 031177e4..501b53b9 100644 --- a/src/features/onboarding/steps/step-preferences.tsx +++ b/src/features/onboarding/steps/step-preferences.tsx @@ -2,9 +2,12 @@ import { useState } from "react"; import { useOnboarding } from "@onboardjs/react"; +import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +const MAX_AVATAR_SIZE_BYTES = 2 * 1024 * 1024; + export const StepPreferences = () => { const { next, updateContext, state } = useOnboarding(); const [theme, setTheme] = useState<"light" | "dark">("dark"); @@ -13,8 +16,17 @@ export const StepPreferences = () => { const onFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; + if (!file.type.startsWith("image/")) { + toast.error("Please select an image file."); + return; + } + if (file.size > MAX_AVATAR_SIZE_BYTES) { + toast.error("Image is too large. Please select a file under 2MB."); + return; + } const reader = new FileReader(); reader.onload = () => setAvatarDataUrl(reader.result as string); + reader.onerror = () => toast.error("Failed to read the selected image. Please try again."); reader.readAsDataURL(file); };