GrammyLi / bbs

论坛
0 stars 0 forks source link

【FormModal 封装】 #2

Open GrammyLi opened 3 months ago

GrammyLi commented 3 months ago
import React, { useEffect, useState } from "react";
import { Button, Form, Modal, Spin } from "antd";
import "./FormModal.less";

interface FormModalProps {
  visible: boolean;
  onCancel: () => void;
  onFinish: (values: any) => void;
  loading?: boolean;
  isloading?: boolean;
  title: string;
  width?: number;
  formData: {
    label: string;
    name: string;
    render: React.ReactNode;
    rules?: any[];
    style?: React.CSSProperties;
  }[];
  initialValues?: any;
}

const FormModal: React.FC<FormModalProps> = ({
  visible,
  onCancel,
  onFinish,
  loading = false,
  isloading = false,
  title,
  width = 520,
  formData,
  initialValues,
}) => {
  const [form] = Form.useForm();

  useEffect(() => {
    form.setFieldsValue(initialValues);
  }, [initialValues, form]);

  return (
    <Modal
      visible={visible}
      title={title}
      onCancel={onCancel}
      footer={null}
      width={width}
    >
      <Spin tip="Loading..." spinning={isloading}>
        <Form form={form} onFinish={onFinish} layout="vertical">
          {formData.map(({ label, name, render, rules, style }, index) => (
            <Form.Item
              label={label}
              name={name}
              key={index}
              rules={rules || []}
              style={style || {}}
            >
              {render}
            </Form.Item>
          ))}
          <Form.Item>
            <div className="form-modal__buttons">
              <Button onClick={onCancel}>取消</Button>
              <Button type="primary" htmlType="submit" loading={loading}>
                提交
              </Button>
            </div>
          </Form.Item>
        </Form>
      </Spin>
    </Modal>
  );
};

export default FormModal;

使用

import React, { useState } from "react";
import { Button, Input } from "antd";
import FormModal from "./FormModal";
import { teamSetUserInfo } from "@/services/team";
import { getTeamId } from "@/utils/localstorage";

const MyComponent: React.FC = () => {
  const [visible, setVisible] = useState(false);
  const [loading, setLoading] = useState(false);
  const [isloading, setIsLoading] = useState(false);

  const handleCancel = () => {
    setVisible(false);
  };

  const handleFinish = async (values: any) => {
    setLoading(true);
    const data = {
      team_id: getTeamId()!,
      user_id: values.userId,
      username: values.username,
      invite_reason: values.invite_reason,
    };
    const response = await teamSetUserInfo(data);
    if (response.code === 200) {
      message.success("用户信息更新成功");
      // 重新加载成员列表
      // reloadMemberList();
      setVisible(false);
    } else {
      message.error(response.msg);
    }
    setLoading(false);
  };

  const initialValues = {
    userId: "123",
    username: "testUser",
    invite_reason: "Join the team",
  };

  const formData = [
    {
      label: "用户名",
      name: "username",
      render: <Input />,
      rules: [{ required: true, message: "请输入用户名" }],
    },
    {
      label: "加入理由",
      name: "invite_reason",
      render: <Input.TextArea rows={4} />,
      rules: [{ required: true, message: "请输入加入理由" }],
    },
  ];

  return (
    <div>
      <Button onClick={() => setVisible(true)}>编辑成员信息</Button>
      <FormModal
        visible={visible}
        onCancel={handleCancel}
        onFinish={handleFinish}
        loading={loading}
        isloading={isloading}
        title="编辑成员信息"
        formData={formData}
        initialValues={initialValues}
      />
    </div>
  );
};

export default MyComponent;
GrammyLi commented 3 months ago
import { Button, Form, Modal, Spin } from "antd";
import React, { useEffect } from "react";
import "./index.less";

interface FormModalProps {
    visible: boolean;
    onCancel: () => void;
    onFinish: (values: any) => void;
    loading?: boolean;
    isloading?: boolean;
    title: string;
    width?: number;
    formData: {
        label: string;
        name: string;
        render: React.ReactNode;
        rules?: any[];
        style?: React.CSSProperties;
    }[];
    initialValues?: any;
}

const FormModal: React.FC<FormModalProps> = ({
    visible,
    onCancel,
    onFinish,
    loading = false,
    isloading = false,
    title,
    width = 520,
    formData,
    initialValues,
}) => {
    const [form] = Form.useForm();

    useEffect(() => {
        form.setFieldsValue(initialValues);
    }, [initialValues, form]);

    return (
        <Modal
            visible={visible}
            title={title}
            onCancel={onCancel}
            footer={null}
            width={width}
        >
            <Spin tip="Loading..." spinning={isloading}>
                <Form form={form} onFinish={onFinish} layout="vertical">
                    {formData.map(({ label, name, render, rules, style }, index) => (
                        <Form.Item
                            label={label}
                            name={name}
                            key={index}
                            rules={rules || []}
                            style={style || {}}
                        >
                            {render}
                        </Form.Item>
                    ))}
                    <Form.Item>
                        <div className="form-modal__buttons">
                            <Button onClick={onCancel}>取消</Button>
                            <Button type="primary" htmlType="submit" loading={loading}>
                                提交
                            </Button>
                        </div>
                    </Form.Item>
                </Form>
            </Spin>
        </Modal>
    );
};

export default FormModal;

.form-modal__buttons { display: flex; align-items: center; justify-content: flex-end; padding: 24px 0 0; button { margin-left: 20px; } }

使用

import FormModal from "@/components/FormModal";
import { teamSetUserInfo } from "@/services/team";
import { getTeamId } from "@/utils/localstorage";
import { Form, Input, message } from "antd";
import React, { useEffect, useState } from "react";
import "./index.less";

interface EditMemberModalProps {
    visible: boolean;
    onClose: () => void;
    userInfo: {
        userId?: string;
        username?: string;
        inviteReason?: string;
    };
    reloadMemberList: () => void;
}

const EditMemberModal: React.FC<EditMemberModalProps> = ({
    visible,
    onClose,
    userInfo,
    reloadMemberList,
}) => {
    const [form] = Form.useForm();
    const { userId, username = "", inviteReason = "" } = userInfo;
    const [loading, setLoading] = useState(false);
    const [initialValues, setInitialValues] = useState({});

    useEffect(() => {
        if (visible) {
            setInitialValues({
                username,
                invite_reason: inviteReason,
            });
        }
    }, [visible, form, username, inviteReason]);

    const handleFinish = async (values: any) => {
        setLoading(true);
        const data = {
            team_id: getTeamId()!,
            user_id: userId,
            username: values.username,
            invite_reason: values.invite_reason,
        };
        const response = await teamSetUserInfo(data);
        if (response.code === 200) {
            message.success("用户信息更新成功");
            // 重新加载成员列表
            reloadMemberList && reloadMemberList();
            onClose();
        } else {
            message.error(response.msg);
        }
        setLoading(false);
    };

    const formData = [
        {
            label: "用户名",
            name: "username",
            render: <Input />,
            rules: [{ required: true, message: "请输入用户名" }],
        },
        {
            label: "加入理由",
            name: "invite_reason",
            render: <Input.TextArea rows={4} />,
            // rules: [{ required: true, message: "请输入加入理由" }],
        },
    ];

    return (
        <>
            <FormModal
                visible={visible}
                onCancel={onClose}
                onFinish={handleFinish}
                loading={loading}
                title="编辑成员信息"
                formData={formData}
                initialValues={initialValues}
            />
        </>
    );
};

export default EditMemberModal;