大改动
This commit is contained in:
@@ -27,11 +27,12 @@ export default () => {
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const getArticleList = async () => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const { data } = await getArticleListAPI();
|
||||
setArticleList(data);
|
||||
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
@@ -39,9 +40,9 @@ export default () => {
|
||||
};
|
||||
|
||||
const delArticleData = async (id: number) => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// 普通删除:可从回收站恢复
|
||||
await delArticleDataAPI(id, true);
|
||||
await getArticleList();
|
||||
@@ -151,9 +152,9 @@ export default () => {
|
||||
];
|
||||
|
||||
const onFilterSubmit = async (values: FilterForm) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const query: FilterArticle = {
|
||||
key: values.title,
|
||||
cateIds: values.cateIds,
|
||||
@@ -166,6 +167,7 @@ export default () => {
|
||||
|
||||
const { data } = await getArticleListAPI({ query });
|
||||
setArticleList(data);
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
|
||||
@@ -25,6 +25,7 @@ const CatePage = () => {
|
||||
const { data } = await getCateListAPI();
|
||||
data.sort((a, b) => a.order - b.order)
|
||||
setList(data);
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
@@ -46,14 +47,16 @@ const CatePage = () => {
|
||||
|
||||
const editCateData = async (id: number) => {
|
||||
try {
|
||||
setEditLoading(true)
|
||||
|
||||
setIsMethod("edit");
|
||||
setIsModelOpen(true);
|
||||
setEditLoading(true)
|
||||
|
||||
const { data } = await getCateDataAPI(id);
|
||||
setIsCateShow(data.type === "cate" ? false : true);
|
||||
setCate(data);
|
||||
form.setFieldsValue(data);
|
||||
|
||||
setEditLoading(false)
|
||||
} catch (error) {
|
||||
setEditLoading(false)
|
||||
@@ -61,9 +64,9 @@ const CatePage = () => {
|
||||
};
|
||||
|
||||
const delCateData = async (id: number) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
await delCateDataAPI(id);
|
||||
await getCateList();
|
||||
message.success('🎉 删除分类成功');
|
||||
|
||||
@@ -150,9 +150,9 @@ export default () => {
|
||||
const [replyInfo, setReplyInfo] = useState("")
|
||||
const [isReplyModalOpen, setIsReplyModalOpen] = useState(false);
|
||||
const handleReply = async () => {
|
||||
setBtnLoading(true)
|
||||
|
||||
try {
|
||||
setBtnLoading(true)
|
||||
|
||||
await addCommentDataAPI({
|
||||
avatar: user.avatar,
|
||||
url: web.url,
|
||||
@@ -169,6 +169,8 @@ export default () => {
|
||||
message.success('🎉 回复评论成功');
|
||||
setIsReplyModalOpen(false)
|
||||
setReplyInfo("")
|
||||
|
||||
setBtnLoading(true)
|
||||
} catch (error) {
|
||||
setBtnLoading(false)
|
||||
}
|
||||
|
||||
@@ -32,19 +32,20 @@ export default () => {
|
||||
// 获取文章数据
|
||||
const getArticleData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const { data } = await getArticleDataAPI(id)
|
||||
setData(data)
|
||||
setContent(data.content)
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 回显数据
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
setPublishOpen(false)
|
||||
|
||||
// 有Id就回显指定的数据
|
||||
@@ -93,9 +94,9 @@ export default () => {
|
||||
|
||||
// 解析接口数据
|
||||
const parsingData = async (command: string) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const res = await fetch(`/ai/v1/chat/completions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -142,12 +143,12 @@ export default () => {
|
||||
|
||||
// 保留最后一行未处理的数据
|
||||
receivedText = lines[lines.length - 1];
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// AI功能
|
||||
|
||||
@@ -32,9 +32,9 @@ export default () => {
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const data = {
|
||||
content,
|
||||
images: JSON.stringify(imageList),
|
||||
@@ -52,29 +52,29 @@ export default () => {
|
||||
await addRecordDataAPI(data)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
navigate("/record")
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
const getRecordData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const { data } = await getRecordDataAPI(id)
|
||||
setContent(data.content)
|
||||
setImageList(JSON.parse(data.images as string))
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 回显数据
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
// 有Id就回显指定的数据
|
||||
if (id) getRecordData()
|
||||
}, [id])
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
export interface Result {
|
||||
timeSpan: string[];
|
||||
fields: string[];
|
||||
items: [
|
||||
string[][],
|
||||
number[][],
|
||||
any[],
|
||||
any[]
|
||||
];
|
||||
}
|
||||
|
||||
export interface MonthlySums {
|
||||
[key: string]: {
|
||||
pv: number;
|
||||
ip: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChartOneState {
|
||||
series: {
|
||||
name: string;
|
||||
data: number[];
|
||||
}[];
|
||||
}
|
||||
@@ -2,9 +2,32 @@ import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { ApexOptions } from 'apexcharts';
|
||||
import ReactApexChart from 'react-apexcharts';
|
||||
import { MonthlySums, ChartOneState } from './type';
|
||||
import dayjs from 'dayjs';
|
||||
import { Result } from '../../type';
|
||||
|
||||
interface Result {
|
||||
timeSpan: string[];
|
||||
fields: string[];
|
||||
items: [
|
||||
string[][],
|
||||
number[][],
|
||||
any[],
|
||||
any[]
|
||||
];
|
||||
}
|
||||
|
||||
interface MonthlySums {
|
||||
[key: string]: {
|
||||
pv: number;
|
||||
ip: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface ChartOneState {
|
||||
series: {
|
||||
name: string;
|
||||
data: number[];
|
||||
}[];
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
@@ -124,9 +147,9 @@ export default () => {
|
||||
|
||||
// 获取统计数据
|
||||
const getDataList = useCallback(async () => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const siteId = import.meta.env.VITE_BAIDU_TONGJI_SITE_ID;
|
||||
const token = import.meta.env.VITE_BAIDU_TONGJI_ACCESS_TOKEN;
|
||||
|
||||
@@ -134,16 +157,16 @@ export default () => {
|
||||
const data = await response.json();
|
||||
const { result } = data;
|
||||
setResult(result);
|
||||
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
}, [startDate, endDate]);
|
||||
|
||||
useEffect(() => {
|
||||
getDataList();
|
||||
}, [getDataList]);
|
||||
}, []);
|
||||
|
||||
// 切换不同范围的数据
|
||||
const scopeData = useMemo(() => {
|
||||
@@ -239,6 +262,7 @@ export default () => {
|
||||
// 当数据发生变化时,更新图表选项和状态
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
|
||||
setOptions((data) => ({
|
||||
...data,
|
||||
xaxis: { ...options.xaxis, categories: scopeData.categories || [] }
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
export interface MonthlySums {
|
||||
[key: string]: {
|
||||
pv: number;
|
||||
ip: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChartOneState {
|
||||
series: {
|
||||
name: string;
|
||||
data: number[];
|
||||
}[];
|
||||
}
|
||||
@@ -31,9 +31,9 @@ export default () => {
|
||||
|
||||
// 获取统计数据
|
||||
const getDataList = async () => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const siteId = import.meta.env.VITE_BAIDU_TONGJI_SITE_ID;
|
||||
const token = import.meta.env.VITE_BAIDU_TONGJI_ACCESS_TOKEN;
|
||||
|
||||
@@ -78,11 +78,10 @@ export default () => {
|
||||
|
||||
setStats({ pv, ip, bounce: (bounce / count) || 0, avgTime: formatTime(avgTime / count) || "00:00:00" })
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
10
src/pages/Dashboard/components/Stats/type.d.ts
vendored
10
src/pages/Dashboard/components/Stats/type.d.ts
vendored
@@ -1,10 +0,0 @@
|
||||
export interface Result {
|
||||
timeSpan: string[];
|
||||
fields: string[];
|
||||
items: [
|
||||
string[][],
|
||||
number[][],
|
||||
any[],
|
||||
any[]
|
||||
];
|
||||
}
|
||||
@@ -25,24 +25,25 @@ export default () => {
|
||||
|
||||
const getArticleList = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const { data } = await getArticleListAPI({ query: { isDel: 1 } });
|
||||
setArticleList(data as Article[]);
|
||||
setArticleList(data);
|
||||
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getArticleList()
|
||||
}, []);
|
||||
|
||||
const delArticleData = async (id: number) => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// 严格删除:彻底从数据库删除,无法恢复
|
||||
await delArticleDataAPI(id);
|
||||
await getArticleList();
|
||||
@@ -55,12 +56,14 @@ export default () => {
|
||||
};
|
||||
|
||||
const reductionArticleData = async (id: number) => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
await reductionArticleDataAPI(id)
|
||||
navigate("/article")
|
||||
notification.success({ message: '🎉 还原文章成功' })
|
||||
navigate("/article")
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -23,23 +23,25 @@ export default () => {
|
||||
|
||||
const getArticleList = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const { data } = await getArticleListAPI({ query: { isDraft: 1 } });
|
||||
setArticleList(data as Article[]);
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
}
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
getArticleList()
|
||||
}, []);
|
||||
|
||||
const delArticleData = async (id: number) => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
await delArticleDataAPI(id);
|
||||
await getArticleList();
|
||||
form.resetFields()
|
||||
|
||||
@@ -36,56 +36,56 @@ export default () => {
|
||||
|
||||
// 获取目录列表
|
||||
const getDirList = async () => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const { data } = await getDirListAPI()
|
||||
setDirList(data)
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 获取指定目录的文件列表
|
||||
const getFileList = async (dir: string) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const { data } = await getFileListAPI(dir)
|
||||
if (!fileList.length && !data.length) message.error("该目录中没有文件")
|
||||
setFileList(data)
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 删除图片
|
||||
const onDeleteImage = async (data: File) => {
|
||||
setBtnLoading(true)
|
||||
|
||||
try {
|
||||
setBtnLoading(true)
|
||||
|
||||
await delFileDataAPI(data.url)
|
||||
await getFileList(dirName)
|
||||
message.success("🎉 删除图片成功")
|
||||
setFile({} as File)
|
||||
setOpenFileInfoDrawer(false)
|
||||
setOpenFilePreviewDrawer(false)
|
||||
|
||||
setBtnLoading(false)
|
||||
} catch (error) {
|
||||
setBtnLoading(false)
|
||||
}
|
||||
|
||||
setBtnLoading(false)
|
||||
}
|
||||
|
||||
// 下载图片
|
||||
const onDownloadImage = (data: File) => {
|
||||
setDownloadLoading(true)
|
||||
|
||||
try {
|
||||
setDownloadLoading(true)
|
||||
|
||||
fetch(data.url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
@@ -98,11 +98,11 @@ export default () => {
|
||||
URL.revokeObjectURL(url);
|
||||
link.remove();
|
||||
});
|
||||
|
||||
setDownloadLoading(false)
|
||||
} catch (error) {
|
||||
setDownloadLoading(false)
|
||||
}
|
||||
|
||||
setDownloadLoading(false)
|
||||
};
|
||||
|
||||
// 打开目录
|
||||
|
||||
@@ -129,9 +129,9 @@ export default () => {
|
||||
};
|
||||
|
||||
const editFootprintData = async (id: number) => {
|
||||
setEditLoading(true);
|
||||
|
||||
try {
|
||||
setEditLoading(true);
|
||||
|
||||
setIsMethod("edit");
|
||||
setIsModelOpen(true);
|
||||
|
||||
@@ -142,17 +142,17 @@ export default () => {
|
||||
|
||||
setFootprint(data);
|
||||
form.setFieldsValue(data);
|
||||
|
||||
setEditLoading(false);
|
||||
} catch (error) {
|
||||
setEditLoading(false);
|
||||
}
|
||||
|
||||
setEditLoading(false);
|
||||
};
|
||||
|
||||
|
||||
const onSubmit = async () => {
|
||||
setBtnLoading(true)
|
||||
|
||||
try {
|
||||
setBtnLoading(true)
|
||||
|
||||
form.validateFields().then(async (values: Footprint) => {
|
||||
values.createTime = values.createTime.valueOf()
|
||||
values.images = values.images ? (values.images as string).split("\n") : []
|
||||
@@ -166,6 +166,7 @@ export default () => {
|
||||
}
|
||||
|
||||
await getFootprintList();
|
||||
setBtnLoading(false)
|
||||
reset()
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -176,9 +177,9 @@ export default () => {
|
||||
const closeModel = () => reset();
|
||||
|
||||
const onFilterSubmit = async (values: FilterForm) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const query: FilterData = {
|
||||
key: values.address,
|
||||
startDate: values.createTime && values.createTime[0].valueOf() + '',
|
||||
@@ -187,18 +188,18 @@ export default () => {
|
||||
|
||||
const { data } = await getFootprintListAPI({ query });
|
||||
setFootprintList(data);
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 通过详细地址获取纬度
|
||||
const getGeocode = async () => {
|
||||
setEditLoading(true)
|
||||
|
||||
try {
|
||||
setEditLoading(true)
|
||||
|
||||
const address = form.getFieldValue("address")
|
||||
|
||||
const { data } = await axios.get('https://restapi.amap.com/v3/geocode/geo', {
|
||||
@@ -215,17 +216,15 @@ export default () => {
|
||||
// 立即触发校验
|
||||
form.validateFields(['position']);
|
||||
|
||||
setEditLoading(false)
|
||||
|
||||
return data.geocodes[0].location;
|
||||
} else {
|
||||
message.warning('未找到该地址的经纬度');
|
||||
}
|
||||
|
||||
setEditLoading(false)
|
||||
} catch (error) {
|
||||
setEditLoading(false)
|
||||
}
|
||||
|
||||
setEditLoading(false)
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -24,6 +24,8 @@ export default () => {
|
||||
// 从github获取最近10次迭代记录
|
||||
const getCommitData = async (project: string) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const res = await fetch(`https://api.github.com/repos/LiuYuYang01/${project}/commits?per_page=10`)
|
||||
const data = await res.json()
|
||||
const result = data?.map((item: Commit) => (
|
||||
@@ -47,11 +49,11 @@ export default () => {
|
||||
setServer_IterativeRecording(result)
|
||||
break;
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -7,19 +7,21 @@ import { loginDataAPI } from '@/api/User';
|
||||
import { useUserStore } from '@/stores';
|
||||
|
||||
export default () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const store = useUserStore();
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const [form] = useForm();
|
||||
|
||||
const [isPassVisible, setIsPassVisible] = useState(false);
|
||||
const store = useUserStore();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const returnUrl = new URLSearchParams(location.search).get('returnUrl') || '/';
|
||||
|
||||
const onSubmit = async () => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
const values = await form.validateFields();
|
||||
const { data } = await loginDataAPI(values);
|
||||
|
||||
@@ -33,12 +35,11 @@ export default () => {
|
||||
description: `Hello ${data.user.name} 欢迎回来`,
|
||||
});
|
||||
|
||||
setLoading(false)
|
||||
navigate(returnUrl);
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -86,25 +86,26 @@ export default () => {
|
||||
|
||||
const getOssList = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const { data } = await getOssListAPI();
|
||||
setOssList(data);
|
||||
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getOssList();
|
||||
getOssPlatformList()
|
||||
}, []);
|
||||
|
||||
const enableOssData = async (id: number) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
await enableOssDataAPI(id);
|
||||
await getOssList();
|
||||
message.success('启用成功');
|
||||
@@ -114,9 +115,9 @@ export default () => {
|
||||
};
|
||||
|
||||
const disableOssData = async (id: number) => {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
await disableOssDataAPI(id);
|
||||
await getOssList();
|
||||
message.success('禁用成功');
|
||||
@@ -126,25 +127,25 @@ export default () => {
|
||||
};
|
||||
|
||||
const editOssData = async (record: Oss) => {
|
||||
setEditLoading(true)
|
||||
|
||||
try {
|
||||
setEditLoading(true)
|
||||
|
||||
setIsModalOpen(true);
|
||||
|
||||
const { data } = await getOssDataAPI(record.id)
|
||||
setOss(data);
|
||||
form.setFieldsValue(data);
|
||||
|
||||
setEditLoading(false)
|
||||
} catch (error) {
|
||||
setEditLoading(false)
|
||||
}
|
||||
|
||||
setEditLoading(false)
|
||||
};
|
||||
|
||||
const delOssData = async (id: number) => {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
await delOssDataAPI(id);
|
||||
await getOssList();
|
||||
message.success('🎉 删除存储配置成功');
|
||||
@@ -166,9 +167,9 @@ export default () => {
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
setBtnLoading(true);
|
||||
|
||||
try {
|
||||
setBtnLoading(true);
|
||||
|
||||
const values = await form.validateFields();
|
||||
|
||||
if (oss.id) {
|
||||
@@ -179,15 +180,14 @@ export default () => {
|
||||
message.success('🎉 新增存储配置成功');
|
||||
}
|
||||
|
||||
await getOssList();
|
||||
setIsModalOpen(false);
|
||||
getOssList();
|
||||
form.resetFields();
|
||||
|
||||
setBtnLoading(false);
|
||||
} catch (error) {
|
||||
setBtnLoading(false);
|
||||
}
|
||||
|
||||
setBtnLoading(false)
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user