refactor: setting modals to pages

This commit is contained in:
zerosoul
2022-04-12 18:21:59 +08:00
parent bcfadfb2d4
commit 20373c4376
28 changed files with 473 additions and 477 deletions
@@ -0,0 +1,42 @@
// import React from "react";
import { useEffect } from "react";
import toast from "react-hot-toast";
import { useNavigate, useMatch } from "react-router-dom";
import Modal from "../../common/component/Modal";
import { useLazyRemoveChannelQuery } from "../../app/services/channel";
import StyledModal from "../../common/component/styled/Modal";
import Button from "../../common/component/styled/Button";
export default function DeleteConfirmModal({ id, closeModal }) {
const navigateTo = useNavigate();
const pathMatched = useMatch(`/chat/channel/${id}`);
const [deleteChannel, { isLoading, isSuccess }] = useLazyRemoveChannelQuery();
const handleDelete = () => {
deleteChannel(id);
};
useEffect(() => {
if (isSuccess) {
toast.success("delete channel successfully!");
closeModal();
navigateTo("/chat");
}
}, [isSuccess, id, pathMatched]);
if (!id) return null;
return (
<Modal id="modal-modal">
<StyledModal
title="Delete Channel"
description="Are you sure want to delete this channel?"
buttons={
<>
<Button onClick={closeModal.bind(null, undefined)}>Cancel</Button>
<Button onClick={handleDelete} className="danger">
{isLoading ? "Deleting" : `Delete`}
</Button>
</>
}
// className="animate__animated animate__fadeInDown animate__faster"
></StyledModal>
</Modal>
);
}
+129
View File
@@ -0,0 +1,129 @@
import { useState, useEffect } from "react";
import styled from "styled-components";
import toast from "react-hot-toast";
import {
useGetChannelQuery,
useUpdateChannelMutation,
} from "../../app/services/channel";
import Input from "../../common/component/styled/Input";
import Label from "../../common/component/styled/Label";
import Textarea from "../../common/component/styled/Textarea";
import SaveTip from "../../common/component/SaveTip";
import channelIcon from "../../assets/icons/channel.svg?url";
import { useSelector } from "react-redux";
const StyledWrapper = styled.div`
position: relative;
width: 512px;
height: 100%;
display: flex;
flex-direction: column;
gap: 24px;
.inputs {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 24px;
.input {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
.name {
padding-left: 36px;
background-image: url(${channelIcon});
background-size: 20px;
background-position-x: 8px;
background-position-y: 8px;
background-repeat: no-repeat;
}
}
}
`;
export default function Overview({ id = 0 }) {
const loginUser = useSelector(
(store) => store.contacts.byId[store.authData.uid]
);
const { data, refetch } = useGetChannelQuery(id);
const [changed, setChanged] = useState(false);
const [values, setValues] = useState(null);
const [updateChannel, { isSuccess: updated }] = useUpdateChannelMutation();
const handleUpdate = () => {
const { name, description } = values;
updateChannel({ id, name, description });
};
const handleChange = (evt) => {
const newValue = evt.target.value;
const { type } = evt.target.dataset;
setValues((prev) => {
return { ...prev, [type]: newValue };
});
};
const handleReset = () => {
console.log("reset", data);
setValues(data);
};
useEffect(() => {
if (data) {
setValues(data);
}
}, [data]);
useEffect(() => {
if (data && values) {
const { name, description } = values;
const { name: oName, description: oDescription } = data;
if (oName !== name || oDescription !== description) {
setChanged(true);
} else {
setChanged(false);
}
}
}, [data, values]);
useEffect(() => {
if (updated) {
toast.success("Channel updated!");
refetch();
}
}, [updated]);
if (!values || !id) return null;
const { name, description } = values;
const isAdmin = loginUser?.is_admin;
return (
<StyledWrapper>
<div className="inputs">
<div className="input">
<Label htmlFor="name">Channel Name</Label>
<Input
disabled={!isAdmin}
className="name"
data-type="name"
onChange={handleChange}
value={name}
name="name"
id="name"
placeholder="Channel Name"
/>
</div>
<div className="input">
<Label htmlFor="desc">Channel Topic</Label>
<Textarea
disabled={!isAdmin}
data-type="description"
onChange={handleChange}
value={description ?? ""}
rows={4}
name="name"
id="name"
placeholder="Let everyone know how to use this channel."
/>
</div>
</div>
{changed && (
<SaveTip saveHandler={handleUpdate} resetHandler={handleReset} />
)}
{/* <button onClick={handleUpdate} className="btn">update</button> */}
</StyledWrapper>
);
}
+52
View File
@@ -0,0 +1,52 @@
import { useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import StyledSettingContainer from "../../common/component/StyledSettingContainer";
import DeleteConfirmModal from "./DeleteConfirmModal";
import useNavs from "./navs";
export default function ChannelSetting() {
const navigate = useNavigate();
const { cid } = useParams();
const navs = useNavs(cid);
const flatenNavs = navs
.map(({ items }) => {
return items;
})
.flat();
const [currNav, setCurrNav] = useState(flatenNavs[0]);
const [deleteConfirm, setDeleteConfirm] = useState(false);
const close = () => {
navigate(-1);
};
const toggleDeleteConfrim = () => {
setDeleteConfirm((prev) => !prev);
};
const updateNav = (name) => {
const tmp = flatenNavs.find((n) => n.name == name);
if (tmp) {
setCurrNav(tmp);
}
};
if (!cid) return null;
return (
<>
<StyledSettingContainer
updateNav={updateNav}
nav={currNav}
closeModal={close}
title="Channel Setting"
navs={navs}
dangers={[
{
title: "Delete Channel",
handler: toggleDeleteConfrim,
},
]}
>
{currNav.component}
</StyledSettingContainer>
{deleteConfirm && (
<DeleteConfirmModal closeModal={toggleDeleteConfrim} id={cid} />
)}
</>
);
}
+42
View File
@@ -0,0 +1,42 @@
import Overview from "./Overview";
import ManageMembers from "../../common/component/ManageMembers";
const useNavs = (channelId) => {
const navs = [
{
title: "General",
items: [
{
name: "overview",
title: "Overview",
component: <Overview id={channelId} />,
},
{
name: "members",
title: "Members",
component: <ManageMembers cid={channelId} />,
},
// {
// name: "permissions",
// title: "Permissions",
// },
// {
// name: "invites",
// title: "Invites",
// },
// {
// name: "integrations",
// title: "Integrations",
// },
],
},
// {
// title: "User Management",
// items: [
// ],
// },
];
return navs;
};
export default useNavs;