started rewritting settings page
This commit is contained in:
@@ -12,6 +12,11 @@ export const getUserAPI = async () => {
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getUserDetailedAPI = async () => {
|
||||
const response = await axios.get("/user-service/user-detailed");
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// POST
|
||||
|
||||
export const loginAPI = async (email: string, password: string) => {
|
||||
|
||||
@@ -176,7 +176,7 @@ const FileItem: React.FC<FileItemProps> = memo((props) => {
|
||||
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[130px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden bg-white ",
|
||||
elementSelected || elementMultiSelected
|
||||
? "border-[#3c85ee]"
|
||||
: "border-[#ebe9f9]"
|
||||
: "border-gray-third"
|
||||
)}
|
||||
onClick={fileClick}
|
||||
onContextMenu={onContextMenu}
|
||||
|
||||
@@ -88,7 +88,7 @@ const FolderItem: React.FC<FolderItemProps> = memo((props) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"p-[12px] border border-[#ebe9f9] rounded-[4px] overflow-hidden cursor-pointer animate hover:border-[#3c85ee]",
|
||||
"p-[12px] border border-gray-third rounded-[4px] overflow-hidden cursor-pointer animate hover:border-[#3c85ee]",
|
||||
{
|
||||
"bg-[#3c85ee]": elementSelected || elementMultiSelected,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useClickOutOfBounds, useUtils } from "../../hooks/utils";
|
||||
import AddNewDropdown from "../AddNewDropdown/AddNewDropedown";
|
||||
import AddNewDropdown from "../AddNewDropdown/AddNewDropdown";
|
||||
import TrashIcon from "../../icons/TrashIcon";
|
||||
import classNames from "classnames";
|
||||
import PhotoIcon from "../../icons/PhotoIcon";
|
||||
|
||||
@@ -98,7 +98,7 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
|
||||
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[130px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden bg-white",
|
||||
elementSelected || elementMultiSelected
|
||||
? "border-[#3c85ee]"
|
||||
: "border-[#ebe9f9]"
|
||||
: "border-gray-third"
|
||||
)}
|
||||
onClick={quickItemClick}
|
||||
onContextMenu={onContextMenu}
|
||||
|
||||
@@ -80,7 +80,7 @@ const RightSection = memo(() => {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"!hidden desktopMode:!flex min-w-[260px] max-w-[260px] border-l border-[#e8eef2] p-6 bg-white right-0 justify-center relative mt-1.5",
|
||||
"!hidden desktopMode:!flex min-w-[260px] max-w-[260px] border-l border-gray-secondary p-6 bg-white right-0 justify-center relative mt-1.5",
|
||||
selectedItem.id === "" ? "flex justify-center items-center" : ""
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import ChevronOutline from "../../icons/ChevronOutline";
|
||||
import Header from "../Header/Header";
|
||||
import classNames from "classnames";
|
||||
import AccountIcon from "../../icons/AccountIcon";
|
||||
import TuneIcon from "../../icons/TuneIcon";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import SettingsPageAccount from "./SettingsPageAccount";
|
||||
import { getUserDetailedAPI } from "../../api/user";
|
||||
import Spinner from "../Spinner/Spinner";
|
||||
import Swal from "sweetalert2";
|
||||
import SettingsPageGeneral from "./SettingsPageGeneral";
|
||||
|
||||
const SettingsPage = () => {
|
||||
const [user, setUser] = useState(null);
|
||||
const [tab, setTab] = useState("account");
|
||||
const navigate = useNavigate();
|
||||
|
||||
const goHome = () => {
|
||||
window.location.assign("/home");
|
||||
};
|
||||
|
||||
const getUser = async () => {
|
||||
try {
|
||||
const userResponse = await getUserDetailedAPI();
|
||||
setUser(userResponse);
|
||||
} catch (e) {
|
||||
console.log("Loading user details error", e);
|
||||
const result = await Swal.fire({
|
||||
title: "Error loading user account",
|
||||
text: "There was an error loading your account, would you like to logout?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Yes, logout",
|
||||
});
|
||||
if (result.value) {
|
||||
} else {
|
||||
navigate("/home");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUser();
|
||||
}, []);
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<div className="w-screen h-screen flex justify-center items-center">
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<div className="mt-[70px] flex flex-row">
|
||||
<div className="px-4 border-r border-gray-secondary w-64 h-screen">
|
||||
<a
|
||||
onClick={goHome}
|
||||
className="text-gray-600 hover:text-primary cursor-pointer flex flex-row items-center space-x-1 pt-6"
|
||||
>
|
||||
<ChevronOutline className="w-6 h-6 rotate-90" />
|
||||
<p>HOME</p>
|
||||
</a>
|
||||
<div className="mt-8 space-y-2">
|
||||
<div
|
||||
className={classNames(
|
||||
"pl-2 mr-5 py-2 hover:bg-white-hover rounded-md cursor-pointer animate flex flex-row items-center w-full",
|
||||
tab === "account"
|
||||
? "text-primary bg-white-hover"
|
||||
: "text-gray-primary"
|
||||
)}
|
||||
onClick={() => setTab("account")}
|
||||
>
|
||||
<AccountIcon className="w-6 h-6" />
|
||||
<p className="ml-3">Account</p>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"pl-2 mr-5 py-2 hover:bg-white-hover rounded-md cursor-pointer animate flex flex-row items-center w-full",
|
||||
tab === "general"
|
||||
? "text-primary bg-white-hover"
|
||||
: "text-gray-primary"
|
||||
)}
|
||||
onClick={() => setTab("general")}
|
||||
>
|
||||
<TuneIcon className="w-6 h-6" />
|
||||
<p className="ml-3">General</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 px-64 w-full">
|
||||
{tab === "account" && <SettingsPageAccount user={user} />}
|
||||
{tab === "general" && <SettingsPageGeneral />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsPage;
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
|
||||
interface SettingsPageAccountProps {
|
||||
user: {
|
||||
_id: string;
|
||||
email: string;
|
||||
};
|
||||
}
|
||||
|
||||
const SettingsPageAccount: React.FC<SettingsPageAccountProps> = ({ user }) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="bg-white-hover p-3 flex items-center w-full">
|
||||
<p className="text-base">Account</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="p-3 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Email</p>
|
||||
<p>{user.email}</p>
|
||||
</div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Change password</p>
|
||||
<p className="text-primary hover:text-primary-hover cursor-pointer">
|
||||
Change
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Logout account</p>
|
||||
<p className="text-primary hover:text-primary-hover cursor-pointer">
|
||||
Logout
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Logout all account</p>
|
||||
<p className="text-primary hover:text-primary-hover cursor-pointer">
|
||||
Logout all
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsPageAccount;
|
||||
@@ -0,0 +1,98 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const SettingsPageGeneral = () => {
|
||||
const [listViewStyle, setListViewStyle] = useState("list");
|
||||
const [sortBy, setSortBy] = useState("date");
|
||||
const [orderBy, setOrderBy] = useState("descending");
|
||||
|
||||
const fileListStyleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const value = e.target.value;
|
||||
setListViewStyle(value);
|
||||
if (value === "grid") {
|
||||
window.localStorage.setItem("grid-mode", "true");
|
||||
} else {
|
||||
window.localStorage.removeItem("grid-mode");
|
||||
}
|
||||
};
|
||||
|
||||
const sortByChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const value = e.target.value;
|
||||
setSortBy(value);
|
||||
if (value === "name") {
|
||||
window.localStorage.setItem("sort-name", "true");
|
||||
} else {
|
||||
window.localStorage.removeItem("sort-name");
|
||||
}
|
||||
};
|
||||
|
||||
const orderByChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const value = e.target.value;
|
||||
setOrderBy(value);
|
||||
|
||||
if (value === "ascending") {
|
||||
window.localStorage.setItem("order-asc", "true");
|
||||
} else {
|
||||
window.localStorage.removeItem("order-asc");
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const gridModeLocalStorage = window.localStorage.getItem("grid-mode");
|
||||
const gridModeEnabled = gridModeLocalStorage === "true";
|
||||
|
||||
const sortByLocalStorage = window.localStorage.getItem("sort-name");
|
||||
const sortByNameEnabled = sortByLocalStorage === "true";
|
||||
|
||||
const orderByLocalStorage = window.localStorage.getItem("order-asc");
|
||||
const orderByAscendingEnabled = orderByLocalStorage === "true";
|
||||
|
||||
setListViewStyle(gridModeEnabled ? "grid" : "list");
|
||||
setSortBy(sortByNameEnabled ? "name" : "date");
|
||||
setOrderBy(orderByAscendingEnabled ? "ascending" : "descending");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="bg-white-hover p-3 flex items-center w-full">
|
||||
<p className="text-base">General settings</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">File list style</p>
|
||||
<select
|
||||
value={listViewStyle}
|
||||
onChange={fileListStyleChange}
|
||||
className="text-primary"
|
||||
>
|
||||
<option value="list">List</option>
|
||||
<option value="grid">Grid</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Sort by</p>
|
||||
<select
|
||||
value={sortBy}
|
||||
onChange={sortByChange}
|
||||
className="text-primary"
|
||||
>
|
||||
<option value="date">Date</option>
|
||||
<option value="name">Name</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="px-3 py-4 flex flex-row justify-between items-center border-b border-gray-secondary">
|
||||
<p className="text-gray-primary">Order by</p>
|
||||
<select
|
||||
value={orderBy}
|
||||
onChange={orderByChange}
|
||||
className="text-primary"
|
||||
>
|
||||
<option value="descending">Descending</option>
|
||||
<option value="ascending">Ascending</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsPageGeneral;
|
||||
@@ -0,0 +1,15 @@
|
||||
type AccountIconType = React.SVGAttributes<SVGSVGElement>;
|
||||
|
||||
const AccountIcon: React.FC<AccountIconType> = (props) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
|
||||
<title>account-box</title>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M6,17C6,15 10,13.9 12,13.9C14,13.9 18,15 18,17V18H6M15,9A3,3 0 0,1 12,12A3,3 0 0,1 9,9A3,3 0 0,1 12,6A3,3 0 0,1 15,9M3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3H5C3.89,3 3,3.9 3,5Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccountIcon;
|
||||
@@ -0,0 +1,15 @@
|
||||
type TuneIconType = React.SVGAttributes<SVGSVGElement>;
|
||||
|
||||
const TuneIcon: React.FC<TuneIconType> = (props) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
|
||||
<title>tune</title>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3,17V19H9V17H3M3,5V7H13V5H3M13,21V19H21V17H13V15H11V21H13M7,9V11H3V13H7V15H9V9H7M21,13V11H11V13H21M15,9H17V7H21V5H17V3H15V9Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default TuneIcon;
|
||||
@@ -16,6 +16,7 @@ import uuid from "uuid";
|
||||
import ResetPasswordPage from "../components/ResetPasswordPage";
|
||||
import SettingsPage from "../components/SettingsPage";
|
||||
import Homepage from "../components/Homepage/Homepage";
|
||||
import SettingsPage2 from "../components/SettingsPage/SettingsPage";
|
||||
|
||||
// export const history = createHistory();
|
||||
|
||||
@@ -103,6 +104,15 @@ const AppRouter = () => {
|
||||
<Route path="/verify-email/:id" element={<VerifyEmailPage />} />
|
||||
<Route path="/reset-password/:id" element={<ResetPasswordPage />} />
|
||||
<Route path="/settings" element={<SettingsPage />} />
|
||||
<Route
|
||||
key={1}
|
||||
path="/settings2"
|
||||
element={
|
||||
<PrivateRoute>
|
||||
<SettingsPage2 />
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
@@ -12,6 +12,8 @@ module.exports = {
|
||||
"primary-hover": "#326bcc",
|
||||
"white-hover": "#f6f5fd",
|
||||
"gray-primary": "#637381",
|
||||
"gray-secondary": "#e8eef2",
|
||||
"gray-third": "#ebe9f9",
|
||||
},
|
||||
},
|
||||
screens: {
|
||||
|
||||
Reference in New Issue
Block a user