style: apply prettier formatting across frontend components and pages
Some checks failed
Build and Push Backend Image / build (push) Successful in 1m4s
Build and Push Frontend Image / build (push) Has been cancelled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 10:49:35 +01:00
parent 9c5dba5c90
commit f2871b98db
35 changed files with 706 additions and 589 deletions

View File

@@ -320,6 +320,5 @@
{/if}
</div>
</div>
</div>
</div>

View File

@@ -5,8 +5,7 @@
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3",
variants: {
variant: {
default:
"bg-primary text-primary-foreground [a&]:hover:bg-primary/90 border-transparent",
default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90 border-transparent",
secondary:
"bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent",
destructive:

View File

@@ -13,7 +13,7 @@
bind:ref
class={cn(
"relative size-(--cell-size) p-0 text-center text-sm focus-within:z-20 [&:first-child[data-selected]_[data-bits-day]]:rounded-s-md [&:last-child[data-selected]_[data-bits-day]]:rounded-e-md",
className
className,
)}
{...restProps}
/>

View File

@@ -29,7 +29,7 @@
"focus:border-ring focus:ring-ring/50 focus:relative",
// inner spans
"[&>span]:text-xs [&>span]:opacity-70",
className
className,
)}
{...restProps}
/>

View File

@@ -13,7 +13,7 @@
bind:ref
class={cn(
"text-muted-foreground w-(--cell-size) rounded-md text-[0.8rem] font-normal",
className
className,
)}
{...restProps}
/>

View File

@@ -13,7 +13,7 @@
bind:ref
class={cn(
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
className
className,
)}
{...restProps}
/>

View File

@@ -15,7 +15,7 @@
<span
class={cn(
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
className
className,
)}
>
<CalendarPrimitive.MonthSelect

View File

@@ -24,7 +24,7 @@
class={cn(
buttonVariants({ variant }),
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
className
className,
)}
children={children || Fallback}
{...restProps}

View File

@@ -24,7 +24,7 @@
class={cn(
buttonVariants({ variant }),
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
className
className,
)}
children={children || Fallback}
{...restProps}

View File

@@ -14,7 +14,7 @@
<span
class={cn(
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
className
className,
)}
>
<CalendarPrimitive.YearSelect

View File

@@ -51,7 +51,7 @@ get along, so we shut typescript up by casting `value` to `never`.
{disableDaysOutsideMonth}
class={cn(
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
className
className,
)}
{locale}
{monthFormat}

View File

@@ -24,7 +24,7 @@
{align}
class={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--bits-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
className,
)}
{...restProps}
/>

View File

@@ -17,10 +17,12 @@
<div class="min-h-screen bg-background">
<div class="container mx-auto px-4">
<!-- Mobile top nav -->
<div class="lg:hidden flex items-center gap-2 py-3 border-b border-border/40">
<a href="/" class="text-xs text-muted-foreground hover:text-foreground transition-colors shrink-0 mr-2">
<a
href="/"
class="text-xs text-muted-foreground hover:text-foreground transition-colors shrink-0 mr-2"
>
{$_("admin.nav.back_mobile")}
</a>
{#each navLinks as link (link.href)}

View File

@@ -5,7 +5,10 @@ export async function load({ params, fetch, cookies }) {
const token = cookies.get("session_token") || "";
const [articles, modelsResult] = await Promise.all([
adminListArticles(fetch, token).catch(() => []),
adminListUsers({ role: "model", limit: 200 }, fetch, token).catch(() => ({ items: [], total: 0 })),
adminListUsers({ role: "model", limit: 200 }, fetch, token).catch(() => ({
items: [],
total: 0,
})),
]);
const article = articles.find((a) => a.id === params.id);
if (!article) throw error(404, "Article not found");

View File

@@ -107,13 +107,13 @@
<button
type="button"
class={`px-3 py-1 transition-colors ${editorTab === "write" ? "bg-primary/10 text-primary" : "text-muted-foreground"}`}
onclick={() => (editorTab = "write")}
>{$_("admin.common.write")}</button>
onclick={() => (editorTab = "write")}>{$_("admin.common.write")}</button
>
<button
type="button"
class={`px-3 py-1 transition-colors ${editorTab === "preview" ? "bg-primary/10 text-primary" : "text-muted-foreground"}`}
onclick={() => (editorTab = "preview")}
>{$_("admin.common.preview")}</button>
onclick={() => (editorTab = "preview")}>{$_("admin.common.preview")}</button
>
</div>
</div>
<div class="sm:grid sm:grid-cols-2 sm:gap-4 min-h-96">
@@ -127,7 +127,9 @@
{#if preview}
{@html preview}
{:else}
<p class="text-muted-foreground italic text-sm">{$_("admin.article_form.preview_placeholder")}</p>
<p class="text-muted-foreground italic text-sm">
{$_("admin.article_form.preview_placeholder")}
</p>
{/if}
</div>
</div>
@@ -152,7 +154,11 @@
<SelectTrigger class="w-full">
{#if selectedAuthor}
{#if selectedAuthor.avatar}
<img src={getAssetUrl(selectedAuthor.avatar, "mini")} alt="" class="h-5 w-5 rounded-full object-cover shrink-0" />
<img
src={getAssetUrl(selectedAuthor.avatar, "mini")}
alt=""
class="h-5 w-5 rounded-full object-cover shrink-0"
/>
{/if}
{selectedAuthor.artist_name}
{:else}
@@ -164,7 +170,11 @@
{#each data.authors as author (author.id)}
<SelectItem value={author.id}>
{#if author.avatar}
<img src={getAssetUrl(author.avatar, "mini")} alt="" class="h-5 w-5 rounded-full object-cover shrink-0" />
<img
src={getAssetUrl(author.avatar, "mini")}
alt=""
class="h-5 w-5 rounded-full object-cover shrink-0"
/>
{/if}
{author.artist_name}
</SelectItem>
@@ -195,7 +205,11 @@
</label>
<div class="flex gap-3 pt-2">
<Button onclick={handleSubmit} disabled={saving} class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90">
<Button
onclick={handleSubmit}
disabled={saving}
class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
{saving ? $_("admin.common.saving") : $_("admin.common.save_changes")}
</Button>
<Button variant="outline" href="/admin/articles">{$_("common.cancel")}</Button>

View File

@@ -98,13 +98,22 @@
</div>
<div class="space-y-1.5">
<Label for="slug">{$_("admin.common.slug_field")}</Label>
<Input id="slug" bind:value={slug} placeholder={$_("admin.article_form.slug_placeholder")} />
<Input
id="slug"
bind:value={slug}
placeholder={$_("admin.article_form.slug_placeholder")}
/>
</div>
</div>
<div class="space-y-1.5">
<Label for="excerpt">{$_("admin.article_form.excerpt")}</Label>
<Textarea id="excerpt" bind:value={excerpt} placeholder={$_("admin.article_form.excerpt_placeholder")} rows={2} />
<Textarea
id="excerpt"
bind:value={excerpt}
placeholder={$_("admin.article_form.excerpt_placeholder")}
rows={2}
/>
</div>
<!-- Markdown editor with live preview -->
@@ -115,13 +124,13 @@
<button
type="button"
class={`px-3 py-1 transition-colors ${editorTab === "write" ? "bg-primary/10 text-primary" : "text-muted-foreground"}`}
onclick={() => (editorTab = "write")}
>{$_("admin.common.write")}</button>
onclick={() => (editorTab = "write")}>{$_("admin.common.write")}</button
>
<button
type="button"
class={`px-3 py-1 transition-colors ${editorTab === "preview" ? "bg-primary/10 text-primary" : "text-muted-foreground"}`}
onclick={() => (editorTab = "preview")}
>{$_("admin.common.preview")}</button>
onclick={() => (editorTab = "preview")}>{$_("admin.common.preview")}</button
>
</div>
</div>
<!-- Mobile: single pane toggled; Desktop: side by side -->
@@ -137,7 +146,9 @@
{#if preview}
{@html preview}
{:else}
<p class="text-muted-foreground italic text-sm">{$_("admin.article_form.preview_placeholder")}</p>
<p class="text-muted-foreground italic text-sm">
{$_("admin.article_form.preview_placeholder")}
</p>
{/if}
</div>
</div>
@@ -146,13 +157,19 @@
<div class="space-y-1.5">
<Label>{$_("admin.common.cover_image")}</Label>
<FileDropZone accept="image/*" maxFileSize={10 * MEGABYTE} onUpload={handleImageUpload} />
{#if imageId}<p class="text-xs text-green-600 mt-1">{$_("admin.common.image_uploaded")}</p>{/if}
{#if imageId}<p class="text-xs text-green-600 mt-1">
{$_("admin.common.image_uploaded")}
</p>{/if}
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="space-y-1.5">
<Label for="category">{$_("admin.article_form.category")}</Label>
<Input id="category" bind:value={category} placeholder={$_("admin.article_form.category_placeholder")} />
<Input
id="category"
bind:value={category}
placeholder={$_("admin.article_form.category_placeholder")}
/>
</div>
<div class="space-y-1.5">
<Label>{$_("admin.common.publish_date")}</Label>
@@ -171,7 +188,11 @@
</label>
<div class="flex gap-3 pt-2">
<Button onclick={handleSubmit} disabled={saving} class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90">
<Button
onclick={handleSubmit}
disabled={saving}
class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
{saving ? $_("admin.common.creating") : $_("admin.article_form.create")}
</Button>
<Button variant="outline" href="/admin/articles">{$_("common.cancel")}</Button>

View File

@@ -87,7 +87,9 @@
<div class="py-3 sm:py-6 sm:pl-6">
<div class="flex items-center justify-between mb-6 px-3 sm:px-0">
<h1 class="text-2xl font-bold">{$_("admin.users.title")}</h1>
<span class="text-sm text-muted-foreground">{$_("admin.users.total", { values: { total: data.total } })}</span>
<span class="text-sm text-muted-foreground"
>{$_("admin.users.total", { values: { total: data.total } })}</span
>
</div>
<!-- Filters -->
@@ -120,11 +122,21 @@
<table class="w-full text-sm">
<thead class="bg-muted/30">
<tr>
<th class="px-4 py-3 text-left font-medium text-muted-foreground">{$_("admin.users.col_user")}</th>
<th class="px-4 py-3 text-left font-medium text-muted-foreground hidden sm:table-cell">{$_("admin.users.col_email")}</th>
<th class="px-4 py-3 text-left font-medium text-muted-foreground">{$_("admin.users.col_role")}</th>
<th class="px-4 py-3 text-left font-medium text-muted-foreground hidden md:table-cell">{$_("admin.users.col_joined")}</th>
<th class="px-4 py-3 text-right font-medium text-muted-foreground">{$_("admin.users.col_actions")}</th>
<th class="px-4 py-3 text-left font-medium text-muted-foreground"
>{$_("admin.users.col_user")}</th
>
<th class="px-4 py-3 text-left font-medium text-muted-foreground hidden sm:table-cell"
>{$_("admin.users.col_email")}</th
>
<th class="px-4 py-3 text-left font-medium text-muted-foreground"
>{$_("admin.users.col_role")}</th
>
<th class="px-4 py-3 text-left font-medium text-muted-foreground hidden md:table-cell"
>{$_("admin.users.col_joined")}</th
>
<th class="px-4 py-3 text-right font-medium text-muted-foreground"
>{$_("admin.users.col_actions")}</th
>
</tr>
</thead>
<tbody class="divide-y divide-border/30">
@@ -147,12 +159,18 @@
{/if}
<div class="min-w-0">
<div class="flex items-center gap-1.5">
<span class="font-medium truncate">{user.artist_name || user.first_name || "—"}</span>
<span class="font-medium truncate"
>{user.artist_name || user.first_name || "—"}</span
>
{#if user.is_admin}
<Badge variant="default" class="shrink-0 text-[10px] px-1.5 py-0">{$_("admin.users.admin_badge")}</Badge>
<Badge variant="default" class="shrink-0 text-[10px] px-1.5 py-0"
>{$_("admin.users.admin_badge")}</Badge
>
{/if}
</div>
<span class="text-xs text-muted-foreground sm:hidden truncate block">{user.email}</span>
<span class="text-xs text-muted-foreground sm:hidden truncate block"
>{user.email}</span
>
</div>
</div>
</td>
@@ -173,7 +191,9 @@
</SelectContent>
</Select>
</td>
<td class="px-4 py-3 text-muted-foreground hidden md:table-cell">{formatDate(user.date_created)}</td>
<td class="px-4 py-3 text-muted-foreground hidden md:table-cell"
>{formatDate(user.date_created)}</td
>
<td class="px-4 py-3 text-right">
<div class="flex items-center justify-end gap-1">
<Button size="sm" variant="ghost" href="/admin/users/{user.id}">
@@ -195,7 +215,9 @@
{#if data.items.length === 0}
<tr>
<td colspan="5" class="px-4 py-8 text-center text-muted-foreground">{$_("admin.users.no_results")}</td>
<td colspan="5" class="px-4 py-8 text-center text-muted-foreground"
>{$_("admin.users.no_results")}</td
>
</tr>
{/if}
</tbody>
@@ -206,7 +228,13 @@
{#if data.total > data.limit}
<div class="flex items-center justify-between mt-4 px-3 sm:px-0">
<span class="text-sm text-muted-foreground">
{$_("admin.users.showing", { values: { start: data.offset + 1, end: Math.min(data.offset + data.limit, data.total), total: data.total } })}
{$_("admin.users.showing", {
values: {
start: data.offset + 1,
end: Math.min(data.offset + data.limit, data.total),
total: data.total,
},
})}
</span>
<div class="flex gap-2">
<Button
@@ -244,7 +272,9 @@
<Dialog.Header>
<Dialog.Title>{$_("admin.users.delete_title")}</Dialog.Title>
<Dialog.Description>
{$_("admin.users.delete_description", { values: { name: deleteTarget?.artist_name || deleteTarget?.email } })}
{$_("admin.users.delete_description", {
values: { name: deleteTarget?.artist_name || deleteTarget?.email },
})}
</Dialog.Description>
</Dialog.Header>
<Dialog.Footer>

View File

@@ -106,7 +106,11 @@
</Button>
<div>
<h1 class="text-2xl font-bold">{data.user.artist_name || data.user.email}</h1>
<p class="text-xs text-muted-foreground">{data.user.email} · {data.user.role}{data.user.is_admin ? " · " + $_("admin.users.admin_badge").toLowerCase() : ""}</p>
<p class="text-xs text-muted-foreground">
{data.user.email} · {data.user.role}{data.user.is_admin
? " · " + $_("admin.users.admin_badge").toLowerCase()
: ""}
</p>
</div>
</div>
@@ -155,8 +159,14 @@
</div>
<!-- Admin flag -->
<label class="flex items-center gap-3 rounded-lg border border-border/40 px-4 py-3 cursor-pointer hover:bg-muted/20 transition-colors">
<input type="checkbox" bind:checked={isAdmin} class="h-4 w-4 rounded accent-primary shrink-0" />
<label
class="flex items-center gap-3 rounded-lg border border-border/40 px-4 py-3 cursor-pointer hover:bg-muted/20 transition-colors"
>
<input
type="checkbox"
bind:checked={isAdmin}
class="h-4 w-4 rounded accent-primary shrink-0"
/>
<div>
<span class="text-sm font-medium">{$_("admin.user_edit.is_admin")}</span>
<p class="text-xs text-muted-foreground">{$_("admin.user_edit.is_admin_hint")}</p>
@@ -164,7 +174,11 @@
</label>
<div class="flex gap-3">
<Button onclick={handleSave} disabled={saving} class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90">
<Button
onclick={handleSave}
disabled={saving}
class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
{saving ? $_("admin.common.saving") : $_("admin.common.save_changes")}
</Button>
</div>

View File

@@ -97,7 +97,11 @@
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="space-y-1.5">
<Label for="title">{$_("admin.common.title_field")}</Label>
<Input id="title" bind:value={title} placeholder={$_("admin.video_form.title_placeholder")} />
<Input
id="title"
bind:value={title}
placeholder={$_("admin.video_form.title_placeholder")}
/>
</div>
<div class="space-y-1.5">
<Label for="slug">{$_("admin.common.slug_field")}</Label>
@@ -107,7 +111,12 @@
<div class="space-y-1.5">
<Label for="description">{$_("admin.video_form.description")}</Label>
<Textarea id="description" bind:value={description} placeholder={$_("admin.video_form.description_placeholder")} rows={3} />
<Textarea
id="description"
bind:value={description}
placeholder={$_("admin.video_form.description_placeholder")}
rows={3}
/>
</div>
<div class="space-y-1.5">
@@ -127,7 +136,7 @@
{#if movieId}
<video
src={getAssetUrl(movieId)}
poster={imageId ? getAssetUrl(imageId, "preview") ?? undefined : undefined}
poster={imageId ? (getAssetUrl(imageId, "preview") ?? undefined) : undefined}
controls
class="w-full rounded-lg bg-black max-h-72 mb-2"
></video>
@@ -142,7 +151,11 @@
<div class="space-y-1.5">
<Label>{$_("admin.common.publish_date")}</Label>
<DatePicker bind:value={uploadDate} placeholder={$_("admin.common.publish_date")} showTime={false} />
<DatePicker
bind:value={uploadDate}
placeholder={$_("admin.common.publish_date")}
showTime={false}
/>
</div>
<div class="flex gap-6">
@@ -162,7 +175,9 @@
<Select type="multiple" bind:value={selectedModelIds}>
<SelectTrigger class="w-full">
{#if selectedModelIds.length}
{$_("admin.video_form.models_selected", { values: { count: selectedModelIds.length } })}
{$_("admin.video_form.models_selected", {
values: { count: selectedModelIds.length },
})}
{:else}
<span class="text-muted-foreground">{$_("admin.video_form.no_models")}</span>
{/if}
@@ -171,7 +186,11 @@
{#each data.models as model (model.id)}
<SelectItem value={model.id}>
{#if model.avatar}
<img src={getAssetUrl(model.avatar, "mini")} alt="" class="h-5 w-5 rounded-full object-cover shrink-0" />
<img
src={getAssetUrl(model.avatar, "mini")}
alt=""
class="h-5 w-5 rounded-full object-cover shrink-0"
/>
{/if}
{model.artist_name}
</SelectItem>
@@ -182,7 +201,11 @@
{/if}
<div class="flex gap-3 pt-2">
<Button onclick={handleSubmit} disabled={saving} class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90">
<Button
onclick={handleSubmit}
disabled={saving}
class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
{saving ? $_("admin.common.saving") : $_("admin.common.save_changes")}
</Button>
<Button variant="outline" href="/admin/videos">{$_("common.cancel")}</Button>

View File

@@ -137,13 +137,17 @@
<div class="space-y-1.5">
<Label>{$_("admin.common.cover_image")}</Label>
<FileDropZone accept="image/*" maxFileSize={10 * MEGABYTE} onUpload={handleImageUpload} />
{#if imageId}<p class="text-xs text-green-600 mt-1">{$_("admin.common.image_uploaded")}</p>{/if}
{#if imageId}<p class="text-xs text-green-600 mt-1">
{$_("admin.common.image_uploaded")}
</p>{/if}
</div>
<div class="space-y-1.5">
<Label>{$_("admin.video_form.video_file")}</Label>
<FileDropZone accept="video/*" maxFileSize={2000 * MEGABYTE} onUpload={handleVideoUpload} />
{#if movieId}<p class="text-xs text-green-600 mt-1">{$_("admin.video_form.video_uploaded")}</p>{/if}
{#if movieId}<p class="text-xs text-green-600 mt-1">
{$_("admin.video_form.video_uploaded")}
</p>{/if}
</div>
<div class="space-y-1.5">
@@ -153,7 +157,11 @@
<div class="space-y-1.5">
<Label>{$_("admin.common.publish_date")}</Label>
<DatePicker bind:value={uploadDate} placeholder={$_("admin.common.publish_date")} showTime={false} />
<DatePicker
bind:value={uploadDate}
placeholder={$_("admin.common.publish_date")}
showTime={false}
/>
</div>
<div class="flex gap-6">
@@ -189,7 +197,11 @@
{/if}
<div class="flex gap-3 pt-2">
<Button onclick={handleSubmit} disabled={saving} class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90">
<Button
onclick={handleSubmit}
disabled={saving}
class="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
{saving ? $_("admin.common.creating") : $_("admin.video_form.create")}
</Button>
<Button variant="outline" href="/admin/videos">{$_("common.cancel")}</Button>