mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 16:55:37 +02:00
⭐ feat(www): Add the home page UI (#155)
This commit is contained in:
98
packages/ui/src/avatar.tsx
Normal file
98
packages/ui/src/avatar.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { component$ } from "@builder.io/qwik";
|
||||
|
||||
const DEFAULT_COLORS = ['#6A5ACD', '#E63525','#20B2AA', '#E87D58'];
|
||||
|
||||
const getModulo = (value: number, divisor: number, useEvenCheck?: number) => {
|
||||
const remainder = value % divisor;
|
||||
if (useEvenCheck && Math.floor(value / Math.pow(10, useEvenCheck) % 10) % 2 === 0) {
|
||||
return -remainder;
|
||||
}
|
||||
return remainder;
|
||||
};
|
||||
|
||||
const generateColors = (name: string, colors = DEFAULT_COLORS) => {
|
||||
const hashCode = name.split('').reduce((acc, char) => {
|
||||
acc = ((acc << 5) - acc) + char.charCodeAt(0);
|
||||
return acc & acc;
|
||||
}, 0);
|
||||
|
||||
const hash = Math.abs(hashCode);
|
||||
const numColors = colors.length;
|
||||
|
||||
return Array.from({ length: 3 }, (_, index) => ({
|
||||
color: colors[(hash + index) % numColors],
|
||||
translateX: getModulo(hash * (index + 1), 4, 1),
|
||||
translateY: getModulo(hash * (index + 1), 4, 2),
|
||||
scale: 1.2 + getModulo(hash * (index + 1), 2) / 10,
|
||||
rotate: getModulo(hash * (index + 1), 360, 1)
|
||||
}));
|
||||
};
|
||||
type Props = {
|
||||
name: string;
|
||||
size?: number;
|
||||
class?:string;
|
||||
colors?: string[]
|
||||
}
|
||||
|
||||
export default component$(({ class:className, name, size = 80, colors = DEFAULT_COLORS }: Props) => {
|
||||
const colorData = generateColors(name, colors);
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox={`0 0 ${size} ${size}`}
|
||||
fill="none"
|
||||
role="img"
|
||||
class={className}
|
||||
aria-describedby={name}
|
||||
width={size}
|
||||
height={size}
|
||||
>
|
||||
<title id={name}>{`Fallback avatar for ${name}`}</title>
|
||||
<mask
|
||||
id="mask__marble"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x={0}
|
||||
y={0}
|
||||
width={size}
|
||||
height={size}
|
||||
>
|
||||
<rect width={size} height={size} rx={size * 2} fill="#FFFFFF" />
|
||||
</mask>
|
||||
<g mask="url(#mask__marble)">
|
||||
<rect width={size} height={size} fill={colorData[0].color} />
|
||||
<path
|
||||
filter="url(#prefix__filter0_f)"
|
||||
d="M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z"
|
||||
fill={colorData[1].color}
|
||||
transform={`
|
||||
translate(${colorData[1].translateX} ${colorData[1].translateY})
|
||||
rotate(${colorData[1].rotate} ${size / 2} ${size / 2})
|
||||
scale(${colorData[1].scale})
|
||||
`}
|
||||
/>
|
||||
<path
|
||||
filter="url(#prefix__filter0_f)"
|
||||
style={{ mixBlendMode: "overlay" }}
|
||||
d="M22.216 24L0 46.75l14.108 38.129L78 86l-3.081-59.276-22.378 4.005 12.972 20.186-23.35 27.395L22.215 24z"
|
||||
fill={colorData[2].color}
|
||||
transform={`
|
||||
translate(${colorData[2].translateX} ${colorData[2].translateY})
|
||||
rotate(${colorData[2].rotate} ${size / 2} ${size / 2})
|
||||
scale(${colorData[2].scale})
|
||||
`}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="prefix__filter0_f"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="s-rGB"
|
||||
>
|
||||
<feFlood flood-opacity={0} result="BackgroundImageFix" />
|
||||
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation={7} result="effect1_foregroundBlur" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
})
|
||||
@@ -1,19 +1,39 @@
|
||||
import { $, component$, useOnDocument, useSignal } from "@builder.io/qwik";
|
||||
import { cn } from "./design";
|
||||
import Avatar from "./avatar"
|
||||
import { Dropdown } from '@qwik-ui/headless';
|
||||
import { disablePageScroll, enablePageScroll } from '@fluejs/noscroll';
|
||||
import { $, component$, useOnDocument, useSignal } from "@builder.io/qwik";
|
||||
|
||||
|
||||
export const HomeNavBar = component$(() => {
|
||||
const hasScrolled = useSignal(false);
|
||||
|
||||
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) {
|
||||
disablePageScroll()
|
||||
} else {
|
||||
enablePageScroll()
|
||||
}
|
||||
})
|
||||
|
||||
useOnDocument(
|
||||
'scroll',
|
||||
$(() => {
|
||||
hasScrolled.value = window.scrollY > 0;
|
||||
})
|
||||
);
|
||||
//
|
||||
//
|
||||
return (
|
||||
<nav class={cn("fixed w-full 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-700")} >
|
||||
<div class="flex flex-row justify-center absolute items-center top-0 bottom-0">
|
||||
<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 "
|
||||
@@ -27,31 +47,101 @@ export const HomeNavBar = component$(() => {
|
||||
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>
|
||||
<svg viewBox="0 0 498.05 70.508" xmlns="http://www.w3.org/2000/svg" class="aspect-[498/71] text-gray-600 w-[100px] h-auto" >
|
||||
<g stroke-linecap="round" fill-rule="evenodd" font-size="9pt" stroke="currentColor" stroke-width="0.25mm" fill="currentColor">
|
||||
<path
|
||||
fill="currentColor"
|
||||
pathLength="1"
|
||||
stroke="currentColor"
|
||||
d="M 261.23 41.65 L 212.402 41.65 Q 195.313 41.65 195.313 27.002 L 195.313 14.795 A 17.814 17.814 0 0 1 196.311 8.57 Q 199.443 0.146 212.402 0.146 L 283.203 0.146 L 283.203 14.844 L 217.236 14.844 Q 215.337 14.844 214.945 16.383 A 3.67 3.67 0 0 0 214.844 17.285 L 214.844 24.561 Q 214.844 27.002 217.236 27.002 L 266.113 27.002 Q 283.203 27.002 283.203 41.65 L 283.203 53.857 A 17.814 17.814 0 0 1 282.205 60.083 Q 279.073 68.506 266.113 68.506 L 195.313 68.506 L 195.313 53.809 L 261.23 53.809 A 3.515 3.515 0 0 0 262.197 53.688 Q 263.672 53.265 263.672 51.367 L 263.672 44.092 A 3.515 3.515 0 0 0 263.551 43.126 Q 263.128 41.65 261.23 41.65 Z M 185.547 53.906 L 185.547 68.506 L 114.746 68.506 Q 97.656 68.506 97.656 53.857 L 97.656 14.795 A 17.814 17.814 0 0 1 98.655 8.57 Q 101.787 0.146 114.746 0.146 L 168.457 0.146 Q 185.547 0.146 185.547 14.795 L 185.547 31.885 A 17.827 17.827 0 0 1 184.544 38.124 Q 181.621 45.972 170.174 46.538 A 36.906 36.906 0 0 1 168.457 46.582 L 117.188 46.582 L 117.236 51.465 Q 117.236 53.906 119.629 53.955 L 185.547 53.906 Z M 19.531 14.795 L 19.531 68.506 L 0 68.506 L 0 0.146 L 70.801 0.146 Q 87.891 0.146 87.891 14.795 L 87.891 68.506 L 68.359 68.506 L 68.359 17.236 Q 68.359 14.795 65.967 14.795 L 19.531 14.795 Z M 449.219 68.506 L 430.176 46.533 L 400.391 46.533 L 400.391 68.506 L 380.859 68.506 L 380.859 0.146 L 451.66 0.146 A 24.602 24.602 0 0 1 458.423 0.994 Q 466.007 3.166 468.021 10.907 A 25.178 25.178 0 0 1 468.75 17.236 L 468.75 31.885 A 18.217 18.217 0 0 1 467.887 37.73 Q 465.954 43.444 459.698 45.455 A 23.245 23.245 0 0 1 454.492 46.436 L 473.633 68.506 L 449.219 68.506 Z M 292.969 0 L 371.094 0.098 L 371.094 14.795 L 341.846 14.795 L 341.846 68.506 L 322.266 68.506 L 322.217 14.795 L 292.969 14.844 L 292.969 0 Z M 478.516 0.146 L 498.047 0.146 L 498.047 68.506 L 478.516 68.506 L 478.516 0.146 Z M 400.391 14.844 L 400.391 31.885 L 446.826 31.885 Q 448.726 31.885 449.117 30.345 A 3.67 3.67 0 0 0 449.219 29.443 L 449.219 17.285 Q 449.219 14.844 446.826 14.844 L 400.391 14.844 Z M 117.188 31.836 L 163.574 31.934 Q 165.528 31.895 165.918 30.355 A 3.514 3.514 0 0 0 166.016 29.492 L 166.016 17.236 Q 166.016 15.337 164.476 14.945 A 3.67 3.67 0 0 0 163.574 14.844 L 119.629 14.795 Q 117.188 14.795 117.188 17.188 L 117.188 31.836 Z" />
|
||||
</g>
|
||||
</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="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>
|
||||
<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, key) => (
|
||||
<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
|
||||
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
|
||||
</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">
|
||||
<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>
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Group>
|
||||
</Dropdown.Popover>
|
||||
</Dropdown.Root>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-10 rounded-md gap-[1px] px-1 flex flex-row justify-center mx-auto items-center ">
|
||||
<button class="focus:ring-primary-500 focus:ring-2 p-2 flex flex-row gap-1 justify-center items-center outline-none rounded-md transition-all duration-200 select-none cursor-pointer bg-gray-300/70 dark:hover:bg-gray-700/70">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M2 21.25a.75.75 0 0 0 0 1.5h20a.75.75 0 0 0 0-1.5h-5V16c0-1.886 0-2.828-.586-3.414S14.886 12 13 12h-2c-1.886 0-2.828 0-3.414.586S7 14.114 7 16v5.25zM9.25 15a.75.75 0 0 1 .75-.75h4a.75.75 0 0 1 0 1.5h-4a.75.75 0 0 1-.75-.75m0 3a.75.75 0 0 1 .75-.75h4a.75.75 0 0 1 0 1.5h-4a.75.75 0 0 1-.75-.75" clip-rule="evenodd" /><path fill="currentColor" d="M8 4.5c.943 0 1.414 0 1.707.293S10 5.557 10 6.5v1.792q.234.114.414.294c.404.404.53.978.569 1.914V12c-1.874 0-2.813.002-3.397.586C7 13.172 7 14.114 7 16v5.25H3V12c0-1.886 0-2.828.586-3.414A1.5 1.5 0 0 1 4 8.292V6.5c0-.943 0-1.414.293-1.707S5.057 4.5 6 4.5h.25V3a.75.75 0 0 1 1.5 0v1.5zm12.644.747c-.356-.514-.984-.75-2.24-1.22c-2.455-.921-3.682-1.381-4.543-.785C13 3.84 13 5.15 13 7.772V12c1.886 0 2.828 0 3.414.586S17 14.114 17 16v5.25h4V7.772c0-1.34 0-2.011-.356-2.525" opacity=".5" /></svg>
|
||||
Home
|
||||
</button>
|
||||
<button class="focus:ring-primary-500 focus:ring-2 p-2 flex flex-row gap-1 justify-center items-center outline-none rounded-md transition-all duration-200 select-none cursor-pointer hover:bg-gray-300/70 dark:hover:bg-gray-700/70">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="currentColor" d="M4.035 11.573c.462-2.309.693-3.463 1.522-4.143s2.007-.68 4.362-.68h4.162c2.355 0 3.532 0 4.361.68c.83.68 1.06 1.834 1.523 4.143l.6 3c.664 3.32.996 4.98.096 6.079s-2.594 1.098-5.98 1.098H9.32c-3.386 0-5.08 0-5.98-1.098s-.568-2.758.096-6.079z" opacity=".5" /><circle cx="15" cy="9.75" r="1" fill="currentColor" /><circle cx="9" cy="9.75" r="1" fill="currentColor" /><path fill="currentColor" d="M9.75 5.75a2.25 2.25 0 0 1 4.5 0v1h.431q.565 0 1.069.002V5.75a3.75 3.75 0 1 0-7.5 0v1.002q.504-.003 1.069-.002h.431z" /></svg>
|
||||
Store
|
||||
</button>
|
||||
</div>
|
||||
<div class="gap-4 flex flex-row justify-center h-full items-center">
|
||||
<button class="focus:ring-primary-500 focus:ring-2 outline-none rounded-full transition-all flex items-center duration-200 select-none cursor-pointer hover:bg-gray-300/70 dark:hover:bg-gray-700/70" >
|
||||
<img src="https://avatars.githubusercontent.com/u/71614375?v=4" height={24} width={24} class="size-[28px] rounded-full" alt="Avatar" />
|
||||
</button>
|
||||
|
||||
<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.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 "
|
||||
>
|
||||
<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="M13 22H6.59c-1.545 0-2.774-.752-3.877-1.803c-2.26-2.153 1.45-3.873 2.865-4.715a10.67 10.67 0 0 1 7.922-1.187m3-7.795a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0M16 22l3-3m0 0l3-3m-3 3l-3-3m3 3l3 3" color="currentColor" /></svg>
|
||||
<span class="group-hover:hidden">Leave Team</span>
|
||||
<span class="hidden group-hover:block">Hold to leave</span>
|
||||
</span>
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Group>
|
||||
</Dropdown.Popover>
|
||||
</Dropdown.Root>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
|
||||
@@ -11,5 +11,6 @@ export * from "./router-head"
|
||||
export * from "./team-counter"
|
||||
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 Book } from "./book"
|
||||
export { default as SimpleFooter } from "./simple-footer"
|
||||
@@ -19,9 +19,18 @@ const navLinks = [
|
||||
|
||||
export const NavBar = component$(() => {
|
||||
const location = useLocation()
|
||||
|
||||
|
||||
const hasScrolled = useSignal(false);
|
||||
|
||||
useOnDocument(
|
||||
'scroll',
|
||||
$(() => {
|
||||
hasScrolled.value = window.scrollY > 0;
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<nav class={cn("w-full relative 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")} >
|
||||
<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" >
|
||||
<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" >
|
||||
|
||||
55
packages/ui/src/simple-footer.tsx
Normal file
55
packages/ui/src/simple-footer.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { component$ } from "@builder.io/qwik";
|
||||
import { cn } from "./design";
|
||||
import { Link } from "@builder.io/qwik-city";
|
||||
|
||||
type Props = {
|
||||
class?: string;
|
||||
}
|
||||
|
||||
export default component$(({ class: className }: Props) => {
|
||||
return (
|
||||
<footer class={cn("w-full max-w-[750px] px-4 mx-auto z-20 pb-16 text-sm text-gray-600/70 dark:text-gray-400/70", className)}>
|
||||
<hr class="border-none w-full h-[1.5px] bg-gray-300 dark:bg-gray-700" />
|
||||
<div class="py-4 px-3 flex justify-between">
|
||||
<div class="flex gap-4 items-center h-6 leading-none -ml-3">
|
||||
<Link href="/" class="hover:text-gray-700 dark:hover:text-gray-300 -mt-1 transition-all duration-200">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
class="size-6"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g
|
||||
id="layer1">
|
||||
<path
|
||||
d="M 2.2673611,5.0942341 H 21.732639 V 6.1658185 H 2.2673611 Z m 0,6.3699749 H 21.732639 v 1.071583 H 2.2673611 Z m 0,6.369972 H 21.732639 v 1.071585 H 2.2673611 Z"
|
||||
style="font-size:12px;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:currentColor;stroke-width:3.72245;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
</Link>
|
||||
<Link href="/about" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200">
|
||||
About Us
|
||||
</Link>
|
||||
<Link href="/pricing" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200">
|
||||
Pricing
|
||||
</Link>
|
||||
<Link href="/docs" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200">
|
||||
Docs
|
||||
</Link>
|
||||
</div>
|
||||
<div class="flex items-center [&_svg]:size-5 -mr-3 gap-4">
|
||||
<Link href="mailto:hi@nestri.io" target="_blank" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" color="currentColor"><path d="m7 8.5l2.942 1.74c1.715 1.014 2.4 1.014 4.116 0L17 8.5" /><path d="M2.016 13.476c.065 3.065.098 4.598 1.229 5.733c1.131 1.136 2.705 1.175 5.854 1.254c1.94.05 3.862.05 5.802 0c3.149-.079 4.723-.118 5.854-1.254c1.131-1.135 1.164-2.668 1.23-5.733c.02-.986.02-1.966 0-2.952c-.066-3.065-.099-4.598-1.23-5.733c-1.131-1.136-2.705-1.175-5.854-1.254a115 115 0 0 0-5.802 0c-3.149.079-4.723.118-5.854 1.254c-1.131 1.135-1.164 2.668-1.23 5.733a69 69 0 0 0 0 2.952" /></g></svg>
|
||||
</Link>
|
||||
<Link href="https://github.com/nestrilabs/nestri" target="_blank" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200 -mt-0.5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .999c-6.074 0-11 5.05-11 11.278c0 4.983 3.152 9.21 7.523 10.702c.55.104.727-.246.727-.543v-2.1c-3.06.683-3.697-1.33-3.697-1.33c-.5-1.304-1.222-1.65-1.222-1.65c-.998-.7.076-.686.076-.686c1.105.08 1.686 1.163 1.686 1.163c.98 1.724 2.573 1.226 3.201.937c.098-.728.383-1.226.698-1.508c-2.442-.286-5.01-1.253-5.01-5.574c0-1.232.429-2.237 1.132-3.027c-.114-.285-.49-1.432.107-2.985c0 0 .924-.303 3.026 1.156c.877-.25 1.818-.375 2.753-.38c.935.005 1.876.13 2.755.38c2.1-1.459 3.023-1.156 3.023-1.156c.598 1.554.222 2.701.108 2.985c.706.79 1.132 1.796 1.132 3.027c0 4.332-2.573 5.286-5.022 5.565c.394.35.754 1.036.754 2.088v3.095c0 .3.176.652.734.542C19.852 21.484 23 17.258 23 12.277C23 6.048 18.075.999 12 .999" /></svg>
|
||||
</Link>
|
||||
<Link href="https://discord.com/invite/Y6etn3qKZ3" target="_blank" class="hover:text-gray-700 dark:hover:text-gray-300 transition-all duration-200 -mt-0.5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M19.27 5.33C17.94 4.71 16.5 4.26 15 4a.1.1 0 0 0-.07.03c-.18.33-.39.76-.53 1.09a16.1 16.1 0 0 0-4.8 0c-.14-.34-.35-.76-.54-1.09c-.01-.02-.04-.03-.07-.03c-1.5.26-2.93.71-4.27 1.33c-.01 0-.02.01-.03.02c-2.72 4.07-3.47 8.03-3.1 11.95c0 .02.01.04.03.05c1.8 1.32 3.53 2.12 5.24 2.65c.03.01.06 0 .07-.02c.4-.55.76-1.13 1.07-1.74c.02-.04 0-.08-.04-.09c-.57-.22-1.11-.48-1.64-.78c-.04-.02-.04-.08-.01-.11c.11-.08.22-.17.33-.25c.02-.02.05-.02.07-.01c3.44 1.57 7.15 1.57 10.55 0c.02-.01.05-.01.07.01c.11.09.22.17.33.26c.04.03.04.09-.01.11c-.52.31-1.07.56-1.64.78c-.04.01-.05.06-.04.09c.32.61.68 1.19 1.07 1.74c.03.01.06.02.09.01c1.72-.53 3.45-1.33 5.25-2.65c.02-.01.03-.03.03-.05c.44-4.53-.73-8.46-3.1-11.95c-.01-.01-.02-.02-.04-.02M8.52 14.91c-1.03 0-1.89-.95-1.89-2.12s.84-2.12 1.89-2.12c1.06 0 1.9.96 1.89 2.12c0 1.17-.84 2.12-1.89 2.12m6.97 0c-1.03 0-1.89-.95-1.89-2.12s.84-2.12 1.89-2.12c1.06 0 1.9.96 1.89 2.12c0 1.17-.83 2.12-1.89 2.12" /></svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user