refactor: add typescript support to project
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user