ditch js client
|
@ -1,6 +1,6 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["server", "clients/leptos", "lib", "tools/socket_blaster"]
|
||||
members = ["server", "client", "lib", "tools/socket_blaster"]
|
||||
default-members = ["server", "lib"]
|
||||
|
||||
[workspace.dependencies]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
[build]
|
||||
target = "clients/leptos/index.html"
|
||||
target = "client/index.html"
|
||||
dist = "dist"
|
||||
minify = "on_release"
|
||||
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 685 B After Width: | Height: | Size: 685 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
2
clients/solid/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
node_modules
|
||||
dist
|
|
@ -1,34 +0,0 @@
|
|||
## Usage
|
||||
|
||||
Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.
|
||||
|
||||
This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template.
|
||||
|
||||
```bash
|
||||
$ npm install # or pnpm install or yarn install
|
||||
```
|
||||
|
||||
### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm run dev` or `npm start`
|
||||
|
||||
Runs the app in the development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br>
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `dist` folder.<br>
|
||||
It correctly bundles Solid in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br>
|
||||
Your app is ready to be deployed!
|
||||
|
||||
## Deployment
|
||||
|
||||
You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"$schema": "https://shadcn-solid.com/schema.json",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": {
|
||||
"path": "src/index.css",
|
||||
"variable": true
|
||||
},
|
||||
"color": "neutral",
|
||||
"prefix": ""
|
||||
},
|
||||
"alias": {
|
||||
"component": "@/components",
|
||||
"cn": "@/libs/cn"
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<title>Cards for Humanity</title>
|
||||
<style>
|
||||
/* hax */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body, html {
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script src="/src/index.tsx" type="module"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"name": "Cards for Humanity",
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.9.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.49",
|
||||
"solid-devtools": "^0.29.3",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"typescript": "^5.6.3",
|
||||
"vite": "^5.4.11",
|
||||
"vite-plugin-solid": "^2.10.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@corvu/drawer": "^0.2.2",
|
||||
"@corvu/tailwind": "^0.1.5",
|
||||
"@kobalte/core": "^0.13.7",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"corvu": "^0.7.1",
|
||||
"joi": "^17.13.3",
|
||||
"solid-js": "^1.9.3",
|
||||
"tailwind-merge": "^2.5.4",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
}
|
||||
}
|
2525
clients/solid/pnpm-lock.yaml
generated
|
@ -1,7 +0,0 @@
|
|||
module.exports = {
|
||||
purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 685 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 15 KiB |
|
@ -1 +0,0 @@
|
|||
{"name":"Cards for Humanity","short_name":"C4H","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
|
@ -1,54 +0,0 @@
|
|||
import type { JSXElement } from "solid-js";
|
||||
import { lazy } from "solid-js";
|
||||
import { ColorModeProvider, ColorModeScript } from "@kobalte/core";
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsIndicator,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/components/ui/tabs";
|
||||
import Home from "@/pages/Home";
|
||||
import Footer from "@/components/Footer";
|
||||
import { Websocket, WebsocketProvider } from "./components/Websocket";
|
||||
|
||||
const Browser = lazy(() => import("@/pages/Browser"));
|
||||
const Game = lazy(() => import("@/pages/Game"));
|
||||
|
||||
export default function App(): JSXElement {
|
||||
return (
|
||||
<>
|
||||
<ColorModeScript />
|
||||
<ColorModeProvider>
|
||||
<WebsocketProvider>
|
||||
<div class="lg:container m-auto relative">
|
||||
<div class="transition-all p-1 lg:p-5 lg:rounded-2xl lg:shadow-xl min-h-screen lg:min-h-0 dark:bg-black">
|
||||
<h1 class="text-4xl sm:text-6xl md:text-7xl lg:text-8xl tracking-tighter">
|
||||
Cards For Humanity
|
||||
</h1>
|
||||
<br />
|
||||
<Tabs defaultValue="home">
|
||||
<TabsList>
|
||||
<TabsTrigger value="home">Home</TabsTrigger>
|
||||
<TabsTrigger value="browser">Browser</TabsTrigger>
|
||||
<TabsTrigger value="game">Game</TabsTrigger>
|
||||
<TabsIndicator variant="underline" />
|
||||
</TabsList>
|
||||
<TabsContent value="home">
|
||||
<Home />
|
||||
</TabsContent>
|
||||
<TabsContent value="browser">
|
||||
<Browser />
|
||||
</TabsContent>
|
||||
<TabsContent value="game">
|
||||
<Game />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</WebsocketProvider>
|
||||
</ColorModeProvider>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
import { JSXElement } from "solid-js";
|
||||
|
||||
export function Chat(): JSXElement {
|
||||
return <>chat</>;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { createEffect, createSignal, JSXElement, useContext } from "solid-js";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useWebsocket, WebsocketContext, WebsocketProvider } from "./Websocket";
|
||||
|
||||
export function Debug(): JSXElement {
|
||||
const connected = useWebsocket;
|
||||
// const [connected, set_connected] = createSignal(false);
|
||||
const [user_count, _set_user_count] = createSignal("0");
|
||||
const [game_count, _set_game_count] = createSignal("0");
|
||||
|
||||
// const toggle = () => set_connected(!connected());
|
||||
createEffect(() => console.log(connected()));
|
||||
|
||||
return (
|
||||
<div class="my-2 w-auto">
|
||||
<h2 class="p-1 text-2xl">Debug:</h2>
|
||||
<p class="p-1">
|
||||
Connection Status: {connected() ? "Connected" : "Disconnected"}
|
||||
</p>
|
||||
<p class="p-1">Users Online: {user_count()}</p>
|
||||
<p class="p-1">Active Games: {game_count()}</p>
|
||||
<div class="p-1">
|
||||
<Button
|
||||
onClick={() => set_connected(!connected())}
|
||||
disabled={connected()}
|
||||
>
|
||||
"Connect"
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => set_connected(!connected())}
|
||||
disabled={!connected()}
|
||||
>
|
||||
"Disconnect"
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
import { JSXElement } from "solid-js";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerLabel,
|
||||
DrawerTrigger,
|
||||
} from "@/components/ui/drawer";
|
||||
import { Chat } from "@/components/Chat";
|
||||
import { Debug } from "@/components/Debug";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
|
||||
export default function Footer(): JSXElement {
|
||||
return (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
<div class="transition-all fixed lg:static bottom-0 left-0 w-full lg:w-auto shadow-inner lg:shadow-none dark:bg-black">
|
||||
<Separator />
|
||||
<div class="flex justify-between">
|
||||
<Popover>
|
||||
<PopoverTrigger>Debug</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<Debug />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div class="m-2">
|
||||
<a
|
||||
class="p-2"
|
||||
href="https://git.doordesk.net/adam/cards/"
|
||||
target="_blank"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a class="p-2" href="mailto:adam@doordesk.net">
|
||||
Contact
|
||||
</a>
|
||||
</div>
|
||||
<Drawer>
|
||||
<DrawerTrigger>Chat</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerLabel>Chat</DrawerLabel>
|
||||
<Chat />
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
import Joi from "joi";
|
||||
import {
|
||||
createEffect,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
createContext,
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
|
||||
export const WebsocketContext = createContext();
|
||||
|
||||
export function WebsocketProvider(props) {
|
||||
const socket = new WebSocket("ws://127.0.0.1:3030/websocket");
|
||||
|
||||
// Signals
|
||||
let [active_games, set_active_games] = createSignal(null);
|
||||
let [card_packs_meta, set_card_packs_meta] = createSignal(null);
|
||||
let [chat_message, set_chat_message] = createSignal(null);
|
||||
let [chat_update, set_chat_update] = createSignal(null);
|
||||
let [connected, set_connected] = createSignal(false);
|
||||
let [game_meta, set_game_meta] = createSignal(null);
|
||||
let [game_state, set_game_state] = createSignal(null);
|
||||
let [games_count, set_games_count] = createSignal(null);
|
||||
let [judge_round, set_judge_round] = createSignal(null);
|
||||
let [user_update, set_user_update] = createSignal(null);
|
||||
let [users_count, set_users_count] = createSignal(null);
|
||||
|
||||
// Wipe everything on disconnect
|
||||
createEffect(() => {
|
||||
if (!connected()) {
|
||||
set_active_games(null);
|
||||
set_card_packs_meta(null);
|
||||
set_chat_message(null);
|
||||
set_chat_update(null);
|
||||
set_game_meta(null);
|
||||
set_game_state(null);
|
||||
set_games_count(null);
|
||||
set_judge_round(null);
|
||||
set_user_update(null);
|
||||
set_users_count(null);
|
||||
}
|
||||
});
|
||||
|
||||
const state = [connected];
|
||||
|
||||
// Incoming message types
|
||||
const UserUpdate = Joi.object({
|
||||
username: Joi.string(),
|
||||
});
|
||||
|
||||
const ChatMessage = Joi.object({
|
||||
text: Joi.string(),
|
||||
});
|
||||
|
||||
const ServerOnlineUsers = Joi.object({
|
||||
online_users: Joi.number(),
|
||||
});
|
||||
|
||||
const ServerActiveGames = Joi.object({
|
||||
active_games: Joi.number(),
|
||||
});
|
||||
|
||||
const ChatUpdate = Joi.object({
|
||||
room: Joi.string(),
|
||||
users: Joi.number(),
|
||||
});
|
||||
|
||||
const GamesUpdate = Joi.object({
|
||||
games: Joi.array(),
|
||||
});
|
||||
|
||||
const CardPacksMeta = Joi.object({
|
||||
official_meta: Joi.array(),
|
||||
unofficial_meta: Joi.array(),
|
||||
});
|
||||
|
||||
// Message handler
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
let json = JSON.parse(event.data);
|
||||
|
||||
// TODO: This is ridiculous but it works
|
||||
try {
|
||||
Joi.attempt(json, UserUpdate);
|
||||
console.log("UserUpdate! Name is: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, ChatMessage);
|
||||
console.log("Chat Message: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, ServerOnlineUsers);
|
||||
console.log("Online Users: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, ServerActiveGames);
|
||||
console.log("Active Games: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, ChatUpdate);
|
||||
console.log("Chat Update: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, GamesUpdate);
|
||||
console.log("GamesUpdate: ", json);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
Joi.attempt(json, CardPacksMeta);
|
||||
console.log("Card Packs: ", json);
|
||||
} catch {}
|
||||
};
|
||||
socket.addEventListener("message", handleMessage);
|
||||
|
||||
// Close handler
|
||||
const handleClose = (event: CloseEvent) => {
|
||||
set_connected(false);
|
||||
console.log("Disconnected from websocket", event.code, event.reason);
|
||||
};
|
||||
socket.addEventListener("close", handleClose);
|
||||
|
||||
// Open handler
|
||||
const handleOpen = () => {
|
||||
set_connected(true);
|
||||
console.log("Connected to websocket");
|
||||
};
|
||||
socket.addEventListener("open", handleOpen);
|
||||
|
||||
// Cleanup
|
||||
onCleanup(() => {
|
||||
socket.removeEventListener("message", handleMessage);
|
||||
socket.removeEventListener("close", handleClose);
|
||||
socket.close();
|
||||
});
|
||||
|
||||
return (
|
||||
<WebsocketContext.Provider value={state}>
|
||||
{props.children}
|
||||
</WebsocketContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useWebsocket() {
|
||||
return useContext(WebsocketContext);
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type { ButtonRootProps } from "@kobalte/core/button";
|
||||
import { Button as ButtonPrimitive } from "@kobalte/core/button";
|
||||
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import type { VariantProps } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority";
|
||||
import type { ValidComponent } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
export const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-[color,background-color,box-shadow] focus-visible:outline-none focus-visible:ring-[1.5px] focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2",
|
||||
sm: "h-8 rounded-md px-3 text-xs",
|
||||
lg: "h-10 rounded-md px-8",
|
||||
icon: "h-9 w-9",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
type buttonProps<T extends ValidComponent = "button"> = ButtonRootProps<T> &
|
||||
VariantProps<typeof buttonVariants> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const Button = <T extends ValidComponent = "button">(
|
||||
props: PolymorphicProps<T, buttonProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as buttonProps, [
|
||||
"class",
|
||||
"variant",
|
||||
"size",
|
||||
]);
|
||||
|
||||
return (
|
||||
<ButtonPrimitive
|
||||
class={cn(
|
||||
buttonVariants({
|
||||
size: local.size,
|
||||
variant: local.variant,
|
||||
}),
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,128 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type {
|
||||
DialogContentProps,
|
||||
DialogDescriptionProps,
|
||||
DialogTitleProps,
|
||||
} from "@kobalte/core/dialog";
|
||||
import { Dialog as DialogPrimitive } from "@kobalte/core/dialog";
|
||||
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import type { ComponentProps, ParentProps, ValidComponent } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
export const Dialog = DialogPrimitive;
|
||||
export const DialogTrigger = DialogPrimitive.Trigger;
|
||||
|
||||
type dialogContentProps<T extends ValidComponent = "div"> = ParentProps<
|
||||
DialogContentProps<T> & {
|
||||
class?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export const DialogContent = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, dialogContentProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as dialogContentProps, [
|
||||
"class",
|
||||
"children",
|
||||
]);
|
||||
|
||||
return (
|
||||
<DialogPrimitive.Portal>
|
||||
<DialogPrimitive.Overlay
|
||||
class={cn(
|
||||
"fixed inset-0 z-50 bg-background/80 data-[expanded]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[expanded]:fade-in-0",
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
<DialogPrimitive.Content
|
||||
class={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg data-[closed]:duration-200 data-[expanded]:duration-200 data-[expanded]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[expanded]:fade-in-0 data-[closed]:zoom-out-95 data-[expanded]:zoom-in-95 data-[closed]:slide-out-to-left-1/2 data-[closed]:slide-out-to-top-[48%] data-[expanded]:slide-in-from-left-1/2 data-[expanded]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{local.children}
|
||||
<DialogPrimitive.CloseButton class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-[opacity,box-shadow] hover:opacity-100 focus:outline-none focus:ring-[1.5px] focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="h-4 w-4"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M18 6L6 18M6 6l12 12"
|
||||
/>
|
||||
<title>Close</title>
|
||||
</svg>
|
||||
</DialogPrimitive.CloseButton>
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPrimitive.Portal>
|
||||
);
|
||||
};
|
||||
|
||||
type dialogTitleProps<T extends ValidComponent = "h2"> = DialogTitleProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const DialogTitle = <T extends ValidComponent = "h2">(
|
||||
props: PolymorphicProps<T, dialogTitleProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as dialogTitleProps, ["class"]);
|
||||
|
||||
return (
|
||||
<DialogPrimitive.Title
|
||||
class={cn("text-lg font-semibold text-foreground", local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type dialogDescriptionProps<T extends ValidComponent = "p"> =
|
||||
DialogDescriptionProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const DialogDescription = <T extends ValidComponent = "p">(
|
||||
props: PolymorphicProps<T, dialogDescriptionProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as dialogDescriptionProps, ["class"]);
|
||||
|
||||
return (
|
||||
<DialogPrimitive.Description
|
||||
class={cn("text-sm text-muted-foreground", local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const DialogHeader = (props: ComponentProps<"div">) => {
|
||||
const [local, rest] = splitProps(props, ["class"]);
|
||||
|
||||
return (
|
||||
<div
|
||||
class={cn(
|
||||
"flex flex-col space-y-2 text-center sm:text-left",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const DialogFooter = (props: ComponentProps<"div">) => {
|
||||
const [local, rest] = splitProps(props, ["class"]);
|
||||
|
||||
return (
|
||||
<div
|
||||
class={cn(
|
||||
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,107 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type {
|
||||
ContentProps,
|
||||
DescriptionProps,
|
||||
DynamicProps,
|
||||
LabelProps,
|
||||
} from "@corvu/drawer";
|
||||
import DrawerPrimitive from "@corvu/drawer";
|
||||
import type { ComponentProps, ParentProps, ValidComponent } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
export const Drawer = DrawerPrimitive;
|
||||
export const DrawerTrigger = DrawerPrimitive.Trigger;
|
||||
export const DrawerClose = DrawerPrimitive.Close;
|
||||
|
||||
type drawerContentProps<T extends ValidComponent = "div"> = ParentProps<
|
||||
ContentProps<T> & {
|
||||
class?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export const DrawerContent = <T extends ValidComponent = "div">(
|
||||
props: DynamicProps<T, drawerContentProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as drawerContentProps, [
|
||||
"class",
|
||||
"children",
|
||||
]);
|
||||
const ctx = DrawerPrimitive.useContext();
|
||||
|
||||
return (
|
||||
<DrawerPrimitive.Portal>
|
||||
<DrawerPrimitive.Overlay
|
||||
class="fixed inset-0 z-50 data-[transitioning]:transition-colors data-[transitioning]:duration-200"
|
||||
style={{
|
||||
"background-color": `hsl(var(--background) / ${0.8 * ctx.openPercentage()})`,
|
||||
}}
|
||||
/>
|
||||
<DrawerPrimitive.Content
|
||||
class={cn(
|
||||
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-xl border bg-background after:absolute after:inset-x-0 after:top-full after:h-[50%] after:bg-inherit data-[transitioning]:transition-transform data-[transitioning]:duration-200 md:select-none",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||
{local.children}
|
||||
</DrawerPrimitive.Content>
|
||||
</DrawerPrimitive.Portal>
|
||||
);
|
||||
};
|
||||
|
||||
export const DrawerHeader = (props: ComponentProps<"div">) => {
|
||||
const [local, rest] = splitProps(props, ["class"]);
|
||||
|
||||
return (
|
||||
<div
|
||||
class={cn("grid gap-1.5 p-4 text-center sm:text-left", local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const DrawerFooter = (props: ComponentProps<"div">) => {
|
||||
const [local, rest] = splitProps(props, ["class"]);
|
||||
|
||||
return (
|
||||
<div class={cn("mt-auto flex flex-col gap-2 p-4", local.class)} {...rest} />
|
||||
);
|
||||
};
|
||||
|
||||
type DrawerLabelProps = LabelProps & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const DrawerLabel = <T extends ValidComponent = "h2">(
|
||||
props: DynamicProps<T, DrawerLabelProps>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as DrawerLabelProps, ["class"]);
|
||||
|
||||
return (
|
||||
<DrawerPrimitive.Label
|
||||
class={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type DrawerDescriptionProps = DescriptionProps & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const DrawerDescription = <T extends ValidComponent = "p">(
|
||||
props: DynamicProps<T, DrawerDescriptionProps>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as DrawerDescriptionProps, ["class"]);
|
||||
|
||||
return (
|
||||
<DrawerPrimitive.Description
|
||||
class={cn("text-sm text-muted-foreground", local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,65 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import type {
|
||||
PopoverContentProps,
|
||||
PopoverRootProps,
|
||||
} from "@kobalte/core/popover";
|
||||
import { Popover as PopoverPrimitive } from "@kobalte/core/popover";
|
||||
import type { ParentProps, ValidComponent } from "solid-js";
|
||||
import { mergeProps, splitProps } from "solid-js";
|
||||
|
||||
export const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
export const PopoverTitle = PopoverPrimitive.Title;
|
||||
export const PopoverDescription = PopoverPrimitive.Description;
|
||||
|
||||
export const Popover = (props: PopoverRootProps) => {
|
||||
const merge = mergeProps<PopoverRootProps[]>({ gutter: 4 }, props);
|
||||
|
||||
return <PopoverPrimitive {...merge} />;
|
||||
};
|
||||
|
||||
type popoverContentProps<T extends ValidComponent = "div"> = ParentProps<
|
||||
PopoverContentProps<T> & {
|
||||
class?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export const PopoverContent = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, popoverContentProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as popoverContentProps, [
|
||||
"class",
|
||||
"children",
|
||||
]);
|
||||
|
||||
return (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
class={cn(
|
||||
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[expanded]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[expanded]:fade-in-0 data-[closed]:zoom-out-95 data-[expanded]:zoom-in-95",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{local.children}
|
||||
<PopoverPrimitive.CloseButton class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-[opacity,box-shadow] hover:opacity-100 focus:outline-none focus:ring-[1.5px] focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="h-4 w-4"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M18 6L6 18M6 6l12 12"
|
||||
/>
|
||||
<title>Close</title>
|
||||
</svg>
|
||||
</PopoverPrimitive.CloseButton>
|
||||
</PopoverPrimitive.Content>
|
||||
</PopoverPrimitive.Portal>
|
||||
);
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import type { SeparatorRootProps } from "@kobalte/core/separator";
|
||||
import { Separator as SeparatorPrimitive } from "@kobalte/core/separator";
|
||||
import type { ValidComponent } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
type separatorProps<T extends ValidComponent = "hr"> = SeparatorRootProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const Separator = <T extends ValidComponent = "hr">(
|
||||
props: PolymorphicProps<T, separatorProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as separatorProps, ["class"]);
|
||||
|
||||
return (
|
||||
<SeparatorPrimitive
|
||||
class={cn(
|
||||
"shrink-0 bg-border data-[orientation=horizontal]:h-[1px] data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-[1px]",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,133 +0,0 @@
|
|||
import { cn } from "@/libs/cn";
|
||||
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import type {
|
||||
TabsContentProps,
|
||||
TabsIndicatorProps,
|
||||
TabsListProps,
|
||||
TabsRootProps,
|
||||
TabsTriggerProps,
|
||||
} from "@kobalte/core/tabs";
|
||||
import { Tabs as TabsPrimitive } from "@kobalte/core/tabs";
|
||||
import type { VariantProps } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority";
|
||||
import type { ValidComponent, VoidProps } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
type tabsProps<T extends ValidComponent = "div"> = TabsRootProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const Tabs = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, tabsProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as tabsProps, ["class"]);
|
||||
|
||||
return (
|
||||
<TabsPrimitive
|
||||
class={cn("w-full data-[orientation=vertical]:flex", local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type tabsListProps<T extends ValidComponent = "div"> = TabsListProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const TabsList = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, tabsListProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as tabsListProps, ["class"]);
|
||||
|
||||
return (
|
||||
<TabsPrimitive.List
|
||||
class={cn(
|
||||
"relative flex w-full rounded-lg bg-muted p-1 text-muted-foreground data-[orientation=vertical]:flex-col data-[orientation=horizontal]:items-center data-[orientation=vertical]:items-stretch",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type tabsContentProps<T extends ValidComponent = "div"> =
|
||||
TabsContentProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const TabsContent = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, tabsContentProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as tabsContentProps, ["class"]);
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Content
|
||||
class={cn(
|
||||
"transition-shadow duration-200 focus-visible:outline-none focus-visible:ring-[1.5px] focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background data-[orientation=horizontal]:mt-2 data-[orientation=vertical]:ml-2",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type tabsTriggerProps<T extends ValidComponent = "button"> =
|
||||
TabsTriggerProps<T> & {
|
||||
class?: string;
|
||||
};
|
||||
|
||||
export const TabsTrigger = <T extends ValidComponent = "button">(
|
||||
props: PolymorphicProps<T, tabsTriggerProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as tabsTriggerProps, ["class"]);
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Trigger
|
||||
class={cn(
|
||||
"peer relative z-10 inline-flex h-7 w-full items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium outline-none transition-colors disabled:pointer-events-none disabled:opacity-50 data-[selected]:text-foreground",
|
||||
local.class,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const tabsIndicatorVariants = cva(
|
||||
"absolute transition-all duration-200 outline-none",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
block:
|
||||
"data-[orientation=horizontal]:bottom-1 data-[orientation=horizontal]:left-0 data-[orientation=vertical]:right-1 data-[orientation=vertical]:top-0 data-[orientation=horizontal]:h-[calc(100%-0.5rem)] data-[orientation=vertical]:w-[calc(100%-0.5rem)] bg-background shadow rounded-md peer-focus-visible:ring-[1.5px] peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background peer-focus-visible:outline-none",
|
||||
underline:
|
||||
"data-[orientation=horizontal]:-bottom-[1px] data-[orientation=horizontal]:left-0 data-[orientation=vertical]:-right-[1px] data-[orientation=vertical]:top-0 data-[orientation=horizontal]:h-[2px] data-[orientation=vertical]:w-[2px] bg-primary",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "block",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
type tabsIndicatorProps<T extends ValidComponent = "div"> = VoidProps<
|
||||
TabsIndicatorProps<T> &
|
||||
VariantProps<typeof tabsIndicatorVariants> & {
|
||||
class?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export const TabsIndicator = <T extends ValidComponent = "div">(
|
||||
props: PolymorphicProps<T, tabsIndicatorProps<T>>,
|
||||
) => {
|
||||
const [local, rest] = splitProps(props as tabsIndicatorProps, [
|
||||
"class",
|
||||
"variant",
|
||||
]);
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Indicator
|
||||
class={cn(tabsIndicatorVariants({ variant: local.variant }), local.class)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,158 +0,0 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-cyrillic-ext.woff2") format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||
U+FE2E-FE2F;
|
||||
}
|
||||
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-cyrillic.woff2") format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-greek-ext.woff2") format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-greek.woff2") format("woff2");
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1,
|
||||
U+03A3-03FF;
|
||||
}
|
||||
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-vietnamese.woff2") format("woff2");
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||
U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
|
||||
U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-latin-ext.woff2") format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
|
||||
U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/Inter-normal-400-latin.woff2") format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
|
||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 3.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 0 0% 3.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 0 0% 3.9%;
|
||||
|
||||
--primary: 0 0% 9%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
--secondary: 0 0% 96.1%;
|
||||
--secondary-foreground: 0 0% 9%;
|
||||
|
||||
--muted: 0 0% 96.1%;
|
||||
--muted-foreground: 0 0% 45.1%;
|
||||
|
||||
--accent: 0 0% 96.1%;
|
||||
--accent-foreground: 0 0% 9%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--border: 0 0% 89.8%;
|
||||
--input: 0 0% 89.8%;
|
||||
--ring: 0 0% 3.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
[data-kb-theme="dark"] {
|
||||
--background: 0 0% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
||||
--popover: 0 0% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 0 0% 9%;
|
||||
|
||||
--secondary: 0 0% 14.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--muted: 0 0% 14.9%;
|
||||
--muted-foreground: 0 0% 63.9%;
|
||||
|
||||
--accent: 0 0% 14.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--border: 0 0% 14.9%;
|
||||
--input: 0 0% 14.9%;
|
||||
--ring: 0 0% 83.1%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: "Inter", "Arial", sans-serif;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
/* @refresh reload */
|
||||
import "./index.css";
|
||||
import { render } from "solid-js/web";
|
||||
import App from "./App";
|
||||
|
||||
const root = document.getElementById("root");
|
||||
|
||||
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
||||
throw new Error(
|
||||
"Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?",
|
||||
);
|
||||
}
|
||||
|
||||
render(() => <App />, root!);
|
|
@ -1,5 +0,0 @@
|
|||
import type { ClassValue } from "clsx";
|
||||
import clsx from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export const cn = (...classLists: ClassValue[]) => twMerge(clsx(classLists));
|
|
@ -1,9 +0,0 @@
|
|||
import type { JSXElement } from "solid-js";
|
||||
|
||||
export default function Browser(): JSXElement {
|
||||
return (
|
||||
<>
|
||||
browser
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
import type { JSXElement } from "solid-js";
|
||||
|
||||
export default function Game(): JSXElement {
|
||||
return <>game</>;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import type { JSXElement } from "solid-js";
|
||||
|
||||
export default function Home(): JSXElement {
|
||||
return (
|
||||
<>
|
||||
<div class="p-4">
|
||||
<h2 class="text-2xl">Hey!</h2>
|
||||
<p class="indent-4 text-pretty my-3">
|
||||
{
|
||||
"Welcome! Thank you for helping me test this. Please let me know about any issues you may come across. Chances are you already know how to contact me but in case you don't you can email me at "
|
||||
}
|
||||
<a class="link link-info" href="mailto:adam@doordesk.net">
|
||||
adam@doordesk.net
|
||||
</a>
|
||||
{
|
||||
". The server may go down from time to time as bugs are found and as I add updates. If you manage to crash the server or notice it down for a long time please tell me about it."
|
||||
}
|
||||
</p>
|
||||
<p>Have fun!</p>
|
||||
</div>
|
||||
<div class="my-5 flex flex-wrap justify-around">
|
||||
<Button>Find a Game</Button>
|
||||
<Button>Create a Game</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
darkMode: ["class", '[data-kb-theme="dark"]'],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx,css,md,mdx,html,json,scss}",
|
||||
],
|
||||
prefix: "",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
screens: {
|
||||
"2xl": "1400px",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--kb-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--kb-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
"collapsible-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--kb-collapsible-content-height)" },
|
||||
},
|
||||
"collapsible-up": {
|
||||
from: { height: "var(--kb-collapsible-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
"caret-blink": {
|
||||
"0%,70%,100%": { opacity: "1" },
|
||||
"20%,50%": { opacity: "0" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
"collapsible-down": "collapsible-down 0.2s ease-out",
|
||||
"collapsible-up": "collapsible-up 0.2s ease-out",
|
||||
"caret-blink": "caret-blink 1.25s ease-out infinite",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require("tailwindcss-animate")],
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"types": [
|
||||
"vite/client"
|
||||
],
|
||||
"noEmit": true,
|
||||
"isolatedModules": true,
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
import { defineConfig } from "vite";
|
||||
import solidPlugin from "vite-plugin-solid";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
// import devtools from 'solid-devtools/vite';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
/*
|
||||
Uncomment the following line to enable solid-devtools.
|
||||
For more info see https://github.com/thetarnav/solid-devtools/tree/main/packages/extension#readme
|
||||
*/
|
||||
// devtools(),
|
||||
solidPlugin(),
|
||||
],
|
||||
server: {
|
||||
host: "127.0.0.1",
|
||||
port: 3000,
|
||||
},
|
||||
build: {
|
||||
target: "esnext",
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
module.exports = {
|
||||
content: {
|
||||
relative: true,
|
||||
files: ["./clients/leptos/*.html", "./clients/leptos/src/**/*.rs"],
|
||||
files: ["./client/*.html", "./client/src/**/*.rs"],
|
||||
},
|
||||
theme: {
|
||||
extend: {},
|
||||
|
|
2
test
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
cargo watch -i clients -i tools -cx "run -p server -- $1 $2"
|
||||
cargo watch -i client -i tools -cx "run -p server -- $1 $2"
|
||||
|
|