Pass storage handlers to lower functions to ensure state can be properly managed now, init retrieving user settings from backend

This commit is contained in:
Curt Spark 2024-04-29 16:59:01 +01:00
parent 2af602dad4
commit d4a963b162
10 changed files with 149 additions and 57 deletions

View File

@ -26,7 +26,7 @@ function getUserIDbyAuthToken(
authTokenStorageHandler.authTokenValue &&
!userIDStorageHandler.userIDValue
) {
fetch("http://127.0.0.1:8000/api/userIDByAuthToken", {
fetch("http://127.0.0.1:8000/api/user/IDByAuthToken", {
method: "GET",
headers: {
"Content-Type": "application/json",
@ -35,7 +35,6 @@ function getUserIDbyAuthToken(
})
.then((response) => response.json())
.then((responseParsed: Object) => {
console.log(responseParsed);
if (responseParsed.success) {
userIDStorageHandler.setUserIDValue(responseParsed.userID);
}
@ -43,10 +42,6 @@ function getUserIDbyAuthToken(
}
}
function testUserButton() {
return usernameStorageHandler.usernameValue ? "" : "Test User";
}
export default function App() {
const usernameStorageHandler = usernameStorageHandlerInit();
const authTokenStorageHandler = authTokenStorageHandlerInit();
@ -66,6 +61,7 @@ export default function App() {
<NavbarButton>Settings</NavbarButton>
<NavbarButton>Logout</NavbarButton>
<NavbarUserInfo
usernameStorageHandler={usernameStorageHandler}
userID={userIDStorageHandler.userIDValue}
></NavbarUserInfo>
</>
@ -81,11 +77,42 @@ export default function App() {
<Route
path="/blogeditor"
exact
element={<BlogEditor></BlogEditor>}
element={
<BlogEditor
authTokenStorageHandler={authTokenStorageHandler}
></BlogEditor>
}
/>
<Route
path="/settings"
exact
element={
<Settings
authTokenStorageHandler={authTokenStorageHandler}
></Settings>
}
/>
<Route
path="/login"
exact
element={
<Login
authTokenStorageHandler={authTokenStorageHandler}
usernameStorageHandler={usernameStorageHandler}
></Login>
}
/>
<Route
path="/logout"
exact
element={
<Logout
authTokenStorageHandler={authTokenStorageHandler}
usernameStorageHandler={usernameStorageHandler}
userIDStorageHandler={userIDStorageHandler}
></Logout>
}
/>
<Route path="/settings" exact element={<Settings></Settings>} />
<Route path="/login" exact element={<Login></Login>} />
<Route path="/logout" exact element={<Logout></Logout>} />
</Routes>
</div>
</BrowserRouter>

View File

@ -0,0 +1,31 @@
import * as React from "react";
import { Link } from "react-router-dom";
interface Props {
settingField: string;
settingValue: string;
}
function handleSettingFieldChange(eventData, setFunction) {
setFunction(eventData.target.value);
}
export default function AccountDefaultSetting({
settingField,
settingValue,
}: Props) {
const [fieldValue, setFieldValue] = React.useState(settingValue);
return (
<>
<h4 key={settingField + "Header"}>{settingField + ":"}</h4>
<input
type="text"
key={settingField + "Body"}
value={fieldValue}
onChange={(eventData) =>
handleSettingFieldChange(eventData, setFieldValue)
}
></input>
</>
);
}

View File

@ -2,16 +2,18 @@ import * as React from "react";
import { usernameStorageHandlerInit } from "../components/storageHandler.ts";
interface Props {
usernameStorageHandler: object;
userID: number;
}
/* Implement checking whether userInfo name etc reaches a certain character size, if it does then we'll split the string and add ... to the end instead*/
export default function NavbarUserInfo({ userID }: Props) {
const usernameStorageHandler = usernameStorageHandlerInit();
export default function NavbarUserInfo({
usernameStorageHandler,
userID,
}: Props) {
if (!usernameStorageHandler.usernameValue) {
fetch("http://127.0.0.1:8000/api/publicInfo/" + userID.toString(), {
fetch("http://127.0.0.1:8000/api/user/publicInfo/" + userID.toString(), {
method: "GET",
headers: {
"Content-Type": "application/json",

View File

@ -1,17 +1,7 @@
import * as React from "react";
import useLocalStorage from "./useLocalStorage.ts";
/*
React Hooks may not be a good fit for this role as these functions need to be recalled within every page to be accessible
Could look at using global variables to avoid this (But it appears to be frowned upon? And react has trouble updating usestate hooks when it comes to globals it seems)
Or could simply stop using react hooks for this role
It appears to work for now so will leave be
Confirmed that react cannot currently find and update DOM elements in other files. This will need to be changed
For now when changing these values (Logging in etc) I just refresh the page
*/
export const usernameStorageHandlerInit = () => {
export const usernameStorageHandlerInit = (): object => {
const [usernameValue, setUsernameValue, deleteUsernameValue] =
useLocalStorage("username");
@ -22,7 +12,7 @@ export const usernameStorageHandlerInit = () => {
};
};
export const userIDStorageHandlerInit = () => {
export const userIDStorageHandlerInit = (): object => {
const [userIDValue, setUserIDValue, deleteUserIDValue] =
useLocalStorage("userID");
@ -33,7 +23,7 @@ export const userIDStorageHandlerInit = () => {
};
};
export const authTokenStorageHandlerInit = () => {
export const authTokenStorageHandlerInit = (): object => {
const [authTokenValue, setAuthTokenValue, deleteAuthTokenValue] =
useLocalStorage("authtoken");

View File

@ -28,6 +28,11 @@ h1 {
margin: 0px;
}
h4 {
padding: 0px;
margin: 0px;
}
a {
text-decoration: none;
}

View File

@ -1,12 +1,13 @@
import * as React from "react";
import { Navigate } from "react-router-dom";
import { authTokenStorageHandlerInit } from "../components/storageHandler.ts";
import TilingItem from "../components/TilingItem.tsx";
export default function Home() {
const authTokenStorageHandler = authTokenStorageHandlerInit();
interface Props {
authTokenStorageHandler: object;
}
export default function Home({ authTokenStorageHandler }: Props) {
if (!authTokenStorageHandler.authTokenValue) {
return <Navigate to="/home"></Navigate>;
}

View File

@ -1,14 +1,11 @@
import * as React from "react";
import { Navigate } from "react-router-dom";
import {
usernameStorageHandlerInit,
authTokenStorageHandlerInit,
} from "../components/storageHandler.ts";
export default function Login() {
const usernameStorageHandler = usernameStorageHandlerInit();
const authTokenStorageHandler = authTokenStorageHandlerInit();
interface Props {
authTokenStorageHandler: object;
}
export default function Login({ authTokenStorageHandler }: Props) {
const [usernameFormValue, setUsernameFormValue] = React.useState("");
function handleUsernameFormChange(eventData) {
setUsernameFormValue(eventData.target.value);
@ -46,7 +43,6 @@ export default function Login() {
console.log(responseParsed);
if (responseParsed.success) {
authTokenStorageHandler.setAuthTokenValue(responseParsed.authToken);
window.location.reload();
} else {
console.log("Login failure!");
}

View File

@ -1,25 +1,25 @@
import * as React from "react";
import { Navigate } from "react-router-dom";
import {
usernameStorageHandlerInit,
authTokenStorageHandlerInit,
userIDStorageHandlerInit,
} from "../components/storageHandler.ts";
export default function Logout() {
const authTokenStorageHandler = authTokenStorageHandlerInit();
const userIDStorageHandler = userIDStorageHandlerInit();
const usernameStorageHandler = usernameStorageHandlerInit();
interface Props {
authTokenStorageHandler: object;
usernameStorageHandler: object;
userIDStorageHandler: object;
}
export default function Logout({
usernameStorageHandler,
authTokenStorageHandler,
userIDStorageHandler,
}: Props) {
if (!authTokenStorageHandler.authTokenValue) {
return <Navigate to="/home"></Navigate>;
}
function onLogoutButtonClick() {
authTokenStorageHandler.deleteAuthTokenValue();
userIDStorageHandler.deleteUserIDValue();
usernameStorageHandler.deleteUsernameValue();
window.location.reload();
authTokenStorageHandler.setAuthTokenValue("");
userIDStorageHandler.setUserIDValue("");
usernameStorageHandler.setUsernameValue("");
}
return (

View File

@ -1,13 +1,15 @@
import * as React from "react";
import { Navigate } from "react-router-dom";
import { authTokenStorageHandlerInit } from "../components/storageHandler.ts";
import TilingItem from "../components/TilingItem.tsx";
import SettingButton from "../components/SettingButton.tsx";
import AccountSetting from "./settings/Account.tsx";
import SecuritySetting from "./settings/Security.tsx";
import NotFoundSetting from "./settings/NotFound.tsx";
interface Props {
authTokenStorageHandler: object;
}
function renderCurrentSetting(setting: string) {
switch (setting) {
case "Account":
@ -19,7 +21,7 @@ function renderCurrentSetting(setting: string) {
}
}
export default function Home() {
export default function Home({ authTokenStorageHandler }: Props) {
const settings = ["Account", "Security"];
const [currentSetting, setCurrentSetting] = React.useState(settings[0]);
/* Make object to pass by reference */
@ -28,8 +30,6 @@ export default function Home() {
setCurrentSetting,
};
const authTokenStorageHandler = authTokenStorageHandlerInit();
if (!authTokenStorageHandler.authTokenValue) {
return <Navigate to="/home"></Navigate>;
}

View File

@ -1,11 +1,51 @@
import * as React from "react";
import { authTokenStorageHandlerInit } from "../../components/storageHandler.ts";
import AccountDefaultSetting from "../../components/AccountDefaultSetting.tsx";
function RenderSettingField(settingField: str, settingValue: str) {
switch (settingField) {
default:
return (
<AccountDefaultSetting
key={settingField + "Main"}
settingField={settingField}
settingValue={settingValue}
></AccountDefaultSetting>
);
}
}
export default function AccountSetting() {
const [accountSettings, setAccountSettings] = React.useState({});
const authTokenStorageHandler = authTokenStorageHandlerInit();
React.useEffect(() => {
if (authTokenStorageHandler.authTokenValue) {
fetch("http://127.0.0.1:8000/api/user/settings/account", {
method: "GET",
headers: {
"Content-Type": "application/json",
authToken: authTokenStorageHandler.authTokenValue,
},
})
.then((response) => response.json())
.then((responseParsed: Object) => {
if (responseParsed.success) {
delete responseParsed.success;
delete responseParsed.message;
setAccountSettings(responseParsed);
}
});
}
}, []);
return (
<>
<h1>Account</h1>
<hr></hr>
<p>Now on account!</p>
{Object.entries(accountSettings).map((item, key) =>
RenderSettingField(item[0], item[1]),
)}
</>
);
}