adds data access, login flow, navigation menu.
And some more stuff. :)
This commit is contained in:
@@ -4,6 +4,8 @@ import { useState } from "react";
|
|||||||
import { AuthProvider } from "react-oidc-context";
|
import { AuthProvider } from "react-oidc-context";
|
||||||
import { oidcConfig, userManager } from "muzak/config/auth";
|
import { oidcConfig, userManager } from "muzak/config/auth";
|
||||||
import { Source_Sans_3, Nunito } from "next/font/google";
|
import { Source_Sans_3, Nunito } from "next/font/google";
|
||||||
|
import AuthStatus from "muzak/components/AuthStatus";
|
||||||
|
import NavigationBar from "muzak/components/NavigationBar";
|
||||||
|
|
||||||
const sourceSans = Source_Sans_3({
|
const sourceSans = Source_Sans_3({
|
||||||
weight: ["400"],
|
weight: ["400"],
|
||||||
@@ -14,6 +16,16 @@ const nunito = Nunito({
|
|||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function LayoutContent({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AuthStatus />
|
||||||
|
{children}
|
||||||
|
<NavigationBar />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
@@ -28,7 +40,9 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="en" className={nunito.className}>
|
<html lang="en" className={nunito.className}>
|
||||||
<body className={`bg-game-show ${isAnimate ? "animate" : ""} h-screen`}>
|
<body className={`bg-game-show ${isAnimate ? "animate" : ""} h-screen`}>
|
||||||
<AuthProvider {...oidcConfig}>{children}</AuthProvider>
|
<AuthProvider {...oidcConfig}>
|
||||||
|
<LayoutContent>{children}</LayoutContent>
|
||||||
|
</AuthProvider>
|
||||||
<button
|
<button
|
||||||
className={`absolute top-1 left-1 ${isAnimate ? "pause" : "play"}`}
|
className={`absolute top-1 left-1 ${isAnimate ? "pause" : "play"}`}
|
||||||
onClick={toggleAnimation}
|
onClick={toggleAnimation}
|
||||||
|
|||||||
+18
-21
@@ -1,43 +1,40 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
import { Log } from "oidc-client-ts";
|
import { Log } from "oidc-client-ts";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
|
import { Nunito } from "next/font/google";
|
||||||
|
|
||||||
Log.setLogger(console);
|
Log.setLogger(console);
|
||||||
|
const nunito = Nunito({
|
||||||
|
weight: "900",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
console.log(auth);
|
console.log(auth);
|
||||||
|
|
||||||
switch (auth.activeNavigator) {
|
|
||||||
case "signinSilent":
|
|
||||||
return <div>Signing you in...</div>;
|
|
||||||
case "signoutRedirect":
|
|
||||||
return <div>Signing you out...</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth.isLoading) {
|
|
||||||
return <div>Loading...</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main
|
<main
|
||||||
className={`flex min-h-screen flex-col items-center justify-between p-24`}
|
className={`flex min-h-screen flex-col items-center justify-between p-24`}
|
||||||
>
|
>
|
||||||
{auth.error && <div>{auth.error.message}</div>}
|
|
||||||
{auth.isAuthenticated && (
|
|
||||||
<div>
|
<div>
|
||||||
<p>Hello {auth.user?.profile.name} </p>
|
<h1
|
||||||
</div>
|
className={`${nunito.className} text-outline text-[42px] tracking-tighter text-yellow-500`}
|
||||||
)}
|
>
|
||||||
{auth.isAuthenticated && (
|
Herzlich Willkommen bei Muzak!
|
||||||
<button onClick={() => void auth.removeUser()}>Log out</button>
|
</h1>
|
||||||
)}
|
{auth.isAuthenticated && <></>}
|
||||||
{!auth.isAuthenticated && (
|
{!auth.isAuthenticated && (
|
||||||
<button onClick={() => void auth.signinRedirect()}>Log in</button>
|
<h2
|
||||||
|
className={`${nunito.className} text-outline text-[32px] tracking-tighter text-yellow-500`}
|
||||||
|
>
|
||||||
|
Bitte authentificeren.
|
||||||
|
</h2>
|
||||||
)}
|
)}
|
||||||
<Image src={"/meowl.png"} width="460" height="460" alt="Meowl image" />
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
"use client";
|
||||||
|
import { useAuth } from "react-oidc-context";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { Source_Sans_3, Nunito } from "next/font/google";
|
||||||
|
|
||||||
|
const nunito = Nunito({
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function AuthStatus() {
|
||||||
|
const auth = useAuth();
|
||||||
|
const router = useRouter();
|
||||||
|
const [persistentAuthState, setPersistentAuthState] = useState<{
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
user: any;
|
||||||
|
hasInitialized: boolean;
|
||||||
|
}>({
|
||||||
|
isAuthenticated: false,
|
||||||
|
user: null,
|
||||||
|
hasInitialized: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Only update persistent state when we have a definitive auth state
|
||||||
|
if (!auth.isLoading && !auth.error) {
|
||||||
|
setPersistentAuthState({
|
||||||
|
isAuthenticated: auth.isAuthenticated,
|
||||||
|
user: auth.user,
|
||||||
|
hasInitialized: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [auth.isLoading, auth.isAuthenticated, auth.user, auth.error]);
|
||||||
|
|
||||||
|
// Show loading only on first load, not on subsequent navigations
|
||||||
|
if (!persistentAuthState.hasInitialized && auth.isLoading) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`${nunito.className} absolute top-4 right-4 rounded-lg bg-white/10 px-3 py-2 backdrop-blur-sm`}
|
||||||
|
>
|
||||||
|
<span className="text-sm">...</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayState = persistentAuthState.hasInitialized
|
||||||
|
? persistentAuthState
|
||||||
|
: { isAuthenticated: auth.isAuthenticated, user: auth.user };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`${nunito.className} absolute top-4 right-4 flex items-center gap-2 rounded-lg border-4 border-black bg-white/10 px-3 py-2`}
|
||||||
|
>
|
||||||
|
{displayState.isAuthenticated ? (
|
||||||
|
<>
|
||||||
|
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
||||||
|
<span className="text-sm font-medium">
|
||||||
|
{displayState.user?.profile.name || "Authenticated"}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
void auth.removeUser();
|
||||||
|
router.push("/");
|
||||||
|
}}
|
||||||
|
className="rounded bg-red-500/20 px-2 py-1 text-xs transition-colors hover:bg-red-500/30"
|
||||||
|
>
|
||||||
|
Uitloggen
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="h-2 w-2 rounded-full bg-red-500"></div>
|
||||||
|
<button
|
||||||
|
onClick={() => void auth.signinRedirect()}
|
||||||
|
className="rounded bg-blue-500/20 px-2 py-1 text-xs transition-colors hover:bg-blue-500/30"
|
||||||
|
>
|
||||||
|
Inloggen
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { useAuth } from "react-oidc-context";
|
||||||
|
import { Source_Sans_3, Nunito } from "next/font/google";
|
||||||
|
const source = Source_Sans_3({
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
const font = source.className;
|
||||||
|
|
||||||
|
export default function NavigationBar() {
|
||||||
|
const auth = useAuth();
|
||||||
|
if (!auth.isLoading && !auth.error && auth.isAuthenticated) {
|
||||||
|
return (
|
||||||
|
<nav className="absolute right-0 bottom-0 left-0 flex justify-center">
|
||||||
|
<div
|
||||||
|
className={`${font} flex flex-row items-center gap-6 rounded-tl-lg rounded-tr-lg border-4 border-b-0 border-black bg-sky-900 px-4 py-6 text-white`}
|
||||||
|
>
|
||||||
|
<Link href="/nominations">Nomineren</Link>
|
||||||
|
<Link href="/lobby">Start spel (test)</Link>
|
||||||
|
<Link href="/users">Users</Link>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
"paths": {
|
"paths": {
|
||||||
"muzak/config/*": ["./src/config/*"],
|
"muzak/config/*": ["./src/config/*"],
|
||||||
"muzak/data/*": ["./src/data/*"],
|
"muzak/data/*": ["./src/data/*"],
|
||||||
"muzak/app/*": ["./src/app/*"]
|
"muzak/app/*": ["./src/app/*"],
|
||||||
|
"muzak/components/*": ["./src/components/*"]
|
||||||
},
|
},
|
||||||
|
|
||||||
"allowJs": false,
|
"allowJs": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user