feat(AccountsPage): update accounts list after create user

This commit is contained in:
Vladislav Syrochkin 2025-06-30 12:37:45 +05:00
parent ad312d4ff8
commit 784be40369
2 changed files with 101 additions and 87 deletions

View File

@ -10,17 +10,18 @@ import {
UploadProps, UploadProps,
message, message,
Spin, Spin,
} from 'antd'; } from "antd";
import { useState } from 'react'; import { useState } from "react";
import { useTranslation } from 'react-i18next'; import { useTranslation } from "react-i18next";
import { useUserSelector } from '@/store/userStore'; import { useUserSelector } from "@/store/userStore";
import { UserCreate as NewUserCreate } from '@/types/user'; import { AllUserResponse, UserCreate as NewUserCreate } from "@/types/user";
import { UserService } from '@/services/userService'; import { UserService } from "@/services/userService";
import { LoadingOutlined } from '@ant-design/icons'; import { LoadingOutlined } from "@ant-design/icons";
import { useSearchParams } from "react-router-dom";
const { Option } = Select; const { Option } = Select;
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0]; type FileType = Parameters<GetProp<UploadProps, "beforeUpload">>[0];
const getBase64 = (file: FileType): Promise<string> => const getBase64 = (file: FileType): Promise<string> =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
@ -32,13 +33,19 @@ const getBase64 = (file: FileType): Promise<string> =>
interface UserCreateProps { interface UserCreateProps {
closeDrawer: () => void; closeDrawer: () => void;
setAccounts: React.Dispatch<React.SetStateAction<AllUserResponse>>;
getUsers: () => Promise<void>;
} }
export default function UserCreate({ closeDrawer }: UserCreateProps) { export default function UserCreate({
closeDrawer,
setAccounts,
getUsers,
}: UserCreateProps) {
const user = useUserSelector(); const user = useUserSelector();
const { t } = useTranslation(); const { t } = useTranslation();
const [previewOpen, setPreviewOpen] = useState(false); const [previewOpen, setPreviewOpen] = useState(false);
const [previewImage, setPreviewImage] = useState(''); const [previewImage, setPreviewImage] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [fileList, setFileList] = useState<UploadFile[]>([]); const [fileList, setFileList] = useState<UploadFile[]>([]);
@ -52,49 +59,49 @@ export default function UserCreate({ closeDrawer }: UserCreateProps) {
setPreviewOpen(true); setPreviewOpen(true);
}; };
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => const handleChange: UploadProps["onChange"] = ({ fileList: newFileList }) =>
setFileList(newFileList); setFileList(newFileList);
const onFinish = async (values: NewUserCreate) => { const onFinish = async (values: NewUserCreate) => {
setLoading(true); setLoading(true);
await UserService.createUser(values); await UserService.createUser(values);
await getUsers();
closeDrawer(); closeDrawer();
setLoading(false); setLoading(false);
message.info(t('createdAccountMessage'), 4); message.info(t("createdAccountMessage"), 4);
}; };
const customUploadButton = ( const customUploadButton = (
<div> <div>
<div <div
style={{ style={{
height: '102px', height: "102px",
width: '102px', width: "102px",
backgroundColor: '#E2E2E2', backgroundColor: "#E2E2E2",
borderRadius: '50%', borderRadius: "50%",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
justifyContent: 'center', justifyContent: "center",
marginBottom: 8, marginBottom: 8,
marginTop: 30, marginTop: 30,
cursor: 'pointer', cursor: "pointer",
}} }}
> >
<img <img
src="./icons/drawer/add_photo_alternate.svg" src="./icons/drawer/add_photo_alternate.svg"
alt="add_photo_alternate" alt="add_photo_alternate"
style={{ height: '18px', width: '18px' }} style={{ height: "18px", width: "18px" }}
/> />
</div> </div>
<span style={{ fontSize: '14px', color: '#8c8c8c' }}> <span style={{ fontSize: "14px", color: "#8c8c8c" }}>
{t('selectPhoto')} {t("selectPhoto")}
</span> </span>
</div> </div>
); );
const photoToUpload = ( const photoToUpload = (
<div style={{ height: '102px' }}> <div style={{ height: "102px" }}>
<Upload <Upload
listType="picture-circle" listType="picture-circle"
fileList={fileList} fileList={fileList}
@ -106,11 +113,11 @@ export default function UserCreate({ closeDrawer }: UserCreateProps) {
</Upload> </Upload>
{previewImage && ( {previewImage && (
<Image <Image
wrapperStyle={{ display: 'none' }} wrapperStyle={{ display: "none" }}
preview={{ preview={{
visible: previewOpen, visible: previewOpen,
onVisibleChange: (visible) => setPreviewOpen(visible), onVisibleChange: (visible) => setPreviewOpen(visible),
afterOpenChange: (visible) => !visible && setPreviewImage(''), afterOpenChange: (visible) => !visible && setPreviewImage(""),
}} }}
src={previewImage} src={previewImage}
/> />
@ -121,24 +128,24 @@ export default function UserCreate({ closeDrawer }: UserCreateProps) {
return ( return (
<div <div
style={{ style={{
display: 'flex', display: "flex",
flexDirection: 'column', flexDirection: "column",
height: '100%', height: "100%",
}} }}
> >
<div <div
style={{ style={{
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
justifyContent: 'center', justifyContent: "center",
marginBottom: '36px', marginBottom: "36px",
}} }}
> >
<div <div
style={{ style={{
display: 'flex', display: "flex",
flexDirection: 'column', flexDirection: "column",
alignItems: 'center', alignItems: "center",
}} }}
> >
{photoToUpload} {photoToUpload}
@ -149,83 +156,83 @@ export default function UserCreate({ closeDrawer }: UserCreateProps) {
layout="vertical" layout="vertical"
onFinish={onFinish} onFinish={onFinish}
initialValues={{ initialValues={{
name: '', name: "",
login: '', login: "",
password: '', password: "",
email: '', email: "",
bindTenantId: '', bindTenantId: "",
role: '', role: "",
status: '', status: "",
}} }}
style={{ flex: 1, display: 'flex', flexDirection: 'column' }} style={{ flex: 1, display: "flex", flexDirection: "column" }}
> >
<Form.Item <Form.Item
label={t('name')} label={t("name")}
name="name" name="name"
rules={[{ required: true, message: t('nameMessage') }]} rules={[{ required: true, message: t("nameMessage") }]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('login')} label={t("login")}
name="login" name="login"
rules={[{ required: true, message: t('loginMessage') }]} rules={[{ required: true, message: t("loginMessage") }]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('password')} label={t("password")}
name="password" name="password"
rules={[{ required: true, message: t('passwordMessage') }]} rules={[{ required: true, message: t("passwordMessage") }]}
> >
<Input.Password /> <Input.Password />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('email')} label={t("email")}
name="email" name="email"
rules={[ rules={[
{ required: true, message: t('emailMessage') }, { required: true, message: t("emailMessage") },
{ type: 'email', message: t('emailErrorMessage') }, { type: "email", message: t("emailErrorMessage") },
]} ]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('tenant')} label={t("tenant")}
name="bindTenantId" name="bindTenantId"
rules={[{ required: true, message: t('tenantMessage') }]} rules={[{ required: true, message: t("tenantMessage") }]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('role')} label={t("role")}
name="role" name="role"
rules={[{ required: true, message: t('roleMessage') }]} rules={[{ required: true, message: t("roleMessage") }]}
> >
<Select placeholder={t('roleMessage')}> <Select placeholder={t("roleMessage")}>
{user && user.role === 'OWNER' ? ( {user && user.role === "OWNER" ? (
<Option value="ADMIN">{t('ADMIN')}</Option> <Option value="ADMIN">{t("ADMIN")}</Option>
) : undefined} ) : undefined}
<Option value="EDITOR">{t('EDITOR')}</Option> <Option value="EDITOR">{t("EDITOR")}</Option>
<Option value="VIEWER">{t('VIEWER')}</Option> <Option value="VIEWER">{t("VIEWER")}</Option>
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t('status')} label={t("status")}
name="status" name="status"
rules={[{ required: true, message: t('statusMessage') }]} rules={[{ required: true, message: t("statusMessage") }]}
> >
<Select placeholder={t('statusMessage')}> <Select placeholder={t("statusMessage")}>
<Option value="ACTIVE">{t('ACTIVE')}</Option> <Option value="ACTIVE">{t("ACTIVE")}</Option>
<Option value="DISABLED">{t('DISABLED')}</Option> <Option value="DISABLED">{t("DISABLED")}</Option>
<Option value="BLOCKED">{t('BLOCKED')}</Option> <Option value="BLOCKED">{t("BLOCKED")}</Option>
<Option value="DELETED">{t('DELETED')}</Option> <Option value="DELETED">{t("DELETED")}</Option>
</Select> </Select>
</Form.Item> </Form.Item>
@ -236,21 +243,21 @@ export default function UserCreate({ closeDrawer }: UserCreateProps) {
type="primary" type="primary"
htmlType="submit" htmlType="submit"
block block
style={{ color: '#000' }} style={{ color: "#000" }}
> >
{loading ? ( {loading ? (
<> <>
<Spin indicator={<LoadingOutlined spin />} size="small"></Spin>{' '} <Spin indicator={<LoadingOutlined spin />} size="small"></Spin>{" "}
{t('saving')} {t("saving")}
</> </>
) : ( ) : (
<> <>
<img <img
src="/icons/drawer/reg.svg" src="/icons/drawer/reg.svg"
alt="save" alt="save"
style={{ height: '18px', width: '18px' }} style={{ height: "18px", width: "18px" }}
/>{' '} />{" "}
{t('addAccount')} {t("addAccount")}
</> </>
)} )}
</Button> </Button>

View File

@ -14,7 +14,6 @@ export default function AccountsPage() {
const { t } = useTranslation(); const { t } = useTranslation();
const [openCreate, setOpenCreate] = useState(false); const [openCreate, setOpenCreate] = useState(false);
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
console.log("searchParams", searchParams);
const [activeAccount, setActiveAccount] = useState< const [activeAccount, setActiveAccount] = useState<
{ login: string; id: number; name: string; email: string } | undefined { login: string; id: number; name: string; email: string } | undefined
@ -41,16 +40,20 @@ export default function AccountsPage() {
limit: 10, limit: 10,
}); });
useEffect(() => { async function getUsers() {
async function getUsers() { setSearchParams({
const data = await UserService.getUsers(); page: searchParams.get("page") || "1",
setAccounts(data); limit: searchParams.get("limit") || "10",
setSearchParams({ });
page: searchParams.get("page") || "1", const data = await UserService.getUsers(
limit: searchParams.get("limit") || "10", Number(searchParams.get("page")),
}); Number(searchParams.get("limit"))
} );
console.log("searchParams", searchParams);
setAccounts(data);
}
useEffect(() => {
getUsers(); getUsers();
}, []); }, []);
@ -201,7 +204,11 @@ export default function AccountsPage() {
closeDrawer={closeCreateDrawer} closeDrawer={closeCreateDrawer}
type="create" type="create"
> >
<UserCreate closeDrawer={closeCreateDrawer} /> <UserCreate
getUsers={getUsers}
setAccounts={setAccounts}
closeDrawer={closeCreateDrawer}
/>
</ContentDrawer> </ContentDrawer>
<ContentDrawer <ContentDrawer
login={activeAccount?.login} login={activeAccount?.login}