diff options
Diffstat (limited to 'frontend/app/routes')
| -rw-r--r-- | frontend/app/routes/_index.tsx | 36 | ||||
| -rw-r--r-- | frontend/app/routes/admin.dashboard.tsx | 38 | ||||
| -rw-r--r-- | frontend/app/routes/admin.games.tsx | 52 | ||||
| -rw-r--r-- | frontend/app/routes/admin.games_.$gameId.tsx | 172 | ||||
| -rw-r--r-- | frontend/app/routes/admin.users.tsx | 50 | ||||
| -rw-r--r-- | frontend/app/routes/dashboard.tsx | 122 | ||||
| -rw-r--r-- | frontend/app/routes/golf.$gameId.play.tsx | 54 | ||||
| -rw-r--r-- | frontend/app/routes/golf.$gameId.watch.tsx | 54 | ||||
| -rw-r--r-- | frontend/app/routes/login.tsx | 116 | ||||
| -rw-r--r-- | frontend/app/routes/logout.tsx | 4 |
10 files changed, 349 insertions, 349 deletions
diff --git a/frontend/app/routes/_index.tsx b/frontend/app/routes/_index.tsx index b5951ab..c56d4b2 100644 --- a/frontend/app/routes/_index.tsx +++ b/frontend/app/routes/_index.tsx @@ -2,25 +2,25 @@ import type { MetaFunction } from "@remix-run/node"; import { Link } from "@remix-run/react"; export const meta: MetaFunction = () => { - return [{ title: "iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "iOSDC Japan 2024 Albatross.swift" }]; }; export default function Index() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-blue-600 mb-4"> - iOSDC Japan 2024 Albatross.swift - </h1> - <p> - <Link - to="/login" - className="text-lg text-white bg-blue-500 px-4 py-2 rounded hover:bg-blue-600 transition duration-300" - > - Login - </Link> - </p> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-blue-600 mb-4"> + iOSDC Japan 2024 Albatross.swift + </h1> + <p> + <Link + to="/login" + className="text-lg text-white bg-blue-500 px-4 py-2 rounded hover:bg-blue-600 transition duration-300" + > + Login + </Link> + </p> + </div> + </div> + ); } diff --git a/frontend/app/routes/admin.dashboard.tsx b/frontend/app/routes/admin.dashboard.tsx index 1d172af..ce3e910 100644 --- a/frontend/app/routes/admin.dashboard.tsx +++ b/frontend/app/routes/admin.dashboard.tsx @@ -3,29 +3,29 @@ import { Link } from "@remix-run/react"; import { isAuthenticated } from "../.server/auth"; export const meta: MetaFunction = () => { - return [{ title: "[Admin] Dashboard | iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "[Admin] Dashboard | iOSDC Japan 2024 Albatross.swift" }]; }; export async function loader({ request }: LoaderFunctionArgs) { - const { user } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (!user.is_admin) { - throw new Error("Unauthorized"); - } - return null; + const { user } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (!user.is_admin) { + throw new Error("Unauthorized"); + } + return null; } export default function AdminDashboard() { - return ( - <div> - <h1>[Admin] Dashboard</h1> - <p> - <Link to="/admin/users">Users</Link> - </p> - <p> - <Link to="/admin/games">Games</Link> - </p> - </div> - ); + return ( + <div> + <h1>[Admin] Dashboard</h1> + <p> + <Link to="/admin/users">Users</Link> + </p> + <p> + <Link to="/admin/games">Games</Link> + </p> + </div> + ); } diff --git a/frontend/app/routes/admin.games.tsx b/frontend/app/routes/admin.games.tsx index adba7f5..af3554e 100644 --- a/frontend/app/routes/admin.games.tsx +++ b/frontend/app/routes/admin.games.tsx @@ -4,37 +4,37 @@ import { adminApiGetGames } from "../.server/api/client"; import { isAuthenticated } from "../.server/auth"; export const meta: MetaFunction = () => { - return [{ title: "[Admin] Games | iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "[Admin] Games | iOSDC Japan 2024 Albatross.swift" }]; }; export async function loader({ request }: LoaderFunctionArgs) { - const { user, token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (!user.is_admin) { - throw new Error("Unauthorized"); - } - const { games } = await adminApiGetGames(token); - return { games }; + const { user, token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (!user.is_admin) { + throw new Error("Unauthorized"); + } + const { games } = await adminApiGetGames(token); + return { games }; } export default function AdminGames() { - const { games } = useLoaderData<typeof loader>()!; + const { games } = useLoaderData<typeof loader>()!; - return ( - <div> - <div> - <h1>[Admin] Games</h1> - <ul> - {games.map((game) => ( - <li key={game.game_id}> - <Link to={`/admin/games/${game.game_id}`}> - {game.display_name} (id={game.game_id}) - </Link> - </li> - ))} - </ul> - </div> - </div> - ); + return ( + <div> + <div> + <h1>[Admin] Games</h1> + <ul> + {games.map((game) => ( + <li key={game.game_id}> + <Link to={`/admin/games/${game.game_id}`}> + {game.display_name} (id={game.game_id}) + </Link> + </li> + ))} + </ul> + </div> + </div> + ); } diff --git a/frontend/app/routes/admin.games_.$gameId.tsx b/frontend/app/routes/admin.games_.$gameId.tsx index a7bd651..34860ab 100644 --- a/frontend/app/routes/admin.games_.$gameId.tsx +++ b/frontend/app/routes/admin.games_.$gameId.tsx @@ -1,107 +1,107 @@ import type { - ActionFunctionArgs, - LoaderFunctionArgs, - MetaFunction, + ActionFunctionArgs, + LoaderFunctionArgs, + MetaFunction, } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { adminApiGetGame, adminApiPutGame } from "../.server/api/client"; import { isAuthenticated } from "../.server/auth"; export const meta: MetaFunction<typeof loader> = ({ data }) => { - return [ - { - title: data - ? `[Admin] Game Edit ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` - : "[Admin] Game Edit | iOSDC Japan 2024 Albatross.swift", - }, - ]; + return [ + { + title: data + ? `[Admin] Game Edit ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` + : "[Admin] Game Edit | iOSDC Japan 2024 Albatross.swift", + }, + ]; }; export async function loader({ request, params }: LoaderFunctionArgs) { - const { user, token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (!user.is_admin) { - throw new Error("Unauthorized"); - } - const { gameId } = params; - const { game } = await adminApiGetGame(token, Number(gameId)); - return { game }; + const { user, token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (!user.is_admin) { + throw new Error("Unauthorized"); + } + const { gameId } = params; + const { game } = await adminApiGetGame(token, Number(gameId)); + return { game }; } export async function action({ request, params }: ActionFunctionArgs) { - const { user, token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (!user.is_admin) { - throw new Error("Unauthorized"); - } - const { gameId } = params; + const { user, token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (!user.is_admin) { + throw new Error("Unauthorized"); + } + const { gameId } = params; - const formData = await request.formData(); - const action = formData.get("action"); + const formData = await request.formData(); + const action = formData.get("action"); - const nextState = - action === "open" - ? "waiting_entries" - : action === "start" - ? "prepare" - : null; - if (!nextState) { - throw new Error("Invalid action"); - } + const nextState = + action === "open" + ? "waiting_entries" + : action === "start" + ? "prepare" + : null; + if (!nextState) { + throw new Error("Invalid action"); + } - await adminApiPutGame(token, Number(gameId), { - state: nextState, - }); - return null; + await adminApiPutGame(token, Number(gameId), { + state: nextState, + }); + return null; } export default function AdminGameEdit() { - const { game } = useLoaderData<typeof loader>()!; + const { game } = useLoaderData<typeof loader>()!; - return ( - <div> - <div> - <h1>[Admin] Game Edit {game.display_name}</h1> - <ul> - <li>ID: {game.game_id}</li> - <li>State: {game.state}</li> - <li>Display Name: {game.display_name}</li> - <li>Duration Seconds: {game.duration_seconds}</li> - <li> - Started At:{" "} - {game.started_at - ? new Date(game.started_at * 1000).toString() - : "-"} - </li> - <li>Problem ID: {game.problem ? game.problem.problem_id : "-"}</li> - </ul> - <div> - <Form method="post"> - <div> - <button - type="submit" - name="action" - value="open" - disabled={game.state !== "closed"} - > - Open - </button> - </div> - <div> - <button - type="submit" - name="action" - value="start" - disabled={game.state !== "waiting_start"} - > - Start - </button> - </div> - </Form> - </div> - </div> - </div> - ); + return ( + <div> + <div> + <h1>[Admin] Game Edit {game.display_name}</h1> + <ul> + <li>ID: {game.game_id}</li> + <li>State: {game.state}</li> + <li>Display Name: {game.display_name}</li> + <li>Duration Seconds: {game.duration_seconds}</li> + <li> + Started At:{" "} + {game.started_at + ? new Date(game.started_at * 1000).toString() + : "-"} + </li> + <li>Problem ID: {game.problem ? game.problem.problem_id : "-"}</li> + </ul> + <div> + <Form method="post"> + <div> + <button + type="submit" + name="action" + value="open" + disabled={game.state !== "closed"} + > + Open + </button> + </div> + <div> + <button + type="submit" + name="action" + value="start" + disabled={game.state !== "waiting_start"} + > + Start + </button> + </div> + </Form> + </div> + </div> + </div> + ); } diff --git a/frontend/app/routes/admin.users.tsx b/frontend/app/routes/admin.users.tsx index 8d9a8f2..9eed263 100644 --- a/frontend/app/routes/admin.users.tsx +++ b/frontend/app/routes/admin.users.tsx @@ -4,36 +4,36 @@ import { adminApiGetUsers } from "../.server/api/client"; import { isAuthenticated } from "../.server/auth"; export const meta: MetaFunction = () => { - return [{ title: "[Admin] Users | iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "[Admin] Users | iOSDC Japan 2024 Albatross.swift" }]; }; export async function loader({ request }: LoaderFunctionArgs) { - const { user, token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (!user.is_admin) { - throw new Error("Unauthorized"); - } - const { users } = await adminApiGetUsers(token); - return { users }; + const { user, token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (!user.is_admin) { + throw new Error("Unauthorized"); + } + const { users } = await adminApiGetUsers(token); + return { users }; } export default function AdminUsers() { - const { users } = useLoaderData<typeof loader>()!; + const { users } = useLoaderData<typeof loader>()!; - return ( - <div> - <div> - <h1>[Admin] Users</h1> - <ul> - {users.map((user) => ( - <li key={user.user_id}> - {user.display_name} (id={user.user_id} username={user.username}) - {user.is_admin && <span> admin</span>} - </li> - ))} - </ul> - </div> - </div> - ); + return ( + <div> + <div> + <h1>[Admin] Users</h1> + <ul> + {users.map((user) => ( + <li key={user.user_id}> + {user.display_name} (id={user.user_id} username={user.username}) + {user.is_admin && <span> admin</span>} + </li> + ))} + </ul> + </div> + </div> + ); } diff --git a/frontend/app/routes/dashboard.tsx b/frontend/app/routes/dashboard.tsx index 1f80634..1c2137d 100644 --- a/frontend/app/routes/dashboard.tsx +++ b/frontend/app/routes/dashboard.tsx @@ -5,72 +5,72 @@ import { apiGetGames } from "../.server/api/client"; import { isAuthenticated } from "../.server/auth"; export const meta: MetaFunction = () => { - return [{ title: "Dashboard | iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "Dashboard | iOSDC Japan 2024 Albatross.swift" }]; }; export async function loader({ request }: LoaderFunctionArgs) { - const { user, token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); - if (user.is_admin) { - return redirect("/admin/dashboard"); - } - const { games } = await apiGetGames(token); - return { - user, - games, - }; + const { user, token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); + if (user.is_admin) { + return redirect("/admin/dashboard"); + } + const { games } = await apiGetGames(token); + return { + user, + games, + }; } export default function Dashboard() { - const { user, games } = useLoaderData<typeof loader>()!; + const { user, games } = useLoaderData<typeof loader>()!; - return ( - <div className="min-h-screen p-8"> - <div className="p-6 rounded shadow-md max-w-4xl mx-auto"> - <h1 className="text-3xl font-bold mb-4"> - {user.username}{" "} - {user.is_admin && <span className="text-red-500 text-lg">admin</span>} - </h1> - <h2 className="text-2xl font-semibold mb-2">User</h2> - <div className="mb-6"> - <ul className="list-disc list-inside"> - <li>Name: {user.display_name}</li> - </ul> - </div> - <h2 className="text-2xl font-semibold mb-2">Games</h2> - <div> - <ul className="list-disc list-inside"> - {games.map((game) => ( - <li key={game.game_id}> - {game.display_name}{" "} - {game.state === "closed" || game.state === "finished" ? ( - <span className="inline-block px-6 py-2 text-gray-400 bg-gray-200 cursor-not-allowed rounded"> - Entry - </span> - ) : ( - <Link - to={`/golf/${game.game_id}/play`} - className="inline-block px-6 py-2 text-white bg-blue-500 hover:bg-blue-700 rounded" - > - Entry - </Link> - )} - </li> - ))} - </ul> - </div> - <div> - <Form method="post" action="/logout"> - <button - className="mt-6 px-6 py-2 text-white bg-red-500 hover:bg-red-700 rounded" - type="submit" - > - Logout - </button> - </Form> - </div> - </div> - </div> - ); + return ( + <div className="min-h-screen p-8"> + <div className="p-6 rounded shadow-md max-w-4xl mx-auto"> + <h1 className="text-3xl font-bold mb-4"> + {user.username}{" "} + {user.is_admin && <span className="text-red-500 text-lg">admin</span>} + </h1> + <h2 className="text-2xl font-semibold mb-2">User</h2> + <div className="mb-6"> + <ul className="list-disc list-inside"> + <li>Name: {user.display_name}</li> + </ul> + </div> + <h2 className="text-2xl font-semibold mb-2">Games</h2> + <div> + <ul className="list-disc list-inside"> + {games.map((game) => ( + <li key={game.game_id}> + {game.display_name}{" "} + {game.state === "closed" || game.state === "finished" ? ( + <span className="inline-block px-6 py-2 text-gray-400 bg-gray-200 cursor-not-allowed rounded"> + Entry + </span> + ) : ( + <Link + to={`/golf/${game.game_id}/play`} + className="inline-block px-6 py-2 text-white bg-blue-500 hover:bg-blue-700 rounded" + > + Entry + </Link> + )} + </li> + ))} + </ul> + </div> + <div> + <Form method="post" action="/logout"> + <button + className="mt-6 px-6 py-2 text-white bg-red-500 hover:bg-red-700 rounded" + type="submit" + > + Logout + </button> + </Form> + </div> + </div> + </div> + ); } diff --git a/frontend/app/routes/golf.$gameId.play.tsx b/frontend/app/routes/golf.$gameId.play.tsx index 0ce3353..d498200 100644 --- a/frontend/app/routes/golf.$gameId.play.tsx +++ b/frontend/app/routes/golf.$gameId.play.tsx @@ -7,40 +7,40 @@ import GolfPlayApp from "../components/GolfPlayApp.client"; import GolfPlayAppConnecting from "../components/GolfPlayApps/GolfPlayAppConnecting"; export const meta: MetaFunction<typeof loader> = ({ data }) => { - return [ - { - title: data - ? `Golf Playing ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` - : "Golf Playing | iOSDC Japan 2024 Albatross.swift", - }, - ]; + return [ + { + title: data + ? `Golf Playing ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` + : "Golf Playing | iOSDC Japan 2024 Albatross.swift", + }, + ]; }; export async function loader({ params, request }: LoaderFunctionArgs) { - const { token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); + const { token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); - const fetchGame = async () => { - return (await apiGetGame(token, Number(params.gameId))).game; - }; - const fetchSockToken = async () => { - return (await apiGetToken(token)).token; - }; + const fetchGame = async () => { + return (await apiGetGame(token, Number(params.gameId))).game; + }; + const fetchSockToken = async () => { + return (await apiGetToken(token)).token; + }; - const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]); - return { - game, - sockToken, - }; + const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]); + return { + game, + sockToken, + }; } export default function GolfPlay() { - const { game, sockToken } = useLoaderData<typeof loader>(); + const { game, sockToken } = useLoaderData<typeof loader>(); - return ( - <ClientOnly fallback={<GolfPlayAppConnecting />}> - {() => <GolfPlayApp game={game} sockToken={sockToken} />} - </ClientOnly> - ); + return ( + <ClientOnly fallback={<GolfPlayAppConnecting />}> + {() => <GolfPlayApp game={game} sockToken={sockToken} />} + </ClientOnly> + ); } diff --git a/frontend/app/routes/golf.$gameId.watch.tsx b/frontend/app/routes/golf.$gameId.watch.tsx index 0f0e085..0203e27 100644 --- a/frontend/app/routes/golf.$gameId.watch.tsx +++ b/frontend/app/routes/golf.$gameId.watch.tsx @@ -7,40 +7,40 @@ import GolfWatchApp from "../components/GolfWatchApp.client"; import GolfWatchAppConnecting from "../components/GolfWatchApps/GolfWatchAppConnecting"; export const meta: MetaFunction<typeof loader> = ({ data }) => { - return [ - { - title: data - ? `Golf Watching ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` - : "Golf Watching | iOSDC Japan 2024 Albatross.swift", - }, - ]; + return [ + { + title: data + ? `Golf Watching ${data.game.display_name} | iOSDC Japan 2024 Albatross.swift` + : "Golf Watching | iOSDC Japan 2024 Albatross.swift", + }, + ]; }; export async function loader({ params, request }: LoaderFunctionArgs) { - const { token } = await isAuthenticated(request, { - failureRedirect: "/login", - }); + const { token } = await isAuthenticated(request, { + failureRedirect: "/login", + }); - const fetchGame = async () => { - return (await apiGetGame(token, Number(params.gameId))).game; - }; - const fetchSockToken = async () => { - return (await apiGetToken(token)).token; - }; + const fetchGame = async () => { + return (await apiGetGame(token, Number(params.gameId))).game; + }; + const fetchSockToken = async () => { + return (await apiGetToken(token)).token; + }; - const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]); - return { - game, - sockToken, - }; + const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]); + return { + game, + sockToken, + }; } export default function GolfWatch() { - const { game, sockToken } = useLoaderData<typeof loader>(); + const { game, sockToken } = useLoaderData<typeof loader>(); - return ( - <ClientOnly fallback={<GolfWatchAppConnecting />}> - {() => <GolfWatchApp game={game} sockToken={sockToken} />} - </ClientOnly> - ); + return ( + <ClientOnly fallback={<GolfWatchAppConnecting />}> + {() => <GolfWatchApp game={game} sockToken={sockToken} />} + </ClientOnly> + ); } diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index f63df08..95effaa 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -1,74 +1,74 @@ import type { - ActionFunctionArgs, - LoaderFunctionArgs, - MetaFunction, + ActionFunctionArgs, + LoaderFunctionArgs, + MetaFunction, } from "@remix-run/node"; import { Form } from "@remix-run/react"; import { authenticator } from "../.server/auth"; export const meta: MetaFunction = () => { - return [{ title: "Login | iOSDC Japan 2024 Albatross.swift" }]; + return [{ title: "Login | iOSDC Japan 2024 Albatross.swift" }]; }; export async function loader({ request }: LoaderFunctionArgs) { - return await authenticator.isAuthenticated(request, { - successRedirect: "/dashboard", - }); + return await authenticator.isAuthenticated(request, { + successRedirect: "/dashboard", + }); } export async function action({ request }: ActionFunctionArgs) { - return await authenticator.authenticate("default", request, { - successRedirect: "/dashboard", - failureRedirect: "/login", - }); + return await authenticator.authenticate("default", request, { + successRedirect: "/dashboard", + failureRedirect: "/login", + }); } export default function Login() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <Form - method="post" - className="bg-white p-8 rounded shadow-md w-full max-w-sm" - > - <h2 className="text-2xl font-bold mb-6 text-center">Login</h2> - <div className="mb-4"> - <label - htmlFor="username" - className="block text-sm font-medium text-gray-700" - > - Username - </label> - <input - type="text" - name="username" - id="username" - required - className="mt-1 p-2 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" - /> - </div> - <div className="mb-6"> - <label - htmlFor="password" - className="block text-sm font-medium text-gray-700" - > - Password - </label> - <input - type="password" - name="password" - id="password" - autoComplete="current-password" - required - className="mt-1 p-2 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" - /> - </div> - <button - type="submit" - className="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600 transition duration-300" - > - Log In - </button> - </Form> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <Form + method="post" + className="bg-white p-8 rounded shadow-md w-full max-w-sm" + > + <h2 className="text-2xl font-bold mb-6 text-center">Login</h2> + <div className="mb-4"> + <label + htmlFor="username" + className="block text-sm font-medium text-gray-700" + > + Username + </label> + <input + type="text" + name="username" + id="username" + required + className="mt-1 p-2 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" + /> + </div> + <div className="mb-6"> + <label + htmlFor="password" + className="block text-sm font-medium text-gray-700" + > + Password + </label> + <input + type="password" + name="password" + id="password" + autoComplete="current-password" + required + className="mt-1 p-2 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" + /> + </div> + <button + type="submit" + className="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600 transition duration-300" + > + Log In + </button> + </Form> + </div> + ); } diff --git a/frontend/app/routes/logout.tsx b/frontend/app/routes/logout.tsx index 030bde0..012d9e9 100644 --- a/frontend/app/routes/logout.tsx +++ b/frontend/app/routes/logout.tsx @@ -2,6 +2,6 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { authenticator } from "../.server/auth"; export async function action({ request }: ActionFunctionArgs) { - await authenticator.logout(request, { redirectTo: "/" }); - return null; + await authenticator.logout(request, { redirectTo: "/" }); + return null; } |
