refactor: add typescript support to project

This commit is contained in:
HD
2022-06-29 16:54:58 +08:00
parent ccfee28e13
commit 003353e43f
33 changed files with 358 additions and 224 deletions
+15 -7
View File
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useEffect, ChangeEvent } from "react";
import styled from "styled-components";
import toast from "react-hot-toast";
import {
@@ -43,37 +43,44 @@ const StyledWrapper = styled.div`
}
}
`;
interface ChannelFormData {
name: string;
description: string;
}
export default function Overview({ id = 0 }) {
const { loginUser, channel } = useAppSelector((store) => {
const { uid } = store.authData;
return {
loginUser: store.contacts.byId[store.authData.uid],
loginUser: uid ? store.contacts.byId[Number(uid)] : undefined,
channel: store.channels.byId[id]
};
});
const { data, refetch } = useGetChannelQuery(id);
const [changed, setChanged] = useState(false);
const [values, setValues] = useState(null);
const [values, setValues] = useState<ChannelFormData>({ name: "", description: "" });
const [updateChannelIcon] = useUpdateIconMutation();
const [updateChannel, { isSuccess: updated }] = useUpdateChannelMutation();
const handleUpdate = () => {
const { name, description } = values;
updateChannel({ id, name, description });
};
const handleChange = (evt) => {
const handleChange = (evt: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const newValue = evt.target.value;
const { type } = evt.target.dataset;
const { type } = evt.target.dataset as { type: keyof ChannelFormData };
setValues((prev) => {
return { ...prev, [type]: newValue };
});
};
const updateIcon = (image) => {
const updateIcon = (image: File) => {
updateChannelIcon({ gid: id, image });
};
const handleReset = () => {
console.log("reset", data);
setValues(data);
};
@@ -100,6 +107,7 @@ export default function Overview({ id = 0 }) {
toast.success("Channel updated!");
refetch();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [updated]);
if (!values || !id) return null;
+32 -27
View File
@@ -1,7 +1,7 @@
import { useState } from "react";
import { useParams, useNavigate, useSearchParams } from "react-router-dom";
import LeaveChannel from "../../common/component/LeaveChannel";
import StyledSettingContainer from "../../common/component/StyledSettingContainer";
import StyledSettingContainer, { Danger } from "../../common/component/StyledSettingContainer";
import DeleteConfirmModal from "./DeleteConfirmModal";
import useNavs from "./navs";
import { useAppSelector } from "../../app/store";
@@ -9,40 +9,54 @@ import { useAppSelector } from "../../app/store";
let from: string | null = null;
export default function ChannelSetting() {
const { cid } = useParams();
const { cid } = useParams<{ cid: string }>();
const cidNum = Number(cid);
const { isAdmin, loginUid, channel } = useAppSelector((store) => {
return {
loginUid: store.authData.uid,
isAdmin: store.contacts.byId[store.authData.uid]?.is_admin,
channel: store.channels.byId[cid]
isAdmin: store.authData.uid
? store.contacts.byId[Number(store.authData.uid)]?.is_admin
: false,
channel: store.channels.byId[cidNum]
};
});
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const navs = useNavs(cid);
const flatenNavs = navs
.map(({ items }) => {
return items;
})
.flat();
const navs = useNavs(cidNum);
const flattenNaves = navs.map(({ items }) => items).flat();
const navKey = searchParams.get("nav");
from = from ?? (searchParams.get("f") || "/");
const [deleteConfirm, setDeleteConfirm] = useState(false);
const [leaveConfirm, setLeaveConfirm] = useState(false);
const close = () => {
navigate(from);
// todo: check usage
navigate(from!);
from = null;
};
const toggleDeleteConfrim = () => {
const toggleDeleteConfirm = () => {
setDeleteConfirm((prev) => !prev);
};
const toggleLeaveConfrim = () => {
const toggleLeaveConfirm = () => {
setLeaveConfirm((prev) => !prev);
};
if (!cid) return null;
const currNav = flatenNavs.find((n) => n.name == navKey) || flatenNavs[0];
const canDelete = isAdmin || channel?.owner == loginUid;
const currNav = flattenNaves.find((n) => n.name == navKey) || flattenNaves[0];
const canDelete = isAdmin || channel?.owner === Number(loginUid);
const canLeave = !channel?.is_public;
const dangers: Danger[] = [];
if (canLeave) {
dangers.push({
title: "Leave Channel",
handler: toggleLeaveConfirm
});
}
if (canDelete) {
dangers.push({
title: "Delete Channel",
handler: toggleDeleteConfirm
});
}
return (
<>
@@ -51,21 +65,12 @@ export default function ChannelSetting() {
closeModal={close}
title="Channel Setting"
navs={navs}
dangers={[
canLeave && {
title: "Leave Channel",
handler: toggleLeaveConfrim
},
canDelete && {
title: "Delete Channel",
handler: toggleDeleteConfrim
}
]}
dangers={dangers}
>
{currNav.component}
</StyledSettingContainer>
{deleteConfirm && <DeleteConfirmModal closeModal={toggleDeleteConfrim} id={cid} />}
{leaveConfirm && <LeaveChannel closeModal={toggleLeaveConfrim} id={cid} />}
{deleteConfirm && <DeleteConfirmModal closeModal={toggleDeleteConfirm} id={Number(cid)} />}
{leaveConfirm && <LeaveChannel closeModal={toggleLeaveConfirm} id={cidNum} />}
</>
);
}
+16 -3
View File
@@ -1,7 +1,20 @@
import Overview from "./Overview";
import ManageMembers from "../../common/component/ManageMembers";
import { ReactNode } from "react";
const useNavs = (channelId: number) => {
export interface NavItem {
name: string;
title: string;
component: ReactNode;
}
export interface Nav {
name?: string;
title: string;
items: NavItem[];
}
const useNavs = (cid: number): Nav[] => {
return [
{
title: "General",
@@ -9,12 +22,12 @@ const useNavs = (channelId: number) => {
{
name: "overview",
title: "Overview",
component: <Overview id={channelId} />
component: <Overview id={cid} />
},
{
name: "members",
title: "Members",
component: <ManageMembers cid={channelId} />
component: <ManageMembers cid={cid} />
}
// {
// name: "permissions",