diff --git a/src/routes/setting/Overview/OnlyAdminCreateGroup.tsx b/src/routes/setting/Overview/OnlyAdminCreateGroup.tsx new file mode 100644 index 00000000..74ebd880 --- /dev/null +++ b/src/routes/setting/Overview/OnlyAdminCreateGroup.tsx @@ -0,0 +1,53 @@ +import { useAppSelector } from "@/app/store"; +import SettingBlock from "@/components/SettingBlock"; +import { useTranslation } from "react-i18next"; +import StyledRadio from "@/components/styled/Radio"; +import { useGetSystemCommonQuery, useUpdateSystemCommonMutation } from "@/app/services/server"; +import { useEffect } from "react"; +import toast from "react-hot-toast"; +import { shallowEqual } from "react-redux"; +import ServerVersionChecker from "@/components/ServerVersionChecker"; + +type Props = {}; + +const OnlyAdminCreateGroup = ({}: Props) => { + const { t } = useTranslation("setting"); + const { t: ct } = useTranslation(); + const { refetch } = useGetSystemCommonQuery(); + const onlyAdminCreateGroup = useAppSelector( + (store) => store.server.only_admin_can_create_group ?? false, + shallowEqual + ); + const [updateSetting, { isSuccess }] = useUpdateSystemCommonMutation(); + useEffect(() => { + if (isSuccess) { + refetch(); + toast.success(ct("tip.update")); + } + }, [isSuccess]); + const handleChange = (newVal: boolean) => { + updateSetting({ only_admin_can_create_group: newVal }); + }; + return ( + + + { + handleChange(v == "true"); + }} + /> + + + ); +}; + +export default OnlyAdminCreateGroup; diff --git a/src/routes/settingChannel/Overview/AddFriend.tsx b/src/routes/settingChannel/Overview/AddFriend.tsx new file mode 100644 index 00000000..e1f228ac --- /dev/null +++ b/src/routes/settingChannel/Overview/AddFriend.tsx @@ -0,0 +1,51 @@ +import { + // useGetChannelQuery, + useLazyGetChannelQuery, + useUpdateChannelMutation +} from "@/app/services/channel"; +// import { useAppSelector } from "@/app/store"; +import SettingBlock from "@/components/SettingBlock"; +import StyledRadio from "@/components/styled/Radio"; +import React, { useEffect } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +// import { shallowEqual } from "react-redux"; + +type Props = { + id: number; + add_friend: boolean; +}; + +const AddFriend = ({ id, add_friend }: Props) => { + const { t } = useTranslation("setting"); + const { t: ct } = useTranslation(); + const [refetch] = useLazyGetChannelQuery(); + // const onlyAdminCreateGroup = useAppSelector( + // (store) => store.server.only_admin_can_create_group ?? false, + // shallowEqual + // ); + const [updateSetting, { isSuccess }] = useUpdateChannelMutation(); + useEffect(() => { + if (isSuccess) { + refetch(id); + toast.success(ct("tip.update")); + } + }, [isSuccess, id]); + const handleChange = (newVal: boolean) => { + updateSetting({ id, add_friend: newVal }); + }; + return ( + + { + handleChange(v == "true"); + }} + /> + + ); +}; + +export default AddFriend; diff --git a/src/routes/settingChannel/Overview/DMMember.tsx b/src/routes/settingChannel/Overview/DMMember.tsx new file mode 100644 index 00000000..09cc8504 --- /dev/null +++ b/src/routes/settingChannel/Overview/DMMember.tsx @@ -0,0 +1,51 @@ +import { + // useGetChannelQuery, + useLazyGetChannelQuery, + useUpdateChannelMutation +} from "@/app/services/channel"; +// import { useAppSelector } from "@/app/store"; +import SettingBlock from "@/components/SettingBlock"; +import StyledRadio from "@/components/styled/Radio"; +import React, { useEffect } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +// import { shallowEqual } from "react-redux"; + +type Props = { + id: number; + dm_to_member: boolean; +}; + +const DMMember = ({ id, dm_to_member }: Props) => { + const { t } = useTranslation("setting"); + const { t: ct } = useTranslation(); + const [refetch] = useLazyGetChannelQuery(); + // const onlyAdminCreateGroup = useAppSelector( + // (store) => store.server.only_admin_can_create_group ?? false, + // shallowEqual + // ); + const [updateSetting, { isSuccess }] = useUpdateChannelMutation(); + useEffect(() => { + if (isSuccess) { + refetch(id); + toast.success(ct("tip.update")); + } + }, [isSuccess, id]); + const handleChange = (newVal: boolean) => { + updateSetting({ id, dm_to_member: newVal }); + }; + return ( + + { + handleChange(v == "true"); + }} + /> + + ); +}; + +export default DMMember; diff --git a/src/routes/settingChannel/Overview/OnlyOwnerCanSendMsg.tsx b/src/routes/settingChannel/Overview/OnlyOwnerCanSendMsg.tsx new file mode 100644 index 00000000..69333fe0 --- /dev/null +++ b/src/routes/settingChannel/Overview/OnlyOwnerCanSendMsg.tsx @@ -0,0 +1,51 @@ +import { + // useGetChannelQuery, + useLazyGetChannelQuery, + useUpdateChannelMutation +} from "@/app/services/channel"; +// import { useAppSelector } from "@/app/store"; +import SettingBlock from "@/components/SettingBlock"; +import StyledRadio from "@/components/styled/Radio"; +import React, { useEffect } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +// import { shallowEqual } from "react-redux"; + +type Props = { + id: number; + only_owner_can_send_msg: boolean; +}; + +const OnlyOwnerCanSendMsg = ({ id, only_owner_can_send_msg }: Props) => { + const { t } = useTranslation("setting"); + const { t: ct } = useTranslation(); + const [refetch] = useLazyGetChannelQuery(); + // const onlyAdminCreateGroup = useAppSelector( + // (store) => store.server.only_admin_can_create_group ?? false, + // shallowEqual + // ); + const [updateSetting, { isSuccess }] = useUpdateChannelMutation(); + useEffect(() => { + if (isSuccess) { + refetch(id); + toast.success(ct("tip.update")); + } + }, [isSuccess, id]); + const handleChange = (newVal: boolean) => { + updateSetting({ id, only_owner_can_send_msg: newVal }); + }; + return ( + + { + handleChange(v == "true"); + }} + /> + + ); +}; + +export default OnlyOwnerCanSendMsg; diff --git a/src/routes/settingChannel/Overview/ShowEmail.tsx b/src/routes/settingChannel/Overview/ShowEmail.tsx new file mode 100644 index 00000000..4f44bbe9 --- /dev/null +++ b/src/routes/settingChannel/Overview/ShowEmail.tsx @@ -0,0 +1,51 @@ +import { + // useGetChannelQuery, + useLazyGetChannelQuery, + useUpdateChannelMutation +} from "@/app/services/channel"; +// import { useAppSelector } from "@/app/store"; +import SettingBlock from "@/components/SettingBlock"; +import StyledRadio from "@/components/styled/Radio"; +import React, { useEffect } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +// import { shallowEqual } from "react-redux"; + +type Props = { + id: number; + show_email: boolean; +}; + +const ShowEmail = ({ id, show_email }: Props) => { + const { t } = useTranslation("setting"); + const { t: ct } = useTranslation(); + const [refetch] = useLazyGetChannelQuery(); + // const onlyAdminCreateGroup = useAppSelector( + // (store) => store.server.only_admin_can_create_group ?? false, + // shallowEqual + // ); + const [updateSetting, { isSuccess }] = useUpdateChannelMutation(); + useEffect(() => { + if (isSuccess) { + refetch(id); + toast.success(ct("tip.update")); + } + }, [isSuccess, id]); + const handleChange = (newVal: boolean) => { + updateSetting({ id, show_email: newVal }); + }; + return ( + + { + handleChange(v == "true"); + }} + /> + + ); +}; + +export default ShowEmail; diff --git a/src/routes/settingChannel/Overview/index.tsx b/src/routes/settingChannel/Overview/index.tsx new file mode 100644 index 00000000..0798061e --- /dev/null +++ b/src/routes/settingChannel/Overview/index.tsx @@ -0,0 +1,160 @@ +import { ChangeEvent, useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; + +import { + useChangeChannelTypeMutation, + useGetChannelQuery, + useUpdateChannelMutation, + useUpdateIconMutation +} from "@/app/services/channel"; +import { useAppSelector } from "@/app/store"; +import { Channel } from "@/types/channel"; +import AvatarUploader from "@/components/AvatarUploader"; +import SaveTip from "@/components/SaveTip"; +import Input from "@/components/styled/Input"; +import Label from "@/components/styled/Label"; +import Radio from "@/components/styled/Radio"; +import Textarea from "@/components/styled/Textarea"; +import IconChannel from "@/assets/icons/channel.svg"; +import { shallowEqual } from "react-redux"; +import ShowEmail from "./ShowEmail"; +import DMMember from "./DMMember"; +import AddFriend from "./AddFriend"; +import ServerVersionChecker from "@/components/ServerVersionChecker"; +import OnlyOwnerCanSendMsg from "./OnlyOwnerCanSendMsg"; + +export default function Overview({ id = 0 }) { + const { t } = useTranslation("setting", { keyPrefix: "channel" }); + const { t: ct } = useTranslation(); + const loginUser = useAppSelector((store) => store.authData.user, shallowEqual); + const channel = useAppSelector((store) => store.channels.byId[id], shallowEqual); + const { data, refetch } = useGetChannelQuery(id); + const [changed, setChanged] = useState(false); + const [values, setValues] = useState(); + const [updateChannelIcon] = useUpdateIconMutation(); + const [updateChannel, { isSuccess: updated }] = useUpdateChannelMutation(); + const [changeChannelType, { isSuccess: changeTypeSuccess }] = useChangeChannelTypeMutation(); + const handleUpdate = () => { + if (!values) return; + const { name, description } = values; + updateChannel({ id, name, description }); + }; + + const handleChange = (evt: ChangeEvent) => { + const newValue = evt.target.value; + const { type = "" } = evt.target.dataset; + setValues((prev) => { + if (!prev) return prev; + return { ...prev, [type]: newValue }; + }); + }; + + const updateIcon = (image: File) => { + updateChannelIcon({ gid: id, image }); + }; + + const handleReset = () => { + 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(ct("tip.update")); + refetch(); + } + }, [updated]); + useEffect(() => { + if (changeTypeSuccess) { + toast.success(ct("tip.update")); + } + }, [changeTypeSuccess]); + + if (!values || !id || !channel) return null; + const { name, description, show_email, dm_to_member, add_friend, only_owner_can_send_msg } = + values; + const readOnly = !loginUser?.is_admin && channel?.owner != loginUser?.uid; + const inputClass = `w-full flex flex-col items-start gap-2 relative`; + return ( +
+ +
+
+ + #{id} +
+
+ + + +
+
+ +