Use of client-side <A> instead of navigator

This commit is contained in:
aronmal 2023-09-08 10:17:45 +02:00
parent 1e7b46ff69
commit 4390269ed1
Signed by: aronmal
GPG key ID: 816B7707426FC612
5 changed files with 129 additions and 123 deletions

View file

@ -1,7 +1,9 @@
import classNames from "classnames"
import { A } from "solid-start"
function Logo(props: { small?: boolean }) {
return (
<A href="/">
<div class="relative flex flex-col items-center rounded-sm border-x-4 border-y-2 border-shield-gray bg-shield-lightgray md:border-x-8 md:border-y-4">
<h1
class={classNames(
@ -14,6 +16,7 @@ function Logo(props: { small?: boolean }) {
</h1>
<Screws small={props.small} />
</div>
</A>
)
}

View file

@ -1,49 +1,69 @@
import { IconDefinition } from "@fortawesome/fontawesome-svg-core"
import classNames from "classnames"
import { JSX, Show } from "solid-js"
import { JSX } from "solid-js"
import { A } from "solid-start"
import { FontAwesomeIcon } from "./FontAwesomeIcon"
const styles = {
wrapper:
"flex w-full flex-row items-center justify-between rounded-xl py-2 pl-8 pr-4 text-lg text-grayish duration-100 first:mt-4 last:mt-4 sm:py-4 sm:pl-16 sm:pr-8 sm:text-4xl sm:first:mt-8 sm:last:mt-8",
disabled:
"flex w-full flex-row items-center justify-between rounded-lg py-2 pl-8 pr-4 text-lg text-grayish duration-100 first:mt-4 last:mt-4 sm:rounded-xl sm:py-4 sm:pl-16 sm:pr-8 sm:text-4xl sm:first:mt-8 sm:last:mt-8",
enabled:
"border-b-4 border-shield-gray bg-voidDark active:border-b-0 active:border-t-4",
enabled: "border-4 border-dashed border-slate-600 bg-red-950",
disabled: "border-4 border-dashed border-slate-600 bg-red-950",
icon: "ml-2 w-10 text-xl sm:ml-12 sm:text-4xl",
}
function OptionButton(props: {
export function OptionAnchor(props: {
text: string
icon: IconDefinition
callback?: () => void
children?: JSX.Element
nodeWhen?: boolean
href: string
disabled?: boolean
}) {
return (
<Show
when={!props.nodeWhen}
fallback={
<div class={classNames(styles.wrapper, styles.enabled)}>
{props.children}
<FontAwesomeIcon class={styles.icon} icon={props.icon} />
</div>
}
<A
class={classNames(
styles.wrapper,
props.disabled ? styles.disabled : styles.enabled,
)}
href={props.href}
title={!props.disabled ? "" : "Please login"}
>
<span class="mx-auto">{props.text}</span>
<FontAwesomeIcon class={styles.icon} icon={props.icon} />
</A>
)
}
export function OptionButton(props: {
text: string
icon: IconDefinition
callback: () => void
disabled?: boolean
}) {
return (
<button
class={classNames(
styles.wrapper,
!props.disabled ? styles.disabled : styles.enabled,
props.disabled ? styles.disabled : styles.enabled,
)}
onClick={() => props.callback && setTimeout(props.callback, 200)}
onClick={() => setTimeout(props.callback, 200)}
disabled={props.disabled}
title={!props.disabled ? "" : "Please login"}
>
<span class="mx-auto">{props.text}</span>
<FontAwesomeIcon class={styles.icon} icon={props.icon} />
</button>
</Show>
)
}
export default OptionButton
export function OptionDiv(props: {
icon: IconDefinition
children: JSX.Element
}) {
return (
<div class={classNames(styles.wrapper, styles.enabled)}>
{props.children}
<FontAwesomeIcon class={styles.icon} icon={props.icon} />
</div>
)
}

View file

@ -1,10 +1,8 @@
import { useNavigate } from "solid-start"
import { A } from "solid-start"
import BurgerMenu from "~/components/BurgerMenu"
import Logo from "~/components/Logo"
export default function Home() {
const navigator = useNavigate()
return (
<div class="h-full bg-theme">
<div class="mx-auto flex h-full max-w-screen-md flex-col items-center justify-evenly">
@ -13,17 +11,13 @@ export default function Home() {
<div class="flex h-36 w-64 items-center justify-center overflow-hidden rounded-xl border-8 border-black bg-[#2227] sm:h-48 sm:w-96 md:h-72 md:w-[32rem] md:border-[6px] xl:h-[26rem] xl:w-[48rem]">
<video controls preload="metadata" src="/Regelwerk.mp4" />
</div>
<button
<A
id="start"
class="font-farro rounded-lg border-b-4 border-orange-400 bg-warn px-12 pb-4 pt-5 text-2xl font-bold duration-100 active:border-b-0 active:border-t-4 sm:rounded-xl sm:border-b-[6px] sm:px-14 sm:pb-5 sm:pt-6 sm:text-3xl sm:active:border-t-[6px] md:rounded-2xl md:border-b-8 md:px-20 md:pb-6 md:pt-7 md:text-4xl md:active:border-t-8 xl:px-24 xl:pb-8 xl:pt-10 xl:text-5xl"
onClick={() =>
setTimeout(() => {
navigator("/start")
}, 200)
}
href="/start"
>
START
</button>
</A>
</div>
</div>
)

View file

@ -2,7 +2,7 @@ import { signIn } from "@auth/solid-start/client"
import { faLeftLong } from "@fortawesome/pro-solid-svg-icons"
import classNames from "classnames"
import { Show, createEffect, createSignal } from "solid-js"
import { useNavigate, useSearchParams } from "solid-start"
import { A, useNavigate, useSearchParams } from "solid-start"
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import { useSession } from "~/hooks/useSession"
@ -147,14 +147,14 @@ function Login() {
<Show when={errorType}>
<hr class="mt-8 border-gray-400" />
<div class="flex flex-col items-center">
<button
<A
id="back"
onClick={() => navigator("/")}
href="/"
class="mt-10 rounded-lg border-2 border-gray-400 bg-gray-500 bg-opacity-75 px-16 py-2 text-white shadow-inner drop-shadow-md backdrop-blur-md transition-colors duration-300 hover:border-blue-600"
>
<FontAwesomeIcon icon={faLeftLong} />
<span class="mx-4 font-bold">Return</span>
</button>
</A>
</div>
</Show>
</div>

View file

@ -4,12 +4,16 @@ import { GamePropsSchema } from "~/lib/zodSchemas"
// import OtpInput from "react-otp-input"
// import { Icons, toast } from "react-toastify"
import status from "http-status"
import { createEffect, createSignal } from "solid-js"
import { useLocation, useNavigate, useSearchParams } from "solid-start"
import { Show, createEffect, createSignal } from "solid-js"
import { A, useNavigate, useSearchParams } from "solid-start"
import BurgerMenu from "~/components/BurgerMenu"
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import Logo from "~/components/Logo"
import OptionButton from "~/components/OptionButton"
import {
OptionAnchor,
OptionButton,
OptionDiv,
} from "~/components/OptionButton"
import { full } from "~/hooks/useGameProps"
import { useSession } from "~/hooks/useSession"
@ -45,7 +49,6 @@ export function isAuthenticated(res: Response) {
export default function Start() {
const [otp, setOtp] = createSignal("")
const location = useLocation()
const navigator = useNavigate()
const { session } = useSession()
@ -139,32 +142,24 @@ export default function Start() {
<div class="mx-auto flex h-full max-w-screen-md flex-col items-center justify-evenly">
<Logo />
<BurgerMenu />
<div class="flex flex-col items-center rounded-xl border-4 border-black bg-grayish px-4 py-6 shadow-lg sm:mx-8 sm:p-12 md:w-full">
<div class="flex flex-col items-center gap-4 rounded-xl border-4 border-black bg-grayish px-6 pb-6 pt-4 shadow-lg sm:mx-8 sm:px-12 sm:pb-12 sm:pt-8 md:w-full">
<div class="flex w-full justify-between">
<button
<A
id="back"
class="-mt-2 h-14 w-20 self-start rounded-xl border-b-4 border-shield-gray bg-voidDark text-2xl text-grayish duration-100 active:border-b-0 active:border-t-4 sm:-mt-6 sm:w-40 sm:px-2 sm:text-5xl"
onClick={() =>
setTimeout(() => {
navigator("/")
}, 200)
}
class="self-start rounded-lg border-b-4 border-shield-gray bg-voidDark px-8 text-2xl text-grayish duration-100 active:border-b-0 active:border-t-4 sm:rounded-xl sm:px-14 sm:py-1 sm:text-5xl"
href="/"
>
<FontAwesomeIcon icon={faLeftLong} />
</button>
{!session()?.user?.id && (
<button
</A>
<Show when={!session()?.user?.id}>
<A
id="login"
class="-mt-2 h-14 w-20 self-start rounded-xl border-b-4 border-orange-500 bg-yellow-500 text-2xl active:border-b-0 active:border-t-4 sm:-mt-6 sm:w-40 sm:px-2 sm:text-4xl"
onClick={() =>
setTimeout(() => {
navigator("/signin")
}, 200)
}
class="self-start rounded-lg border-b-4 border-orange-500 bg-yellow-500 px-4 text-2xl active:border-b-0 active:border-t-4 sm:rounded-xl sm:px-9 sm:py-2 sm:text-4xl"
href="/signin"
>
Login
</button>
)}
</A>
</Show>
</div>
<div class="flex flex-col items-center gap-6 sm:gap-12">
<OptionButton
@ -173,20 +168,37 @@ export default function Start() {
icon={faPlus}
disabled={!session()}
/>
<OptionButton
<Show
when={query().join && !!session()}
fallback={
<OptionAnchor
text="Raum beitreten"
callback={() =>
navigator(
location.pathname.concat(
"?",
new URLSearchParams({ q: "join" }).toString(),
),
)
}
href="?q=join"
icon={faUserPlus}
disabled={!session()}
nodeWhen={query().join && !!session()}
/>
}
>
<OptionDiv icon={faUserPlus}>
<input
disabled={!session()}
value={otp()}
onInput={(e) =>
setOtp((otp) => {
const value = e.target.value
return /^\d{0,4}$/.test(value) ? value : otp
})
}
/>
</OptionDiv>
</Show>
<Show
when={query().watch}
fallback={
<OptionAnchor text="Zuschauen" icon={faEye} href="?q=watch" />
}
>
<OptionDiv icon={faEye}>
<input
value={otp()}
onInput={(e) =>
@ -196,31 +208,8 @@ export default function Start() {
})
}
/>
</OptionButton>
<OptionButton
text="Zuschauen"
icon={faEye}
callback={() =>
navigator(
location.pathname +
"?" +
new URLSearchParams({
q: "watch",
}).toString(),
)
}
nodeWhen={query().watch}
>
<input
value={otp()}
onInput={(e) =>
setOtp((otp) => {
const value = e.target.value
return /^\d{0,4}$/.test(value) ? value : otp
})
}
/>
</OptionButton>
</OptionDiv>
</Show>
</div>
</div>
</div>