refactor: align article author with VideoModel, streamline selects, fix flyout inert
- Remove ArticleAuthor type; article.author now reuses VideoModel (id, artist_name, slug, avatar) - updateArticle accepts authorId; author selectable in admin article edit page - Article edit: single Select with bind:value + $derived selectedAuthor display - Video edit: replace pill toggles with Select type="multiple" bind:value for models - Video table: replace inline badge spans with Badge component - Magazine: display artist_name throughout, author bio links to model profile - Fix flyout aria-hidden warning: replace with inert attribute Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
import { TagsInput } from "$lib/components/ui/tags-input";
|
||||
import { FileDropZone, MEGABYTE } from "$lib/components/ui/file-drop-zone";
|
||||
import { getAssetUrl } from "$lib/api";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from "$lib/components/ui/select";
|
||||
|
||||
const { data } = $props();
|
||||
|
||||
@@ -24,6 +25,8 @@
|
||||
data.article.publish_date ? new Date(data.article.publish_date).toISOString().slice(0, 16) : "",
|
||||
);
|
||||
let imageId = $state<string | null>(data.article.image ?? null);
|
||||
let authorId = $state(data.article.author?.id ?? "");
|
||||
let selectedAuthor = $derived(data.authors.find((a) => a.id === authorId) ?? null);
|
||||
let saving = $state(false);
|
||||
let editorTab = $state<"write" | "preview">("write");
|
||||
|
||||
@@ -53,6 +56,7 @@
|
||||
excerpt: excerpt || undefined,
|
||||
content: content || undefined,
|
||||
imageId: imageId || undefined,
|
||||
authorId: authorId || null,
|
||||
tags,
|
||||
category: category || undefined,
|
||||
featured,
|
||||
@@ -139,6 +143,34 @@
|
||||
<FileDropZone accept="image/*" maxFileSize={10 * MEGABYTE} onUpload={handleImageUpload} />
|
||||
</div>
|
||||
|
||||
<!-- Author -->
|
||||
<div class="space-y-1.5">
|
||||
<Label>Author</Label>
|
||||
<Select type="single" bind:value={authorId}>
|
||||
<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" />
|
||||
{/if}
|
||||
{selectedAuthor.artist_name}
|
||||
{:else}
|
||||
<span class="text-muted-foreground">No author</span>
|
||||
{/if}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">No author</SelectItem>
|
||||
{#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" />
|
||||
{/if}
|
||||
{author.artist_name}
|
||||
</SelectItem>
|
||||
{/each}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div class="space-y-1.5">
|
||||
<Label for="category">Category</Label>
|
||||
|
||||
Reference in New Issue
Block a user