feat: Connect the frontend to the API (#160)

This commit is contained in:
Wanjohi
2025-01-18 07:12:47 +03:00
committed by GitHub
parent dfe37a6cec
commit f480ced756
56 changed files with 2109 additions and 743 deletions

View File

@@ -260,6 +260,7 @@
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
animation-name: slideFromRight;
}
.modal::backdrop,
.modal-sheet::backdrop {
animation-duration: 0.5s;
@@ -280,7 +281,7 @@
}
.modal[data-closing]::backdrop,
.modal-sheet[data-closing]::backdrop{
.modal-sheet[data-closing]::backdrop {
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
touch-action: none;
@@ -298,7 +299,7 @@
animation-name: modalIn;
}
.modal[data-closing]{
.modal[data-closing] {
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
touch-action: none;
@@ -325,37 +326,138 @@
@keyframes fadeIn {
from {
opacity: 0;
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
to {
opacity: 0;
}
}
@keyframes modalIn {
from {
opacity: 0;
scale: 0.9;
}
to {
opacity: 1;
scale: 1;
}
}
@keyframes modalOut {
to {
opacity: 0;
scale: 0.9;
}
}
/* button, a {
@apply outline-none hover:[box-shadow:0_0_0_2px_#fcfcfc,0_0_0_4px_#8f8f8f] dark:hover:[box-shadow:0_0_0_2px_#161616,0_0_0_4px_#707070] focus:[box-shadow:0_0_0_2px_#fcfcfc,0_0_0_4px_#8f8f8f] dark:focus:[box-shadow:0_0_0_2px_#161616,0_0_0_4px_#707070] [transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)]
} */
to {
opacity: 1;
}
}
@keyframes fadeOut {
to {
opacity: 0;
}
}
@keyframes modalIn {
from {
opacity: 0;
scale: 0.9;
}
to {
opacity: 1;
scale: 1;
}
}
@keyframes modalOut {
to {
opacity: 0;
scale: 0.9;
}
}
[data-component="spinner"] {
--spinner-size: 20px;
--spinner-color: #000;
@media (prefers-color-scheme: dark) {
--spinner-color: #FFF;
}
height: var(--spinner-size, 20px);
width: var(--spinner-size, 20px);
margin-left: calc(var(--spinner-size, 20px)*-1px);
/* display: none; */
&>div {
position: relative;
top: 50%;
left: 50%;
height: var(--spinner-size, 20px);
width: var(--spinner-size, 20px);
}
&>div>div {
animation: spin 1.2s linear infinite;
background: var(--spinner-color);
border-radius: 9999px;
height: 8%;
left: -10%;
position: absolute;
top: -3.9%;
width: 24%;
}
&>div>div:first-child {
animation-delay: -1.2s;
transform: rotate(.0001deg) translate(146%);
}
&>div>div:nth-child(2) {
animation-delay: -1.1s;
transform: rotate(30deg) translate(146%);
}
&>div>div:nth-child(3) {
animation-delay: -1s;
transform: rotate(60deg) translate(146%);
}
&>div>div:nth-child(4) {
animation-delay: -.9s;
transform: rotate(90deg) translate(146%);
}
&>div>div:nth-child(5) {
animation-delay: -.8s;
transform: rotate(120deg) translate(146%);
}
&>div>div:nth-child(6) {
animation-delay: -.7s;
transform: rotate(150deg) translate(146%);
}
&>div>div:nth-child(7) {
animation-delay: -.6s;
transform: rotate(180deg) translate(146%);
}
&>div>div:nth-child(8) {
animation-delay: -.5s;
transform: rotate(210deg) translate(146%);
}
&>div>div:nth-child(9) {
animation-delay: -.4s;
transform: rotate(240deg) translate(146%);
}
&>div>div:nth-child(10) {
animation-delay: -.3s;
transform: rotate(270deg) translate(146%);
}
&>div>div:nth-child(11) {
animation-delay: -.2s;
transform: rotate(300deg) translate(146%);
}
&>div>div:nth-child(12) {
animation-delay: -.1s;
transform: rotate(330deg) translate(146%);
}
}
@keyframes spin {
0% {
opacity: 1;
}
100% {
opacity: .15;
}
}

View File

@@ -28,7 +28,7 @@
"@fontsource/bricolage-grotesque": "^5.0.7",
"@fontsource/geist-mono": "^5.1.0",
"@fontsource/geist-sans": "^5.1.0",
"@modular-forms/qwik": "0.26.1",
"@modular-forms/qwik": "^0.29.0",
"@nestri/core": "*",
"@qwik-ui/headless": "^0.6.4",
"@types/eslint": "^8.56.5",

View File

@@ -0,0 +1,4 @@
export const CONSTANTS = {
githubLink: "https://github.com/nestrilabs/nestri#start",
enterpriseContact: "mailto:enterprise@nestri.io"
}

View File

@@ -1,23 +1,26 @@
import { component$, useSignal, useVisibleTask$ } from "@builder.io/qwik";
import { MotionComponent, transition } from "@nestri/ui/react";
import Book from "./book";
import { CONSTANTS } from "./constants";
import { Link } from "@builder.io/qwik-city";
import { MotionComponent, transition } from "@nestri/ui/react";
import { component$, useSignal, useVisibleTask$ } from "@builder.io/qwik";
export const GithubBanner = component$(() => {
const buttonRef = useSignal<HTMLButtonElement | undefined>()
const bookRef = useSignal<HTMLButtonElement | undefined>()
export const FooterBanner = component$(() => {
const docsLinkRef = useSignal<HTMLElement | undefined>()
const bookRef = useSignal<HTMLElement | undefined>()
// eslint-disable-next-line qwik/no-use-visible-task
useVisibleTask$(() => {
buttonRef.value?.addEventListener("mouseenter", () => {
docsLinkRef.value?.addEventListener("mouseenter", () => {
bookRef.value?.classList.add('flip')
})
buttonRef.value?.addEventListener("mouseleave", () => {
docsLinkRef.value?.addEventListener("mouseleave", () => {
bookRef.value?.classList.remove('flip')
})
return () => {
buttonRef.value?.removeEventListener("mouseenter", () => {
docsLinkRef.value?.removeEventListener("mouseenter", () => {
bookRef.value?.classList.add('flip')
})
buttonRef.value?.removeEventListener("mouseleave", () => {
docsLinkRef.value?.removeEventListener("mouseleave", () => {
bookRef.value?.classList.remove('flip')
})
}
@@ -41,36 +44,36 @@ export const GithubBanner = component$(() => {
<p class="text-lg font-medium text-balance tracking-tight leading-tight">
<b class="text-black dark:text-white font-semibold text-2xl text-balance tracking-[-.96px] leading-tight font-title">Ready to start playing?</b>
<br />
Dive into the documentation or unlock premium features with <u class="font-bold [text-decoration:none]" >Nestri Family</u>
Dive into the documentation or unlock premium features with <u class="font-bold [text-decoration:none]" >Nestri Pro</u>
</p>
</div>
<div class="flex md:flex-row flex-col w-full gap-2 h-max md:items-center">
<button class="h-max w-max relative overflow-hidden rounded-lg flex justify-center text-gray-500 dark:text-gray-100/70 font-title font-bold items-center group py-2 px-4">
<span class="invisible"> Get Nestri Family</span>
<Link href="/pricing" class="h-max w-max relative overflow-hidden rounded-lg flex justify-center text-gray-500 dark:text-gray-100/70 font-title font-bold items-center group py-2 px-4">
<span class="invisible"> Get Nestri Pro</span>
<div class="animate-multicolor before:-z-[1] -z-[2] absolute -right-full left-0 bottom-0 h-full w-[1000px] [background:linear-gradient(90deg,rgb(232,23,98)_1.26%,rgb(30,134,248)_18.6%,rgb(91,108,255)_34.56%,rgb(52,199,89)_49.76%,rgb(245,197,5)_64.87%,rgb(236,62,62)_85.7%)_0%_0%/50%_100%_repeat-x]" />
<div class="select-none absolute justify-center items-center min-w-max inset-auto flex z-[2] rounded-md h-[83%] w-[96%] bg-white dark:bg-black group-hover:bg-transparent transition-all duration-200">
<span class="text-sm group-hover:text-white w-full transition-all duration-200">
<div class="flex justify-around items-center w-full h-max">
Get Nestri Family
Get Nestri Pro
</div>
</span>
</div>
</button>
<button ref={v => buttonRef.value = v} class="w-max focus:ring-primary-500 hover:ring-primary-500 ring-gray-500 rounded-lg outline-none dark:text-gray-100/70 ring-2 text-sm h-max py-2 px-4 flex items-center transition-all duration-200 focus:bg-primary-100 focus:dark:bg-primary-900 focus:text-primary-500 text-gray-500 font-title font-bold justify-between">
</Link>
<a href={CONSTANTS.githubLink} ref={v => docsLinkRef.value = v} class="w-max focus:ring-primary-500 hover:ring-primary-500 ring-gray-500 rounded-lg outline-none dark:text-gray-100/70 ring-2 text-sm h-max py-2 px-4 flex items-center transition-all duration-200 focus:bg-primary-100 focus:dark:bg-primary-900 focus:text-primary-500 text-gray-500 font-title font-bold justify-between">
<div class="size-5 relative mr-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-full h-full" height={20} width={20} viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M14.25 4.48v3.057c0 .111 0 .27.021.406a.94.94 0 0 0 .444.683a.96.96 0 0 0 .783.072c.13-.04.272-.108.378-.159L17 8.005l1.124.534c.106.05.248.119.378.16a.96.96 0 0 0 .783-.073a.94.94 0 0 0 .444-.683c.022-.136.021-.295.021-.406V3.031q.17-.008.332-.013C21.154 2.98 22 3.86 22 4.933v11.21c0 1.112-.906 2.01-2.015 2.08c-.97.06-2.108.179-2.985.41c-1.082.286-2.373.904-3.372 1.436q-.422.224-.878.323V5.174a3.6 3.6 0 0 0 .924-.371q.277-.162.576-.323m5.478 8.338a.75.75 0 0 1-.546.91l-4 1a.75.75 0 1 1-.364-1.456l4-1a.75.75 0 0 1 .91.546M11.25 5.214a3.4 3.4 0 0 1-.968-.339C9.296 4.354 8.05 3.765 7 3.487c-.887-.233-2.041-.352-3.018-.412C2.886 3.008 2 3.9 2 4.998v11.146c0 1.11.906 2.01 2.015 2.079c.97.06 2.108.179 2.985.41c1.081.286 2.373.904 3.372 1.436q.422.224.878.324zM4.273 8.818a.75.75 0 0 1 .91-.546l4 1a.75.75 0 1 1-.365 1.456l-4-1a.75.75 0 0 1-.545-.91m.91 3.454a.75.75 0 1 0-.365 1.456l4 1a.75.75 0 0 0 .364-1.456z" clip-rule="evenodd" /><path fill="currentColor" d="M18.25 3.151c-.62.073-1.23.18-1.75.336a8 8 0 0 0-.75.27v3.182l.75-.356l.008-.005a1.1 1.1 0 0 1 .492-.13q.072 0 .138.01c.175.029.315.1.354.12l.009.005l.75.356V3.15" /></svg>
</div>
Read the Docs
</button>
</a>
</div>
</div>
</div>
<button ref={v => bookRef.value = v} class="h-full max-h-[160px] pt-4 md:w-[65%] w-full flex items-start justify-center overflow-hidden outline-none">
<a href={CONSTANTS.githubLink} ref={v => bookRef.value = v} class="h-full max-h-[160px] pt-4 md:w-[65%] w-full flex items-start justify-center overflow-hidden outline-none">
<Book
textColor="#FFF"
bgColor="#FF4F01"
title="Getting started with Nestri" class="shadow-lg shadow-gray-900 dark:shadow-gray-300" />
</button>
</a>
<div class="animate-multicolor absolute blur-[2px] -right-full left-0 -bottom-[2px] h-4 [background:linear-gradient(90deg,rgb(232,23,98)_1.26%,rgb(30,134,248)_18.6%,rgb(91,108,255)_34.56%,rgb(52,199,89)_49.76%,rgb(245,197,5)_64.87%,rgb(236,62,62)_85.7%)_0%_0%/50%_100%_repeat-x]" />
</div>
</div>

View File

@@ -2,7 +2,7 @@
import { component$ } from "@builder.io/qwik";
import { Link } from "@builder.io/qwik-city";
import { MotionComponent, transition } from "@nestri/ui/react"
import { GithubBanner } from "./github-banner";
import { FooterBanner } from "./footer-banner";
const socialMedia = [
{
@@ -30,13 +30,13 @@ const socialMedia = [
]
type Props = {
showGH?: boolean
showBanner?: boolean
}
export const Footer = component$(({ showGH = true }: Props) => {
export const Footer = component$(({ showBanner = true }: Props) => {
return (
<>
{showGH && <GithubBanner />}
{showBanner && <FooterBanner />}
<footer class="flex justify-center flex-col items-center w-full pt-8 sm:pb-0 pb-8 [&>*]:w-full px-3">
<MotionComponent
initial={{ opacity: 0, y: 50 }}
@@ -70,14 +70,16 @@ export const Footer = component$(({ showGH = true }: Props) => {
<div class="text-gray-950/50 dark:text-gray-50/50 flex flex-col gap-2" >
<p class="text-base opacity-50 cursor-not-allowed" >Docs</p>
<Link href="/pricing" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Pricing</Link>
<Link href="/changelog" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Changelog</Link>
<Link href="/about" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >About Us</Link>
</div>
</div>
<div class="flex flex-col gap-2">
<h2 class="font-title text-sm font-bold" >Company</h2>
<div class="text-gray-950/50 dark:text-gray-50/50 flex flex-col gap-2" >
<Link href="/blog" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Blog</Link>
<Link href="/contact" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Contact Us</Link>
{/* <Link href="/blog" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Blog</Link> */}
{/* <Link href="/contact" class="text-base hover:text-gray-950 dark:hover:text-gray-50 transition-all duration-200 hover:underline hover:underline-offset-4" >Contact Us</Link> */}
<p class="text-base opacity-50 cursor-not-allowed" >Blog</p>
<p class="text-base opacity-50 cursor-not-allowed" >Contact Us</p>
<p class="text-base opacity-50 cursor-not-allowed" >Open Startup</p>
</div>
</div>

View File

@@ -0,0 +1,89 @@
import { Modal } from "@qwik-ui/headless";
import { MotionComponent } from "../react";
import { component$, type QRL } from "@builder.io/qwik";
// const FadeScale = {
// initial: {
// opacity: 0,
// scale: 0.85,
// },
// animate: {
// opacity: 1,
// scale: 1,
// },
// exit: {
// opacity: 0,
// scale: 0.85,
// },
// transition: {
// type: "spring",
// duration: 0.35,
// bounce: 0.1
// }
// };
type StoreSelectProps = {
onSteamPress$: QRL<() => void>
}
export const StoreSelect = component$(({ onSteamPress$ }: StoreSelectProps) => {
return (
// <MotionComponent class="w-full h-full" key="store-select" {...FadeScale} >
<>
<div class="absolute right-6 top-6 z-10">
<Modal.Close class="flex h-8 w-8 cursor-pointer items-center justify-center rounded-full hover:bg-gray-300 transition-all duration-300 ease-out dark:hover:bg-gray-800 focus:scale-90 active:scale-75">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" class="h-5 w-5 stroke-gray-600 will-change-transform"><path d="M18 6L6 18M6 6L18 18" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
</Modal.Close>
</div>
<div >
<div class="flex flex-col space-y-1.5 text-center sm:text-left">
<h2 class="tracking-tight flex items-center justify-between px-6 py-6 text-center font-title text-xl font-semibold">
<div class="flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-full hover:bg-gray-300 transition-all duration-300 ease-out dark:hover:bg-gray-800 focus:scale-90 active:scale-75">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48" class="size-5 text-gray-600"><g fill="none"><path stroke="currentColor" stroke-linejoin="round" stroke-width="4" d="M24 44a19.94 19.94 0 0 0 14.142-5.858A19.94 19.94 0 0 0 44 24a19.94 19.94 0 0 0-5.858-14.142A19.94 19.94 0 0 0 24 4A19.94 19.94 0 0 0 9.858 9.858A19.94 19.94 0 0 0 4 24a19.94 19.94 0 0 0 5.858 14.142A19.94 19.94 0 0 0 24 44Z" /><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M24 28.625v-4a6 6 0 1 0-6-6" /><path fill="currentColor" fill-rule="evenodd" d="M24 37.625a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5" clip-rule="evenodd" /></g></svg>
</div>
<span class="w-full pr-8 text-center font-title font-semibold">Connect Game Store</span>
</h2>
</div>
<div class="flex flex-col gap-3 px-6 pb-4">
<button onClick$={onSteamPress$} class="flex h-[64px] w-full cursor-pointer flex-row items-center justify-between gap-2 rounded-2xl bg-gray-100/70 px-5 transition-all duration-200 ease-out hover:bg-gray-300 focus:bg-gray-300 dark:bg-[#171717] dark:hover:bg-gray-800">
<span class="select-none text-center font-title text-lg font-semibold sm:font-medium">Steam</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" class="size-8 dark:text-white"><g fill="currentColor"><path d="M.329 10.333A8.01 8.01 0 0 0 7.99 16C12.414 16 16 12.418 16 8s-3.586-8-8.009-8A8.006 8.006 0 0 0 0 7.468l.003.006l4.304 1.769A2.2 2.2 0 0 1 5.62 8.88l1.96-2.844l-.001-.04a3.046 3.046 0 0 1 3.042-3.043a3.046 3.046 0 0 1 3.042 3.043a3.047 3.047 0 0 1-3.111 3.044l-2.804 2a2.223 2.223 0 0 1-3.075 2.11a2.22 2.22 0 0 1-1.312-1.568L.33 10.333Z" /><path d="M4.868 12.683a1.715 1.715 0 0 0 1.318-3.165a1.7 1.7 0 0 0-1.263-.02l1.023.424a1.261 1.261 0 1 1-.97 2.33l-.99-.41a1.7 1.7 0 0 0 .882.84Zm3.726-6.687a2.03 2.03 0 0 0 2.027 2.029a2.03 2.03 0 0 0 2.027-2.029a2.03 2.03 0 0 0-2.027-2.027a2.03 2.03 0 0 0-2.027 2.027m2.03-1.527a1.524 1.524 0 1 1-.002 3.048a1.524 1.524 0 0 1 .002-3.048" /></g></svg>
</button>
<div class="flex h-[64px] w-full cursor-pointer flex-row items-center justify-between gap-2 rounded-2xl bg-gray-100/70 px-5 transition-all duration-200 ease-out hover:bg-gray-300 focus:bg-gray-300 dark:bg-[#171717] dark:hover:bg-gray-800">
<span class="select-none text-center font-title text-lg font-semibold sm:font-medium">Epic Games</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="size-8 text-black dark:text-white" viewBox="0 0 24 24" ><path fill="currentColor" d="M3.537 0C2.165 0 1.66.506 1.66 1.879V18.44a4 4 0 0 0 .02.433c.031.3.037.59.316.92c.027.033.311.245.311.245c.153.075.258.13.43.2l8.335 3.491c.433.199.614.276.928.27h.002c.314.006.495-.071.928-.27l8.335-3.492c.172-.07.277-.124.43-.2c0 0 .284-.211.311-.243c.28-.33.285-.621.316-.92a4 4 0 0 0 .02-.434V1.879c0-1.373-.506-1.88-1.878-1.88zm13.366 3.11h.68c1.138 0 1.688.553 1.688 1.696v1.88h-1.374v-1.8c0-.369-.17-.54-.523-.54h-.235c-.367 0-.537.17-.537.539v5.81c0 .369.17.54.537.54h.262c.353 0 .523-.171.523-.54V8.619h1.373v2.143c0 1.144-.562 1.71-1.7 1.71h-.694c-1.138 0-1.7-.566-1.7-1.71V4.82c0-1.144.562-1.709 1.7-1.709zm-12.186.08h3.114v1.274H6.117v2.603h1.648v1.275H6.117v2.774h1.74v1.275h-3.14zm3.816 0h2.198c1.138 0 1.7.564 1.7 1.708v2.445c0 1.144-.562 1.71-1.7 1.71h-.799v3.338h-1.4zm4.53 0h1.4v9.201h-1.4zm-3.13 1.235v3.392h.575c.354 0 .523-.171.523-.54V4.965c0-.368-.17-.54-.523-.54zm-3.74 10.147a1.7 1.7 0 0 1 .591.108a1.8 1.8 0 0 1 .49.299l-.452.546a1.3 1.3 0 0 0-.308-.195a.9.9 0 0 0-.363-.068a.7.7 0 0 0-.28.06a.7.7 0 0 0-.224.163a.8.8 0 0 0-.151.243a.8.8 0 0 0-.056.299v.008a.9.9 0 0 0 .056.31a.7.7 0 0 0 .157.245a.7.7 0 0 0 .238.16a.8.8 0 0 0 .303.058a.8.8 0 0 0 .445-.116v-.339h-.548v-.565H7.37v1.255a2 2 0 0 1-.524.307a1.8 1.8 0 0 1-.683.123a1.6 1.6 0 0 1-.602-.107a1.5 1.5 0 0 1-.478-.3a1.4 1.4 0 0 1-.318-.455a1.4 1.4 0 0 1-.115-.58v-.008a1.4 1.4 0 0 1 .113-.57a1.5 1.5 0 0 1 .312-.46a1.4 1.4 0 0 1 .474-.309a1.6 1.6 0 0 1 .598-.111h.045zm11.963.008a2 2 0 0 1 .612.094a1.6 1.6 0 0 1 .507.277l-.386.546a1.6 1.6 0 0 0-.39-.205a1.2 1.2 0 0 0-.388-.07a.35.35 0 0 0-.208.052a.15.15 0 0 0-.07.127v.008a.16.16 0 0 0 .022.084a.2.2 0 0 0 .076.066a1 1 0 0 0 .147.06q.093.03.236.061a3 3 0 0 1 .43.122a1.3 1.3 0 0 1 .328.17a.7.7 0 0 1 .207.24a.74.74 0 0 1 .071.337v.008a.9.9 0 0 1-.081.382a.8.8 0 0 1-.229.285a1 1 0 0 1-.353.18a1.6 1.6 0 0 1-.46.061a2.2 2.2 0 0 1-.71-.116a1.7 1.7 0 0 1-.593-.346l.43-.514q.416.335.9.335a.46.46 0 0 0 .236-.05a.16.16 0 0 0 .082-.142v-.008a.15.15 0 0 0-.02-.077a.2.2 0 0 0-.073-.066a1 1 0 0 0-.143-.062a3 3 0 0 0-.233-.062a5 5 0 0 1-.413-.113a1.3 1.3 0 0 1-.331-.16a.7.7 0 0 1-.222-.243a.73.73 0 0 1-.082-.36v-.008a.9.9 0 0 1 .074-.359a.8.8 0 0 1 .214-.283a1 1 0 0 1 .34-.185a1.4 1.4 0 0 1 .448-.066zm-9.358.025h.742l1.183 2.81h-.825l-.203-.499H8.623l-.198.498h-.81zm2.197.02h.814l.663 1.08l.663-1.08h.814v2.79h-.766v-1.602l-.711 1.091h-.016l-.707-1.083v1.593h-.754zm3.469 0h2.235v.658h-1.473v.422h1.334v.61h-1.334v.442h1.493v.658h-2.255zm-5.3.897l-.315.793h.624zm-1.145 5.19h8.014l-4.09 1.348z" /></svg>
</div>
<div class="flex h-[64px] w-full cursor-pointer flex-row items-center justify-between gap-2 rounded-2xl bg-gray-100/70 px-5 transition-all duration-200 ease-out hover:bg-gray-300 focus:bg-gray-300 dark:bg-[#171717] dark:hover:bg-gray-800">
<span class="select-none text-center font-title text-lg font-semibold sm:font-medium">GOG.com</span>
<svg preserveAspectRatio="xMidYMax meet" viewBox="0 0 34 31" width="24" height="24" class="size-8 text-black dark:text-white" >
<path fill="currentColor" d="M31,31H3a3,3,0,0,1-3-3V3A3,3,0,0,1,3,0H31a3,3,0,0,1,3,3V28A3,3,0,0,1,31,31ZM4,24.5A1.5,1.5,0,0,0,5.5,26H11V24H6.5a.5.5,0,0,1-.5-.5v-3a.5.5,0,0,1,.5-.5H11V18H5.5A1.5,1.5,0,0,0,4,19.5Zm8-18A1.5,1.5,0,0,0,10.5,5h-5A1.5,1.5,0,0,0,4,6.5v5A1.5,1.5,0,0,0,5.5,13H9V11H6.5a.5.5,0,0,1-.5-.5v-3A.5.5,0,0,1,6.5,7h3a.5.5,0,0,1,.5.5v6a.5.5,0,0,1-.5.5H4v2h6.5A1.5,1.5,0,0,0,12,14.5Zm0,13v5A1.5,1.5,0,0,0,13.5,26h5A1.5,1.5,0,0,0,20,24.5v-5A1.5,1.5,0,0,0,18.5,18h-5A1.5,1.5,0,0,0,12,19.5Zm9-13A1.5,1.5,0,0,0,19.5,5h-5A1.5,1.5,0,0,0,13,6.5v5A1.5,1.5,0,0,0,14.5,13h5A1.5,1.5,0,0,0,21,11.5Zm9,0A1.5,1.5,0,0,0,28.5,5h-5A1.5,1.5,0,0,0,22,6.5v5A1.5,1.5,0,0,0,23.5,13H27V11H24.5a.5.5,0,0,1-.5-.5v-3a.5.5,0,0,1,.5-.5h3a.5.5,0,0,1,.5.5v6a.5.5,0,0,1-.5.5H22v2h6.5A1.5,1.5,0,0,0,30,14.5ZM30,18H22.5A1.5,1.5,0,0,0,21,19.5V26h2V20.5a.5.5,0,0,1,.5-.5h1v6h2V20H28v6h2ZM18.5,11h-3a.5.5,0,0,1-.5-.5v-3a.5.5,0,0,1,.5-.5h3a.5.5,0,0,1,.5.5v3A.5.5,0,0,1,18.5,11Zm-4,9h3a.5.5,0,0,1,.5.5v3a.5.5,0,0,1-.5.5h-3a.5.5,0,0,1-.5-.5v-3A.5.5,0,0,1,14.5,20Z" />
</svg>
</div>
<div class="flex h-[64px] w-full cursor-pointer flex-row items-center justify-between gap-2 rounded-2xl bg-gray-100/70 px-5 transition-all duration-200 ease-out hover:bg-gray-300 focus:bg-gray-300 dark:bg-[#171717] dark:hover:bg-gray-800">
<span class="select-none text-center font-title text-lg font-semibold sm:font-medium">Amazon Games</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="size-8 text-black dark:text-white" viewBox="0 0 291.29 134.46" fill="currentColor">
<path fill-rule="evenodd" d="M50.38,59.78c1.09-3.68,1-8.31,1-13.08V12.56c0-1.64.4-6.32-.25-7.29s-3.15-.75-4.9-.75c-5,0-7.22-.69-7.67,4.08l-.19.13c-3.92-3-7.65-5.85-14.84-5.72l-2.39.19a22.76,22.76,0,0,0-4.08,1A19.69,19.69,0,0,0,6.31,15a36.62,36.62,0,0,0-2.08,7.36,23.87,23.87,0,0,0-.38,7.54c.38,2.36.15,4.42.63,6.48,1.74,7.39,5.21,13.15,11.57,15.9a20.21,20.21,0,0,0,11.13,1.39A21,21,0,0,0,34.35,51l2.7-2h.06A22.54,22.54,0,0,1,37,55.75c-1.12,6.39-3,8.54-9.37,9.68a18,18,0,0,1-5.41.13l-5.28-.69L9.2,63a1.69,1.69,0,0,0-1.26,1.07,40.2,40.2,0,0,0,.25,7.8c.89,1.48,3.75,2.07,5.54,2.64,6,1.91,15.69,2.83,22.19.57C43.36,72.52,48.07,67.51,50.38,59.78ZM37.17,22.87V40.41a15.23,15.23,0,0,1-4.33,2.14c-10.59,3.32-14.59-4.12-14.59-13.89a25.33,25.33,0,0,1,1.13-8.87c.93-2.4,2.37-4.5,4.72-5.47.84-.34,1.85-.26,2.76-.63a21.18,21.18,0,0,1,7.8,1.2L37,16C37.57,17,37.17,21.31,37.17,22.87ZM79.74,56.32a25.65,25.65,0,0,0,8.36-3.21l3.33-2.45c.86,1.11.52,2.8,1.63,3.65s9.68,1.16,10.5,0,.44-3.67.44-5.41V26.46c0-4.37.33-9.26-.69-12.7C100.92,5.67,94.08,2.89,83.51,3l-5.66.37a62,62,0,0,0-9.56,2.08c-1.36.47-3.44.82-4,2.07s-.45,7.84.31,8.36c1.12.77,6.5-1,8-1.32,4.34-.94,14.24-1.9,16.66,1.2C91,18,90.71,22.37,90.67,26.39c-1,.24-2.72-.42-3.77-.63l-4.78-.5a18,18,0,0,0-5.28.19c-8.2,1.41-14,4.53-15.9,12.13C58,49.27,68.13,58.77,79.74,56.32ZM77.35,34.63c1.19-.7,2.67-.51,4.15-1.07,3.35,0,6.18.51,9,.63.51,1.12.14,6.83.12,8.55-2.39,3.17-12,6.33-15.27,1.82C73,41.23,74.57,36.26,77.35,34.63Zm38.53,16c0,1.75-.21,3.48.88,4.15.62.37,2.09.19,3,.19,2.09,0,9.28.44,10.06-.57,1-1.25.44-7.82.44-10.12V16.84a19.35,19.35,0,0,1,6.1-2.27c3.38-.79,7.86-.8,9.55,1.45,1.49,2,1.26,5.56,1.26,9.05v19c0,2.58-.58,9.79.88,10.69.9.54,5,.19,6.41.19s5.54.34,6.42-.32c1.18-.89.69-7.28.69-9.56q0-14.13.06-28.29c.48-.79,2.45-1.11,3.4-1.44,4.14-1.46,10.62-2.42,12.63,1.63,1,2.1.69,5.92.69,9V44.81c0,2.24-.5,8.33.44,9.56.55.71,1.83.57,3.08.57,1.88,0,9.33.33,10.19-.32,1.24-.94.75-4.74.75-6.85V28.22c0-8.24.64-15.75-3-20.44-6.52-8.5-23.71-3.95-30,1.45h-.25C157.15,5.18,153,2.9,146.44,3l-2.64.19a30.21,30.21,0,0,0-5.28,1.19,40.58,40.58,0,0,0-6.35,3l-3.08,1.89c-1.12-1.35-.44-3.54-2-4.46-.61-.37-8.67-.47-9.8-.19a2,2,0,0,0-1.07.69c-.66,1-.32,7.59-.32,9.49Zm96.32,2.13c6.17,3.87,17.31,4.71,26.09,2.52,2.21-.55,6.52-1.33,7.29-3.14a48.27,48.27,0,0,0,.12-7.55,1.83,1.83,0,0,0-.81-.94c-.79-.34-2,.24-2.77.44l-6.48,1.19a23.66,23.66,0,0,1-7.16.26,39.37,39.37,0,0,1-5-.7c-4.92-1.49-8.19-5.16-8.24-11.44,1.17-.53,5-.12,6.6-.12h16c2.3,0,6,.47,7.41-.57,1.89-1.41,1.75-10.85,1.14-13.89-2.07-10.3-8.28-16-20.75-15.78l-1.51.06-4.53.63c-4.86,1.22-9.05,3.46-11.75,6.85a25.69,25.69,0,0,0-3.71,6C201.68,22.42,201,33,203.08,40,204.76,45.59,207.71,49.93,212.2,52.73Zm3.7-32.56c1.13-3.25,3-5.62,6.29-6.66L225,13c7.46-.07,9.52,3.79,9.43,11.26-1,.46-4.25.12-5.66.12H215.21C214.8,23.33,215.58,21.1,215.9,20.17Zm77.65,13.2c-3-5.2-9.52-7.23-15.34-9.62-2.76-1.13-7.28-2.08-7.93-5.28-1.37-6.84,12.69-4.86,16.85-3.83,1.16.28,3.85,1.33,4.59.37s.38-3.29.38-4.77c0-1.23.16-2.8-.32-3.59-.72-1.21-2.61-1.55-4.08-2A36.6,36.6,0,0,0,276,3l-3.59.25A29.08,29.08,0,0,0,265.88,5a14.84,14.84,0,0,0-8,7.79c-2.23,5.52-.14,12.84,3.21,15.53,4,3.23,9.43,5.07,14.58,7.17,2.6,1.06,5.55,1.67,6.1,4.78,1.49,8.45-14.51,5.39-19.3,4.15-1-.27-4.16-1.34-5-.88-1.14.65-.69,3.85-.69,5.59,0,1-.15,2.42.25,3.08,1.2,2,7.83,3.26,10.75,3.84,11.6,2.3,21.92-1.62,25.65-8.93C295.3,43.59,295.64,37,293.55,33.37ZM252.81,83l-2.2.13a37.54,37.54,0,0,0-6.35.69,43.91,43.91,0,0,0-13.52,4.72c-1,.61-5,2.58-4.27,4.4.57,1.46,6.36.25,8.23.12,3.7-.25,5.51-.57,9-.56h6.41a35.9,35.9,0,0,1,5.73.37,8.52,8.52,0,0,1,3.45,1.64c1.46,1.25,1.19,5.49.69,7.48a139.33,139.33,0,0,1-5.78,18.86c-.41,1-3.64,7.3-.06,6.54,1.62-.35,4.9-4,5.91-5.22,5-6.39,8.15-13.75,10.5-23,.54-2.15,1.78-10.6.56-12.57C269.11,83.34,258.52,82.89,252.81,83ZM245,101l-5.72,2.51-9.49,3.58c-8.44,3.27-17.84,5.41-27.23,7.74l-11,2.07-12.95,1.7-4.15.31c-1.66.35-3.61.15-5.47.44a83.4,83.4,0,0,1-12.38.51l-9.37.06-6.73-.25-4.33-.25c-1-.2-2.18-.06-3.27-.26l-13.14-1.44c-3.89-.73-8.07-1-11.76-2l-3.08-.51L93.5,112.65c-8.16-2.55-16.27-4.54-23.89-7.48-8.46-3.27-17.29-6.84-24.77-11.26l-7.41-4.27c-1.35-.81-2.44-2-4.59-2-1.6.79-2.09,1.83-1,3.71a12.73,12.73,0,0,0,2.89,2.83l3.4,3.14c4.9,3.9,9.82,7.91,15.15,11.38,4.6,3,9.5,5.55,14.33,8.36l7.23,3.46c4.13,1.82,8.42,3.7,12.76,5.4l11.13,3.71c6,2,12.53,3,19,4.59l13.64,2,4.4.32,7.42.56h2.7a30.39,30.39,0,0,0,7.92.07l2.83-.07,3.46-.06,11.82-.94c5.3-1.18,10.88-1,15.9-2.52l11.57-2.82a195.36,195.36,0,0,0,20.31-7.11,144.13,144.13,0,0,0,23.63-12.57c2.56-1.72,6.18-3,6.86-6.6C250.75,101.43,247.63,100.27,245,101Z" transform="translate(-3.69 -3)" />
</svg>
</div>
</div>
<div class="flex px-6 pb-4" >
<button class="group flex h-[48px] w-full select-none items-center justify-center gap-2 rounded-full text-base font-semibold dark:text-gray-400/70 text-gray-600/70 transition-all duration-200 ease-out hover:text-gray-800 dark:hover:text-gray-200 focus:scale-95 active:scale-95 sm:font-medium">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 shrink-0 transition-all duration-200 ease-out" width="32" height="32" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m9 15l-2.968 2.968A2.362 2.362 0 0 1 2 16.298V15l1.357-6.784A4 4 0 0 1 7.279 5h9.442a4 4 0 0 1 3.922 3.216L22 15v1.297a2.362 2.362 0 0 1-4.032 1.67L15 15z" /><path d="m9 5l1 2h4l1-2" /></g></svg>
I don't own any games
</button>
</div>
</div>
</>
// </MotionComponent>
)
})
export const SteamLoad = component$(() => {
return (
<MotionComponent key="steam-load">
<div class="h-[200px] w-[240px] bg-red-500">
</div>
</MotionComponent>
)
})

View File

@@ -0,0 +1,34 @@
import { SteamLoad, StoreSelect } from "./default";
import { Modal } from "@qwik-ui/headless";
import { $, component$, useSignal } from "@builder.io/qwik";
export default component$(() => {
const storeSelect = useSignal(true)
return (
<Modal.Root class="w-full" >
<Modal.Trigger class="w-full border-gray-400/70 dark:border-gray-700/70 hover:ring-2 hover:ring-[#8f8f8f] dark:hover:ring-[#707070] outline-none group transition-all duration-200 border-[2px] h-14 rounded-xl px-4 gap-2 flex items-center justify-between overflow-hidden bg-white dark:bg-black hover:bg-gray-300/70 dark:hover:bg-gray-700/70 disabled:opacity-50">
<div class="py-2 w-2/3 flex flex-col">
<p class="text-text-100 shrink truncate w-full flex">DESKTOP-EUO8VSF</p>
</div>
<div
style={{
"--cutout-avatar-percentage-visible": 0.2,
"--head-margin-percentage": 0.1,
"--size": "3rem"
}}
class="relative h-full flex w-1/3 justify-end">
<img draggable={false} alt="game" width={256} height={256} src="/images/steam.png" class="h-12 shadow-lg shadow-gray-900 ring-gray-400/70 ring-1 bg-black w-12 translate-y-4 rotate-[14deg] rounded-lg object-cover transition-transform sm:h-16 sm:w-16 group-hover:scale-110" />
</div>
</Modal.Trigger>
<Modal.Panel class="
dark:backdrop:bg-[#0009] backdrop:bg-[#b3b5b799] backdrop:backdrop-grayscale-[.3] w-full max-w-[360px] max-h-[75vh] rounded-[28px] border dark:border-[#191918] border-[#e2e2e2]
dark:[box-shadow:0_0_0_1px_rgba(255,255,255,0.08),_0_3.3px_2.7px_rgba(0,0,0,.1),0_8.3px_6.9px_rgba(0,0,0,.13),0_17px_14.2px_rgba(0,0,0,.17),0_35px_29.2px_rgba(0,0,0,.22),0px_-4px_4px_0px_rgba(0,0,0,.04)_inset] dark:bg-[#111110]
[box-shadow:0_0_0_1px_rgba(19,21,23,0.08),_0_3.3px_2.7px_rgba(0,0,0,.03),0_8.3px_6.9px_rgba(0,0,0,.04),0_17px_14.2px_rgba(0,0,0,.05),0_35px_29.2px_rgba(0,0,0,.06),0px_-4px_4px_0px_rgba(0,0,0,.07)_inset] bg-[#fdfdfc]
backdrop-blur-lg modal" >
<div class="size-full flex flex-col relative text-gray-800 dark:text-gray-200">
{storeSelect.value ? <StoreSelect onSteamPress$={$(() => { console.log("clicked") })} /> : <SteamLoad />}
</div>
</Modal.Panel>
</Modal.Root>
)
})

View File

@@ -1,20 +1,31 @@
import { cn } from "./design";
import Avatar from "./avatar"
import { Dropdown } from '@qwik-ui/headless';
import { MotionComponent } from "./react";
import { Dropdown, Modal } from '@qwik-ui/headless';
import { disablePageScroll, enablePageScroll } from '@fluejs/noscroll';
import { $, component$, useOnDocument, useSignal } from "@builder.io/qwik";
type Props = {
avatarUrl?: string;
discriminator: string | number;
username: string;
}
export const HomeNavBar = component$(() => {
export const HomeNavBar = component$(({ avatarUrl, username, discriminator }: Props) => {
const hasScrolled = useSignal(false);
const defaultTeam = `${username}'s Games`
const selectedTeam = useSignal(defaultTeam)
const isNewTeam = useSignal(false);
const isNewMember = useSignal(false);
const isHolding = useSignal(false);
const showInviteSuccess = useSignal(false);
const newTeamName = useSignal('');
const inviteName = useSignal('');
const inviteEmail = useSignal('');
const teams = useSignal([
{ name: defaultTeam }
]);
const actions = [
{ label: "Hell Diver's Europe", disabled: false },
{ label: "WanjohiRyan's Games", disabled: false },
{ label: "CyberPunk Marathon", disabled: false },
{ label: "Emulation Hackers", disabled: true },
{ label: "testing-123", disabled: false },
];
const onDialogOpen = $((open: boolean) => {
if (open) {
@@ -24,111 +35,213 @@ export const HomeNavBar = component$(() => {
}
})
const handlePointerDown = $(() => {
isHolding.value = true
});
const handlePointerUp = $(() => {
isHolding.value = false
});
const handleAddTeam = $((e: any) => {
e.preventDefault();
if (newTeamName.value.trim()) {
teams.value = [...teams.value, { name: newTeamName.value.trim() }];
// selectedTeam.value = newTeamName.value.trim()
newTeamName.value = '';
isNewTeam.value = false;
}
});
const handleInvite = $((e: any) => {
e.preventDefault();
if (inviteName.value && inviteEmail.value) {
// Here you would typically make an API call to send the invitation
console.log('Sending invite to:', { name: inviteName.value, email: inviteEmail.value });
inviteName.value = '';
inviteEmail.value = '';
isNewMember.value = false;
showInviteSuccess.value = true;
setTimeout(() => {
showInviteSuccess.value = false;
}, 3000);
}
});
useOnDocument(
'scroll',
$(() => {
hasScrolled.value = window.scrollY > 0;
})
);
//
const handleDeleteTeam = $(() => {
// Only delete if it's not the default team
if (selectedTeam.value !== defaultTeam) {
teams.value = teams.value.filter(team => team.name !== selectedTeam.value);
selectedTeam.value = defaultTeam;
}
});
const handleDeleteAnimationComplete = $(() => {
if (isHolding.value) {
// isDeleting.value = true;
// Reset the holding state
isHolding.value = false;
handleDeleteTeam();
}
});
return (
<nav class={cn("fixed w-screen justify-between top-0 z-50 px-2 sm:px-6 text-xs sm:text-sm leading-[1] text-gray-950/70 dark:text-gray-50/70 h-[66px] before:backdrop-blur-[15px] before:absolute before:-z-[1] before:top-0 before:left-0 before:w-full before:h-full flex items-center", hasScrolled.value && "shadow-[0_2px_20px_1px] shadow-gray-300 dark:shadow-gray-700")} >
<div class="flex flex-row justify-center relative items-center top-0 bottom-0">
<div class="flex-shrink-0 gap-2 flex justify-center items-center">
<svg
class="size-8 "
width="100%"
height="100%"
viewBox="0 0 12.8778 9.7377253"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg">
<path
d="m 2.093439,1.7855532 h 8.690922 V 2.2639978 H 2.093439 Z m 0,2.8440874 h 8.690922 V 5.1080848 H 2.093439 Z m 0,2.8440866 h 8.690922 V 7.952172 H 2.093439 Z"
style="font-size:12px;fill:#ff4f01;fill-opacity:1;fill-rule:evenodd;stroke:#ff4f01;stroke-width:1.66201;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1" />
</svg>
<>
<nav class={cn("fixed w-screen justify-between top-0 z-50 px-2 sm:px-6 text-xs sm:text-sm leading-[1] text-gray-950/70 dark:text-gray-50/70 h-[66px] before:backdrop-blur-[15px] before:absolute before:-z-[1] before:top-0 before:left-0 before:w-full before:h-full flex items-center", hasScrolled.value && "shadow-[0_2px_20px_1px] shadow-gray-300 dark:shadow-gray-700")} >
<div class="flex flex-row justify-center relative items-center top-0 bottom-0">
<div class="flex-shrink-0 gap-2 flex justify-center items-center">
<svg
class="size-8 "
width="100%"
height="100%"
viewBox="0 0 12.8778 9.7377253"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg">
<path
d="m 2.093439,1.7855532 h 8.690922 V 2.2639978 H 2.093439 Z m 0,2.8440874 h 8.690922 V 5.1080848 H 2.093439 Z m 0,2.8440866 h 8.690922 V 7.952172 H 2.093439 Z"
style="font-size:12px;fill:#ff4f01;fill-opacity:1;fill-rule:evenodd;stroke:#ff4f01;stroke-width:1.66201;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1" />
</svg>
</div>
<div class="relative z-[5] animate-fade-in opacity-0 items-center flex">
<hr class="dark:bg-gray-700/70 bg-gray-400/70 w-0.5 rounded-md mx-3 rotate-[16deg] h-7 border-none" />
<Dropdown.Root onOpenChange$={onDialogOpen}>
<Dropdown.Trigger class="text-sm [&>svg:first-child]:size-5 rounded-full h-8 focus:bg-gray-300/70 dark:focus:bg-gray-700/70 focus:ring-[#8f8f8f] dark:focus:ring-[#707070] focus:ring-2 outline-none dark:text-gray-400 text-gray-600 gap-2 px-3 cursor-pointer inline-flex transition-all duration-150 items-center hover:bg-gray-300/70 dark:hover:bg-gray-700/70 ">
<Avatar name={selectedTeam.value} />
<span class="truncate shrink max-w-[20ch]">{selectedTeam.value}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M72.61 83.06a8 8 0 0 1 1.73-8.72l48-48a8 8 0 0 1 11.32 0l48 48A8 8 0 0 1 176 88H80a8 8 0 0 1-7.39-4.94M176 168H80a8 8 0 0 0-5.66 13.66l48 48a8 8 0 0 0 11.32 0l48-48A8 8 0 0 0 176 168" /></svg>
</Dropdown.Trigger>
<Dropdown.Popover
class="bg-[hsla(0,0%,100%,.5)] dark:bg-[hsla(0,0%,100%,.026)] min-w-[160px] max-w-[240px] backdrop-blur-md rounded-lg py-1 px-2 border border-[#e8e8e8] dark:border-[#2e2e2e] [box-shadow:0_8px_30px_rgba(0,0,0,.12)]">
<Dropdown.RadioGroup onChange$={(v: string) => selectedTeam.value = v} value={selectedTeam.value} class="w-full flex overflow-hidden flex-col gap-1 [&_*]:w-full [&_[data-checked]]:bg-[rgba(0,0,0,.071)] dark:[&_[data-checked]]:bg-[hsla(0,0%,100%,.077)] [&_[data-checked]]:rounded-md [&_[data-checked]]:text-[#171717] [&_[data-checked]_svg]:block cursor-pointer [&_[data-highlighted]]:text-[#171717] dark:[&_[data-checked]]:text-[#ededed] dark:[&_[data-highlighted]]:text-[#ededed] [&_[data-highlighted]]:bg-[rgba(0,0,0,.071)] dark:[&_[data-highlighted]]:bg-[hsla(0,0%,100%,.077)] [&_[data-highlighted]]:rounded-md">
{teams.value.map((team) => (
<Dropdown.RadioItem
key={team.name}
value={team.name}
class="leading-none text-sm items-center flex px-2 h-8 rounded-md outline-none relative select-none w-full"
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate [&>svg]:size-5 ">
<Avatar class="flex-shrink-0 rounded-full" name={team.name} />
{team.name}
</span>
<span class="py-1 px-1 text-primary-500 [&>svg]:size-5 [&>svg]:hidden !w-max" >
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 24 24"><path fill="currentColor" d="m10 13.6l5.9-5.9q.275-.275.7-.275t.7.275t.275.7t-.275.7l-6.6 6.6q-.3.3-.7.3t-.7-.3l-2.6-2.6q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275z" /></svg>
</span>
</Dropdown.RadioItem>
))}
</Dropdown.RadioGroup>
<Dropdown.Separator class="w-full dark:bg-[#2e2e2e] bg-[#e8e8e8] border-0 h-[1px] my-1" />
<Dropdown.Group class="flex flex-col gap-1 w-full">
<Dropdown.Item
onClick$={() => isNewTeam.value = true}
class="leading-none w-full text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative"
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v14m-7-7h14" /></svg>
New Team
</span>
</Dropdown.Item>
<Dropdown.Item
onClick$={() => isNewMember.value = true}
class={cn("leading-none w-full text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative", selectedTeam.value === defaultTeam && "opacity-50 pointer-events-none !cursor-not-allowed")}
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0-8 0m8 12h6m-3-3v6M6 21v-2a4 4 0 0 1 4-4h4" /></svg>
Send an invite
</span>
</Dropdown.Item>
<button
onPointerDown$={handlePointerDown}
onPointerUp$={handlePointerUp}
onPointerLeave$={handlePointerUp}
onKeyDown$={(e) => e.key === "Enter" && handlePointerDown()}
onKeyUp$={(e) => e.key === "Enter" && handlePointerUp()}
disabled={selectedTeam.value === defaultTeam}
class={cn("leading-none relative overflow-hidden transition-all duration-200 text-sm group items-center text-red-500 [&>*]:w-full [&>qwik-react]:absolute [&>qwik-react]:h-full [&>qwik-react]:left-0 hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none select-none w-full", selectedTeam.value === defaultTeam && "opacity-50 pointer-events-none !cursor-not-allowed")}>
<MotionComponent
client:load
class="absolute left-0 top-0 bottom-0 bg-red-500 opacity-50 w-full h-full rounded-md"
initial={{ scaleX: 0 }}
animate={{
scaleX: isHolding.value ? 1 : 0
}}
style={{
transformOrigin: 'left',
}}
transition={{
duration: isHolding.value ? 2 : 0.5,
ease: "linear"
}}
onAnimationComplete$={handleDeleteAnimationComplete}
/>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m19.5 5.5l-.402 6.506M4.5 5.5l.605 10.025c.154 2.567.232 3.85.874 4.774c.317.456.726.842 1.2 1.131c.671.41 1.502.533 2.821.57m10-7l-7 7m7 0l-7-7M3 5.5h18m-4.944 0l-.683-1.408c-.453-.936-.68-1.403-1.071-1.695a2 2 0 0 0-.275-.172C13.594 2 13.074 2 12.035 2c-1.066 0-1.599 0-2.04.234a2 2 0 0 0-.278.18c-.395.303-.616.788-1.058 1.757L8.053 5.5" color="currentColor" /></svg>
<span class="group-hover:hidden">Delete Team</span>
<span class="hidden group-hover:block">Hold to delete</span>
</span>
</button>
</Dropdown.Group>
</Dropdown.Popover>
</Dropdown.Root>
</div>
</div>
<div class="relative z-[5] animate-fade-in opacity-0 items-center flex">
<hr class="dark:bg-gray-700/70 bg-gray-400/70 w-0.5 rounded-md mx-3 rotate-[16deg] h-7 border-none" />
<div class="gap-4 flex flex-row justify-center h-full animate-fade-in opacity-0 items-center">
<Dropdown.Root onOpenChange$={onDialogOpen}>
<Dropdown.Trigger class="text-sm [&>svg:first-child]:size-5 rounded-full h-8 focus:bg-gray-300/70 dark:focus:bg-gray-700/70 focus:ring-[#8f8f8f] dark:focus:ring-[#707070] focus:ring-2 outline-none dark:text-gray-400 text-gray-600 gap-2 px-3 cursor-pointer inline-flex transition-all duration-150 items-center hover:bg-gray-300/70 dark:hover:bg-gray-700/70 ">
<Avatar name="WanjohiRyan's Games" />
<span class="truncate shrink max-w-[20ch]">WanjohiRyan's Games</span>
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M72.61 83.06a8 8 0 0 1 1.73-8.72l48-48a8 8 0 0 1 11.32 0l48 48A8 8 0 0 1 176 88H80a8 8 0 0 1-7.39-4.94M176 168H80a8 8 0 0 0-5.66 13.66l48 48a8 8 0 0 0 11.32 0l48-48A8 8 0 0 0 176 168" /></svg>
<Dropdown.Trigger class="focus:bg-gray-300/70 dark:focus:bg-gray-700/70 focus:ring-[#8f8f8f] dark:focus:ring-[#707070] text-gray-600 dark:text-gray-400 [&>svg:first-child]:size-5 text-sm focus:ring-2 outline-none rounded-full transition-all flex items-center duration-150 select-none cursor-pointer hover:bg-gray-300/70 dark:hover:bg-gray-700/70 gap-1 px-3 h-8" >
{avatarUrl ? (<img src={avatarUrl} height={20} width={20} class="size-6 rounded-full" alt="Avatar" />) : (<Avatar name={`${username}#${discriminator}`} />)}
<span class="truncate shrink max-w-[20ch] sm:flex hidden">{`${username}#${discriminator}`}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="size-4 sm:block hidden" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M72.61 83.06a8 8 0 0 1 1.73-8.72l48-48a8 8 0 0 1 11.32 0l48 48A8 8 0 0 1 176 88H80a8 8 0 0 1-7.39-4.94M176 168H80a8 8 0 0 0-5.66 13.66l48 48a8 8 0 0 0 11.32 0l48-48A8 8 0 0 0 176 168" /></svg>
</Dropdown.Trigger>
<Dropdown.Popover
class="bg-[hsla(0,0%,100%,.5)] dark:bg-[hsla(0,0%,100%,.026)] min-w-[160px] max-w-[240px] backdrop-blur-md rounded-lg py-1 px-2 border border-[#e8e8e8] dark:border-[#2e2e2e] [box-shadow:0_8px_30px_rgba(0,0,0,.12)]">
<Dropdown.Group class="flex flex-col gap-1">
{actions.map((action) => (
<Dropdown.Item
key={action.label}
class="leading-none text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none "
disabled={action.disabled}
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<Avatar class="flex-shrink-0 rounded-full" name={action.label} />
{action.label}
</span>
{/* <div class="ml-auto">
<kbd class="[text-shadow:hsla(0,0%,100%,.5)_0_0_1px] gap-1 items-center flex justify-center truncate px-1.5 text-xs min-w-5 h-5 rounded-[4px] bg-[rgba(0,0,0,.047)] dark:bg-[hsla(0,0%,100%,.056)] text-[#6f6f6f] dark:text-[#a0a0a0]">
{key + 1}
</kbd>
</div> */}
</Dropdown.Item>
))}
</Dropdown.Group>
<Dropdown.Separator class="w-full dark:bg-[#2e2e2e] bg-[#e8e8e8] border-0 h-[1px] my-1" />
<Dropdown.Group class="flex flex-col gap-1">
<Dropdown.Item
onClick$={() => window.location.href = "mailto:feedback@nestri.io"}
class="leading-none text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none "
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v14m-7-7h14" /></svg>
New Team
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="currentColor" d="M22 8.5a6.5 6.5 0 0 0-11.626-3.993A9.5 9.5 0 0 1 19.5 14q0 .165-.006.33l.333.088a1.3 1.3 0 0 0 1.592-1.591l-.128-.476c-.103-.385-.04-.791.125-1.153A6.5 6.5 0 0 0 22 8.5" /><path fill="currentColor" fill-rule="evenodd" d="M18 14a8 8 0 0 1-11.45 7.22a1.67 1.67 0 0 0-1.15-.13l-1.227.329a1.3 1.3 0 0 1-1.591-1.592L2.91 18.6a1.67 1.67 0 0 0-.13-1.15A8 8 0 1 1 18 14M6.5 15a1 1 0 1 0 0-2a1 1 0 0 0 0 2m3.5 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2m3.5 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2" clip-rule="evenodd" /></svg>
Send Feedback
</span>
</Dropdown.Item>
<Dropdown.Item class="leading-none transition-all duration-200 text-sm group items-center text-red-500 hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none">
<button
onPointerDown$={handlePointerDown}
onPointerUp$={handlePointerUp}
onPointerLeave$={handlePointerUp}
onKeyDown$={(e) => e.key === "Enter" && handlePointerDown()}
onKeyUp$={(e) => e.key === "Enter" && handlePointerUp()}
class="leading-none relative overflow-hidden transition-all duration-200 text-sm group items-center text-red-500 [&>*]:w-full [&>qwik-react]:absolute [&>qwik-react]:h-full [&>qwik-react]:left-0 hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none select-none w-full">
<MotionComponent
client:load
class="absolute left-0 top-0 bottom-0 bg-red-500 opacity-50 w-full h-full rounded-md"
initial={{ scaleX: 0 }}
animate={{
scaleX: isHolding.value ? 1 : 0
}}
style={{
transformOrigin: 'left',
}}
transition={{
duration: isHolding.value ? 2 : 0.5,
ease: "linear"
}}
/>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m19.5 5.5l-.402 6.506M4.5 5.5l.605 10.025c.154 2.567.232 3.85.874 4.774c.317.456.726.842 1.2 1.131c.671.41 1.502.533 2.821.57m10-7l-7 7m7 0l-7-7M3 5.5h18m-4.944 0l-.683-1.408c-.453-.936-.68-1.403-1.071-1.695a2 2 0 0 0-.275-.172C13.594 2 13.074 2 12.035 2c-1.066 0-1.599 0-2.04.234a2 2 0 0 0-.278.18c-.395.303-.616.788-1.058 1.757L8.053 5.5" color="currentColor" /></svg>
<span class="group-hover:hidden">Delete Team</span>
<span class="hidden group-hover:block">Hold to delete</span>
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><g fill="none"><path fill="currentColor" fill-rule="evenodd" d="M10.138 1.815A3 3 0 0 1 14 4.688v14.624a3 3 0 0 1-3.862 2.873l-6-1.8A3 3 0 0 1 2 17.512V6.488a3 3 0 0 1 2.138-2.873zM15 4a1 1 0 0 1 1-1h3a3 3 0 0 1 3 3v1a1 1 0 1 1-2 0V6a1 1 0 0 0-1-1h-3a1 1 0 0 1-1-1m6 12a1 1 0 0 1 1 1v1a3 3 0 0 1-3 3h-3a1 1 0 1 1 0-2h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1M9 11a1 1 0 1 0 0 2h.001a1 1 0 1 0 0-2z" clip-rule="evenodd" /><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 12h5m0 0l-2-2m2 2l-2 2" /></g></svg>
<span class="group-hover:hidden">Log out</span>
<span class="hidden group-hover:block">Hold to logout</span>
</span>
</Dropdown.Item>
</button>
</Dropdown.Group>
</Dropdown.Popover>
</Dropdown.Root>
</div>
</div>
<div class="gap-4 flex flex-row justify-center h-full animate-fade-in opacity-0 items-center">
<Dropdown.Root onOpenChange$={onDialogOpen}>
<Dropdown.Trigger class="focus:bg-gray-300/70 dark:focus:bg-gray-700/70 focus:ring-[#8f8f8f] dark:focus:ring-[#707070] text-gray-600 dark:text-gray-400 [&>svg:first-child]:size-5 text-sm focus:ring-2 outline-none rounded-full transition-all flex items-center duration-150 select-none cursor-pointer hover:bg-gray-300/70 dark:hover:bg-gray-700/70 gap-1 px-3 h-8" >
<img src="https://avatars.githubusercontent.com/u/71614375?v=4" height={20} width={20} class="size-6 rounded-full" alt="Avatar" />
{/* <Avatar name="WanjohiRyan#47" /> */}
<span class="truncate shrink max-w-[20ch] sm:flex hidden">WanjohiRyan#47</span>
<svg xmlns="http://www.w3.org/2000/svg" class="size-4 sm:block hidden" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M72.61 83.06a8 8 0 0 1 1.73-8.72l48-48a8 8 0 0 1 11.32 0l48 48A8 8 0 0 1 176 88H80a8 8 0 0 1-7.39-4.94M176 168H80a8 8 0 0 0-5.66 13.66l48 48a8 8 0 0 0 11.32 0l48-48A8 8 0 0 0 176 168" /></svg>
</Dropdown.Trigger>
<Dropdown.Popover
class="bg-[hsla(0,0%,100%,.5)] dark:bg-[hsla(0,0%,100%,.026)] min-w-[160px] max-w-[240px] backdrop-blur-md rounded-lg py-1 px-2 border border-[#e8e8e8] dark:border-[#2e2e2e] [box-shadow:0_8px_30px_rgba(0,0,0,.12)]">
<Dropdown.Group class="flex flex-col gap-1">
<Dropdown.Item
class="leading-none text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none "
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><path fill="currentColor" d="M22 8.5a6.5 6.5 0 0 0-11.626-3.993A9.5 9.5 0 0 1 19.5 14q0 .165-.006.33l.333.088a1.3 1.3 0 0 0 1.592-1.591l-.128-.476c-.103-.385-.04-.791.125-1.153A6.5 6.5 0 0 0 22 8.5" /><path fill="currentColor" fill-rule="evenodd" d="M18 14a8 8 0 0 1-11.45 7.22a1.67 1.67 0 0 0-1.15-.13l-1.227.329a1.3 1.3 0 0 1-1.591-1.592L2.91 18.6a1.67 1.67 0 0 0-.13-1.15A8 8 0 1 1 18 14M6.5 15a1 1 0 1 0 0-2a1 1 0 0 0 0 2m3.5 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2m3.5 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2" clip-rule="evenodd" /></svg>
Send Feedback
</span>
</Dropdown.Item>
<Dropdown.Item
class="leading-none text-sm items-center text-[#6f6f6f] dark:text-[#a0a0a0] hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none "
>
<span class="w-full max-w-[20ch] flex items-center gap-2 truncate overflow-visible [&>svg]:size-5 ">
<svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0" viewBox="0 0 24 24"><g fill="none"><path fill="currentColor" fill-rule="evenodd" d="M10.138 1.815A3 3 0 0 1 14 4.688v14.624a3 3 0 0 1-3.862 2.873l-6-1.8A3 3 0 0 1 2 17.512V6.488a3 3 0 0 1 2.138-2.873zM15 4a1 1 0 0 1 1-1h3a3 3 0 0 1 3 3v1a1 1 0 1 1-2 0V6a1 1 0 0 0-1-1h-3a1 1 0 0 1-1-1m6 12a1 1 0 0 1 1 1v1a3 3 0 0 1-3 3h-3a1 1 0 1 1 0-2h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1M9 11a1 1 0 1 0 0 2h.001a1 1 0 1 0 0-2z" clip-rule="evenodd" /><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 12h5m0 0l-2-2m2 2l-2 2" /></g></svg>
Log out
</span>
</Dropdown.Item>
</Dropdown.Group>
<Dropdown.Separator class="w-full dark:bg-[#2e2e2e] bg-[#e8e8e8] border-0 h-[1px] my-1" />
{/* <Dropdown.Separator class="w-full dark:bg-[#2e2e2e] bg-[#e8e8e8] border-0 h-[1px] my-1" />
<Dropdown.Group class="flex flex-col gap-1">
<Dropdown.Item
class="leading-none transition-all duration-200 text-sm group items-center text-red-500 hover:text-[#171717] dark:hover:text-[#ededed] hover:bg-[rgba(0,0,0,.071)] dark:hover:bg-[hsla(0,0%,100%,.077)] flex px-2 gap-2 h-8 rounded-md cursor-pointer outline-none relative select-none "
@@ -139,10 +252,97 @@ export const HomeNavBar = component$(() => {
<span class="hidden group-hover:block">Hold to leave</span>
</span>
</Dropdown.Item>
</Dropdown.Group>
</Dropdown.Popover>
</Dropdown.Root>
</div>
</nav>
</Dropdown.Group> */}
</Dropdown.Popover>
</Dropdown.Root>
</div>
</nav>
<Modal.Root bind:show={isNewTeam} class="w-full">
<Modal.Panel
class="dark:bg-black bg-white [box-shadow:0_8px_30px_rgba(0,0,0,.12)]
dark:backdrop:bg-[#0009] backdrop:bg-[#b3b5b799] backdrop:backdrop-grayscale-[.3] max-h-[75vh] rounded-xl
backdrop-blur-md modal max-w-[400px] w-full border dark:border-gray-800 border-gray-200">
<form preventdefault:submit onSubmit$={handleAddTeam}>
<main class="size-full flex flex-col relative py-4 px-5">
<div class="dark:text-white text-black">
<h3 class="font-semibold text-2xl tracking-tight mb-1 font-title">Create a team</h3>
<div class="text-sm dark:text-gray-200/70 text-gray-800/70" >
Continue to start playing with on Pro with increased usage, additional security features, and support
</div>
</div>
<div class="mt-3 flex flex-col gap-3" >
<div>
<label for="name" class="text-sm dark:text-gray-200 text-gray-800 pb-2 pt-1" >
Team Name
</label>
<input
//@ts-expect-error
onInput$={(e) => newTeamName.value = e.target!.value}
required value={newTeamName.value} id="name" type="text" placeholder="Enter team name" class="[transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)] w-full bg-transparent px-2 py-3 h-10 border text-black dark:text-white dark:border-gray-700/70 border-gray-300/70 rounded-md text-sm outline-none leading-none focus:ring-gray-300 dark:focus:ring-gray-700 focus:ring-2" />
</div>
</div>
</main>
<footer class="dark:text-gray-200/70 text-gray-800/70 dark:bg-gray-900 bg-gray-100 ring-1 ring-gray-200 dark:ring-gray-800 select-none flex gap-2 items-center justify-between w-full bottom-0 left-0 py-3 px-5 text-sm leading-none">
<Modal.Close class="rounded-lg [transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)] py-3 px-4 hover:bg-gray-200 dark:hover:bg-gray-800 flex items-center justify-center">
Cancel
</Modal.Close>
<button
type="submit"
class="flex items-center justify-center gap-2 border-2 border-gray-300 dark:border-gray-700 rounded-lg bg-gray-200 dark:bg-gray-800 py-3 px-4 hover:bg-gray-300 dark:hover:bg-gray-700 [transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)]" >
Continue
</button>
</footer>
</form>
</Modal.Panel>
</Modal.Root >
<Modal.Root bind:show={isNewMember} class="w-full">
<Modal.Panel
class="dark:bg-black bg-white [box-shadow:0_8px_30px_rgba(0,0,0,.12)]
dark:backdrop:bg-[#0009] backdrop:bg-[#b3b5b799] backdrop:backdrop-grayscale-[.3] max-h-[75vh] rounded-xl
backdrop-blur-md modal max-w-[400px] w-full border dark:border-gray-800 border-gray-200">
<form preventdefault:submit onSubmit$={handleInvite}>
<main class="size-full flex flex-col relative py-4 px-5">
<div class="dark:text-white text-black">
<h3 class="font-semibold text-2xl tracking-tight mb-1 font-title">Send an invite</h3>
<div class="text-sm dark:text-gray-200/70 text-gray-800/70" >
Friends will receive an email allowing them to join this team
</div>
</div>
<div class="mt-3 flex flex-col gap-3" >
<div>
<label for="name" class="text-sm dark:text-gray-200 text-gray-800 pb-2 pt-1" >
Name
</label>
<input
value={inviteName.value}
//@ts-expect-error
onInput$={(e) => inviteName.value = e.target!.value}
id="name" type="text" placeholder="Jane Doe" class="[transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)] w-full bg-transparent px-2 py-3 h-10 border text-black dark:text-white dark:border-gray-700/70 border-gray-300/70 rounded-md text-sm outline-none leading-none focus:ring-gray-300 dark:focus:ring-gray-700 focus:ring-2" />
</div>
<div>
<label for="email" class="text-sm dark:text-gray-200 text-gray-800 pb-2 pt-1" >
Email
</label>
<input
value={inviteEmail.value}
//@ts-expect-error
onInput$={(e) => inviteEmail.value = e.target!.value}
id="email" type="email" placeholder="jane@doe.com" class="[transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)] w-full px-2 bg-transparent py-3 h-10 border text-black dark:text-white dark:border-gray-700/70 border-gray-300/70 rounded-md text-sm outline-none leading-none focus:ring-gray-300 dark:focus:ring-gray-700 focus:ring-2" />
</div>
</div>
</main>
<footer class="dark:text-gray-200/70 text-gray-800/70 dark:bg-gray-900 bg-gray-100 ring-1 ring-gray-200 dark:ring-gray-800 select-none flex gap-2 items-center justify-between w-full bottom-0 left-0 py-3 px-5 text-sm leading-none">
<Modal.Close class="rounded-lg [transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)] py-3 px-4 hover:bg-gray-200 dark:hover:bg-gray-800 flex items-center justify-center">
Cancel
</Modal.Close>
<button type="submit" class="flex items-center justify-center gap-2 border-2 border-gray-300 dark:border-gray-700 rounded-lg bg-gray-200 dark:bg-gray-800 py-3 px-4 hover:bg-gray-300 dark:hover:bg-gray-700 [transition:all_0.3s_cubic-bezier(0.4,0,0.2,1)]" >
Send an invite
</button>
</footer>
</form>
</Modal.Panel>
</Modal.Root>
</>
)
})

View File

@@ -9,9 +9,12 @@ export * from "./footer"
export * from "./card"
export * from "./router-head"
export * from "./team-counter"
export * from "./constants"
export * from "./svg"
export * as auth from "./popup"
export * as Modal from "./modal"
export { default as Book } from "./book"
export { default as Portal } from "./portal"
export { default as Avatar } from "./avatar"
export { default as SimpleFooter } from "./simple-footer"
export { default as SimpleFooter } from "./simple-footer"
export { default as GameStoreButton } from "./game-store"

View File

@@ -4,8 +4,8 @@ import { buttonVariants, cn } from "./design";
const navLinks = [
{
name: "Changelog",
href: "/changelog"
name: "About Us",
href: "/about"
},
{
name: "Pricing",
@@ -13,11 +13,15 @@ const navLinks = [
},
{
name: "Login",
href: "/login"
}
]
export const NavBar = component$(() => {
type Props = {
link?: string
}
export const NavBar = component$(({ link }: Props) => {
const location = useLocation()
const hasScrolled = useSignal(false);
@@ -30,8 +34,16 @@ export const NavBar = component$(() => {
);
return (
<nav class={cn("w-full sticky top-0 z-50 px-4 text-sm font-extrabold bg-gray-100/70 dark:bg-gray-900/70 before:backdrop-blur-[15px] before:absolute before:-z-[1] before:top-0 before:left-0 before:w-full before:h-full", hasScrolled.value && "shadow-[0_2px_20px_1px] shadow-gray-300 dark:shadow-gray-700")} >
<div class="mx-auto flex max-w-xl items-center border-b-2 dark:border-gray-50/50 border-gray-950/50" >
<nav class={cn("w-full sticky top-0 z-50 text-sm font-extrabold bg-gray-100/70 dark:bg-gray-900/70 before:backdrop-blur-[15px] before:absolute before:-z-[1] before:top-0 before:left-0 before:w-full before:h-full max-w-full overflow-hidden", hasScrolled.value && "shadow-[0_2px_20px_1px] shadow-gray-300 dark:shadow-gray-700")} >
<button onClick$={() => window.location.href = link as string} class="w-full text-gray-900/70 bg-gray-400/30 dark:bg-gray-600/30 dark:text-gray-100/30 whitespace-nowrap font-mono text-sm py-3">
<div class="flex relative">
<span class="whitespace-pre marquee-animation">
Launching Soon · Login to reserve your username · Launching Soon · Login to reserve your username · Launching Soon · Login to reserve your username ·
Launching Soon · Login to reserve your username · Launching Soon · Login to reserve your username · Launching Soon · Login to reserve your username ·
</span>
</div>
</button>
<div class="px-4 mx-auto flex max-w-xl items-center border-b-2 dark:border-gray-50/50 border-gray-950/50" >
<Link class="outline-none focus:ring-2 py-1 px-3 -ml-3 rounded-lg focus:ring-primary-500 duration-200 transition-all" href="/" >
<h1 class="text-lg font-title" >
Nestri
@@ -40,7 +52,7 @@ export const NavBar = component$(() => {
<ul class="ml-0 -mr-4 flex font-medium m-4 flex-1 gap-1 tracking-[0.035em] items-center justify-end dark:text-primary-50/70 text-primary-950/70">
{navLinks.map((linkItem, key) => (
<li key={`linkItem-${key}`}>
<Link href={linkItem.href} class={cn(buttonVariants.ghost({ intent: "gray", size: "sm" }), "hover:bg-gray-300/70 dark:hover:bg-gray-700/70 focus:ring-2 outline-none focus:ring-primary-500 duration-200 transition-all", location.url.pathname === linkItem.href && "bg-gray-300/70 hover:bg-gray-300/70 dark:bg-gray-700/70 dark:hover:bg-gray-700/70")}>
<Link href={linkItem.href ? linkItem.href : link} class={cn(buttonVariants.ghost({ intent: "gray", size: "sm" }), "hover:bg-gray-300/70 dark:hover:bg-gray-700/70 focus:ring-2 outline-none focus:ring-primary-500 duration-200 transition-all", location.url.pathname === linkItem.href && "bg-gray-300/70 hover:bg-gray-300/70 dark:bg-gray-700/70 dark:hover:bg-gray-700/70")}>
{linkItem.name}
</Link>
</li>

View File

@@ -0,0 +1,32 @@
/** @jsxImportSource react */
import { qwikify$ } from '@builder.io/qwik-react';
import { type MotionProps, AnimatePresence } from 'framer-motion';
import React, { type ReactNode } from 'react';
interface ReactAnimateComponentProps extends MotionProps {
// as?: keyof JSX.IntrinsicElements;
children?: ReactNode;
// class?: string;
// id: string;
}
export const ReactAnimateComponent = ({
// as = 'div',
// id,
children,
// class: className,
// ...motionProps
}: ReactAnimateComponentProps) => {
// const MotionTag = motion[as as keyof typeof motion] as React.ComponentType<any>;
return (
<AnimatePresence mode='wait'>
{children}
{/* <MotionTag id={id} className={className} {...(motionProps as any)}>
</MotionTag> */}
</AnimatePresence>
);
};
export const AnimateComponent = qwikify$(ReactAnimateComponent);

View File

@@ -5,4 +5,5 @@ export * from "./button"
export * from "./cursor"
export * from "./motion"
export * from "./title"
export * from "./text"
export * from "./text"
export * from "./animate"

11
packages/ui/src/svg.tsx Normal file

File diff suppressed because one or more lines are too long