Moved login and primitive error popups to auth hook
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import type { PropsWithChildren } from "react";
|
import type { PropsWithChildren } from "react";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { useAuth } from "~/hooks/auth";
|
import { useAuth } from "~/hooks/auth";
|
||||||
import { Button, Modal, Spinner } from "@heroui/react";
|
import { useEffect, useState } from "react";
|
||||||
|
import { Button, Modal, Spinner, Alert } from "@heroui/react";
|
||||||
|
|
||||||
export default function Guard({ children }: PropsWithChildren) {
|
export default function Guard({ children }: PropsWithChildren) {
|
||||||
const { user, loading, login, logout } = useAuth();
|
const { user, loading, login, logout } = useAuth();
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export default function User() {
|
|||||||
return (
|
return (
|
||||||
<Button isPending={true}>
|
<Button isPending={true}>
|
||||||
<Spinner color="current" size="md" />
|
<Spinner color="current" size="md" />
|
||||||
Loading...
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Alert, Spinner } from "@heroui/react";
|
||||||
import {
|
import {
|
||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
@@ -32,10 +33,30 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
|||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [searchParams, setSeachParams] = useSearchParams();
|
const [searchParams, setSeachParams] = useSearchParams();
|
||||||
|
const [popupShowed, setPopupShowed] = useState(false);
|
||||||
|
const [error, setError] = useState("");
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user !== null && !loading) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setPopupShowed(true);
|
||||||
|
}, 2000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
} else if (error !== "") {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setPopupShowed(true);
|
||||||
|
}, 10000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setPopupShowed(false);
|
||||||
|
}
|
||||||
|
}, [user, loading, error]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
|
try {
|
||||||
if (searchParams.get("openid.ns") !== null) {
|
if (searchParams.get("openid.ns") !== null) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
let query = searchParams.toString();
|
let query = searchParams.toString();
|
||||||
@@ -45,7 +66,7 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
|||||||
{ credentials: "include" },
|
{ credentials: "include" },
|
||||||
).then((r) => r.text());
|
).then((r) => r.text());
|
||||||
if (response === "nok") {
|
if (response === "nok") {
|
||||||
// TODO: signal error to user
|
setError("An error occured during the information exchange between Steam and Porning.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,9 +74,15 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
|||||||
credentials: "include",
|
credentials: "include",
|
||||||
}).then((r) => r.json());
|
}).then((r) => r.json());
|
||||||
|
|
||||||
console.log(data);
|
if (data === null) {
|
||||||
|
setError("An error occured while trying to fetch your user profile. Please contact an administrator.")
|
||||||
|
}
|
||||||
|
|
||||||
setUser(data);
|
setUser(data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
} catch (_) {
|
||||||
|
setError("An error occured while communicating with the server.")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
load();
|
load();
|
||||||
@@ -75,6 +102,53 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthContext.Provider value={{ user, loading, login, logout }}>
|
<AuthContext.Provider value={{ user, loading, login, logout }}>
|
||||||
|
{loading ? (
|
||||||
|
<div className="flex justify-center fixed top-12 w-dvw z-50">
|
||||||
|
<Alert
|
||||||
|
className="w-fit h-fit border border-white"
|
||||||
|
status="accent"
|
||||||
|
>
|
||||||
|
<Alert.Indicator>
|
||||||
|
<Spinner size="sm" />
|
||||||
|
</Alert.Indicator>
|
||||||
|
<Alert.Content>
|
||||||
|
<Alert.Title>Logging in...</Alert.Title>
|
||||||
|
<Alert.Description>
|
||||||
|
Please wait while we log you in and sync your
|
||||||
|
data. This may take a few moments.
|
||||||
|
</Alert.Description>
|
||||||
|
</Alert.Content>
|
||||||
|
</Alert>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
(!popupShowed &&
|
||||||
|
user !== null && (
|
||||||
|
<div className="flex justify-center fixed top-12 w-dvw z-50">
|
||||||
|
<Alert
|
||||||
|
className="w-fit h-fit border border-white"
|
||||||
|
status="success"
|
||||||
|
>
|
||||||
|
<Alert.Indicator />
|
||||||
|
<Alert.Content>
|
||||||
|
<Alert.Title>Login sucessful!</Alert.Title>
|
||||||
|
</Alert.Content>
|
||||||
|
</Alert>
|
||||||
|
</div>
|
||||||
|
)) || (!popupShowed && error !== "" && (
|
||||||
|
<div className="flex justify-center fixed top-12 w-dvw z-50">
|
||||||
|
<Alert
|
||||||
|
className="w-fit h-fit border border-white"
|
||||||
|
status="danger"
|
||||||
|
>
|
||||||
|
<Alert.Indicator />
|
||||||
|
<Alert.Content>
|
||||||
|
<Alert.Title>An error occured.</Alert.Title>
|
||||||
|
<Alert.Description>{error}</Alert.Description>
|
||||||
|
</Alert.Content>
|
||||||
|
</Alert>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
{children}
|
{children}
|
||||||
</AuthContext.Provider>
|
</AuthContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user