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,19 +1,22 @@
import classNames from "classnames" import classNames from "classnames"
import { A } from "solid-start"
function Logo(props: { small?: boolean }) { function Logo(props: { small?: boolean }) {
return ( return (
<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"> <A href="/">
<h1 <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">
class={classNames( <h1
"font-checkpoint mx-16 my-2 flex flex-col gap-2 border-y-2 border-slate-700 text-center text-2xl leading-tight tracking-widest sm:mx-24 sm:my-3 sm:gap-3 sm:border-y-[3px] sm:text-4xl md:mx-36 md:my-4 md:gap-4 md:border-y-4 md:text-5xl", class={classNames(
{ "xl:gap-6 xl:py-2 xl:text-6xl": !props.small }, "font-checkpoint mx-16 my-2 flex flex-col gap-2 border-y-2 border-slate-700 text-center text-2xl leading-tight tracking-widest sm:mx-24 sm:my-3 sm:gap-3 sm:border-y-[3px] sm:text-4xl md:mx-36 md:my-4 md:gap-4 md:border-y-4 md:text-5xl",
)} { "xl:gap-6 xl:py-2 xl:text-6xl": !props.small },
> )}
<span>Leaky</span> >
<span>Ships</span> <span>Leaky</span>
</h1> <span>Ships</span>
<Screws small={props.small} /> </h1>
</div> <Screws small={props.small} />
</div>
</A>
) )
} }

View file

@ -1,49 +1,69 @@
import { IconDefinition } from "@fortawesome/fontawesome-svg-core" import { IconDefinition } from "@fortawesome/fontawesome-svg-core"
import classNames from "classnames" import classNames from "classnames"
import { JSX, Show } from "solid-js" import { JSX } from "solid-js"
import { A } from "solid-start"
import { FontAwesomeIcon } from "./FontAwesomeIcon" import { FontAwesomeIcon } from "./FontAwesomeIcon"
const styles = { const styles = {
wrapper: 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", "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",
disabled: enabled:
"border-b-4 border-shield-gray bg-voidDark active:border-b-0 active:border-t-4", "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", icon: "ml-2 w-10 text-xl sm:ml-12 sm:text-4xl",
} }
function OptionButton(props: { export function OptionAnchor(props: {
text: string text: string
icon: IconDefinition icon: IconDefinition
callback?: () => void href: string
children?: JSX.Element
nodeWhen?: boolean
disabled?: boolean disabled?: boolean
}) { }) {
return ( return (
<Show <A
when={!props.nodeWhen} class={classNames(
fallback={ styles.wrapper,
<div class={classNames(styles.wrapper, styles.enabled)}> props.disabled ? styles.disabled : styles.enabled,
{props.children} )}
<FontAwesomeIcon class={styles.icon} icon={props.icon} /> href={props.href}
</div> title={!props.disabled ? "" : "Please login"}
}
> >
<button <span class="mx-auto">{props.text}</span>
class={classNames( <FontAwesomeIcon class={styles.icon} icon={props.icon} />
styles.wrapper, </A>
!props.disabled ? styles.disabled : styles.enabled,
)}
onClick={() => props.callback && 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 OptionButton(props: {
text: string
icon: IconDefinition
callback: () => void
disabled?: boolean
}) {
return (
<button
class={classNames(
styles.wrapper,
props.disabled ? styles.disabled : styles.enabled,
)}
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>
)
}
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 BurgerMenu from "~/components/BurgerMenu"
import Logo from "~/components/Logo" import Logo from "~/components/Logo"
export default function Home() { export default function Home() {
const navigator = useNavigate()
return ( return (
<div class="h-full bg-theme"> <div class="h-full bg-theme">
<div class="mx-auto flex h-full max-w-screen-md flex-col items-center justify-evenly"> <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]"> <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" /> <video controls preload="metadata" src="/Regelwerk.mp4" />
</div> </div>
<button <A
id="start" 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" 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={() => href="/start"
setTimeout(() => {
navigator("/start")
}, 200)
}
> >
START START
</button> </A>
</div> </div>
</div> </div>
) )

View file

@ -2,7 +2,7 @@ import { signIn } from "@auth/solid-start/client"
import { faLeftLong } from "@fortawesome/pro-solid-svg-icons" import { faLeftLong } from "@fortawesome/pro-solid-svg-icons"
import classNames from "classnames" import classNames from "classnames"
import { Show, createEffect, createSignal } from "solid-js" 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 { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import { useSession } from "~/hooks/useSession" import { useSession } from "~/hooks/useSession"
@ -147,14 +147,14 @@ function Login() {
<Show when={errorType}> <Show when={errorType}>
<hr class="mt-8 border-gray-400" /> <hr class="mt-8 border-gray-400" />
<div class="flex flex-col items-center"> <div class="flex flex-col items-center">
<button <A
id="back" 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" 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} /> <FontAwesomeIcon icon={faLeftLong} />
<span class="mx-4 font-bold">Return</span> <span class="mx-4 font-bold">Return</span>
</button> </A>
</div> </div>
</Show> </Show>
</div> </div>

View file

@ -4,12 +4,16 @@ import { GamePropsSchema } from "~/lib/zodSchemas"
// import OtpInput from "react-otp-input" // import OtpInput from "react-otp-input"
// import { Icons, toast } from "react-toastify" // import { Icons, toast } from "react-toastify"
import status from "http-status" import status from "http-status"
import { createEffect, createSignal } from "solid-js" import { Show, createEffect, createSignal } from "solid-js"
import { useLocation, useNavigate, useSearchParams } from "solid-start" import { A, useNavigate, useSearchParams } from "solid-start"
import BurgerMenu from "~/components/BurgerMenu" import BurgerMenu from "~/components/BurgerMenu"
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon" import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import Logo from "~/components/Logo" import Logo from "~/components/Logo"
import OptionButton from "~/components/OptionButton" import {
OptionAnchor,
OptionButton,
OptionDiv,
} from "~/components/OptionButton"
import { full } from "~/hooks/useGameProps" import { full } from "~/hooks/useGameProps"
import { useSession } from "~/hooks/useSession" import { useSession } from "~/hooks/useSession"
@ -45,7 +49,6 @@ export function isAuthenticated(res: Response) {
export default function Start() { export default function Start() {
const [otp, setOtp] = createSignal("") const [otp, setOtp] = createSignal("")
const location = useLocation()
const navigator = useNavigate() const navigator = useNavigate()
const { session } = useSession() 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"> <div class="mx-auto flex h-full max-w-screen-md flex-col items-center justify-evenly">
<Logo /> <Logo />
<BurgerMenu /> <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"> <div class="flex w-full justify-between">
<button <A
id="back" 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" 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"
onClick={() => href="/"
setTimeout(() => {
navigator("/")
}, 200)
}
> >
<FontAwesomeIcon icon={faLeftLong} /> <FontAwesomeIcon icon={faLeftLong} />
</button> </A>
{!session()?.user?.id && ( <Show when={!session()?.user?.id}>
<button <A
id="login" 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" 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"
onClick={() => href="/signin"
setTimeout(() => {
navigator("/signin")
}, 200)
}
> >
Login Login
</button> </A>
)} </Show>
</div> </div>
<div class="flex flex-col items-center gap-6 sm:gap-12"> <div class="flex flex-col items-center gap-6 sm:gap-12">
<OptionButton <OptionButton
@ -173,54 +168,48 @@ export default function Start() {
icon={faPlus} icon={faPlus}
disabled={!session()} disabled={!session()}
/> />
<OptionButton <Show
text="Raum beitreten" when={query().join && !!session()}
callback={() => fallback={
navigator( <OptionAnchor
location.pathname.concat( text="Raum beitreten"
"?", href="?q=join"
new URLSearchParams({ q: "join" }).toString(), icon={faUserPlus}
), disabled={!session()}
) />
} }
icon={faUserPlus}
disabled={!session()}
nodeWhen={query().join && !!session()}
> >
<input <OptionDiv icon={faUserPlus}>
value={otp()} <input
onInput={(e) => disabled={!session()}
setOtp((otp) => { value={otp()}
const value = e.target.value onInput={(e) =>
return /^\d{0,4}$/.test(value) ? value : otp setOtp((otp) => {
}) const value = e.target.value
} return /^\d{0,4}$/.test(value) ? value : otp
/> })
</OptionButton> }
<OptionButton />
text="Zuschauen" </OptionDiv>
icon={faEye} </Show>
callback={() => <Show
navigator( when={query().watch}
location.pathname + fallback={
"?" + <OptionAnchor text="Zuschauen" icon={faEye} href="?q=watch" />
new URLSearchParams({
q: "watch",
}).toString(),
)
} }
nodeWhen={query().watch}
> >
<input <OptionDiv icon={faEye}>
value={otp()} <input
onInput={(e) => value={otp()}
setOtp((otp) => { onInput={(e) =>
const value = e.target.value setOtp((otp) => {
return /^\d{0,4}$/.test(value) ? value : otp const value = e.target.value
}) return /^\d{0,4}$/.test(value) ? value : otp
} })
/> }
</OptionButton> />
</OptionDiv>
</Show>
</div> </div>
</div> </div>
</div> </div>