"use client"; import {Avatar, AvatarFallback, AvatarImage} from "@/components/ui/avatar"; import {UploadIcon} from "lucide-react"; import {toast} from "sonner"; import {uploadUserImageAction} from "@/features/upload/upload.action"; import {useMutation} from "@tanstack/react-query"; import {updateImageUserAction} from "@/features/profile/avatar.action"; import {useRouter} from "next/navigation"; import {User} from "@/db/schema/02_user"; import React, {ChangeEvent} from "react"; import type {AvatarMode} from "@/features/onboarding/types"; export type AvatarWithUploadProps = { user: User; avatarMode?: AvatarMode; avatarUrl?: string; }; export const AvatarWithUpload = (props: AvatarWithUploadProps) => { const user = props.user; const canUpload = !props.avatarMode || props.avatarMode === "internal"; const src = props.avatarUrl ?? user.image ?? undefined; const router = useRouter(); const submitImage = useMutation({ mutationFn: async (file: File) => { const formData = new FormData(); formData.set("file", file); const result = await uploadUserImageAction(formData); const inner = result?.data; if (inner?.success) { const updateUser = await updateImageUserAction(inner.value ?? ""); const dataUser = updateUser?.data; if (updateUser?.serverError || !dataUser) { toast.error(updateUser?.serverError); return; } toast.success(inner.actionSuccess?.message); router.refresh(); } else { toast.error(inner?.actionError?.message); } }, }); const handleImageUpload = async (event: ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; const allowedFormats = ["image/jpeg", "image/png", "image/webp"]; if (!allowedFormats.includes(file.type)) { toast.error("Only JPG, PNG or WebP images are allowed."); return; } const maxSizeInMB = 5; if (file.size > maxSizeInMB * 1024 * 1024) { toast.error(`Image must be smaller than ${maxSizeInMB}MB.`); return; } submitImage.mutate(file); }; return (
{(user.name?.charAt(0) ?? user.email?.charAt(0) ?? "?").toUpperCase()} {canUpload && (
{ const fileInput = document.createElement("input"); fileInput.type = "file"; fileInput.accept = ".jpg,.jpeg,.png,.webp"; fileInput.onchange = (e: Event) => handleImageUpload(e as unknown as React.ChangeEvent); fileInput.click(); }} className="cursor-pointer absolute inset-0 flex justify-center items-center opacity-0 transition-opacity hover:opacity-30 hover:bg-gray-500 hover:bg-opacity-50 rounded-full w-24 h-24 lg:w-32 lg:h-32" >
)}
); };