added shadcn and started PROJECT.md for tracking
This commit is contained in:
189
src/lib/components/data-table-cell-viewer.svelte
Normal file
189
src/lib/components/data-table-cell-viewer.svelte
Normal file
@@ -0,0 +1,189 @@
|
||||
<script lang="ts">
|
||||
import TrendingUpIcon from "@tabler/icons-svelte/icons/trending-up";
|
||||
import { scaleUtc } from "d3-scale";
|
||||
import { curveNatural } from "d3-shape";
|
||||
import { AreaChart } from "layerchart";
|
||||
import * as Chart from "#lib/components/ui/chart/index.js";
|
||||
import * as Drawer from "#lib/components/ui/drawer/index.js";
|
||||
import * as Select from "#lib/components/ui/select/index.js";
|
||||
import { IsMobile } from "#lib/hooks/is-mobile.svelte.js";
|
||||
import { Button } from "#lib/components/ui/button/index.js";
|
||||
import { Input } from "#lib/components/ui/input/index.js";
|
||||
import { Label } from "#lib/components/ui/label/index.js";
|
||||
import { Separator } from "#lib/components/ui/separator/index.js";
|
||||
import type { Schema } from "./schemas.js";
|
||||
|
||||
const chartData = [
|
||||
{ date: new Date("2024-01-01"), desktop: 186, mobile: 80 },
|
||||
{ date: new Date("2024-02-01"), desktop: 305, mobile: 200 },
|
||||
{ date: new Date("2024-03-01"), desktop: 237, mobile: 120 },
|
||||
{ date: new Date("2024-04-01"), desktop: 73, mobile: 190 },
|
||||
{ date: new Date("2024-05-01"), desktop: 209, mobile: 130 },
|
||||
{ date: new Date("2024-06-01"), desktop: 214, mobile: 140 },
|
||||
];
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: "Desktop",
|
||||
color: "var(--primary)",
|
||||
},
|
||||
mobile: {
|
||||
label: "Mobile",
|
||||
color: "var(--primary)",
|
||||
},
|
||||
} satisfies Chart.ChartConfig;
|
||||
|
||||
const isMobile = new IsMobile();
|
||||
|
||||
let { item }: { item: Schema } = $props();
|
||||
|
||||
let type = $derived(item.type);
|
||||
let status = $derived(item.status);
|
||||
let reviewer = $derived(item.reviewer);
|
||||
</script>
|
||||
|
||||
<Drawer.Root direction={isMobile.current ? "bottom" : "right"}>
|
||||
<Drawer.Trigger>
|
||||
{#snippet child({ props })}
|
||||
<Button variant="link" class="w-fit px-0 text-start text-foreground" {...props}>
|
||||
{item.header}
|
||||
</Button>
|
||||
{/snippet}
|
||||
</Drawer.Trigger>
|
||||
<Drawer.Content>
|
||||
<Drawer.Header class="gap-1">
|
||||
<Drawer.Title>{item.header}</Drawer.Title>
|
||||
<Drawer.Description>Showing total visitors for the last 6 months</Drawer.Description>
|
||||
</Drawer.Header>
|
||||
<div class="flex flex-col gap-4 overflow-y-auto px-4 text-sm">
|
||||
{#if !isMobile.current}
|
||||
<Chart.Container config={chartConfig}>
|
||||
<AreaChart
|
||||
data={chartData}
|
||||
x="date"
|
||||
xScale={scaleUtc()}
|
||||
yDomain={[0, 600]}
|
||||
series={[
|
||||
{
|
||||
key: "mobile",
|
||||
label: "Mobile",
|
||||
color: chartConfig.mobile.color,
|
||||
},
|
||||
{
|
||||
key: "desktop",
|
||||
label: "Desktop",
|
||||
color: chartConfig.desktop.color,
|
||||
},
|
||||
]}
|
||||
seriesLayout="stack"
|
||||
props={{
|
||||
area: {
|
||||
curve: curveNatural,
|
||||
fillOpacity: 0.4,
|
||||
line: { class: "stroke-1" },
|
||||
motion: "tween",
|
||||
},
|
||||
xAxis: {
|
||||
format: (v) => v.toLocaleDateString("en-US", { month: "short" }),
|
||||
},
|
||||
yAxis: { ticks: [0, 300, 600] },
|
||||
}}
|
||||
>
|
||||
{#snippet tooltip()}
|
||||
<Chart.Tooltip
|
||||
labelFormatter={(v: Date) => {
|
||||
return v.toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
});
|
||||
}}
|
||||
indicator="dot"
|
||||
/>
|
||||
{/snippet}
|
||||
</AreaChart>
|
||||
</Chart.Container>
|
||||
<Separator />
|
||||
<div class="grid gap-2">
|
||||
<div class="flex gap-2 leading-none font-medium">
|
||||
Trending up by 5.2% this month
|
||||
<TrendingUpIcon class="size-4" />
|
||||
</div>
|
||||
<div class="text-muted-foreground">
|
||||
Showing total visitors for the last 6 months. This is just some random text to test the
|
||||
layout. It spans multiple lines and should wrap around.
|
||||
</div>
|
||||
</div>
|
||||
<Separator />
|
||||
{/if}
|
||||
<form class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="header">Header</Label>
|
||||
<Input id="header" value={item.header} />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="type">Type</Label>
|
||||
<Select.Root type="single" bind:value={type}>
|
||||
<Select.Trigger id="type" class="w-full">
|
||||
{type ?? "Select a type"}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="Table of Contents">Table of Contents</Select.Item>
|
||||
<Select.Item value="Executive Summary">Executive Summary</Select.Item>
|
||||
<Select.Item value="Technical Approach">Technical Approach</Select.Item>
|
||||
<Select.Item value="Design">Design</Select.Item>
|
||||
<Select.Item value="Capabilities">Capabilities</Select.Item>
|
||||
<Select.Item value="Focus Documents">Focus Documents</Select.Item>
|
||||
<Select.Item value="Narrative">Narrative</Select.Item>
|
||||
<Select.Item value="Cover Page">Cover Page</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="status">Status</Label>
|
||||
<Select.Root type="single" bind:value={status}>
|
||||
<Select.Trigger id="status" class="w-full">
|
||||
{status ?? "Select a status"}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="Done">Done</Select.Item>
|
||||
<Select.Item value="In Progress">In Progress</Select.Item>
|
||||
<Select.Item value="Not Started">Not Started</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="target">Target</Label>
|
||||
<Input id="target" value={item.target} />
|
||||
</div>
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="limit">Limit</Label>
|
||||
<Input id="limit" value={item.limit} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3">
|
||||
<Label for="reviewer">Reviewer</Label>
|
||||
<Select.Root type="single" bind:value={reviewer}>
|
||||
<Select.Trigger id="reviewer" class="w-full">
|
||||
{reviewer ?? "Select a reviewer"}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="Eddie Lake">Eddie Lake</Select.Item>
|
||||
<Select.Item value="Jamik Tashpulatov">Jamik Tashpulatov</Select.Item>
|
||||
<Select.Item value="Emily Whalen">Emily Whalen</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<Drawer.Footer>
|
||||
<Button>Submit</Button>
|
||||
<Drawer.Close>
|
||||
{#snippet child({ props })}
|
||||
<Button variant="outline" {...props}>Done</Button>
|
||||
{/snippet}
|
||||
</Drawer.Close>
|
||||
</Drawer.Footer>
|
||||
</Drawer.Content>
|
||||
</Drawer.Root>
|
||||
Reference in New Issue
Block a user