120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { For, JSXElement, Show } from "solid-js";
|
|
import { A } from "@solidjs/router";
|
|
import { Icon } from "./Icons.tsx";
|
|
|
|
interface PageContainerProps {
|
|
children?: JSXElement;
|
|
}
|
|
|
|
export function PageContainer(props: PageContainerProps): JSXElement {
|
|
return <div class="admin-page-container">{props.children}</div>;
|
|
}
|
|
|
|
export function Divider(): JSXElement {
|
|
return <hr class="text-line mt-1 mb-3"/>;
|
|
}
|
|
|
|
interface CodeBoxProps {
|
|
code: string;
|
|
class?: string;
|
|
}
|
|
|
|
export function CodeBox(props: CodeBoxProps): JSXElement {
|
|
return (
|
|
<div class={"text-ss p-3 bg-neutral-800 text-neutral-100 border border-neutral-700 rounded-default " + (props.class || "")}>
|
|
<pre><code>{props.code}</code></pre>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface PageHeaderProps {
|
|
text: string | JSXElement;
|
|
class?: string;
|
|
}
|
|
|
|
export function PageHeader(props: PageHeaderProps): JSXElement {
|
|
return (
|
|
<header class={props.class || ""}>
|
|
<div class="mt-1">
|
|
<h1 class="text-center text-2xl font-light text-ink mb-2">{props.text}</h1>
|
|
<hr class="text-line mb-2"/>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|
|
interface PageLinkProps {
|
|
href: string;
|
|
newTab?: boolean;
|
|
class?: string;
|
|
children?: JSXElement;
|
|
}
|
|
|
|
export function PageLink(props: PageLinkProps): JSXElement {
|
|
return (
|
|
<a
|
|
href={props.href}
|
|
class={"text-sky-700 dark:text-sky-400 hover:text-sky-800 hover:underline hover:decoration-1 " + (props.class || "")}
|
|
target={props.newTab ? "_blank" : undefined} rel={props.newTab ? "noopener noreferrer" : undefined}>{props.children}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
export function Loader(props: { class?: string; style?: string }): JSXElement {
|
|
return (
|
|
<div class={"flex items-center justify-center p-8 " + (props.class || "")} style={props.style}>
|
|
<div class="h-8 w-8 border-4 border-sky-700 border-t-transparent rounded-full animate-spin"></div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface BreadcrumbItem {
|
|
url: string;
|
|
displayText: string;
|
|
}
|
|
|
|
interface BreadcrumbsProps {
|
|
items: BreadcrumbItem[];
|
|
}
|
|
|
|
export function Breadcrumbs(props: BreadcrumbsProps): JSXElement {
|
|
return (
|
|
<div class="flex flex-row items-center text-ink-faint text-ss">
|
|
<For each={props.items}>{(crumb, index) => (
|
|
index() !== props.items.length - 1
|
|
? (
|
|
<span class="flex items-center">
|
|
<A href={crumb.url} class="text-ink-muted cursor-pointer no-underline hover:text-ink hover:underline">{crumb.displayText}</A>
|
|
<Icon icon="chevron-right" size={12} class="mx-[0.15rem] opacity-50"/>
|
|
</span>
|
|
)
|
|
: (
|
|
<span class="text-ink font-medium">{crumb.displayText}</span>
|
|
)
|
|
)}</For>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface ManagerPageHeaderProps {
|
|
title: string;
|
|
description?: string;
|
|
action?: JSXElement;
|
|
}
|
|
|
|
export function ManagerPageHeader(props: ManagerPageHeaderProps): JSXElement {
|
|
return (
|
|
<div class="page-header">
|
|
<div>
|
|
<h2 class="page-title">{props.title}</h2>
|
|
<Show when={props.description}>
|
|
<p class="page-desc">{props.description}</p>
|
|
</Show>
|
|
</div>
|
|
<Show when={props.action}>
|
|
{props.action}
|
|
</Show>
|
|
</div>
|
|
);
|
|
}
|