这是基于vue-vben-admin 模板适用于abp vNext的前端管理项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

83 lines
2.5 KiB

import { themeVars } from "@/theme/theme.css";
import { fBytes } from "@/utils/format-number";
import { Typography, Upload } from "antd";
import type { UploadChangeParam, UploadFile, UploadProps } from "antd/es/upload";
import { useState } from "react";
import { Iconify } from "../icon";
import { StyledUploadAvatar } from "./styles";
import { beforeAvatarUpload, getBlobUrl } from "./utils";
interface Props extends UploadProps {
defaultAvatar?: string;
helperText?: React.ReactElement | string;
}
export function UploadAvatar({ helperText, defaultAvatar = "", ...other }: Props) {
const [imageUrl, setImageUrl] = useState<string>(defaultAvatar);
const [isHover, setIsHover] = useState(false);
const handelHover = (hover: boolean) => {
setIsHover(hover);
};
const handleChange: UploadProps["onChange"] = (info: UploadChangeParam<UploadFile>) => {
if (info.file.status === "uploading") {
return;
}
if (info.file.status === "done" || info.file.status === "error") {
// TODO: Get this url from response in real world.
if (info.file.originFileObj) {
setImageUrl(getBlobUrl(info.file.originFileObj));
}
}
};
const renderPreview = <img src={imageUrl} alt="" className="absolute rounded-full" />;
const renderPlaceholder = (
<div
style={{
backgroundColor: !imageUrl || isHover ? themeVars.colors.background.neutral : "transparent",
}}
className="absolute z-10 flex h-full w-full flex-col items-center justify-center"
>
<Iconify icon="solar:camera-add-bold" size={32} />
<div className="mt-1 text-xs">Upload Photo</div>
</div>
);
const renderContent = (
<div
className="relative flex h-full w-full items-center justify-center overflow-hidden rounded-full"
onMouseEnter={() => handelHover(true)}
onMouseLeave={() => handelHover(false)}
>
{imageUrl ? renderPreview : null}
{!imageUrl || isHover ? renderPlaceholder : null}
</div>
);
const defaultHelperText = (
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
Allowed *.jpeg, *.jpg, *.png, *.gif
<br /> max size of {fBytes(3145728)}
</Typography.Text>
);
const renderHelpText = <div className="text-center">{helperText || defaultHelperText}</div>;
return (
<StyledUploadAvatar>
<Upload
name="avatar"
showUploadList={false}
listType="picture-circle"
className="avatar-uploader !flex items-center justify-center"
{...other}
beforeUpload={beforeAvatarUpload}
onChange={handleChange}
>
{renderContent}
</Upload>
{renderHelpText}
</StyledUploadAvatar>
);
}