feat: update navigation labels and add new components for item listing
Deploy to Cloudflare Pages / deploy (push) Failing after 41s

This commit is contained in:
2026-07-06 10:10:19 +07:00 Unverified
parent 4227947510
commit 2cd05c866c
9 changed files with 156 additions and 11 deletions
+26
View File
@@ -0,0 +1,26 @@
<script lang="ts">
import { cn } from "$lib/utils";
import FileExclamationPointIcon from "@lucide/svelte/icons/file-exclamation-point";
import type { HTMLImgAttributes } from "svelte/elements";
const props: HTMLImgAttributes = $props();
let loaded = $state(false);
let error = $state(false);
$effect(() => {
void props.src;
loaded = false;
error = false;
});
</script>
{#if error}
<div class="flex items-center justify-center opacity-50">
<FileExclamationPointIcon />
</div>{:else}
<img
{...props}
onload={() => (loaded = true)}
onerror={() => (error = true)}
class={cn("opacity-0", loaded && "opacity-100")}
/>
{/if}
+49
View File
@@ -0,0 +1,49 @@
<script lang="ts" module>
import { type VariantProps, tv } from "tailwind-variants";
export const badgeVariants = tv({
base: "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-colors focus-visible:ring-[3px] [&>svg]:pointer-events-none",
variants: {
variant: {
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
link: "text-primary underline-offset-4 hover:underline",
},
},
defaultVariants: {
variant: "default",
},
});
export type BadgeVariant = VariantProps<typeof badgeVariants>["variant"];
</script>
<script lang="ts">
import type { HTMLAnchorAttributes } from "svelte/elements";
import { cn, type WithElementRef } from "$lib/utils.js";
let {
ref = $bindable(null),
href,
class: className,
variant = "default",
children,
...restProps
}: WithElementRef<HTMLAnchorAttributes> & {
variant?: BadgeVariant;
} = $props();
</script>
<svelte:element
this={href ? "a" : "span"}
bind:this={ref}
data-slot="badge"
{href}
class={cn(badgeVariants({ variant }), className)}
{...restProps}
>
{@render children?.()}
</svelte:element>
+2
View File
@@ -0,0 +1,2 @@
export { default as Badge } from "./badge.svelte";
export { badgeVariants, type BadgeVariant } from "./badge.svelte";
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"nav": { "nav": {
"home": "Home", "home": "Home",
"search": "Search", "list": "Fridge",
"scan": "Scan", "scan": "Scan",
"guide": "Guide", "guide": "Guide",
"settings": "Settings" "settings": "Settings"
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"nav": { "nav": {
"home": "หน้าหลัก", "home": "หน้าหลัก",
"search": "ค้นหา", "list": "รายการ",
"scan": "สแกน", "scan": "สแกน",
"guide": "ไกด์", "guide": "ไกด์",
"settings": "การตั้งค่า" "settings": "การตั้งค่า"
+14
View File
@@ -0,0 +1,14 @@
<script>
import Item from "./item.svelte";
</script>
<div class="flex flex-col gap-2 p-2">
{#each Array(20)}
<Item
name="ข้าวมันไก่"
expiry={new Date()}
icon="abc"
category="อาหารจารเดียว"
/>
{/each}
</div>
+48
View File
@@ -0,0 +1,48 @@
<script lang="ts">
import Image from "$lib/components/image.svelte";
import Badge from "$lib/components/ui/badge/badge.svelte";
const {
icon,
name,
expiry,
category,
}: { icon: string; name: string; expiry: Date; category: string } = $props();
</script>
<button
type="button"
title={`Item ${name}`}
class="flex cursor-pointer items-start gap-3 rounded-md border p-3 text-left transition-colors hover:bg-accent"
>
<div
class="flex size-16 shrink-0 items-center justify-center rounded bg-muted"
>
<!-- {r.paid ? (
<Check class="size-5 text-green-500" />
) : r.expires && new Date(r.expires) <= new Date() ? (
<Circle class="size-5 text-muted-foreground" />
) : (
<Clock class="size-5 text-yellow-500" />
)} -->
<Image src={icon} />
</div>
<div class="flex min-w-0 flex-1 flex-col gap-0.5">
<div class="flex items-center gap-2">
<span class="truncate font-medium">{name}</span>
</div>
<span class="truncate text-xs text-muted-foreground">{expiry}</span>
<div class="flex items-center gap-2 text-xs">
<Badge variant="outline">{category}</Badge>
<span class="font-medium">123 ฿</span>
<!-- {r.paid ? (
<span class="text-green-500">ชำระแล้ว</span>
) : r.expires && new Date(r.expires) <= new Date() ? (
<span class="text-muted-foreground">หมดเวลา</span>
) : (
<span class="text-yellow-500">รอชำระ</span>
)} -->
<span class="text-green-500">ชำระแล้ว</span>
</div>
</div>
</button>
+15 -8
View File
@@ -2,7 +2,7 @@
import NavButton from "$lib/components/nav/nav-button.svelte"; import NavButton from "$lib/components/nav/nav-button.svelte";
import NavCam from "$lib/components/nav/nav-cam.svelte"; import NavCam from "$lib/components/nav/nav-cam.svelte";
import HomeIcon from "@lucide/svelte/icons/house"; import HomeIcon from "@lucide/svelte/icons/house";
import SearchIcon from "@lucide/svelte/icons/search"; import ListIcon from "@lucide/svelte/icons/list";
import GuideIcon from "@lucide/svelte/icons/book-image"; import GuideIcon from "@lucide/svelte/icons/book-image";
import SettingsIcon from "@lucide/svelte/icons/settings"; import SettingsIcon from "@lucide/svelte/icons/settings";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
@@ -10,13 +10,13 @@
let { children } = $props(); let { children } = $props();
</script> </script>
<div> <div class="wrap flex h-dvh flex-col overflow-hidden">
<div class="content"> <div class="content">
{@render children()} {@render children()}
</div> </div>
<div class="navbar flex items-center justify-evenly bg-sidebar"> <div class="navbar flex items-center justify-evenly bg-sidebar">
<NavButton label={$_("nav.home")} icon={HomeIcon} href="/app/home" /> <NavButton label={$_("nav.home")} icon={HomeIcon} href="/app/home" />
<NavButton label={$_("nav.search")} icon={SearchIcon} href="/app/search" /> <NavButton label={$_("nav.list")} icon={ListIcon} href="/app/list" />
<NavCam /> <NavCam />
<NavButton label={$_("nav.guide")} icon={GuideIcon} href="/app/guide" /> <NavButton label={$_("nav.guide")} icon={GuideIcon} href="/app/guide" />
<NavButton <NavButton
@@ -29,14 +29,21 @@
<style> <style>
.navbar { .navbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 64px; height: 64px;
flex-shrink: 0;
} }
.content { .content {
padding-bottom: 64px; min-height: 0;
overflow-y: auto;
flex: 1;
}
.content {
scrollbar-width: none;
}
.content::-webkit-scrollbar {
display: none;
} }
</style> </style>
-1
View File
@@ -1 +0,0 @@
search here