CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/account/upload-profile-image.tsx
Views: 687
1
// Upload user avatar image
2
3
// similar to code in next/components/account/config/account/avatar.tsx
4
5
import { useState } from "react";
6
import { Alert, Upload } from "antd";
7
import ImgCrop from "antd-img-crop";
8
import imageToDataURL from "@cocalc/frontend/misc/image-to-data";
9
import { Avatar } from "./avatar/avatar";
10
11
// This is what facebook uses, and it makes
12
// 40x40 look very good. It takes about 20KB
13
// per image.
14
15
const AVATAR_SIZE: number = 160;
16
17
interface Props {
18
account_id: string;
19
onChange: (data) => void;
20
}
21
22
export default function UploadProfileImage({ account_id, onChange }: Props) {
23
const [error, setError] = useState<string>("");
24
return (
25
<div>
26
<ImgCrop
27
modalTitle={"Edit Profile Image"}
28
cropShape="rect"
29
rotationSlider
30
maxZoom={5}
31
onModalOk={(file) => {
32
const reader = new FileReader();
33
reader.addEventListener(
34
"load",
35
async (e) => {
36
if (!e.target?.result) return; // typescript
37
const src = e.target.result as string;
38
onChange(
39
await imageToDataURL(
40
src,
41
AVATAR_SIZE,
42
AVATAR_SIZE,
43
"image/png",
44
),
45
);
46
},
47
false,
48
);
49
if (typeof file != "object") {
50
setError(
51
"WARNING: unable to read, since avatar is assumed to be a Blob",
52
);
53
return;
54
}
55
reader.readAsDataURL(file as any);
56
}}
57
>
58
<Upload.Dragger
59
name="file"
60
onDrop={(e) => {
61
e.preventDefault();
62
e.stopPropagation();
63
}}
64
>
65
<p className="ant-upload-drag-icon">
66
<Avatar account_id={account_id} size={AVATAR_SIZE/2} />
67
</p>
68
<p className="ant-upload-text">
69
Click or drag image to this area to upload
70
</p>
71
</Upload.Dragger>
72
</ImgCrop>
73
{error && (
74
<Alert
75
style={{ marginTop: "15px" }}
76
type="error"
77
message={error}
78
showIcon
79
/>
80
)}
81
</div>
82
);
83
}
84
85