diff --git a/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx b/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx index bd01eef..b6dde62 100644 --- a/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx +++ b/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx @@ -1,4 +1,10 @@ -import { ActionFunctionArgs, json, redirect, LoaderFunctionArgs } from "@remix-run/node"; +import { + ActionFunctionArgs, + json, + redirect, + LoaderFunctionArgs, + MetaFunction, +} from "@remix-run/node"; import { type ApiError, ErrorCode, firstErrorFor } from "~/lib/api/error"; import serverRequest, { writeCookie } from "~/lib/request.server"; import { AuthResponse, CallbackResponse } from "~/lib/api/auth"; @@ -12,12 +18,18 @@ import { import { Trans, useTranslation } from "react-i18next"; import { Form, Button, Alert } from "react-bootstrap"; import ErrorAlert from "~/components/ErrorAlert"; +import i18n from "~/i18next.server"; + +export const meta: MetaFunction = ({ data }) => { + return [{ title: `${data?.meta.title || "Log in"} - pronouns.cc` }]; +}; export const shouldRevalidate: ShouldRevalidateFunction = ({ actionResult }) => { return !actionResult; }; export const loader = async ({ request }: LoaderFunctionArgs) => { + const t = await i18n.getFixedT(request); const url = new URL(request.url); const code = url.searchParams.get("code"); @@ -32,7 +44,13 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { if (resp.has_account) { return json( - { hasAccount: true, user: resp.user!, ticket: null, remoteUser: null }, + { + meta: { title: t("log-in.callback.title.discord-success") }, + hasAccount: true, + user: resp.user!, + ticket: null, + remoteUser: null, + }, { headers: { "Set-Cookie": writeCookie("pronounscc-token", resp.token!), @@ -42,6 +60,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { } return json({ + meta: { title: t("log-in.callback.title.discord-register") }, hasAccount: false, user: null, ticket: resp.ticket!, diff --git a/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx b/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx index adc4ce9..226b859 100644 --- a/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx +++ b/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx @@ -5,7 +5,12 @@ import { redirect, ActionFunctionArgs, } from "@remix-run/node"; -import { Form as RemixForm, useActionData, useLoaderData } from "@remix-run/react"; +import { + Form as RemixForm, + ShouldRevalidateFunction, + useActionData, + useLoaderData, +} from "@remix-run/react"; import { Form, Button, ButtonGroup, ListGroup, Row, Col } from "react-bootstrap"; import { useTranslation } from "react-i18next"; import i18n from "~/i18next.server"; @@ -19,6 +24,10 @@ export const meta: MetaFunction = ({ data }) => { return [{ title: `${data?.meta.title || "Log in"} - pronouns.cc` }]; }; +export const shouldRevalidate: ShouldRevalidateFunction = ({ actionResult }) => { + return !actionResult; +}; + export const loader = async ({ request }: LoaderFunctionArgs) => { const t = await i18n.getFixedT(request); const token = getToken(request); diff --git a/Foxnouns.Frontend/app/routes/auth.welcome/route.tsx b/Foxnouns.Frontend/app/routes/auth.welcome/route.tsx new file mode 100644 index 0000000..341da15 --- /dev/null +++ b/Foxnouns.Frontend/app/routes/auth.welcome/route.tsx @@ -0,0 +1,52 @@ +import { LoaderFunctionArgs, redirect, json, MetaFunction } from "@remix-run/node"; +import i18n from "~/i18next.server"; +import serverRequest, { getToken } from "~/lib/request.server"; +import { User } from "~/lib/api/user"; +import { useTranslation } from "react-i18next"; +import { Link, useLoaderData } from "@remix-run/react"; +import { Button } from "react-bootstrap"; + +export const meta: MetaFunction = ({ data }) => { + return [{ title: `${data?.meta.title || "Welcome"} - pronouns.cc` }]; +}; + +export const loader = async ({ request }: LoaderFunctionArgs) => { + const t = await i18n.getFixedT(request); + const token = getToken(request); + let user: User; + + if (token) { + try { + user = await serverRequest("GET", "/users/@me", { token }); + } catch (e) { + return redirect("/auth/log-in"); + } + } else { + return redirect("/auth/log-in"); + } + + return json({ meta: { title: t("welcome.title") }, user }); +}; + +export default function WelcomePage() { + const { t } = useTranslation(); + const { user } = useLoaderData(); + + return ( +
+

{t("welcome.header")}

+

{t("welcome.blurb")}

+

{t("welcome.customize-profile")}

+

{t("welcome.customize-profile-blurb")}

+

{t("welcome.create-members")}

+

{t("welcome.create-members-blurb")}

+

{t("welcome.custom-preferences")}

+

{t("welcome.custom-preferences-blurb")}

+ + + +
+ ); +} diff --git a/Foxnouns.Frontend/public/locales/en.json b/Foxnouns.Frontend/public/locales/en.json index f2dfbf2..d3c8d85 100644 --- a/Foxnouns.Frontend/public/locales/en.json +++ b/Foxnouns.Frontend/public/locales/en.json @@ -32,6 +32,10 @@ }, "log-in": { "callback": { + "title": { + "discord-success": "Log in with Discord", + "discord-register": "Register with Discord" + }, "success": "Successfully logged in!", "success-link": "Welcome back, <1>@{{username}}!", "redirect-hint": "If you're not redirected to your profile in a few seconds, press the link above.", @@ -58,5 +62,13 @@ "tumblr": "Log in with Tumblr" }, "invalid-credentials": "Invalid email address or password, please check your spelling and try again." + }, + "welcome": { + "title": "Welcome", + "header": "Welcome to pronouns.cc!", + "customize-profile": "Customize your profile", + "create-members": "Create members", + "custom-preferences": "Customize your preferences", + "profile-button": "Go to your profile" } } diff --git a/Foxnouns.Frontend/vite.config.ts b/Foxnouns.Frontend/vite.config.ts index e609580..a678fb6 100644 --- a/Foxnouns.Frontend/vite.config.ts +++ b/Foxnouns.Frontend/vite.config.ts @@ -20,5 +20,9 @@ export default defineConfig({ changeOrigin: true, }, }, + hmr: { + host: "localhost", + protocol: "ws", + }, }, });