Compare commits

..

3 Commits

3 changed files with 142 additions and 30 deletions

View File

@@ -14,7 +14,7 @@ export function Notification({
message, message,
}: NotificationType) { }: NotificationType) {
return ( return (
<div className="flex justify-center fixed top-12 w-dvw z-50"> <div className="flex justify-center fixed top-12 w-dvw z-1000">
<Alert className="w-fit h-fit border border-white" status={type}> <Alert className="w-fit h-fit border border-white" status={type}>
{loading ? ( {loading ? (
<Alert.Indicator> <Alert.Indicator>

View File

@@ -1,7 +1,6 @@
import { import {
Modal, Modal,
Button, Button,
InputGroup,
Input, Input,
TextField, TextField,
Form, Form,
@@ -9,9 +8,11 @@ import {
Description, Description,
Label, Label,
Typography, Typography,
Spinner,
} from "@heroui/react"; } from "@heroui/react";
import type { Dispatch, SetStateAction } from "react"; import { useState, type Dispatch, type SetStateAction } from "react";
import { useAuth } from "~/hooks/auth"; import { useAuth } from "~/hooks/auth";
import { useNotification } from "~/hooks/notification";
export function Settings({ export function Settings({
show, show,
@@ -20,7 +21,82 @@ export function Settings({
show: boolean; show: boolean;
setShow: Dispatch<SetStateAction<boolean>>; setShow: Dispatch<SetStateAction<boolean>>;
}) { }) {
const { user, loading, login, logout } = useAuth(); const { user, update } = useAuth();
const { notify } = useNotification();
const [loading, setLoading] = useState(false);
const notifySucess = () => {
notify(
{
type: "success",
loading: false,
title: "Settings successfully updated!",
message: "",
},
2000,
)
};
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const data: Record<string, string> = {};
// Convert FormData to plain object
formData.forEach((value, key) => {
data[key] = value.toString();
});
const save = async () => {
setLoading(true);
await fetch(`${import.meta.env.VITE_BASE_API_URL}/update`, {
body: JSON.stringify(data),
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
}).catch((e) => {
notify(
{
type: "danger",
loading: false,
title: "An error occured.",
message: `An error occured: ${e}`,
},
10000,
);
});
await update();
setLoading(false);
notifySucess();
};
save();
};
const loadFromSteam = async () => {
setLoading(true);
await fetch(`${import.meta.env.VITE_BASE_API_URL}/reload`, {
credentials: "include",
}).catch((e) => {
notify(
{
type: "danger",
loading: false,
title: "An error occured.",
message: `An error occured: ${e}`,
},
10000,
);
});
await update();
setLoading(false);
notifySucess();
};
return ( return (
<div> <div>
<Modal isOpen={show}> <Modal isOpen={show}>
@@ -39,14 +115,14 @@ export function Settings({
}} }}
/> />
<Modal.Body> <Modal.Body>
<Form className="w-full"> <Form className="w-full" onSubmit={onSubmit}>
<Fieldset> <Fieldset>
<Typography.Heading level={3}> <Typography.Heading level={3}>
Account settings. Account settings.
</Typography.Heading> </Typography.Heading>
<Typography.Paragraph size="sm"> <Typography.Paragraph size="sm">
Update your profile information Update your profile information
either manually or from Steam.{" "} either manually or from Steam.
<br /> <br />
Change several settings concerning Change several settings concerning
some functionnalities of the app. some functionnalities of the app.
@@ -73,8 +149,21 @@ export function Settings({
</Fieldset.Group> </Fieldset.Group>
<Fieldset.Actions className="flex justify-end"> <Fieldset.Actions className="flex justify-end">
<div className="flex-1"> <div className="flex-1">
<Button variant="tertiary"> <Button
Load from Steam variant="tertiary"
isPending={loading}
onPress={() => {
loadFromSteam();
}}
>
{loading ? (
<Spinner
color="current"
size="md"
/>
) : (
"Load from Steam"
)}
</Button> </Button>
</div> </div>
<Button <Button
@@ -82,10 +171,23 @@ export function Settings({
onPress={() => { onPress={() => {
setShow(false); setShow(false);
}} }}
isPending={loading}
> >
Cancel Cancel
</Button> </Button>
<Button type="submit">Save</Button> <Button
type="submit"
isPending={loading}
>
{loading ? (
<Spinner
color="current"
size="md"
/>
) : (
"Save"
)}
</Button>
</Fieldset.Actions> </Fieldset.Actions>
</Fieldset> </Fieldset>
</Form> </Form>

View File

@@ -20,6 +20,7 @@ type AuthContextType = {
loading: boolean; loading: boolean;
login: () => void; login: () => void;
logout: () => Promise<void>; logout: () => Promise<void>;
update: () => Promise<boolean>;
}; };
const AuthContext = createContext<AuthContextType>({ const AuthContext = createContext<AuthContextType>({
@@ -27,6 +28,9 @@ const AuthContext = createContext<AuthContextType>({
loading: false, loading: false,
login: () => {}, login: () => {},
logout: async () => {}, logout: async () => {},
update: async () => {
return false;
},
}); });
export function AuthProvider({ children }: PropsWithChildren) { export function AuthProvider({ children }: PropsWithChildren) {
@@ -70,24 +74,7 @@ export function AuthProvider({ children }: PropsWithChildren) {
}); });
} }
let data = await fetch(`${import.meta.env.VITE_BASE_API_URL}/me`, { if (await update()) {
credentials: "include",
})
.then((r) => r.json())
.catch((e) => {
notify(
{
type: "danger",
loading: false,
title: "An error occured.",
message: `An error occured: ${e}`,
},
10000,
);
});
if (data !== undefined) {
setUser(data);
notify( notify(
{ {
type: "success", type: "success",
@@ -98,7 +85,6 @@ export function AuthProvider({ children }: PropsWithChildren) {
2000, 2000,
); );
} }
setLoading(false); setLoading(false);
}; };
@@ -140,8 +126,32 @@ export function AuthProvider({ children }: PropsWithChildren) {
}); });
}; };
const update = async () => {
let data = await fetch(`${import.meta.env.VITE_BASE_API_URL}/me`, {
credentials: "include",
})
.then((r) => r.json())
.catch((e) => {
notify(
{
type: "danger",
loading: false,
title: "An error occured.",
message: `An error occured: ${e}`,
},
10000,
);
});
if (data !== undefined) {
setUser(data);
return true;
}
return false;
};
return ( return (
<AuthContext.Provider value={{ user, loading, login, logout }}> <AuthContext.Provider value={{ user, loading, login, logout, update }}>
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
); );