UI/Header: move header into subpages & fix general layout
This commit is contained in:
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user