-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprofile-picture-upload.tsx
More file actions
87 lines (81 loc) · 2.78 KB
/
profile-picture-upload.tsx
File metadata and controls
87 lines (81 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"use client";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/primitives/avatar";
import { FilePicker } from "@/components/primitives/file-picker";
import { cn } from "@/lib/utils";
import { useAuth } from "@/providers/client-auth-provider";
import EditIcon from "@public/assets/icons/edit.svg";
interface ProfilePictureUploadProps {
currentImage?: string;
name?: string;
disabled?: boolean;
userId?: string;
onUploaded?: (objectKey: string) => void;
}
export function ProfilePictureUpload({
currentImage,
name,
disabled = false,
userId,
onUploaded,
}: ProfilePictureUploadProps) {
const { user } = useAuth();
const displayImage = currentImage ?? user?.image ?? undefined;
const displayName = name ?? user?.name ?? "User avatar";
const fallback = displayName.trim().slice(0, 2).toUpperCase();
return (
<div className="flex flex-col items-center gap-3">
<FilePicker
objectType="user"
id={userId ?? user?.id ?? ""}
disabled={disabled}
targetSize={120}
onUploaded={onUploaded}
// onUploaded={(objectKey) => {
// const base = process.env.NEXT_PUBLIC_MINIO_PUBLIC_URL!;
// const bucket = process.env.NEXT_PUBLIC_MINIO_BUCKET!;
// const imageUrl = `${base}/${bucket}/${objectKey}`;
// clientApi.profile.update.mutate({ userId: userId ?? user!.id, imageUrl });
// }}
>
{/* Click target */}
<button
type="button"
aria-label="Upload profile picture"
aria-disabled={disabled}
disabled={disabled}
className={cn(
"group relative size-[120px] rounded-[25%] outline-none",
"focus-visible:ring-2 focus-visible:ring-primary",
disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"
)}
>
<Avatar
className={cn(
"h-full w-full overflow-hidden rounded-[25%] border-2 transition-colors",
disabled ? "border-border" : "border-border group-hover:border-primary"
)}
>
<AvatarImage
src={displayImage}
alt={displayName}
className="h-full w-full rounded-[25%] object-cover"
/>
<AvatarFallback className="rounded-[25%]">
{fallback}
</AvatarFallback>
</Avatar>
{/* Hover overlay */}
<div
className={cn(
"pointer-events-none absolute inset-0 grid place-items-center rounded-[25%]",
"bg-black/50 opacity-0 transition-opacity",
"group-hover:opacity-100"
)}
>
<EditIcon className="h-6 w-6 fill-white" aria-hidden="true" />
</div>
</button>
</FilePicker>
</div>
);
}