feat: middle save
This commit is contained in:
parent
2521a26442
commit
fdf4750919
2 changed files with 107 additions and 71 deletions
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { AuthState, useAuthStore } from "../../store/auth";
|
import { useAuthStore } from "../../store/auth";
|
||||||
|
|
||||||
import "./settings.scss";
|
import "./settings.scss";
|
||||||
import { DynamicIcon } from "lucide-react/dynamic";
|
import { DynamicIcon } from "lucide-react/dynamic";
|
||||||
|
@ -33,26 +33,16 @@ function Settings() {
|
||||||
return (
|
return (
|
||||||
<div className="ka-settings">
|
<div className="ka-settings">
|
||||||
<h2 className="ka-title">General</h2>
|
<h2 className="ka-title">General</h2>
|
||||||
<AccountSetting auth={auth} />
|
<AccountSetting />
|
||||||
|
|
||||||
<h2 className="ka-title">Private Directory</h2>
|
<h2 className="ka-title">Private Directory</h2>
|
||||||
<SettingBox>
|
<PrivateDirectory />
|
||||||
{/* TODO: create private dir panel */}
|
|
||||||
<></>
|
|
||||||
</SettingBox>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SettingBox({ children }: { children: React.ReactNode }) {
|
function AccountSetting() {
|
||||||
return (
|
const auth = useAuthStore();
|
||||||
<div className="setting-box">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function AccountSetting({ auth }: { auth: AuthState }) {
|
|
||||||
const orRef = useRef<HTMLInputElement>(null);
|
const orRef = useRef<HTMLInputElement>(null);
|
||||||
const pwRef = useRef<HTMLInputElement>(null);
|
const pwRef = useRef<HTMLInputElement>(null);
|
||||||
const ckRef = useRef<HTMLInputElement>(null);
|
const ckRef = useRef<HTMLInputElement>(null);
|
||||||
|
@ -64,74 +54,69 @@ function AccountSetting({ auth }: { auth: AuthState }) {
|
||||||
<h4>Account Setting</h4>
|
<h4>Account Setting</h4>
|
||||||
<span>You can modify your account. This is a sensitive option. Please reconsider if you want to change your account information.</span>
|
<span>You can modify your account. This is a sensitive option. Please reconsider if you want to change your account information.</span>
|
||||||
<hr className="line" />
|
<hr className="line" />
|
||||||
|
{/* TODO: split to component */}
|
||||||
<div className="box-row">
|
<div className="box-row">
|
||||||
<div className="box-col">
|
<div className="box-col">
|
||||||
<h6>Change Password</h6>
|
<h6>Change Password</h6>
|
||||||
<span>If you change your password, you will need to log in again.</span>
|
<span>If you change your password, you will need to log in again.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form className="box-col form" id="pw-change">
|
<form className="box-col form" id="pw-change" onSubmit={ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
const origin = orRef.current?.value;
|
||||||
|
const password = pwRef.current?.value;
|
||||||
|
const check = ckRef.current?.value;
|
||||||
|
|
||||||
|
if (!origin || !password || !check) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origin === "" || password === "" || check === "") {
|
||||||
|
alert("You must need to write all inputs");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password !== check) {
|
||||||
|
alert("New password is not matches!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = new URLSearchParams();
|
||||||
|
form.append("password", origin);
|
||||||
|
form.append("new_password", password);
|
||||||
|
|
||||||
|
fetch("/api/auth/update", {
|
||||||
|
body: form,
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Basic ${auth.token}`
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.status !== 200) {
|
||||||
|
alert(`${res.status} ${res.statusText}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("password changed!");
|
||||||
|
document.location.href = "/logout";
|
||||||
|
});
|
||||||
|
}}>
|
||||||
<PasswordInput placeholder="Password" ref={orRef} />
|
<PasswordInput placeholder="Password" ref={orRef} />
|
||||||
<PasswordInput placeholder="New Password" ref={pwRef} />
|
<PasswordInput placeholder="New Password" ref={pwRef} />
|
||||||
<PasswordInput placeholder="Check Password" ref={ckRef} />
|
<PasswordInput placeholder="Check Password" ref={ckRef} />
|
||||||
|
|
||||||
<button type="submit" className="danger" onClick={ev => {
|
<button type="submit" className="danger">Change Password</button>
|
||||||
ev.preventDefault();
|
|
||||||
const origin = orRef.current?.value;
|
|
||||||
const password = pwRef.current?.value;
|
|
||||||
const check = ckRef.current?.value;
|
|
||||||
|
|
||||||
if (!origin || !password || !check) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (origin === "" || password === "" || check === "") {
|
|
||||||
alert("You must need to write all inputs");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password !== check) {
|
|
||||||
alert("New password is not matches!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const form = new URLSearchParams();
|
|
||||||
form.append("password", origin);
|
|
||||||
form.append("new_password", password);
|
|
||||||
|
|
||||||
fetch("/api/auth/update", {
|
|
||||||
body: form,
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Authorization": `Basic ${auth.token}`
|
|
||||||
}
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.status !== 200) {
|
|
||||||
alert(`${res.status} ${res.statusText}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
alert("password changed!");
|
|
||||||
document.location.href = "/logout";
|
|
||||||
});
|
|
||||||
}}>Change Password</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* TODO: split to component */}
|
||||||
<div className="box-row">
|
<div className="box-row">
|
||||||
<div className="box-col">
|
<div className="box-col">
|
||||||
<h6>Delete Account</h6>
|
<h6>Delete Account</h6>
|
||||||
<span>You can delete account. This action is irreversible. Please proceed with caution.</span>
|
<span>You can delete account. This action is irreversible. Please proceed with caution.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form className="box-col form">
|
<form className="box-col form" onSubmit={ev => {
|
||||||
<label className="checkbox">
|
|
||||||
<input type="checkbox" onChange={ev => {
|
|
||||||
setRemove(ev.target.checked);
|
|
||||||
}} />
|
|
||||||
<span>I agree to remove my account.</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<button type="submit" className="danger" disabled={!remove} onClick={ev => {
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
fetch("/api/auth/delete", {
|
fetch("/api/auth/delete", {
|
||||||
|
@ -148,13 +133,56 @@ function AccountSetting({ auth }: { auth: AuthState }) {
|
||||||
alert("Your account has been deactivated and removed");
|
alert("Your account has been deactivated and removed");
|
||||||
document.location.href = "/logout";
|
document.location.href = "/logout";
|
||||||
});
|
});
|
||||||
}}>Remove Account</button>
|
}}>
|
||||||
|
<label className="checkbox">
|
||||||
|
<input type="checkbox" onChange={ev => {
|
||||||
|
setRemove(ev.target.checked);
|
||||||
|
}} />
|
||||||
|
<span>I agree to remove my account.</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button type="submit" className="danger" disabled={!remove}>Remove Account</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</SettingBox>
|
</SettingBox>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function PrivateDirectory() {
|
||||||
|
const pathRef = useRef<HTMLInputElement>(null);
|
||||||
|
const [disabled, setDisabled] = useState(true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingBox>
|
||||||
|
<h4>Directory Management</h4>
|
||||||
|
<span></span>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{/* TODO: split to component */}
|
||||||
|
<div className="box-row">
|
||||||
|
<div className="box-col">
|
||||||
|
<h6>Add Directory</h6>
|
||||||
|
<span>You can add private directory here.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form className="box-col form" onSubmit={ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
}}>
|
||||||
|
<input type="text" placeholder="Directory Path" ref={pathRef} required onChange={ev => {
|
||||||
|
setDisabled(ev.target.value === "");
|
||||||
|
}} />
|
||||||
|
<button type="submit" className="success" disabled={disabled}>Add Directory</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="ka-privdir">
|
||||||
|
<div className="dir-head"></div>
|
||||||
|
<div className="dir-body"></div>
|
||||||
|
</div> */}
|
||||||
|
</SettingBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function PasswordInput({ placeholder, ref }: { placeholder: string; ref: React.RefObject<HTMLInputElement | null> }) {
|
function PasswordInput({ placeholder, ref }: { placeholder: string; ref: React.RefObject<HTMLInputElement | null> }) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
|
|
||||||
|
@ -171,4 +199,12 @@ function PasswordInput({ placeholder, ref }: { placeholder: string; ref: React.R
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SettingBox({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="setting-box">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
color: var(--description-color);
|
color: var(--description-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.setting-box {
|
.setting-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -77,10 +81,6 @@
|
||||||
border-radius: 25px 0 0 25px;
|
border-radius: 25px 0 0 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-pass {
|
.input-pass {
|
||||||
height: 40;
|
height: 40;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
Loading…
Reference in a new issue