refactor: setting modals to pages
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
// import { useState, useEffect } from "react";
|
||||
import StyledContainer from "./StyledContainer";
|
||||
import Input from "../../../common/component/styled/Input";
|
||||
import Textarea from "../../../common/component/styled/Textarea";
|
||||
import Label from "../../../common/component/styled/Label";
|
||||
import Toggle from "../../../common/component/styled/Toggle";
|
||||
import SaveTip from "../../../common/component/SaveTip";
|
||||
import useConfig from "./useConfig";
|
||||
export default function ConfigAgora() {
|
||||
const {
|
||||
changed,
|
||||
reset,
|
||||
values,
|
||||
setValues,
|
||||
toggleEnable,
|
||||
updateConfig,
|
||||
} = useConfig("agora");
|
||||
const handleUpdate = () => {
|
||||
// const { token_url, description } = values;
|
||||
updateConfig(values);
|
||||
};
|
||||
const handleChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
const { type } = evt.target.dataset;
|
||||
setValues((prev) => {
|
||||
return { ...prev, [type]: newValue };
|
||||
});
|
||||
};
|
||||
// if (!values) return null;
|
||||
const {
|
||||
url,
|
||||
project_id,
|
||||
app_id,
|
||||
app_certificate,
|
||||
rtm_key,
|
||||
rtm_secret,
|
||||
enabled = false,
|
||||
} = values ?? {};
|
||||
return (
|
||||
<StyledContainer>
|
||||
<div className="inputs">
|
||||
<div className="input row">
|
||||
<Label>Enable</Label>
|
||||
<Toggle onClick={toggleEnable} data-checked={enabled}></Toggle>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="url">Agora Url</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="url"
|
||||
onChange={handleChange}
|
||||
value={url || "https://api.agora.io"}
|
||||
name="url"
|
||||
placeholder="Agora URL"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="project_id">Project ID</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
// type={"number"}
|
||||
data-type="project_id"
|
||||
onChange={handleChange}
|
||||
value={project_id}
|
||||
name="project_id"
|
||||
placeholder="Project ID"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="app_id">App ID</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="app_id"
|
||||
onChange={handleChange}
|
||||
value={app_id}
|
||||
name="app_id"
|
||||
placeholder="APP ID"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="app_certificate">APP Certificate</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="app_certificate"
|
||||
onChange={handleChange}
|
||||
value={app_certificate}
|
||||
name="app_certificate"
|
||||
placeholder="APP Certificate"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="rtm_key">RTM Key</Label>
|
||||
<Textarea
|
||||
disabled={!enabled}
|
||||
data-type="rtm_key"
|
||||
onChange={handleChange}
|
||||
value={rtm_key}
|
||||
name="rtm_key"
|
||||
placeholder="RTM Key"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="rtm_secret">RTM Secret</Label>
|
||||
<Textarea
|
||||
disabled={!enabled}
|
||||
data-type="rtm_secret"
|
||||
onChange={handleChange}
|
||||
value={rtm_secret}
|
||||
name="rtm_secret"
|
||||
placeholder="RTM Secret"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
|
||||
{/* <button onClick={handleUpdate} className="btn">update</button> */}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// import { useState, useEffect } from "react";
|
||||
import StyledContainer from "./StyledContainer";
|
||||
import Input from "../../../common/component/styled/Input";
|
||||
import Textarea from "../../../common/component/styled/Textarea";
|
||||
import Toggle from "../../../common/component/styled/Toggle";
|
||||
import Label from "../../../common/component/styled/Label";
|
||||
import SaveTip from "../../../common/component/SaveTip";
|
||||
import useConfig from "./useConfig";
|
||||
|
||||
export default function ConfigFirebase() {
|
||||
const {
|
||||
values,
|
||||
toggleEnable,
|
||||
updateConfig,
|
||||
setValues,
|
||||
reset,
|
||||
changed,
|
||||
} = useConfig("firebase");
|
||||
const handleUpdate = () => {
|
||||
// const { token_url, description } = values;
|
||||
updateConfig(values);
|
||||
};
|
||||
const handleChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
const { type } = evt.target.dataset;
|
||||
setValues((prev) => {
|
||||
return { ...prev, [type]: newValue };
|
||||
});
|
||||
};
|
||||
// if (!values) return null;
|
||||
const { token_url, project_id, private_key, client_email, enabled = false } =
|
||||
values ?? {};
|
||||
return (
|
||||
<StyledContainer>
|
||||
<div className="inputs">
|
||||
<div className="input row">
|
||||
<Label>Enable</Label>
|
||||
<Toggle onClick={toggleEnable} data-checked={enabled}></Toggle>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="name">Token Url</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="token_url"
|
||||
onChange={handleChange}
|
||||
value={token_url || "https://oauth2.googleapis.com/token"}
|
||||
name="token_url"
|
||||
placeholder="Token URL"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Project ID</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="project_id"
|
||||
onChange={handleChange}
|
||||
value={project_id}
|
||||
name="project_id"
|
||||
placeholder="Project ID"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Private Key</Label>
|
||||
<Textarea
|
||||
rows={10}
|
||||
disabled={!enabled}
|
||||
data-type="private_key"
|
||||
onChange={handleChange}
|
||||
value={private_key}
|
||||
name="private_key"
|
||||
placeholder="Private key"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Client Email</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="client_email"
|
||||
onChange={handleChange}
|
||||
value={client_email}
|
||||
name="client_email"
|
||||
placeholder="Client Email address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
|
||||
{/* <button onClick={handleUpdate} className="btn">update</button> */}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// import { useState, useEffect } from "react";
|
||||
import StyledContainer from "./StyledContainer";
|
||||
import Textarea from "../../../common/component/styled/Textarea";
|
||||
import Toggle from "../../../common/component/styled/Toggle";
|
||||
import Label from "../../../common/component/styled/Label";
|
||||
import SaveTip from "../../../common/component/SaveTip";
|
||||
import useConfig from "./useConfig";
|
||||
|
||||
export default function Logins() {
|
||||
const { values, updateConfig, setValues, reset, changed } = useConfig(
|
||||
"login"
|
||||
);
|
||||
const handleUpdate = () => {
|
||||
// const { token_url, description } = values;
|
||||
updateConfig(values);
|
||||
};
|
||||
const handleChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
const { type } = evt.target.dataset;
|
||||
const items = newValue ? newValue.split("\n") : [];
|
||||
setValues((prev) => {
|
||||
return { ...prev, [type]: items };
|
||||
});
|
||||
};
|
||||
const handleToggle = (val) => {
|
||||
setValues((prev) => {
|
||||
return { ...prev, ...val };
|
||||
});
|
||||
};
|
||||
if (!values) return null;
|
||||
const { google, metamask, password, oidc = [] } = values ?? {};
|
||||
return (
|
||||
<StyledContainer>
|
||||
<div className="inputs">
|
||||
<div className="input row">
|
||||
<Label>Password</Label>
|
||||
<Toggle
|
||||
onClick={handleToggle.bind(null, { password: !password })}
|
||||
data-checked={password}
|
||||
></Toggle>
|
||||
</div>
|
||||
<div className="input row">
|
||||
<Label>Google</Label>
|
||||
<Toggle
|
||||
onClick={handleToggle.bind(null, { google: !google })}
|
||||
data-checked={google}
|
||||
></Toggle>
|
||||
</div>
|
||||
<div className="input row">
|
||||
<Label>Metamask</Label>
|
||||
<Toggle
|
||||
onClick={handleToggle.bind(null, { metamask: !metamask })}
|
||||
data-checked={metamask}
|
||||
></Toggle>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">OIDC</Label>
|
||||
<Textarea
|
||||
rows={10}
|
||||
data-type="oidc"
|
||||
onChange={handleChange}
|
||||
value={oidc.join("\n")}
|
||||
name="oidc"
|
||||
placeholder="Input issuer list, one line, one issuer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <div className="input">
|
||||
<Label htmlFor="name">Token Url</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="token_url"
|
||||
onChange={handleChange}
|
||||
value={token_url || "https://oauth2.googleapis.com/token"}
|
||||
name="token_url"
|
||||
placeholder="Token URL"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Project ID</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
type={"number"}
|
||||
data-type="project_id"
|
||||
onChange={handleChange}
|
||||
value={project_id}
|
||||
name="project_id"
|
||||
placeholder="Project ID"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Private Key</Label>
|
||||
<Textarea
|
||||
rows={10}
|
||||
disabled={!enabled}
|
||||
data-type="private_key"
|
||||
onChange={handleChange}
|
||||
value={private_key}
|
||||
name="private_key"
|
||||
placeholder="Private key"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Client Email</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="client_email"
|
||||
onChange={handleChange}
|
||||
value={client_email}
|
||||
name="client_email"
|
||||
placeholder="Client Email address"
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
|
||||
{/* <button onClick={handleUpdate} className="btn">update</button> */}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
const StyledTest = styled.div`
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
white-space: nowrap;
|
||||
margin-top: 24px;
|
||||
`;
|
||||
import { useSendTestEmailMutation } from "../../../app/services/server";
|
||||
import iconQuestion from "../../../assets/icons/question.svg?url";
|
||||
import useConfig from "./useConfig";
|
||||
import StyledContainer from "./StyledContainer";
|
||||
import Input from "../../../common/component/styled/Input";
|
||||
import Button from "../../../common/component/styled/Button";
|
||||
import Toggle from "../../../common/component/styled/Toggle";
|
||||
import Label from "../../../common/component/styled/Label";
|
||||
import SaveTip from "../../../common/component/SaveTip";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
export default function ConfigSMTP() {
|
||||
const [testEmail, setTestEmail] = useState("");
|
||||
const [sendTestEmail, { isSuccess, isError }] = useSendTestEmailMutation();
|
||||
const {
|
||||
reset,
|
||||
updateConfig,
|
||||
values,
|
||||
setValues,
|
||||
changed,
|
||||
toggleEnable,
|
||||
} = useConfig("smtp");
|
||||
|
||||
const handleUpdate = () => {
|
||||
// const { token_url, description } = values;
|
||||
updateConfig({ ...values, port: Number(values.port ?? 0) });
|
||||
};
|
||||
const handleChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
const { type } = evt.target.dataset;
|
||||
setValues((prev) => {
|
||||
return { ...prev, [type]: newValue };
|
||||
});
|
||||
};
|
||||
const handleTestEmailChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
setTestEmail(newValue);
|
||||
};
|
||||
const handleTestClick = () => {
|
||||
console.log("test");
|
||||
sendTestEmail({
|
||||
to: testEmail,
|
||||
subject: "test title",
|
||||
content: "test content",
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
toast.success("Send Test Email Successfully");
|
||||
}
|
||||
if (isError) {
|
||||
toast.error("Send Test Email Fail");
|
||||
}
|
||||
}, [isSuccess, isError]);
|
||||
|
||||
// if (!values) return null;
|
||||
const { host, port, from, username, password, enabled = false } =
|
||||
values ?? {};
|
||||
console.log("values", values);
|
||||
return (
|
||||
<StyledContainer>
|
||||
<div className="inputs">
|
||||
<div className="input row">
|
||||
<Label>Enable</Label>
|
||||
<Toggle onClick={toggleEnable} data-checked={enabled}></Toggle>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="name">Host</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="host"
|
||||
onChange={handleChange}
|
||||
value={host}
|
||||
name="host"
|
||||
placeholder="SMTP Host"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Port</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
type={"number"}
|
||||
data-type="port"
|
||||
onChange={handleChange}
|
||||
value={port}
|
||||
name="port"
|
||||
placeholder="SMTP Port"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">From</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="from"
|
||||
onChange={handleChange}
|
||||
value={from}
|
||||
name="from"
|
||||
placeholder="SMTP From"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Username</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="username"
|
||||
onChange={handleChange}
|
||||
value={username}
|
||||
name="username"
|
||||
placeholder="SMTP Username"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Password</Label>
|
||||
<Input
|
||||
type={"password"}
|
||||
disabled={!enabled}
|
||||
data-type="password"
|
||||
onChange={handleChange}
|
||||
value={password}
|
||||
name="password"
|
||||
placeholder="SMTP Password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tip">
|
||||
<img src={iconQuestion} alt="question icon" />
|
||||
<a
|
||||
href="https://rustchat.com/doc/smtp-setting"
|
||||
target="_blank"
|
||||
className="link"
|
||||
rel="noreferrer"
|
||||
>
|
||||
How to set up SMTP?
|
||||
</a>
|
||||
</div>
|
||||
<StyledTest>
|
||||
<Input
|
||||
type={"email"}
|
||||
disabled={!enabled}
|
||||
onChange={handleTestEmailChange}
|
||||
value={testEmail}
|
||||
name="email"
|
||||
placeholder="test@email.com"
|
||||
/>
|
||||
<Button disabled={!enabled || !testEmail} onClick={handleTestClick}>
|
||||
Send Test Email
|
||||
</Button>
|
||||
</StyledTest>
|
||||
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
|
||||
{/* <button onClick={handleUpdate} className="btn">update</button> */}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import styled from "styled-components";
|
||||
const StyledContainer = 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;
|
||||
&.row {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tip {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
.link {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #06b6d4;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledContainer;
|
||||
@@ -0,0 +1,107 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { isObjectEqual } from "../../../common/utils";
|
||||
import toast from "react-hot-toast";
|
||||
import {
|
||||
useGetAgoraConfigQuery,
|
||||
useGetFirebaseConfigQuery,
|
||||
useGetSMTPConfigQuery,
|
||||
useGetLoginConfigQuery,
|
||||
useUpdateLoginConfigMutation,
|
||||
useUpdateSMTPConfigMutation,
|
||||
useUpdateAgoraConfigMutation,
|
||||
useUpdateFirebaseConfigMutation,
|
||||
} from "../../../app/services/server";
|
||||
export default function useConfig(config = "smtp") {
|
||||
const [changed, setChanged] = useState(false);
|
||||
const [values, setValues] = useState({});
|
||||
const { data: Login, refetch: refetchLogin } = useGetLoginConfigQuery();
|
||||
const [
|
||||
updateLoginConfig,
|
||||
{ isSuccess: LoginUpdated },
|
||||
] = useUpdateLoginConfigMutation();
|
||||
const { data: SMTP, refetch: refetchSMTP } = useGetSMTPConfigQuery();
|
||||
const [
|
||||
updateSMTPConfig,
|
||||
{ isSuccess: SMTPUpdated },
|
||||
] = useUpdateSMTPConfigMutation();
|
||||
const { data: Agora, refetch: refetchAgora } = useGetAgoraConfigQuery();
|
||||
const [
|
||||
updateAgoraConfig,
|
||||
{ isSuccess: AgoraUpdated },
|
||||
] = useUpdateAgoraConfigMutation();
|
||||
const {
|
||||
data: Firebase,
|
||||
refetch: refetchFirebase,
|
||||
} = useGetFirebaseConfigQuery();
|
||||
const [
|
||||
updateFirebaseConfig,
|
||||
{ isSuccess: FirebaseUpdated },
|
||||
] = useUpdateFirebaseConfigMutation();
|
||||
|
||||
const datas = {
|
||||
login: Login,
|
||||
smtp: SMTP,
|
||||
agora: Agora,
|
||||
firebase: Firebase,
|
||||
};
|
||||
const updateFns = {
|
||||
login: updateLoginConfig,
|
||||
smtp: updateSMTPConfig,
|
||||
agora: updateAgoraConfig,
|
||||
firebase: updateFirebaseConfig,
|
||||
};
|
||||
const refetchs = {
|
||||
smtp: refetchSMTP,
|
||||
agora: refetchAgora,
|
||||
firebase: refetchFirebase,
|
||||
login: refetchLogin,
|
||||
};
|
||||
const updateds = {
|
||||
login: LoginUpdated,
|
||||
smtp: SMTPUpdated,
|
||||
agora: AgoraUpdated,
|
||||
firebase: FirebaseUpdated,
|
||||
};
|
||||
const data = datas[config];
|
||||
const updateConfig = updateFns[config];
|
||||
const refetch = refetchs[config];
|
||||
const updated = updateds[config];
|
||||
const reset = () => {
|
||||
setValues(data ?? {});
|
||||
};
|
||||
|
||||
const toggleEnable = () => {
|
||||
setValues((prev) => {
|
||||
return { ...prev, enabled: !prev.enabled };
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if (updated) {
|
||||
toast.success("Configuration Updated!");
|
||||
refetch();
|
||||
}
|
||||
}, [updated]);
|
||||
useEffect(() => {
|
||||
console.log("wtf", data);
|
||||
// if (data) {
|
||||
setValues(data ?? {});
|
||||
// }
|
||||
}, [data]);
|
||||
useEffect(() => {
|
||||
// if (data && values) {
|
||||
if (!isObjectEqual(data, values)) {
|
||||
setChanged(true);
|
||||
} else {
|
||||
setChanged(false);
|
||||
}
|
||||
// }
|
||||
}, [data, values]);
|
||||
return {
|
||||
reset,
|
||||
changed,
|
||||
updateConfig,
|
||||
values,
|
||||
setValues,
|
||||
toggleEnable,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user