UI/Header: move header into subpages & fix general layout

This commit is contained in:
Johannes Kirschbauer
2024-12-10 15:15:11 +01:00
parent 8ae29bd385
commit a7191b1c90
3 changed files with 132 additions and 134 deletions

View File

@@ -1,33 +1,13 @@
import { createQuery } from "@tanstack/solid-query"; import { JSX } from "solid-js";
import { activeURI } from "../App"; import { Typography } from "../components/Typography";
import { callApi } from "../api";
import { Accessor, Show } from "solid-js";
import { useNavigate } from "@solidjs/router";
import Icon from "../components/icon";
import { Button } from "../components/button";
interface HeaderProps { interface HeaderProps {
clan_dir: Accessor<string | null>; title: string;
toolbar?: JSX.Element;
} }
export const Header = (props: HeaderProps) => { export const Header = (props: HeaderProps) => {
const { clan_dir } = props;
const navigate = useNavigate();
const query = createQuery(() => ({
queryKey: [clan_dir(), "meta"],
queryFn: async () => {
const curr = clan_dir();
if (curr) {
const result = await callApi("show_clan_meta", { uri: curr });
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
}
},
}));
return ( return (
<div class="navbar"> <div class="navbar border-b px-6 py-4 border-def-3">
<div class="flex-none"> <div class="flex-none">
<span class="tooltip tooltip-bottom lg:hidden" data-tip="Menu"> <span class="tooltip tooltip-bottom lg:hidden" data-tip="Menu">
<label <label
@@ -38,19 +18,13 @@ export const Header = (props: HeaderProps) => {
</label> </label>
</span> </span>
</div> </div>
<div class="flex-1"></div> <div class="flex-1">
<div class="flex-none"> <Typography hierarchy="title" size="m" weight="medium">
<Show when={activeURI()}> {props.title}
{(d) => ( </Typography>
<span class="tooltip tooltip-bottom" data-tip="Clan Settings"> </div>
<Button <div class="flex-none items-center justify-center gap-3">
variant="light" {props.toolbar}
onClick={() => navigate(`/clans/${window.btoa(d())}`)}
startIcon={<Icon icon="Settings" />}
></Button>
</span>
)}
</Show>
</div> </div>
</div> </div>
); );

View File

@@ -1,16 +1,14 @@
import { Component, createEffect, Show } from "solid-js"; import { Component, createEffect } from "solid-js";
import { Header } from "./header";
import { Sidebar } from "@/src/components/Sidebar"; import { Sidebar } from "@/src/components/Sidebar";
import { activeURI, clanList } from "../App"; import { clanList } from "../App";
import { RouteSectionProps, useNavigate } from "@solidjs/router"; import { RouteSectionProps, useNavigate } from "@solidjs/router";
export const Layout: Component<RouteSectionProps> = (props) => { export const Layout: Component<RouteSectionProps> = (props) => {
const navigate = useNavigate(); const navigate = useNavigate();
createEffect(() => { createEffect(() => {
console.log("Layout props", props.location);
console.log( console.log(
"empty ClanList, redirect to welcome page", "empty ClanList, redirect to welcome page",
clanList().length === 0, clanList().length === 0
); );
if (clanList().length === 0) { if (clanList().length === 0) {
navigate("/welcome"); navigate("/welcome");
@@ -25,10 +23,7 @@ export const Layout: Component<RouteSectionProps> = (props) => {
type="checkbox" type="checkbox"
class="drawer-toggle hidden" class="drawer-toggle hidden"
/> />
<div class="drawer-content overflow-x-hidden overflow-y-scroll p-2"> <div class="drawer-content my-2 ml-8 overflow-x-hidden overflow-y-scroll rounded-lg border bg-def-1 border-def-3">
<Show when={props.location.pathname !== "welcome"}>
<Header clan_dir={activeURI} />
</Show>
{props.children} {props.children}
</div> </div>
<div <div

View File

@@ -14,6 +14,7 @@ import { createQuery, useQueryClient } from "@tanstack/solid-query";
import { useNavigate } from "@solidjs/router"; import { useNavigate } from "@solidjs/router";
import { Button } from "@/src/components/button"; import { Button } from "@/src/components/button";
import Icon from "@/src/components/icon"; import Icon from "@/src/components/icon";
import { Header } from "@/src/layout/header";
type MachinesModel = Extract< type MachinesModel = Extract<
OperationResponse<"list_inventory_machines">, OperationResponse<"list_inventory_machines">,
@@ -65,96 +66,124 @@ export const MachineListView: Component = () => {
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div> <>
<div class="tooltip tooltip-bottom" data-tip="Open Clan"></div> <Header
<div class="tooltip tooltip-bottom" data-tip="Refresh"> title="Your Machines"
<Button toolbar={
variant="light" <>
onClick={() => refresh()} <span class="tooltip tooltip-bottom" data-tip="Reload">
startIcon={<Icon icon="Reload" />} <Button
></Button> variant="light"
</div> size="s"
onClick={() => refresh()}
startIcon={<Icon icon="Reload" />}
></Button>
</span>
<div class="tooltip tooltip-bottom" data-tip="Create machine"> <div class="border border-def-3">
<Button <span class="tooltip tooltip-bottom" data-tip="List View">
variant="light" <Button
onClick={() => navigate("create")} variant="dark"
startIcon={<Icon icon="Plus" />} size="s"
></Button> startIcon={<Icon icon="List" />}
</div> ></Button>
{/* <Show when={filter()}> */}
<div class="my-1 flex w-full gap-2 p-2">
<div class="size-6 p-1">
<Icon icon="Filter" />
</div>
<For each={filter().tags.sort()}>
{(tag) => (
<button
type="button"
onClick={() =>
setFilter((prev) => {
return {
...prev,
tags: prev.tags.filter((t) => t !== tag),
};
})
}
>
<span class="rounded-full px-3 py-1 bg-inv-4 fg-inv-1">
{tag}
</span> </span>
</button> <span class="tooltip tooltip-bottom" data-tip="Grid View">
)} <Button
</For> variant="light"
</div> size="s"
{/* </Show> */} startIcon={<Icon icon="Grid" />}
<Switch> ></Button>
<Match when={inventoryQuery.isLoading}> </span>
{/* Loading skeleton */} </div>
<div> <span class="tooltip tooltip-bottom" data-tip="New Machine">
<div class="card card-side m-2 bg-base-100 shadow-lg"> <Button
<figure class="pl-2"> onClick={() => navigate("create")}
<div class="skeleton size-12"></div> size="s"
</figure> variant="light"
<div class="card-body"> startIcon={<Icon icon="Plus" />}
<h2 class="card-title"> >
<div class="skeleton h-12 w-80"></div> New Machine
</h2> </Button>
<div class="skeleton h-8 w-72"></div> </span>
</>
}
/>
<div>
{/* <Show when={filter()}> */}
<div class="my-1 flex w-full gap-2 p-2">
<div class="size-6 p-1">
<Icon icon="Filter" />
</div>
<For each={filter().tags.sort()}>
{(tag) => (
<button
type="button"
onClick={() =>
setFilter((prev) => {
return {
...prev,
tags: prev.tags.filter((t) => t !== tag),
};
})
}
>
<span class="rounded-full px-3 py-1 bg-inv-4 fg-inv-1">
{tag}
</span>
</button>
)}
</For>
</div>
{/* </Show> */}
<Switch>
<Match when={inventoryQuery.isLoading}>
{/* Loading skeleton */}
<div>
<div class="card card-side m-2 bg-base-100 shadow-lg">
<figure class="pl-2">
<div class="skeleton size-12"></div>
</figure>
<div class="card-body">
<h2 class="card-title">
<div class="skeleton h-12 w-80"></div>
</h2>
<div class="skeleton h-8 w-72"></div>
</div>
</div> </div>
</div> </div>
</div> </Match>
</Match> <Match
<Match when={!inventoryQuery.isLoading && inventoryMachines().length === 0}
when={!inventoryQuery.isLoading && inventoryMachines().length === 0} >
> <div class="mt-8 flex w-full flex-col items-center justify-center gap-2">
<div class="mt-8 flex w-full flex-col items-center justify-center gap-2"> <span class="text-lg text-neutral">
<span class="text-lg text-neutral"> No machines defined yet. Click below to define one.
No machines defined yet. Click below to define one. </span>
</span> <Button
<Button variant="light"
variant="light" class="size-28 overflow-hidden p-2"
class="size-28 overflow-hidden p-2" onClick={() => navigate("/machines/create")}
onClick={() => navigate("/machines/create")} >
> <span class="material-icons text-6xl font-light">add</span>
<span class="material-icons text-6xl font-light">add</span> </Button>
</Button> </div>
</div> </Match>
</Match> <Match when={!inventoryQuery.isLoading}>
<Match when={!inventoryQuery.isLoading}> <ul>
<ul> <For each={inventoryMachines()}>
<For each={inventoryMachines()}> {([name, info]) => (
{([name, info]) => ( <MachineListItem
<MachineListItem name={name}
name={name} info={info}
info={info} setFilter={setFilter}
setFilter={setFilter} />
/> )}
)} </For>
</For> </ul>
</ul> </Match>
</Match> </Switch>
</Switch> </div>
</div> </>
); );
}; };