better initial load
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import { createSignal, createEffect, Show, onMount } from "solid-js";
|
||||
import { useNavigate } from "@solidjs/router";
|
||||
import { useNavigate, cache, redirect } from "@solidjs/router";
|
||||
import { getEvent } from "vinxi/http";
|
||||
import Eye from "~/components/icons/Eye";
|
||||
import EyeSlash from "~/components/icons/EyeSlash";
|
||||
import { validatePassword, isValidEmail } from "~/lib/validation";
|
||||
import { checkAuthStatus } from "~/server/utils";
|
||||
|
||||
type UserProfile = {
|
||||
id: string;
|
||||
@@ -14,6 +16,22 @@ type UserProfile = {
|
||||
hasPassword: boolean;
|
||||
};
|
||||
|
||||
const checkAuth = cache(async () => {
|
||||
"use server";
|
||||
const event = getEvent()!;
|
||||
const { isAuthenticated } = await checkAuthStatus(event);
|
||||
|
||||
if (!isAuthenticated) {
|
||||
throw redirect("/login");
|
||||
}
|
||||
|
||||
return { isAuthenticated };
|
||||
}, "accountAuthCheck");
|
||||
|
||||
export const route = {
|
||||
load: () => checkAuth()
|
||||
};
|
||||
|
||||
export default function AccountPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -72,16 +90,10 @@ export default function AccountPage() {
|
||||
const result = await response.json();
|
||||
if (result.result?.data) {
|
||||
setUser(result.result.data);
|
||||
} else {
|
||||
// Not logged in, redirect to login
|
||||
navigate("/login");
|
||||
}
|
||||
} else {
|
||||
navigate("/login");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch user profile:", err);
|
||||
navigate("/login");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,33 @@ import { Typewriter } from "~/components/Typewriter";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Typewriter speed={100} keepAlive={2000}>
|
||||
<main class="text-subtext0 mx-auto p-4 text-center">
|
||||
{/* fill in a ipsum lorem */}
|
||||
ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
|
||||
ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
|
||||
</main>
|
||||
</Typewriter>
|
||||
<main class="p-4 text-xl">
|
||||
<Typewriter speed={30} keepAlive={2000}>
|
||||
<div class="text-4xl">Hey!</div>
|
||||
</Typewriter>
|
||||
|
||||
<Typewriter speed={80} keepAlive={2000}>
|
||||
<div>
|
||||
My name is <span class="text-green">Mike Freno</span>, I'm a{" "}
|
||||
<span class="text-blue">Software Engineer</span> based in{" "}
|
||||
<span class="text-yellow">Brooklyn, NY</span>
|
||||
</div>
|
||||
</Typewriter>
|
||||
<Typewriter speed={100}>
|
||||
I'm a passionate dev tooling and game developer, recently been working
|
||||
in the world of Love2D and you can see some of my work here: <a></a>
|
||||
I'm a huge lover of open source software, and
|
||||
</Typewriter>
|
||||
<Typewriter speed={50} keepAlive={false}>
|
||||
<div>My Collection of By-the-ways:</div>
|
||||
</Typewriter>
|
||||
<Typewriter speed={50} keepAlive={false}>
|
||||
<ul class="list-disc pl-8">
|
||||
<li>I use Neovim</li>
|
||||
<li>I use Arch Linux</li>
|
||||
<li>I use Rust</li>
|
||||
</ul>
|
||||
</Typewriter>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { createSignal, createEffect, onCleanup, Show } from "solid-js";
|
||||
import { A, useNavigate, useSearchParams } from "@solidjs/router";
|
||||
import {
|
||||
A,
|
||||
useNavigate,
|
||||
useSearchParams,
|
||||
cache,
|
||||
redirect
|
||||
} from "@solidjs/router";
|
||||
import { getEvent } from "vinxi/http";
|
||||
import GoogleLogo from "~/components/icons/GoogleLogo";
|
||||
import GitHub from "~/components/icons/GitHub";
|
||||
import Eye from "~/components/icons/Eye";
|
||||
@@ -7,6 +14,23 @@ import EyeSlash from "~/components/icons/EyeSlash";
|
||||
import CountdownCircleTimer from "~/components/CountdownCircleTimer";
|
||||
import { isValidEmail, validatePassword } from "~/lib/validation";
|
||||
import { getClientCookie } from "~/lib/cookies.client";
|
||||
import { checkAuthStatus } from "~/server/utils";
|
||||
|
||||
const checkAuth = cache(async () => {
|
||||
"use server";
|
||||
const event = getEvent()!;
|
||||
const { isAuthenticated } = await checkAuthStatus(event);
|
||||
|
||||
if (isAuthenticated) {
|
||||
throw redirect("/account");
|
||||
}
|
||||
|
||||
return { isAuthenticated };
|
||||
}, "loginAuthCheck");
|
||||
|
||||
export const route = {
|
||||
load: () => checkAuth()
|
||||
};
|
||||
|
||||
export default function LoginPage() {
|
||||
const navigate = useNavigate();
|
||||
@@ -64,7 +88,7 @@ export default function LoginPage() {
|
||||
if (timer) {
|
||||
timerInterval = setInterval(
|
||||
() => calcRemainder(timer),
|
||||
1000,
|
||||
1000
|
||||
) as unknown as number;
|
||||
onCleanup(() => {
|
||||
if (timerInterval) {
|
||||
@@ -84,7 +108,7 @@ export default function LoginPage() {
|
||||
server_error: "Server error - please try again later",
|
||||
missing_params: "Invalid login link - missing parameters",
|
||||
link_expired: "Login link has expired - please request a new one",
|
||||
access_denied: "Access denied - you cancelled the login",
|
||||
access_denied: "Access denied - you cancelled the login"
|
||||
};
|
||||
setError(errorMessages[errorParam] || "An error occurred during login");
|
||||
}
|
||||
@@ -138,8 +162,8 @@ export default function LoginPage() {
|
||||
body: JSON.stringify({
|
||||
email,
|
||||
password,
|
||||
passwordConfirmation: passwordConf,
|
||||
}),
|
||||
passwordConfirmation: passwordConf
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
@@ -175,7 +199,7 @@ export default function LoginPage() {
|
||||
const response = await fetch("/api/trpc/auth.emailPasswordLogin", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ email, password, rememberMe }),
|
||||
body: JSON.stringify({ email, password, rememberMe })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
@@ -209,7 +233,7 @@ export default function LoginPage() {
|
||||
const response = await fetch("/api/trpc/auth.requestEmailLinkLogin", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ email, rememberMe }),
|
||||
body: JSON.stringify({ email, rememberMe })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
@@ -223,7 +247,7 @@ export default function LoginPage() {
|
||||
}
|
||||
timerInterval = setInterval(
|
||||
() => calcRemainder(timer),
|
||||
1000,
|
||||
1000
|
||||
) as unknown as number;
|
||||
}
|
||||
} else {
|
||||
@@ -310,7 +334,7 @@ export default function LoginPage() {
|
||||
{/* Main content */}
|
||||
<div class="pt-24 md:pt-48">
|
||||
{/* Error message */}
|
||||
<div class="absolute -mt-12 text-center text-3xl italic text-red-400">
|
||||
<div class="absolute -mt-12 text-center text-3xl text-red-400 italic">
|
||||
<Show when={error() === "passwordMismatch"}>
|
||||
Passwords did not match!
|
||||
</Show>
|
||||
@@ -333,7 +357,7 @@ export default function LoginPage() {
|
||||
setRegister(false);
|
||||
setUsePassword(false);
|
||||
}}
|
||||
class="pl-1 text-blue underline hover:brightness-125"
|
||||
class="text-blue pl-1 underline hover:brightness-125"
|
||||
>
|
||||
Click here to Login
|
||||
</button>
|
||||
@@ -347,7 +371,7 @@ export default function LoginPage() {
|
||||
setRegister(true);
|
||||
setUsePassword(false);
|
||||
}}
|
||||
class="pl-1 text-blue underline hover:brightness-125"
|
||||
class="text-blue pl-1 underline hover:brightness-125"
|
||||
>
|
||||
Click here to Register
|
||||
</button>
|
||||
@@ -393,7 +417,7 @@ export default function LoginPage() {
|
||||
setShowPasswordInput(!showPasswordInput());
|
||||
passwordRef?.focus();
|
||||
}}
|
||||
class="absolute ml-60 mt-14"
|
||||
class="absolute mt-14 ml-60"
|
||||
type="button"
|
||||
>
|
||||
<Show
|
||||
@@ -418,7 +442,7 @@ export default function LoginPage() {
|
||||
</div>
|
||||
<div
|
||||
class={`${
|
||||
showPasswordLengthWarning() ? "" : "select-none opacity-0"
|
||||
showPasswordLengthWarning() ? "" : "opacity-0 select-none"
|
||||
} text-center text-red-500 transition-opacity duration-200 ease-in-out`}
|
||||
>
|
||||
Password too short! Min Length: 8
|
||||
@@ -446,7 +470,7 @@ export default function LoginPage() {
|
||||
setShowPasswordConfInput(!showPasswordConfInput());
|
||||
passwordConfRef?.focus();
|
||||
}}
|
||||
class="absolute ml-60 mt-14"
|
||||
class="absolute mt-14 ml-60"
|
||||
type="button"
|
||||
>
|
||||
<Show
|
||||
@@ -476,7 +500,7 @@ export default function LoginPage() {
|
||||
passwordConfRef &&
|
||||
passwordConfRef.value.length >= 6
|
||||
? ""
|
||||
: "select-none opacity-0"
|
||||
: "opacity-0 select-none"
|
||||
} text-center text-red-500 transition-opacity duration-200 ease-in-out`}
|
||||
>
|
||||
Passwords do not match!
|
||||
@@ -495,8 +519,8 @@ export default function LoginPage() {
|
||||
showPasswordError()
|
||||
? "text-red-500"
|
||||
: showPasswordSuccess()
|
||||
? "text-green-500"
|
||||
: "select-none opacity-0"
|
||||
? "text-green-500"
|
||||
: "opacity-0 select-none"
|
||||
} flex min-h-[16px] justify-center italic transition-opacity duration-300 ease-in-out`}
|
||||
>
|
||||
<Show when={showPasswordError()}>
|
||||
@@ -519,13 +543,13 @@ export default function LoginPage() {
|
||||
loading()
|
||||
? "bg-zinc-400"
|
||||
: "bg-blue hover:brightness-125 active:scale-90"
|
||||
} flex w-36 justify-center rounded py-3 text-white transition-all duration-300 ease-out`}
|
||||
} flex w-36 justify-center rounded py-3 text-white transition-all duration-300 ease-out`}
|
||||
>
|
||||
{register()
|
||||
? "Sign Up"
|
||||
: usePassword()
|
||||
? "Sign In"
|
||||
: "Get Link"}
|
||||
? "Sign In"
|
||||
: "Get Link"}
|
||||
</button>
|
||||
}
|
||||
>
|
||||
@@ -579,7 +603,7 @@ export default function LoginPage() {
|
||||
<div
|
||||
class={`${
|
||||
emailSent() ? "" : "user-select opacity-0"
|
||||
} flex min-h-4 justify-center text-center italic text-green transition-opacity duration-300 ease-in-out`}
|
||||
} text-green flex min-h-4 justify-center text-center italic transition-opacity duration-300 ease-in-out`}
|
||||
>
|
||||
<Show when={emailSent()}>Email Sent!</Show>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user