From f89ee937c0eb7584b4507434af3a18298ef4cd79 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Fri, 5 Jun 2026 16:53:20 +0200 Subject: [PATCH] fixed sanitazer and academy --- .../Auth/RegisteredUserController.php | 1 + app/Http/Controllers/GroupController.php | 21 +- .../Settings/AcademyAdminController.php | 12 + .../Studio/StudioNewsController.php | 34 +- .../Controllers/User/TopAuthorsController.php | 3 +- .../Controllers/Web/DiscoverController.php | 20 +- app/Services/ContentSanitizer.php | 83 +- app/Services/HomepageService.php | 28 +- app/Services/RSS/RSSFeedBuilder.php | 2 + ...8yel5.js => ArtworkShareModal-BI8kkaqs.js} | 2 +- ...oiu-_pw.js => vendor-realtime-DYEIbD6w.js} | 4 +- bootstrap/ssr/ssr-manifest.json | 37 +- bootstrap/ssr/ssr.js | 2244 ++++++++++------- .../Pages/Admin/Academy/ChallengeEditor.jsx | 639 +++++ resources/js/Pages/Admin/Academy/CrudForm.jsx | 19 +- resources/js/Pages/Group/GroupShow.jsx | 4 +- resources/js/Pages/Home/HomeNews.jsx | 62 +- .../js/Pages/Studio/StudioNewsEditor.jsx | 11 +- resources/js/Pages/World/WorldIndex.jsx | 4 +- resources/js/Pages/World/WorldShow.jsx | 4 +- resources/scss/nova.scss | 4 + resources/views/news/show.blade.php | 22 + resources/views/rss/channel.blade.php | 1 + resources/views/rss/feed.blade.php | 1 + .../views/web/home/sections/news.blade.php | 139 +- tests/Feature/Groups/GroupsFeatureTest.php | 24 +- tests/Feature/Studio/StudioNewsPagesTest.php | 8 +- tests/Feature/View/SeoHeadTagsTest.php | 45 + tests/Feature/Worlds/WorldPagesTest.php | 5 +- 29 files changed, 2444 insertions(+), 1039 deletions(-) rename bootstrap/ssr/assets/{ArtworkShareModal-BPM8yel5.js => ArtworkShareModal-BI8kkaqs.js} (99%) rename bootstrap/ssr/assets/{vendor-realtime-Koiu-_pw.js => vendor-realtime-DYEIbD6w.js} (100%) create mode 100644 resources/js/Pages/Admin/Academy/ChallengeEditor.jsx diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php index 5e76d4b1..d464da0a 100644 --- a/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -42,6 +42,7 @@ class RegisteredUserController extends Controller return view('auth.register', [ 'prefillEmail' => (string) $request->query('email', ''), + 'page_canonical' => route('register'), 'turnstile' => [ 'enabled' => $this->turnstileVerifier->isEnabled(), 'siteKey' => $this->turnstileVerifier->siteKey(), diff --git a/app/Http/Controllers/GroupController.php b/app/Http/Controllers/GroupController.php index 92c58608..d1cb7831 100644 --- a/app/Http/Controllers/GroupController.php +++ b/app/Http/Controllers/GroupController.php @@ -79,6 +79,7 @@ class GroupController extends Controller { $this->authorize('view', $group); + $section = in_array($section, ['overview', 'artworks', 'collections', 'members', 'about', 'posts', 'projects', 'releases', 'challenges', 'events', 'activity'], true) ? $section : 'overview'; $viewer = $request->user(); $group->loadMissing('owner.profile'); $members = collect($this->memberships->mapMembers($group, $viewer)) @@ -89,7 +90,8 @@ class GroupController extends Controller return Inertia::render('Group/GroupShow', [ 'group' => $groupPayload, - 'section' => in_array($section, ['overview', 'artworks', 'collections', 'members', 'about', 'posts', 'projects', 'releases', 'challenges', 'events', 'activity'], true) ? $section : 'overview', + 'section' => $section, + 'seo' => $this->seoPayload($group, $section), 'featuredArtworks' => $this->groups->featuredArtworkCards($group), 'artworks' => $this->groups->publicArtworkCards($group), 'featuredCollections' => $this->groups->featuredCollectionCards($group, $viewer), @@ -140,4 +142,19 @@ class GroupController extends Controller { return $this->show($request, $group, 'activity'); } -} \ No newline at end of file + + private function seoPayload(Group $group, string $section): array + { + $canonical = $section === 'overview' + ? route('groups.show', ['group' => $group]) + : route('groups.section', ['group' => $group, 'section' => $section]); + $sectionLabel = $section === 'overview' ? '' : ' '.ucfirst($section); + + return [ + 'title' => trim($group->name.$sectionLabel.' - Skinbase'), + 'description' => $group->headline ?: $group->bio ?: 'Skinbase group', + 'canonical' => $canonical, + 'og_url' => $canonical, + ]; + } +} diff --git a/app/Http/Controllers/Settings/AcademyAdminController.php b/app/Http/Controllers/Settings/AcademyAdminController.php index 1d007e96..6b52ed8c 100644 --- a/app/Http/Controllers/Settings/AcademyAdminController.php +++ b/app/Http/Controllers/Settings/AcademyAdminController.php @@ -767,6 +767,17 @@ final class AcademyAdminController extends Controller ]; } + if ($resource === 'challenges') { + return [ + 'links' => array_filter([ + 'preview' => $record->exists ? route('academy.challenges.show', ['slug' => $record->slug]) : null, + ]), + 'coverUploadUrl' => route('api.studio.academy.lessons.media.upload'), + 'coverDeleteUrl' => route('api.studio.academy.lessons.media.destroy'), + 'coverCdnBaseUrl' => rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/'), + ]; + } + if ($resource !== 'lessons') { return []; } @@ -1200,6 +1211,7 @@ final class AcademyAdminController extends Controller 'voting_starts_at' => optional($record->voting_starts_at)?->format('Y-m-d\TH:i'), 'voting_ends_at' => optional($record->voting_ends_at)?->format('Y-m-d\TH:i'), 'cover_image' => (string) ($record->cover_image ?? ''), + 'cover_image_url' => $this->resolveLessonCoverImageUrl((string) ($record->cover_image ?? '')), 'prize_text' => (string) ($record->prize_text ?? ''), 'required_tags' => implode(', ', (array) ($record->required_tags ?? [])), 'allowed_categories' => implode(', ', (array) ($record->allowed_categories ?? [])), diff --git a/app/Http/Controllers/Studio/StudioNewsController.php b/app/Http/Controllers/Studio/StudioNewsController.php index d1106014..4c9f6c8e 100644 --- a/app/Http/Controllers/Studio/StudioNewsController.php +++ b/app/Http/Controllers/Studio/StudioNewsController.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace App\Http\Controllers\Studio; use App\Http\Controllers\Controller; +use App\Models\User; use App\Services\News\NewsService; +use App\Support\AvatarUrl; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -46,6 +48,8 @@ final class StudioNewsController extends Controller { $this->authorizeNews($request); + $user = $request->user(); + return Inertia::render('Studio/StudioNewsEditor', [ 'title' => 'Create article', 'description' => 'Draft a new News story with editorial workflow, SEO metadata, and related entity links.', @@ -61,11 +65,14 @@ final class StudioNewsController extends Controller 'storeUrl' => route('studio.news.store'), 'coverUploadUrl' => route('api.studio.news.media.upload'), 'coverDeleteUrl' => route('api.studio.news.media.destroy'), + 'bodyMediaUploadUrl' => route('api.studio.news.media.upload'), + 'bodyMediaDeleteUrl' => route('api.studio.news.media.destroy'), 'coverCdnBaseUrl' => rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/'), 'entitySearchUrl' => route('studio.news.entity-search'), 'categoriesUrl' => route('studio.news.categories'), 'tagsUrl' => route('studio.news.tags'), - 'defaultAuthor' => $this->news->searchEntities('user', (string) $request->user()->username)[0] ?? null, + 'defaultAuthor' => $this->mapDefaultAuthor($user), + 'defaultPublishedAt' => now()->format('Y-m-d\TH:i'), ]); } @@ -96,6 +103,8 @@ final class StudioNewsController extends Controller 'relationTypeOptions' => $this->news->relationTypeOptions(), 'coverUploadUrl' => route('api.studio.news.media.upload'), 'coverDeleteUrl' => route('api.studio.news.media.destroy'), + 'bodyMediaUploadUrl' => route('api.studio.news.media.upload'), + 'bodyMediaDeleteUrl' => route('api.studio.news.media.destroy'), 'coverCdnBaseUrl' => rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/'), 'updateUrl' => route('studio.news.update', ['article' => $article->id]), 'destroyUrl' => route('studio.news.destroy', ['article' => $article->id]), @@ -250,6 +259,29 @@ final class StudioNewsController extends Controller ]); } + private function mapDefaultAuthor(mixed $user): ?array + { + if (! $user instanceof User) { + return null; + } + + $user->loadMissing('profile'); + + return [ + 'id' => (int) $user->id, + 'entity_type' => 'user', + 'entity_label' => 'User', + 'title' => (string) ($user->name ?: $user->username), + 'subtitle' => $user->username ? '@' . $user->username : null, + 'description' => Str::limit(trim((string) ($user->profile?->bio ?? '')), 120), + 'url' => $user->username ? route('profile.show', ['username' => $user->username]) : null, + 'image' => null, + 'avatar' => AvatarUrl::forUser((int) $user->id, $user->profile?->avatar_hash ?? null, 96), + 'context_label' => 'Profile', + 'meta' => [], + ]; + } + public function storeCategory(Request $request): RedirectResponse { $this->authorizeNews($request); diff --git a/app/Http/Controllers/User/TopAuthorsController.php b/app/Http/Controllers/User/TopAuthorsController.php index 7833aaaa..1017e637 100644 --- a/app/Http/Controllers/User/TopAuthorsController.php +++ b/app/Http/Controllers/User/TopAuthorsController.php @@ -50,7 +50,8 @@ class TopAuthorsController extends Controller }); $page_title = 'Top Creators'; + $page_canonical = route('creators.top'); - return view('web.authors.top', compact('page_title', 'authors', 'metric')); + return view('web.authors.top', compact('page_title', 'page_canonical', 'authors', 'metric')); } } diff --git a/app/Http/Controllers/Web/DiscoverController.php b/app/Http/Controllers/Web/DiscoverController.php index 9fccfe6b..c8afea04 100644 --- a/app/Http/Controllers/Web/DiscoverController.php +++ b/app/Http/Controllers/Web/DiscoverController.php @@ -65,6 +65,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $results, 'page_title' => 'Trending Artworks', + 'page_canonical' => $this->canonicalRoute('discover.trending'), 'section' => 'trending', 'description' => 'The most-viewed artworks on Skinbase over the past 7 days.', 'icon' => 'fa-fire', @@ -97,6 +98,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $results, 'page_title' => 'Rising Now', + 'page_canonical' => $this->canonicalRoute('discover.rising'), 'section' => 'rising', 'description' => 'Fastest growing artworks right now.', 'icon' => 'fa-rocket', @@ -119,6 +121,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $results, 'page_title' => 'Fresh Uploads', + 'page_canonical' => $this->canonicalRoute('discover.fresh'), 'section' => 'fresh', 'description' => 'The latest artworks just uploaded to Skinbase.', 'icon' => 'fa-bolt', @@ -138,6 +141,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $results, 'page_title' => 'Top Rated Artworks', + 'page_canonical' => $this->canonicalRoute('discover.top-rated'), 'section' => 'top-rated', 'description' => 'The most-loved artworks on Skinbase, ranked by community favourites.', 'icon' => 'fa-medal', @@ -157,6 +161,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $results, 'page_title' => 'Most Downloaded', + 'page_canonical' => $this->canonicalRoute('discover.most-downloaded'), 'section' => 'most-downloaded', 'description' => 'All-time most downloaded artworks on Skinbase.', 'icon' => 'fa-download', @@ -178,9 +183,9 @@ final class DiscoverController extends Controller 'categories:id,name,slug,content_type_id,parent_id,sort_order', 'categories.contentType:id,slug,name', ]) - ->whereRaw('MONTH(published_at) = ?', [$today->month]) - ->whereRaw('DAY(published_at) = ?', [$today->day]) - ->whereRaw('YEAR(published_at) < ?', [$today->year]) + ->whereMonth('published_at', $today->month) + ->whereDay('published_at', $today->day) + ->whereYear('published_at', '<', $today->year) ->orderMissingThumbnailsLast() ->orderByDesc('published_at') ->paginate($perPage) @@ -191,6 +196,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $artworks, 'page_title' => 'On This Day', + 'page_canonical' => $this->canonicalRoute('discover.on-this-day'), 'section' => 'on-this-day', 'description' => 'Artworks published on ' . $today->format('F j') . ' in previous years.', 'icon' => 'fa-calendar-day', @@ -246,6 +252,7 @@ final class DiscoverController extends Controller return view('web.creators.rising', [ 'creators' => $creators, 'page_title' => 'Rising Creators — Skinbase', + 'page_canonical' => $this->canonicalRoute('creators.rising'), ]); } @@ -327,6 +334,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => collect(), 'page_title' => 'Following Feed', + 'page_canonical' => $this->canonicalRoute('discover.following'), 'section' => 'following', 'description' => 'Follow some creators to see their work here.', 'icon' => 'fa-user-group', @@ -366,6 +374,7 @@ final class DiscoverController extends Controller return view('web.discover.index', [ 'artworks' => $artworks, 'page_title' => 'Following Feed', + 'page_canonical' => $this->canonicalRoute('discover.following'), 'section' => 'following', 'description' => 'The latest artworks from creators you follow.', 'icon' => 'fa-user-group', @@ -388,6 +397,11 @@ final class DiscoverController extends Controller return ! $items || $items->isEmpty(); } + private function canonicalRoute(string $routeName): string + { + return route($routeName); + } + private function paginatorHasNoRisingMomentum($paginator): bool { if (! is_object($paginator) || ! method_exists($paginator, 'getCollection')) { diff --git a/app/Services/ContentSanitizer.php b/app/Services/ContentSanitizer.php index 03f2cc31..d458db2c 100644 --- a/app/Services/ContentSanitizer.php +++ b/app/Services/ContentSanitizer.php @@ -37,11 +37,22 @@ class ContentSanitizer 'p', 'br', 'strong', 'em', 'code', 'pre', 'a', 'ul', 'ol', 'li', 'blockquote', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + // Image and embed-related tags used by the rich editor + 'figure', 'figcaption', 'img', 'picture', 'source', 'iframe', + // Basic structural/inline helpers sometimes produced by embeds + 'div', 'span' ]; // Allowed attributes per tag private const ALLOWED_ATTRS = [ 'a' => ['href', 'title', 'rel', 'target'], + 'img' => ['src', 'srcset', 'sizes', 'alt', 'title', 'loading', 'decoding', 'width', 'height', 'style', 'class', 'data-width'], + 'source' => ['srcset', 'src', 'type', 'media', 'sizes'], + 'figure' => ['class', 'data-rich-image', 'data-platform', 'data-video-embed', 'data-social-embed', 'data-artwork-embed'], + 'figcaption' => ['class'], + 'iframe' => ['src', 'title', 'loading', 'frameborder', 'allow', 'allowfullscreen', 'referrerpolicy'], + 'div' => ['class', 'data-href', 'data-show-text'], + 'span' => ['class'], ]; private static ?MarkdownConverter $converter = null; @@ -261,14 +272,82 @@ class ContentSanitizer $allowedAttrs = self::ALLOWED_ATTRS[$tag] ?? []; $attrsToRemove = []; foreach ($child->attributes as $attr) { - if (! in_array($attr->nodeName, $allowedAttrs, true)) { - $attrsToRemove[] = $attr->nodeName; + $name = $attr->nodeName; + + // Allow data-* attributes and class on allowed tags + if (str_starts_with($name, 'data-') || $name === 'class') { + continue; + } + + if (! in_array($name, $allowedAttrs, true)) { + $attrsToRemove[] = $name; } } foreach ($attrsToRemove as $attrName) { $child->removeAttribute($attrName); } + // Validate URL-like attributes for image/source/iframe + if ($tag === 'img') { + $src = $child->getAttribute('src'); + if ($src && ! static::isSafeUrl($src)) { + $toUnwrap[] = $child; + continue; + } + + // Validate srcset: ensure each URL is safe; if not, remove the attribute + $srcset = $child->getAttribute('srcset'); + if ($srcset) { + $parts = array_map('trim', explode(',', $srcset)); + $valid = true; + foreach ($parts as $part) { + if ($part === '') { + continue; + } + // Each part: "url [descriptor]" + $pieces = preg_split('/\s+/', $part); + $url = $pieces[0] ?? ''; + if ($url !== '' && ! static::isSafeUrl($url)) { + $valid = false; + break; + } + } + if (! $valid) { + $child->removeAttribute('srcset'); + } + } + } + + if ($tag === 'source') { + $src = $child->getAttribute('src') ?: $child->getAttribute('srcset'); + if ($src) { + // For srcset allow comma-separated list; validate each + $values = array_map('trim', explode(',', $src)); + $valid = true; + foreach ($values as $v) { + if ($v === '') continue; + $pieces = preg_split('/\s+/', $v); + $url = $pieces[0] ?? ''; + if ($url !== '' && ! static::isSafeUrl($url)) { + $valid = false; + break; + } + } + if (! $valid) { + $toUnwrap[] = $child; + continue; + } + } + } + + if ($tag === 'iframe') { + $src = $child->getAttribute('src'); + if ($src && ! static::isSafeUrl($src)) { + $toUnwrap[] = $child; + continue; + } + } + // Force external links to be safe if ($tag === 'a') { if (! $allowLinks) { diff --git a/app/Services/HomepageService.php b/app/Services/HomepageService.php index 6495c3d5..0c6f2afd 100644 --- a/app/Services/HomepageService.php +++ b/app/Services/HomepageService.php @@ -761,12 +761,12 @@ final class HomepageService /** * Latest 5 news posts from the forum news category. */ - public function getNews(int $limit = 5): array + public function getNews(int $limit = 10): array { return Cache::remember("homepage.news.{$limit}", self::CACHE_TTL, function () use ($limit): array { try { $articles = NewsArticle::query() - ->with('category') + ->with(['category', 'author']) ->published() ->editorialOrder() ->limit($limit) @@ -774,13 +774,23 @@ final class HomepageService if ($articles->isNotEmpty()) { return $articles->map(fn (NewsArticle $article) => [ - 'id' => $article->id, - 'title' => $article->title, - 'date' => $article->published_at, - 'url' => route('news.show', ['slug' => $article->slug]), - 'eyebrow' => $article->category?->name ?: $article->type_label, - 'excerpt' => Str::limit(strip_tags((string) ($article->excerpt ?: $article->rendered_content)), 120), - ])->values()->all(); + 'id' => $article->id, + 'title' => $article->title, + 'date' => $article->published_at, + 'url' => route('news.show', ['slug' => $article->slug]), + 'eyebrow' => $article->category?->name ?: $article->type_label, + 'type' => $article->type ?? null, + 'type_label' => $article->type_label ?? null, + 'category' => $article->category ? ['name' => $article->category->name, 'slug' => $article->category->slug] : null, + 'is_featured' => (bool) ($article->is_featured ?? false), + 'is_pinned' => (bool) ($article->is_pinned ?? false), + 'cover_url' => $article->cover_url ?? null, + 'cover_mobile_url' => $article->cover_mobile_url ?? null, + 'cover_srcset' => $article->cover_srcset ?? null, + 'excerpt' => Str::limit(strip_tags((string) ($article->excerpt ?: $article->rendered_content)), 135), + 'author' => $article->author ? ['name' => $article->author->name ?? $article->author->username, 'username' => $article->author->username ?? null] : null, + 'views' => isset($article->views) ? (int) $article->views : 0, + ])->values()->all(); } $items = DB::table('forum_threads as t') diff --git a/app/Services/RSS/RSSFeedBuilder.php b/app/Services/RSS/RSSFeedBuilder.php index 3e0fa890..df356c01 100644 --- a/app/Services/RSS/RSSFeedBuilder.php +++ b/app/Services/RSS/RSSFeedBuilder.php @@ -61,12 +61,14 @@ final class RSSFeedBuilder string $channelLink, string $feedUrl, Collection $items, + ?string $canonicalUrl = null, ): Response { $xml = view('rss.channel', [ 'channelTitle' => trim($channelTitle) . ' — Skinbase', 'channelDescription' => $channelDescription, 'channelLink' => $channelLink, 'feedUrl' => $feedUrl, + 'canonicalUrl' => $canonicalUrl ?: $feedUrl, 'items' => $items, 'buildDate' => now()->toRfc2822String(), ])->render(); diff --git a/bootstrap/ssr/assets/ArtworkShareModal-BPM8yel5.js b/bootstrap/ssr/assets/ArtworkShareModal-BI8kkaqs.js similarity index 99% rename from bootstrap/ssr/assets/ArtworkShareModal-BPM8yel5.js rename to bootstrap/ssr/assets/ArtworkShareModal-BI8kkaqs.js index 1789116e..9b5f2555 100644 --- a/bootstrap/ssr/assets/ArtworkShareModal-BPM8yel5.js +++ b/bootstrap/ssr/assets/ArtworkShareModal-BI8kkaqs.js @@ -18,7 +18,7 @@ import "./vendor-tooltip-CIQaDNlG.js"; import "node:process"; import "node:path"; import "node:url"; -import "./vendor-realtime-Koiu-_pw.js"; +import "./vendor-realtime-DYEIbD6w.js"; import "buffer"; import "child_process"; import "net"; diff --git a/bootstrap/ssr/assets/vendor-realtime-Koiu-_pw.js b/bootstrap/ssr/assets/vendor-realtime-DYEIbD6w.js similarity index 100% rename from bootstrap/ssr/assets/vendor-realtime-Koiu-_pw.js rename to bootstrap/ssr/assets/vendor-realtime-DYEIbD6w.js index 79b999f8..ae798d41 100644 --- a/bootstrap/ssr/assets/vendor-realtime-Koiu-_pw.js +++ b/bootstrap/ssr/assets/vendor-realtime-DYEIbD6w.js @@ -1,17 +1,17 @@ import require$$0 from "util"; import stream from "stream"; -import require$$4 from "https"; import require$$5 from "url"; import require$$6 from "fs"; import require$$1 from "crypto"; import require$$4$2 from "assert"; import require$$1$1 from "buffer"; import require$$2 from "child_process"; -import require$$4$1 from "events"; import require$$8 from "net"; import require$$10 from "tls"; import { c as commonjsGlobal, g as getDefaultExportFromCjs } from "./vendor-tiptap-DRFaxGEb.js"; +import require$$4$1 from "events"; import require$$3 from "http"; +import require$$4 from "https"; class u { constructor() { this.notificationCreatedEvent = ".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated"; diff --git a/bootstrap/ssr/ssr-manifest.json b/bootstrap/ssr/ssr-manifest.json index e1204998..5f191398 100644 --- a/bootstrap/ssr/ssr-manifest.json +++ b/bootstrap/ssr/ssr-manifest.json @@ -14,10 +14,10 @@ "\u0000D:/Sites/Skinbase26/node_modules/nprogress/nprogress.js?commonjs-es-import": [], "\u0000D:/Sites/Skinbase26/node_modules/nprogress/nprogress.js?commonjs-module": [], "\u0000D:/Sites/Skinbase26/node_modules/pusher-js/dist/node/pusher.js?commonjs-es-import": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000D:/Sites/Skinbase26/node_modules/pusher-js/dist/node/pusher.js?commonjs-module": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000D:/Sites/Skinbase26/node_modules/qs/lib/index.js?commonjs-es-import": [], "\u0000D:/Sites/Skinbase26/node_modules/react-dom/cjs/react-dom-client.development.js?commonjs-exports": [], @@ -97,46 +97,46 @@ "/build/assets/vendor-tiptap-DRFaxGEb.js" ], "\u0000assert?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000buffer?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000child_process?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000commonjsHelpers.js": [ "/build/assets/vendor-tiptap-DRFaxGEb.js" ], "\u0000crypto?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000events?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000fs?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000http?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000https?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000net?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000stream?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000tls?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000url?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "\u0000util?commonjs-external": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "node_modules/@emoji-mart/data/sets/15/native.json": [ "/build/assets/emoji-data-4xGXbtDn.js" @@ -1035,7 +1035,7 @@ "node_modules/inline-style-parser/cjs/index.js": [], "node_modules/is-plain-obj/index.js": [], "node_modules/laravel-echo/dist/echo.js": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "node_modules/linkifyjs/dist/linkify.mjs": [ "/build/assets/vendor-tiptap-DRFaxGEb.js" @@ -1935,7 +1935,7 @@ ], "node_modules/proxy-from-env/index.js": [], "node_modules/pusher-js/dist/node/pusher.js": [ - "/build/assets/vendor-realtime-Koiu-_pw.js" + "/build/assets/vendor-realtime-DYEIbD6w.js" ], "node_modules/qs/lib/formats.js": [], "node_modules/qs/lib/index.js": [], @@ -2055,6 +2055,7 @@ "resources/js/Pages/Admin/Academy/AnalyticsOverview.jsx": [], "resources/js/Pages/Admin/Academy/AnalyticsSearch.jsx": [], "resources/js/Pages/Admin/Academy/Billing.jsx": [], + "resources/js/Pages/Admin/Academy/ChallengeEditor.jsx": [], "resources/js/Pages/Admin/Academy/CourseBuilder.jsx": [], "resources/js/Pages/Admin/Academy/CourseEditor.jsx": [], "resources/js/Pages/Admin/Academy/CrudForm.jsx": [], @@ -2251,7 +2252,7 @@ "resources/js/components/artwork/ArtworkRecommendationsRails.jsx": [], "resources/js/components/artwork/ArtworkShareButton.jsx": [], "resources/js/components/artwork/ArtworkShareModal.jsx": [ - "/build/assets/ArtworkShareModal-BPM8yel5.js" + "/build/assets/ArtworkShareModal-BI8kkaqs.js" ], "resources/js/components/artwork/ArtworkTags.jsx": [], "resources/js/components/artwork/AuthorBioPopover.jsx": [], diff --git a/bootstrap/ssr/ssr.js b/bootstrap/ssr/ssr.js index debe58a7..d6933c44 100644 --- a/bootstrap/ssr/ssr.js +++ b/bootstrap/ssr/ssr.js @@ -17,7 +17,7 @@ import { t as tippy } from "./assets/vendor-tooltip-CIQaDNlG.js"; import minproc from "node:process"; import minpath from "node:path"; import { fileURLToPath } from "node:url"; -import { P as Pusher, E as E$2 } from "./assets/vendor-realtime-Koiu-_pw.js"; +import { P as Pusher, E as E$2 } from "./assets/vendor-realtime-DYEIbD6w.js"; import { u as useReducedMotion, m as motion, A as AnimatePresence } from "./assets/vendor-motion-CotXNotG.js"; import * as s from "process"; import require$$2 from "async_hooks"; @@ -15470,6 +15470,973 @@ const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de __proto__: null, default: AcademyBilling }, Symbol.toStringTag, { value: "Module" })); +const MONTH_NAMES = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +]; +const YEAR_MIN = 1900; +const YEAR_MAX = 2105; +const DAY_ABBR = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]; +function pad(value) { + return String(value).padStart(2, "0"); +} +function daysInMonth(year, month) { + return new Date(year, month + 1, 0).getDate(); +} +function firstWeekday(year, month) { + const day = new Date(year, month, 1).getDay(); + return (day + 6) % 7; +} +function toISODate(date) { + return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; +} +function parseDatePart(value) { + if (!value) return null; + const [year, month, day] = value.split("-").map(Number); + if (!year || !month || !day) return null; + return new Date(year, month - 1, day); +} +function normalizeDateTimeInput(value) { + const raw = String(value || "").trim(); + if (!raw) return { date: "", time: "" }; + const match = raw.match(/^(\d{4}-\d{2}-\d{2})(?:[ T](\d{2}:\d{2})(?::\d{2})?)?(?:Z|[+-]\d{2}:?\d{2})?$/); + if (match) { + return { + date: match[1], + time: match[2] || "" + }; + } + const parsed = new Date(raw); + if (Number.isNaN(parsed.getTime())) { + return { date: raw, time: "" }; + } + return { + date: toISODate(parsed), + time: `${pad(parsed.getHours())}:${pad(parsed.getMinutes())}` + }; +} +function splitDateTime(value) { + const normalized = normalizeDateTimeInput(value); + return { + date: normalized.date, + time: normalized.time.slice(0, 5) + }; +} +function mergeDateTime(date, time) { + if (!date) return ""; + return `${date}T${time || "00:00"}`; +} +function maxDateValue(a, b2) { + if (!a) return b2 || ""; + if (!b2) return a || ""; + return a > b2 ? a : b2; +} +function minDateValue(a, b2) { + if (!a) return b2 || ""; + if (!b2) return a || ""; + return a < b2 ? a : b2; +} +function clampTimeToBounds(date, time, minDateTime, maxDateTime) { + const nextTime = time || "00:00"; + const minParts = splitDateTime(minDateTime); + const maxParts = splitDateTime(maxDateTime); + if (date && minParts.date === date && minParts.time && nextTime < minParts.time) { + return minParts.time; + } + if (date && maxParts.date === date && maxParts.time && nextTime > maxParts.time) { + return maxParts.time; + } + return nextTime; +} +function formatDisplay(value) { + if (!value) return ""; + const { date, time } = splitDateTime(value); + const parsed = parseDatePart(date); + if (!parsed) return ""; + return `${MONTH_NAMES[parsed.getMonth()].slice(0, 3)} ${parsed.getDate()}, ${parsed.getFullYear()}${time ? ` at ${time}` : ""}`; +} +function isSameDay(a, b2) { + return a?.getFullYear() === b2?.getFullYear() && a?.getMonth() === b2?.getMonth() && a?.getDate() === b2?.getDate(); +} +function CalendarGrid({ year, month, selectedDate, onSelect, minDate, maxDate }) { + const count = daysInMonth(year, month); + const start = firstWeekday(year, month); + const prevMonth = month - 1 < 0 ? 11 : month - 1; + const prevYear = month - 1 < 0 ? year - 1 : year; + const prevCount = daysInMonth(prevYear, prevMonth); + const cells = []; + for (let index2 = start - 1; index2 >= 0; index2 -= 1) { + cells.push({ + day: prevCount - index2, + current: false, + date: new Date(prevYear, prevMonth, prevCount - index2) + }); + } + for (let day = 1; day <= count; day += 1) { + cells.push({ day, current: true, date: new Date(year, month, day) }); + } + let nextDay = 1; + while (cells.length % 7 !== 0) { + cells.push({ day: nextDay, current: false, date: new Date(year, month + 1, nextDay) }); + nextDay += 1; + } + const today = /* @__PURE__ */ new Date(); + today.setHours(0, 0, 0, 0); + return /* @__PURE__ */ React.createElement("div", { className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "mb-1 grid grid-cols-7" }, DAY_ABBR.map((day) => /* @__PURE__ */ React.createElement("div", { key: day, className: "py-1 text-center text-[10px] font-semibold text-slate-500" }, day))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-7 gap-y-0.5" }, cells.map((cell, index2) => { + const iso = toISODate(cell.date); + const selected = isSameDay(cell.date, selectedDate); + const todayCell = isSameDay(cell.date, today); + const disabled = minDate && iso < minDate || maxDate && iso > maxDate; + return /* @__PURE__ */ React.createElement( + "button", + { + key: `${iso}-${index2}`, + type: "button", + disabled, + onClick: () => onSelect(iso), + className: [ + "relative mx-auto flex h-8 w-8 items-center justify-center rounded-lg text-sm transition-all", + !cell.current ? "text-slate-600" : "", + cell.current && !selected && !disabled ? "text-white hover:bg-white/10" : "", + selected ? "bg-accent font-semibold text-white shadow shadow-accent/30" : "", + todayCell && !selected ? "text-accent ring-1 ring-accent/50" : "", + disabled ? "cursor-not-allowed opacity-30" : "cursor-pointer" + ].join(" ") + }, + cell.day + ); + }))); +} +function DateTimePicker({ + value = "", + onChange, + label, + placeholder, + error, + hint, + required = false, + clearable = false, + id, + disabled = false, + mode = "datetime", + minDate, + maxDate, + minDateTime, + maxDateTime, + className = "" +}) { + const today = /* @__PURE__ */ new Date(); + const initial = splitDateTime(value); + const initialDate = parseDatePart(initial.date) || today; + const [open, setOpen] = reactExports.useState(false); + const [dropPos, setDropPos] = reactExports.useState({ top: 0, left: 0, width: 320 }); + const [viewYear, setViewYear] = reactExports.useState(initialDate.getFullYear()); + const [viewMonth, setViewMonth] = reactExports.useState(initialDate.getMonth()); + const [draftDate, setDraftDate] = reactExports.useState(initial.date); + const nowTime = `${pad(today.getHours())}:${pad(today.getMinutes())}`; + const defaultDraftTime = (function() { + const baseDate = initial.date || toISODate(initialDate); + const candidate = initial.time || nowTime; + return clampTimeToBounds(baseDate, candidate, minDateTime, maxDateTime); + })(); + const [draftTime, setDraftTime] = reactExports.useState(defaultDraftTime); + const effectivePlaceholder = placeholder || (mode === "date" ? "Pick a date" : "Pick a date and time"); + const triggerRef = reactExports.useRef(null); + const inputId = id ?? (label ? `dtp-${label.toLowerCase().replace(/\s+/g, "-")}` : "date-time-picker"); + const panelId = `dtp-panel-${inputId}`; + reactExports.useEffect(() => { + const next = splitDateTime(value); + setDraftDate(next.date); + const fallbackTime = (() => { + const candidate = next.time || `${pad((/* @__PURE__ */ new Date()).getHours())}:${pad((/* @__PURE__ */ new Date()).getMinutes())}`; + const dateForClamp = next.date || toISODate(initialDate); + return clampTimeToBounds(dateForClamp, candidate, minDateTime, maxDateTime); + })(); + setDraftTime(next.time || fallbackTime); + const nextDate = parseDatePart(next.date); + if (nextDate) { + setViewYear(nextDate.getFullYear()); + setViewMonth(nextDate.getMonth()); + } + }, [value]); + const measure = reactExports.useCallback(() => { + if (!triggerRef.current) return; + const rect = triggerRef.current.getBoundingClientRect(); + const panelWidth = Math.max(rect.width, 320); + const panelHeight = 420; + const openUp = window.innerHeight - rect.bottom < panelHeight + 8 && rect.top > panelHeight + 8; + setDropPos({ + top: openUp ? rect.top - panelHeight - 4 : rect.bottom + 4, + left: Math.min(rect.left, window.innerWidth - panelWidth - 8), + width: panelWidth + }); + }, []); + const openPicker = reactExports.useCallback(() => { + if (disabled) return; + measure(); + setOpen(true); + }, [disabled, measure]); + reactExports.useEffect(() => { + if (!open) return void 0; + const handleMouseDown = (event) => { + if (!triggerRef.current?.contains(event.target) && !document.getElementById(panelId)?.contains(event.target)) { + setOpen(false); + } + }; + document.addEventListener("mousedown", handleMouseDown); + return () => document.removeEventListener("mousedown", handleMouseDown); + }, [open, panelId]); + reactExports.useEffect(() => { + if (!open) return void 0; + const handleScroll = (event) => { + if (document.getElementById(panelId)?.contains(event.target)) return; + setOpen(false); + }; + const handleResize = () => setOpen(false); + window.addEventListener("scroll", handleScroll, true); + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("scroll", handleScroll, true); + window.removeEventListener("resize", handleResize); + }; + }, [open, panelId]); + const applyValue = reactExports.useCallback((date, time) => { + if (!date) { + onChange?.(""); + return; + } + onChange?.(mode === "date" ? date : mergeDateTime(date, time)); + }, [mode, onChange]); + const handleDateSelect = (nextDate) => { + const nextTime = clampTimeToBounds(nextDate, draftTime, minDateTime, maxDateTime); + setDraftDate(nextDate); + setDraftTime(nextTime); + applyValue(nextDate, nextTime); + }; + const handleTimeChange = (event) => { + const nextTime = clampTimeToBounds(draftDate, event.target.value, minDateTime, maxDateTime); + setDraftTime(nextTime); + applyValue(draftDate, nextTime); + }; + const clearValue = (event) => { + event.stopPropagation(); + const now = `${pad((/* @__PURE__ */ new Date()).getHours())}:${pad((/* @__PURE__ */ new Date()).getMinutes())}`; + setDraftDate(""); + setDraftTime(now); + onChange?.(""); + }; + const prevMonth = () => { + if (viewMonth === 0) { + setViewMonth(11); + setViewYear((current) => current - 1); + return; + } + setViewMonth((current) => current - 1); + }; + const nextMonth = () => { + if (viewMonth === 11) { + setViewMonth(0); + setViewYear((current) => current + 1); + return; + } + setViewMonth((current) => current + 1); + }; + const triggerClass = [ + "relative flex h-[42px] w-full cursor-pointer items-center gap-2 rounded-xl border px-3.5 text-sm transition-all duration-150", + "bg-white/[0.06] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0", + error ? "border-red-500/60 focus-visible:ring-red-500/40" : open ? "border-accent/50 ring-2 ring-accent/40" : "border-white/12 hover:border-white/22", + disabled ? "pointer-events-none cursor-not-allowed opacity-50" : "", + className + ].join(" "); + const selectedDate = parseDatePart(draftDate); + const minDateTimeParts = splitDateTime(minDateTime); + const maxDateTimeParts = splitDateTime(maxDateTime); + const effectiveMinDate = maxDateValue(minDate, minDateTimeParts.date); + const effectiveMaxDate = minDateValue(maxDate, maxDateTimeParts.date); + const minTime = draftDate && draftDate === minDateTimeParts.date ? minDateTimeParts.time || void 0 : void 0; + const maxTime = draftDate && draftDate === maxDateTimeParts.date ? maxDateTimeParts.time || void 0 : void 0; + return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1.5" }, label && /* @__PURE__ */ React.createElement("label", { htmlFor: inputId, className: "text-sm font-medium text-white/85 select-none" }, label, required && /* @__PURE__ */ React.createElement("span", { className: "ml-1 text-red-400" }, "*")), /* @__PURE__ */ React.createElement( + "div", + { + ref: triggerRef, + id: inputId, + role: "button", + tabIndex: disabled ? -1 : 0, + "aria-label": label ?? effectivePlaceholder, + className: triggerClass, + onClick: openPicker, + onKeyDown: (event) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + openPicker(); + } + } + }, + /* @__PURE__ */ React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", className: "shrink-0 text-slate-500", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("rect", { x: "1", y: "2.5", width: "12", height: "10.5", rx: "1.5", stroke: "currentColor", strokeWidth: "1.3" }), /* @__PURE__ */ React.createElement("path", { d: "M1 6h12", stroke: "currentColor", strokeWidth: "1.3" }), /* @__PURE__ */ React.createElement("path", { d: "M4 1v3M10 1v3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round" }), /* @__PURE__ */ React.createElement("circle", { cx: "4.5", cy: "9", r: "0.75", fill: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "7", cy: "9", r: "0.75", fill: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "9.5", cy: "9", r: "0.75", fill: "currentColor" })), + /* @__PURE__ */ React.createElement("span", { className: `flex-1 truncate ${value ? "text-white" : "text-slate-500"}` }, value ? formatDisplay(value) : effectivePlaceholder), + clearable && value && /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + tabIndex: -1, + onClick: clearValue, + className: "flex h-5 w-5 items-center justify-center rounded text-slate-500 transition-colors hover:text-white", + "aria-label": "Clear date and time" + }, + /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M1 1l8 8M9 1L1 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })) + ) + ), error && /* @__PURE__ */ React.createElement("p", { role: "alert", className: "text-xs text-red-400" }, error), !error && hint && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500" }, hint), open && reactDomExports.createPortal( + /* @__PURE__ */ React.createElement( + "div", + { + id: panelId, + className: "fixed z-[500] overflow-hidden rounded-2xl border border-white/12 bg-nova-900 shadow-2xl shadow-black/50", + style: { top: dropPos.top, left: dropPos.left, width: dropPos.width } + }, + /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 px-3 pt-3" }, /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: prevMonth, + className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white", + "aria-label": "Previous month" + }, + /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M7 1L3 5l4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) + ), /* @__PURE__ */ React.createElement("div", { className: "flex min-w-0 flex-1 items-center justify-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "whitespace-nowrap text-sm font-semibold text-white" }, MONTH_NAMES[viewMonth]), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 rounded-xl border border-white/10 bg-white/[0.04] px-1 py-1" }, /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => setViewYear((current) => Math.max(YEAR_MIN, current - 1)), + disabled: viewYear <= YEAR_MIN, + className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white disabled:cursor-not-allowed disabled:opacity-30", + "aria-label": "Previous year" + }, + /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-minus text-[11px]", "aria-hidden": "true" }) + ), /* @__PURE__ */ React.createElement("span", { className: "min-w-[72px] px-2 text-center text-sm font-semibold text-white" }, viewYear), /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => setViewYear((current) => Math.min(YEAR_MAX, current + 1)), + disabled: viewYear >= YEAR_MAX, + className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white disabled:cursor-not-allowed disabled:opacity-30", + "aria-label": "Next year" + }, + /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-plus text-[11px]", "aria-hidden": "true" }) + ))), /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: nextMonth, + className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white", + "aria-label": "Next month" + }, + /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M3 1l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) + )), + /* @__PURE__ */ React.createElement( + CalendarGrid, + { + year: viewYear, + month: viewMonth, + selectedDate, + onSelect: handleDateSelect, + minDate: effectiveMinDate, + maxDate: effectiveMaxDate + } + ), + /* @__PURE__ */ React.createElement("div", { className: "border-t border-white/8 px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: `grid gap-3 ${mode === "date" ? "" : "sm:grid-cols-[minmax(0,1fr)_7rem] sm:items-end"}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Selected date"), /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white" }, draftDate ? formatDisplay(draftDate) : "Pick a day")), mode !== "date" ? /* @__PURE__ */ React.createElement("label", { className: "grid gap-1.5 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Time"), /* @__PURE__ */ React.createElement( + "input", + { + type: "time", + value: draftTime, + onChange: handleTimeChange, + min: minTime, + max: maxTime, + className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-white outline-none transition focus:border-accent/50 focus:ring-2 focus:ring-accent/40" + } + )) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex items-center justify-between" }, /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => handleDateSelect(toISODate(/* @__PURE__ */ new Date())), + className: "text-xs font-medium text-accent transition-colors hover:text-accent/80" + }, + "Today" + ), /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => setOpen(false), + className: "rounded-lg border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-medium text-white transition hover:bg-white/[0.08]" + }, + "Done" + ))) + ), + document.body + )); +} +function ShareToast({ message = "Link copied!", visible = false, onHide, duration = 2e3, variant = "success" }) { + const [show, setShow] = reactExports.useState(false); + const config = variant === "error" ? { + border: "border-rose-300/25", + background: "bg-rose-950/90", + text: "text-rose-50", + icon: "text-rose-300", + role: "alert", + live: "assertive", + iconPath: "M12 9v3.75m0 3.75h.007v.008H12v-.008ZM10.29 3.86 1.82 18a1.875 1.875 0 0 0 1.606 2.813h16.148A1.875 1.875 0 0 0 21.18 18L12.71 3.86a1.875 1.875 0 0 0-3.42 0Z" + } : { + border: "border-white/[0.10]", + background: "bg-nova-800/90", + text: "text-white", + icon: "text-emerald-400", + role: "status", + live: "polite", + iconPath: "M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z" + }; + reactExports.useEffect(() => { + if (visible) { + const enterTimer = requestAnimationFrame(() => setShow(true)); + const hideTimer = setTimeout(() => { + setShow(false); + setTimeout(() => onHide?.(), 200); + }, duration); + return () => { + cancelAnimationFrame(enterTimer); + clearTimeout(hideTimer); + }; + } else { + setShow(false); + } + }, [visible, duration, onHide]); + if (!visible) return null; + return reactDomExports.createPortal( + /* @__PURE__ */ React.createElement( + "div", + { + role: config.role, + "aria-live": config.live, + className: [ + "fixed bottom-24 left-1/2 z-[10001] -translate-x-1/2 rounded-full border px-5 py-2.5 text-sm font-medium shadow-xl backdrop-blur-md transition-all duration-200", + config.border, + config.background, + config.text, + show ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0" + ].join(" ") + }, + /* @__PURE__ */ React.createElement("span", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: `h-4 w-4 ${config.icon}` }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: config.iconPath, clipRule: "evenodd" })), message) + ), + document.body + ); +} +function formatBytes$2(bytes) { + const value = Number(bytes || 0); + if (!Number.isFinite(value) || value <= 0) return null; + if (value < 1024 * 1024) return `${Math.round(value / 1024)} KB`; + return `${(value / (1024 * 1024)).toFixed(1)} MB`; +} +function WorldMediaUploadField({ + label, + slot, + value, + previewUrl, + emptyLabel, + helperText, + uploadUrl, + deleteUrl, + worldId = null, + onChange, + isTemporaryValue = false, + accept = "image/jpeg,image/png,image/webp", + maxFileSizeMb = 6 +}) { + const inputRef = reactExports.useRef(null); + const [dragging, setDragging] = reactExports.useState(false); + const [uploading, setUploading] = reactExports.useState(false); + const [error, setError] = reactExports.useState(""); + const [meta, setMeta] = reactExports.useState(null); + const csrfToken2 = reactExports.useMemo(() => { + if (typeof document === "undefined") { + return ""; + } + return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") || ""; + }, []); + const deleteTemporaryUpload = async (path) => { + if (!deleteUrl || !path) return; + const response = await fetch(deleteUrl, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "X-CSRF-TOKEN": csrfToken2, + Accept: "application/json" + }, + credentials: "same-origin", + body: JSON.stringify({ + path, + world_id: worldId || void 0 + }) + }); + const payload = await response.json().catch(() => ({})); + if (!response.ok) { + throw new Error(payload?.message || payload?.error || "Could not remove uploaded image."); + } + }; + const handleFile = async (file) => { + if (!file || uploading) return; + const allowed = ["image/jpeg", "image/png", "image/webp"]; + if (!allowed.includes(String(file.type || "").toLowerCase())) { + setError("Use a JPG, PNG, or WEBP image."); + return; + } + if (file.size > maxFileSizeMb * 1024 * 1024) { + setError(`Image is too large. Maximum allowed size is ${maxFileSizeMb} MB.`); + return; + } + setUploading(true); + setError(""); + try { + if (value && isTemporaryValue) { + await deleteTemporaryUpload(value); + } + const body2 = new FormData(); + body2.append("slot", slot); + body2.append("image", file); + if (worldId) { + body2.append("world_id", String(worldId)); + } + const response = await fetch(uploadUrl, { + method: "POST", + headers: { + "X-CSRF-TOKEN": csrfToken2, + Accept: "application/json" + }, + credentials: "same-origin", + body: body2 + }); + const payload = await response.json().catch(() => ({})); + if (!response.ok) { + throw new Error(payload?.message || payload?.error || "Upload failed."); + } + setMeta({ + width: payload?.width || null, + height: payload?.height || null, + size: formatBytes$2(payload?.size_bytes) + }); + onChange?.({ path: payload?.path || "", url: payload?.url || "" }); + } catch (uploadError) { + setError(uploadError?.message || "Upload failed."); + } finally { + setUploading(false); + if (inputRef.current) { + inputRef.current.value = ""; + } + } + }; + return /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, label), value ? /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: async (event) => { + event.stopPropagation(); + setError(""); + setMeta(null); + try { + if (value && isTemporaryValue) { + setUploading(true); + await deleteTemporaryUpload(value); + } + onChange?.({ path: "", url: "" }); + } catch (deleteError) { + setError(deleteError?.message || "Could not remove uploaded image."); + } finally { + setUploading(false); + } + }, + disabled: uploading, + className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-white" + }, + "Clear" + ) : null), /* @__PURE__ */ React.createElement( + "div", + { + role: "button", + tabIndex: 0, + onClick: () => !uploading && inputRef.current?.click(), + onKeyDown: (event) => { + if (uploading) return; + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + inputRef.current?.click(); + } + }, + onDragOver: (event) => { + event.preventDefault(); + if (!uploading) setDragging(true); + }, + onDragEnter: (event) => { + event.preventDefault(); + if (!uploading) setDragging(true); + }, + onDragLeave: (event) => { + event.preventDefault(); + setDragging(false); + }, + onDrop: (event) => { + event.preventDefault(); + setDragging(false); + void handleFile(event.dataTransfer?.files?.[0]); + }, + className: [ + "rounded-[24px] border border-dashed px-5 py-5 transition outline-none", + uploading ? "cursor-progress border-sky-300/35 bg-sky-400/10" : dragging ? "cursor-pointer border-sky-300/50 bg-sky-400/12" : "cursor-pointer border-white/10 bg-black/20 hover:border-white/20 hover:bg-white/[0.04]" + ].join(" ") + }, + /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl border border-sky-300/20 bg-sky-400/10 text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${uploading ? "fa-circle-notch fa-spin" : "fa-cloud-arrow-up"}` })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, uploading ? "Uploading image…" : "Drop image here or browse"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-5 text-slate-400" }, helperText), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-2 text-[11px] text-slate-400" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "JPG"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "PNG"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "WEBP"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "Max ", maxFileSizeMb, " MB")))), /* @__PURE__ */ React.createElement("div", { className: "h-28 w-full overflow-hidden rounded-[20px] border border-white/10 bg-slate-950 lg:w-44" }, previewUrl ? /* @__PURE__ */ React.createElement("img", { src: previewUrl, alt: "", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center px-4 text-center text-sm text-slate-500" }, emptyLabel))), + value ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 truncate rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-xs text-slate-400" }, "Stored path: ", /* @__PURE__ */ React.createElement("span", { className: "text-slate-200" }, value)) : null, + meta ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-xs text-slate-400" }, "Optimized to ", meta.width, "×", meta.height, meta.size ? ` • ${meta.size}` : "") : null, + error ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, error) : null, + /* @__PURE__ */ React.createElement( + "input", + { + ref: inputRef, + type: "file", + accept, + className: "hidden", + disabled: uploading, + onChange: (event) => { + void handleFile(event.target.files?.[0]); + } + } + ) + )); +} +const CHALLENGE_EDITOR_TABS = [ + { + id: "overview", + label: "Overview", + description: "Title, slug, access, and the compact summary shown in academy challenge lists.", + icon: "fa-compass-drafting", + sections: ["challenge-identity"] + }, + { + id: "brief", + label: "Brief", + description: "Write the creative objective, rules, prizes, required tags, and eligible categories.", + icon: "fa-bullseye", + sections: ["challenge-brief", "challenge-rules"] + }, + { + id: "media", + label: "Media", + description: "Upload the hero cover and tune the visual used on challenge cards.", + icon: "fa-image", + sections: ["challenge-media"] + }, + { + id: "timeline", + label: "Timeline", + description: "Manage submission and voting windows without mixing them into editorial copy.", + icon: "fa-calendar-days", + sections: ["challenge-timeline"] + }, + { + id: "publish", + label: "Publish", + description: "Control status, visibility, featured placement, and the final public preview.", + icon: "fa-rocket-launch", + sections: ["challenge-publishing", "challenge-preview"] + } +]; +const CHALLENGE_FIELD_TAB_MAP = { + title: "overview", + slug: "overview", + excerpt: "overview", + access_level: "overview", + description: "brief", + brief: "brief", + rules: "brief", + prize_text: "brief", + required_tags: "brief", + allowed_categories: "brief", + cover_image: "media", + starts_at: "timeline", + ends_at: "timeline", + voting_starts_at: "timeline", + voting_ends_at: "timeline", + status: "publish", + featured: "publish", + active: "publish" +}; +function getField$3(fields, name2) { + return fields.find((field) => field.name === name2) || null; +} +function FieldError$4({ message }) { + if (!message) return null; + return /* @__PURE__ */ React.createElement("p", { className: "text-xs text-rose-300" }, message); +} +function SectionCard$7({ id, eyebrow, title, description, actions, children, tone = "default", className = "" }) { + const toneClass = tone === "feature" ? "bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.15),transparent_38%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] shadow-[0_24px_70px_rgba(2,6,23,0.28)]" : "bg-white/[0.03]"; + return /* @__PURE__ */ React.createElement("section", { id, className: `min-w-0 scroll-mt-24 rounded-[28px] border border-white/10 p-5 ${toneClass} ${className}`.trim() }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "max-w-3xl" }, eyebrow ? /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/75" }, eyebrow) : null, /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-semibold tracking-[-0.03em] text-white" }, title), description ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, description) : null), actions ? /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, actions) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-5" }, children)); +} +function EditorWorkspaceTabs$2({ activeTab, onChange, errorCounts }) { + const activeMeta = CHALLENGE_EDITOR_TABS.find((tab2) => tab2.id === activeTab) || CHALLENGE_EDITOR_TABS[0]; + return /* @__PURE__ */ React.createElement("div", { className: "sticky top-4 z-20 rounded-[24px] border border-white/10 bg-[linear-gradient(180deg,rgba(7,11,18,0.92),rgba(5,8,14,0.88))] px-3 py-3 shadow-[0_18px_50px_rgba(2,6,23,0.18)] backdrop-blur" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2", role: "tablist", "aria-label": "Challenge editor sections" }, CHALLENGE_EDITOR_TABS.map((tab2) => { + const isActive = tab2.id === activeTab; + const errorCount = Number(errorCounts?.[tab2.id] || 0); + return /* @__PURE__ */ React.createElement( + "button", + { + key: tab2.id, + type: "button", + role: "tab", + "aria-selected": isActive, + "aria-controls": `challenge-editor-panel-${tab2.id}`, + id: `challenge-editor-tab-${tab2.id}`, + onClick: () => onChange(tab2.id), + className: [ + "inline-flex items-center gap-2 rounded-2xl border px-4 py-2.5 text-sm font-semibold transition", + isActive ? "border-sky-300/25 bg-sky-300/12 text-sky-100 ring-1 ring-sky-300/20" : "border-white/10 bg-white/[0.03] text-white/80 hover:border-sky-300/30 hover:bg-sky-300/10 hover:text-white" + ].join(" ") + }, + /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${tab2.icon} text-xs` }), + /* @__PURE__ */ React.createElement("span", null, tab2.label), + errorCount > 0 ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-rose-300/20 bg-rose-300/10 px-2 py-0.5 text-[10px] font-bold uppercase tracking-[0.14em] text-rose-100" }, errorCount) : null + ); + })), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap items-center justify-between gap-3 px-1" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm leading-6 text-slate-400" }, activeMeta.description), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2 text-[11px] uppercase tracking-[0.16em] text-slate-500" }, activeMeta.sections.map((section) => /* @__PURE__ */ React.createElement("span", { key: section, className: "rounded-full border border-white/10 bg-white/[0.03] px-3 py-1.5" }, section.replace("challenge-", "").replace(/-/g, " ")))))); +} +function TextField$4({ label, value, onChange, error, hint, ...rest }) { + return /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, label), /* @__PURE__ */ React.createElement("input", { value: value ?? "", onChange, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none", ...rest }), hint ? /* @__PURE__ */ React.createElement("span", { className: "text-xs leading-5 text-slate-500" }, hint) : null, /* @__PURE__ */ React.createElement(FieldError$4, { message: error })); +} +function TextAreaField$3({ label, value, onChange, error, rows = 4, hint, placeholder }) { + return /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, label), /* @__PURE__ */ React.createElement("textarea", { value: value ?? "", onChange, rows, placeholder, className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-3 leading-7 text-white outline-none placeholder:text-slate-600" }), hint ? /* @__PURE__ */ React.createElement("span", { className: "text-xs leading-5 text-slate-500" }, hint) : null, /* @__PURE__ */ React.createElement(FieldError$4, { message: error })); +} +function ToggleField$3({ label, checked, onChange, help, error }) { + return /* @__PURE__ */ React.createElement("label", { className: `flex cursor-pointer items-start gap-4 rounded-[28px] border px-5 py-4 transition ${checked ? "border-[#f39a24]/35 bg-[#f39a24]/10" : "border-white/10 bg-black/20 hover:border-white/20 hover:bg-white/[0.04]"}` }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: Boolean(checked), onChange, className: "sr-only" }), /* @__PURE__ */ React.createElement("span", { className: `mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-xl border text-sm transition ${checked ? "border-[#f39a24] bg-[#f39a24] text-white" : "border-white/10 bg-[#151a29] text-transparent"}` }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-check" })), /* @__PURE__ */ React.createElement("span", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("span", { className: "block text-base font-semibold tracking-[-0.02em] text-white" }, label), help ? /* @__PURE__ */ React.createElement("span", { className: "mt-1 block text-sm leading-6 text-slate-300" }, help) : null, /* @__PURE__ */ React.createElement(FieldError$4, { message: error }))); +} +function PlainTextPreview({ title, value, fallback }) { + return /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, title), /* @__PURE__ */ React.createElement("div", { className: "mt-3 whitespace-pre-wrap text-sm leading-7 text-slate-300" }, String(value || "").trim() || fallback)); +} +function statusMeta(status2) { + const normalized = String(status2 || "draft"); + const labels = { + draft: "Draft", + scheduled: "Scheduled", + active: "Active", + voting: "Voting", + completed: "Completed", + archived: "Archived" + }; + const classes = { + draft: "border-white/10 bg-white/[0.04] text-slate-300", + scheduled: "border-fuchsia-300/20 bg-fuchsia-300/10 text-fuchsia-100", + active: "border-emerald-300/20 bg-emerald-300/10 text-emerald-100", + voting: "border-sky-300/20 bg-sky-300/10 text-sky-100", + completed: "border-amber-300/20 bg-amber-300/10 text-amber-100", + archived: "border-slate-300/15 bg-slate-300/8 text-slate-300" + }; + return { + label: labels[normalized] || normalized, + className: classes[normalized] || classes.draft + }; +} +function slugifyChallengeTitle(value) { + return String(value || "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 180); +} +function normalizeList(value) { + return String(value || "").split(/[,\n]/).map((item) => item.trim()).filter(Boolean); +} +function normalizeAssetPreview$1(value, cdnBaseUrl) { + const trimmed = String(value || "").trim(); + if (!trimmed) return ""; + if (trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("/")) return trimmed; + return `${String(cdnBaseUrl || "").replace(/\/$/, "")}/${trimmed.replace(/^\//, "")}`; +} +function stripPlainText$1(value) { + return String(value || "").replace(/\s+/g, " ").trim(); +} +function countWords$2(value) { + const text2 = stripPlainText$1(value); + return text2 ? text2.split(/\s+/).length : 0; +} +function formatDateLabel$2(value, fallback = "Not set") { + if (!value) return fallback; + const date = new Date(value); + if (Number.isNaN(date.getTime())) return fallback; + return new Intl.DateTimeFormat("en", { + month: "short", + day: "numeric", + year: "numeric", + hour: "2-digit", + minute: "2-digit" + }).format(date); +} +function daysBetween(start, end) { + const startDate = start ? new Date(start) : null; + const endDate = end ? new Date(end) : null; + if (!startDate || !endDate || Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) { + return null; + } + const diff = endDate.getTime() - startDate.getTime(); + if (diff < 0) return "Dates need review"; + const days = Math.max(1, Math.ceil(diff / (1e3 * 60 * 60 * 24))); + return `${days} day${days === 1 ? "" : "s"}`; +} +function firstErrorMessage$4(errors, fallback = "Please correct the highlighted fields and try again.") { + const queue = [errors]; + while (queue.length > 0) { + const current = queue.shift(); + if (typeof current === "string") { + const message = current.trim(); + if (message) return message; + continue; + } + if (Array.isArray(current)) { + queue.push(...current); + continue; + } + if (current && typeof current === "object") { + queue.push(...Object.values(current)); + } + } + return fallback; +} +function firstChallengeErrorTab(errors) { + const firstKey = Object.keys(errors || {})[0]; + if (!firstKey) return null; + const baseKey = firstKey.split(".")[0]; + return CHALLENGE_FIELD_TAB_MAP[baseKey] || null; +} +function challengeTabErrorCounts(errors) { + const counts = {}; + Object.keys(errors || {}).forEach((key) => { + const tabId = CHALLENGE_FIELD_TAB_MAP[key.split(".")[0]]; + if (!tabId) return; + counts[tabId] = Number(counts[tabId] || 0) + 1; + }); + return counts; +} +function buildChallengePayload(data) { + return { + ...data, + required_tags: normalizeList(data.required_tags), + allowed_categories: normalizeList(data.allowed_categories) + }; +} +function ChallengeEditor({ title, subtitle, fields, record, submitUrl, indexUrl, destroyUrl, method, editorContext = {} }) { + const form = G$1(record); + const slugTouchedRef = reactExports.useRef(String(record?.slug || "").trim() !== ""); + const [activeTab, setActiveTab] = reactExports.useState("overview"); + const [coverPreviewUrl, setCoverPreviewUrl] = reactExports.useState(record?.cover_image_url || normalizeAssetPreview$1(record?.cover_image, editorContext.coverCdnBaseUrl)); + const [stagedCoverPath, setStagedCoverPath] = reactExports.useState(""); + const [toast, setToast] = reactExports.useState({ id: 0, visible: false, message: "", variant: "success" }); + const accessField = getField$3(fields, "access_level"); + const statusField = getField$3(fields, "status"); + const status2 = statusMeta(form.data.status); + const requiredTags = reactExports.useMemo(() => normalizeList(form.data.required_tags), [form.data.required_tags]); + const allowedCategories = reactExports.useMemo(() => normalizeList(form.data.allowed_categories), [form.data.allowed_categories]); + const briefWordCount = countWords$2(`${form.data.description || ""} ${form.data.brief || ""} ${form.data.rules || ""}`); + const submissionWindow = daysBetween(form.data.starts_at, form.data.ends_at); + const votingWindow = daysBetween(form.data.voting_starts_at, form.data.voting_ends_at); + const publicPathPreview = `/academy/challenges/${form.data.slug || "challenge-slug"}`; + const errorCounts = challengeTabErrorCounts(form.errors); + const sectionClassName = (sectionId) => { + const tab2 = CHALLENGE_EDITOR_TABS.find((item) => item.sections.includes(sectionId)); + return tab2 && tab2.id !== activeTab ? "hidden" : ""; + }; + const showToast = (message, variant = "error") => { + setToast({ + id: Date.now() + Math.random(), + visible: true, + message, + variant + }); + }; + const setTitle = (nextTitle) => { + form.setData("title", nextTitle); + if (!slugTouchedRef.current) { + form.setData("slug", slugifyChallengeTitle(nextTitle)); + } + }; + const handleManualCoverChange = (nextValue) => { + setStagedCoverPath(""); + form.setData("cover_image", nextValue); + setCoverPreviewUrl(normalizeAssetPreview$1(nextValue, editorContext.coverCdnBaseUrl)); + }; + const submit = (event) => { + event.preventDefault(); + const payload = buildChallengePayload(form.data); + form.transform(() => payload); + const submitOptions = { + preserveScroll: true, + onError: (errors) => { + const nextTab = firstChallengeErrorTab(errors); + if (nextTab) { + setActiveTab(nextTab); + } + showToast(firstErrorMessage$4(errors), "error"); + }, + onFinish: () => form.transform((data) => data) + }; + if (method === "patch") { + form.patch(submitUrl, submitOptions); + return; + } + form.post(submitUrl, submitOptions); + }; + const deleteChallenge = () => { + if (!destroyUrl) return; + if (!window.confirm("Delete this challenge?")) return; + At.delete(destroyUrl); + }; + return /* @__PURE__ */ React.createElement(AdminLayout, { title, subtitle }, /* @__PURE__ */ React.createElement(Se$1, { title: `Admin - ${title}` }), /* @__PURE__ */ React.createElement("form", { onSubmit: submit, className: "space-y-6 pb-16" }, /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-[28px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.14),transparent_34%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.94))] shadow-[0_24px_70px_rgba(2,6,23,0.34)] backdrop-blur" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b border-white/10 px-5 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2 text-xs font-semibold uppercase tracking-[0.18em] text-slate-400" }, /* @__PURE__ */ React.createElement(xe, { href: indexUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-white transition hover:bg-white/[0.08]" }, "Back to challenges"), /* @__PURE__ */ React.createElement("span", null, destroyUrl ? "Edit challenge" : "New challenge")), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.05em] text-white" }, form.data.title || "Untitled academy challenge"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-6 text-slate-400" }, form.data.excerpt || "Shape a guided creative brief with clear rules, dates, tags, and a public-ready preview.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: `rounded-full border px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.16em] ${status2.className}` }, status2.label), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, form.data.access_level || "free"), editorContext?.links?.preview ? /* @__PURE__ */ React.createElement("a", { href: editorContext.links.preview, className: "rounded-full border border-sky-300/25 bg-sky-300/12 px-4 py-2 text-sm font-semibold text-sky-100" }, "Preview public page") : null)), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 px-5 py-5 md:grid-cols-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Submission window"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, submissionWindow || "Not scheduled")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Voting window"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, votingWindow || "Not scheduled")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Required tags"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, requiredTags.length)), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Brief copy"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, briefWordCount.toLocaleString(), " words")))), /* @__PURE__ */ React.createElement(EditorWorkspaceTabs$2, { activeTab, onChange: setActiveTab, errorCounts }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0 space-y-6" }, /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-identity", eyebrow: "Challenge identity", title: "Name and positioning", description: "Keep the title clear, the slug readable, and the card summary useful for academy discovery.", className: sectionClassName("challenge-identity") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(TextField$4, { label: "Title", value: form.data.title || "", onChange: (event) => setTitle(event.target.value), error: form.errors.title, maxLength: 180, placeholder: "Creator brief: cinematic wallpaper challenge" }), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Slug"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => { + slugTouchedRef.current = false; + form.setData("slug", slugifyChallengeTitle(form.data.title)); + }, className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[10px] font-semibold text-white" }, "Sync")), /* @__PURE__ */ React.createElement("input", { value: form.data.slug || "", onChange: (event) => { + slugTouchedRef.current = String(event.target.value).trim() !== ""; + form.setData("slug", event.target.value); + }, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none", maxLength: 180, placeholder: "cinematic-wallpaper-challenge" }), /* @__PURE__ */ React.createElement(FieldError$4, { message: form.errors.slug }))), /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Excerpt", value: form.data.excerpt || "", onChange: (event) => form.setData("excerpt", event.target.value), error: form.errors.excerpt, rows: 4, hint: "Short public summary used on challenge cards and academy home rails." }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: accessField?.label || "Access", value: form.data.access_level || "", onChange: (nextValue) => form.setData("access_level", String(nextValue || "")), options: accessField?.options || [], searchable: false, className: "bg-black/20", error: form.errors.access_level }), /* @__PURE__ */ React.createElement(TextField$4, { label: "Public path", value: publicPathPreview, readOnly: true, hint: "Generated from the slug. Published challenge pages use this path." }))), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-brief", eyebrow: "Creative brief", title: "Brief and creator direction", description: "Write the task in a way creators can execute without needing extra staff notes.", tone: "feature", className: sectionClassName("challenge-brief") }, /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Description", value: form.data.description || "", onChange: (event) => form.setData("description", event.target.value), error: form.errors.description, rows: 6, hint: "Overview copy for the challenge page. Plain text is safest here because public challenge pages preserve line breaks.", placeholder: "Introduce the creative goal, theme, and expected output." }), /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Brief", value: form.data.brief || "", onChange: (event) => form.setData("brief", event.target.value), error: form.errors.brief, rows: 10, hint: "The main actionable brief. Use line breaks for steps, constraints, or judging criteria.", placeholder: "Objective, deliverable, style direction, and acceptance notes." })), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-rules", eyebrow: "Rules and eligibility", title: "Requirements and rewards", description: "Keep challenge operations close to the brief so staff can audit everything before launch.", className: sectionClassName("challenge-rules") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(260px,0.72fr)]" }, /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Rules", value: form.data.rules || "", onChange: (event) => form.setData("rules", event.target.value), error: form.errors.rules, rows: 10, hint: "Submission rules, judging notes, restrictions, and moderation expectations." }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__PURE__ */ React.createElement(TextField$4, { label: "Prize text", value: form.data.prize_text || "", onChange: (event) => form.setData("prize_text", event.target.value), error: form.errors.prize_text, maxLength: 180, placeholder: "Featured placement plus Academy badge" }), /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Required tags", value: form.data.required_tags || "", onChange: (event) => form.setData("required_tags", event.target.value), error: form.errors.required_tags, rows: 4, hint: "Comma-separated or one per line. Saved as an array.", placeholder: "academy-challenge, cinematic, wallpaper" }), /* @__PURE__ */ React.createElement(TextAreaField$3, { label: "Allowed categories", value: form.data.allowed_categories || "", onChange: (event) => form.setData("allowed_categories", event.target.value), error: form.errors.allowed_categories, rows: 4, hint: "Comma-separated or one per line. Saved as an array.", placeholder: "Wallpapers, Skins, Worlds" })))), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-media", eyebrow: "Visual system", title: "Cover media", description: "Upload clean landscape imagery that works in public challenge cards and the challenge detail hero.", className: sectionClassName("challenge-media") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 lg:grid-cols-2 lg:items-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement( + WorldMediaUploadField, + { + label: "Cover image", + slot: "cover", + value: form.data.cover_image, + previewUrl: coverPreviewUrl, + emptyLabel: "Challenge cover", + helperText: "Use a landscape JPG, PNG, or WEBP. Minimum upload is 600x315; a 16:9 cover will crop best across academy surfaces.", + uploadUrl: editorContext.coverUploadUrl, + deleteUrl: editorContext.coverDeleteUrl, + isTemporaryValue: Boolean(stagedCoverPath) && stagedCoverPath === form.data.cover_image, + onChange: ({ path, url }) => { + setStagedCoverPath(path || ""); + form.setData("cover_image", path || ""); + setCoverPreviewUrl(url || normalizeAssetPreview$1(path || "", editorContext.coverCdnBaseUrl)); + } + } + ), /* @__PURE__ */ React.createElement(FieldError$4, { message: form.errors.cover_image }), /* @__PURE__ */ React.createElement(TextField$4, { label: "Advanced cover path or URL", value: form.data.cover_image || "", onChange: (event) => handleManualCoverChange(event.target.value), error: form.errors.cover_image, placeholder: "Optional external URL or stored object path" })), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[28px] border border-white/10 bg-slate-950" }, coverPreviewUrl ? /* @__PURE__ */ React.createElement("img", { src: coverPreviewUrl, alt: "Challenge cover preview", className: "h-72 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-72 items-center justify-center px-6 text-center text-sm text-slate-500" }, "No challenge cover selected yet.")))), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-timeline", eyebrow: "Timeline", title: "Submission and voting windows", description: "Set the dates that move the challenge from scheduled, to active, to voting, then completed.", className: sectionClassName("challenge-timeline") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(DateTimePicker, { label: "Starts at", value: form.data.starts_at || "", onChange: (nextValue) => form.setData("starts_at", nextValue || ""), error: form.errors.starts_at, clearable: true, className: "bg-black/20" }), /* @__PURE__ */ React.createElement(DateTimePicker, { label: "Ends at", value: form.data.ends_at || "", onChange: (nextValue) => form.setData("ends_at", nextValue || ""), error: form.errors.ends_at, clearable: true, className: "bg-black/20" }), /* @__PURE__ */ React.createElement(DateTimePicker, { label: "Voting starts at", value: form.data.voting_starts_at || "", onChange: (nextValue) => form.setData("voting_starts_at", nextValue || ""), error: form.errors.voting_starts_at, clearable: true, className: "bg-black/20" }), /* @__PURE__ */ React.createElement(DateTimePicker, { label: "Voting ends at", value: form.data.voting_ends_at || "", onChange: (nextValue) => form.setData("voting_ends_at", nextValue || ""), error: form.errors.voting_ends_at, clearable: true, className: "bg-black/20" }))), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-publishing", eyebrow: "Publishing", title: "Status and visibility", description: "Choose how this challenge behaves in academy discovery and whether it appears in featured placements.", className: sectionClassName("challenge-publishing") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: statusField?.label || "Status", value: form.data.status || "", onChange: (nextValue) => form.setData("status", String(nextValue || "")), options: statusField?.options || [], searchable: false, className: "bg-black/20", error: form.errors.status }), /* @__PURE__ */ React.createElement(ToggleField$3, { label: "Featured", checked: Boolean(form.data.featured), onChange: (event) => form.setData("featured", event.target.checked), help: "Promote this challenge on academy rails.", error: form.errors.featured }), /* @__PURE__ */ React.createElement(ToggleField$3, { label: "Active", checked: Boolean(form.data.active), onChange: (event) => form.setData("active", event.target.checked), help: "Inactive challenges stay hidden even when their status is public.", error: form.errors.active }))), /* @__PURE__ */ React.createElement(SectionCard$7, { id: "challenge-preview", eyebrow: "Preview", title: "Public-facing snapshot", description: "Scan the challenge card, brief, rules, tags, and timeline before saving.", tone: "feature", className: sectionClassName("challenge-preview") }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[28px] border border-white/10 bg-slate-950" }, coverPreviewUrl ? /* @__PURE__ */ React.createElement("img", { src: coverPreviewUrl, alt: "Challenge preview", className: "h-64 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-64 items-center justify-center px-6 text-center text-sm text-slate-500" }, "No cover image selected yet.")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-white/10 bg-black/20 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("span", { className: `rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] ${status2.className}` }, status2.label), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-200" }, form.data.access_level || "free"), form.data.featured ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-300/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100" }, "Featured") : null), /* @__PURE__ */ React.createElement("h3", { className: "mt-4 text-3xl font-semibold tracking-[-0.05em] text-white" }, form.data.title || "Untitled academy challenge"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-7 text-slate-300" }, form.data.excerpt || "Add a short challenge summary to explain what creators are building."), form.data.prize_text ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 rounded-2xl border border-[#f39a24]/20 bg-[#f39a24]/10 px-4 py-3 text-sm font-semibold text-[#ffd5cd]" }, form.data.prize_text) : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement(PlainTextPreview, { title: "Brief preview", value: form.data.brief || form.data.description, fallback: "The challenge brief is still empty." }), /* @__PURE__ */ React.createElement(PlainTextPreview, { title: "Rules preview", value: form.data.rules, fallback: "No special rules posted yet." })))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6 xl:sticky xl:top-6 xl:self-start" }, /* @__PURE__ */ React.createElement(SectionCard$7, { eyebrow: "At a glance", title: "Challenge summary", description: "A compact view of the details editors usually check before launch." }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-sky-300/18 bg-sky-300/8 p-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100/80" }, "Public path"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 break-all text-sm font-semibold text-white" }, publicPathPreview)), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-1" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Status"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, status2.label)), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Cover"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, coverPreviewUrl ? "Ready" : "Missing")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Submissions"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, formatDateLabel$2(form.data.starts_at), " to ", formatDateLabel$2(form.data.ends_at))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Voting"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm font-semibold text-white" }, formatDateLabel$2(form.data.voting_starts_at), " to ", formatDateLabel$2(form.data.voting_ends_at))))), /* @__PURE__ */ React.createElement(SectionCard$7, { eyebrow: "Requirements", title: "Tags and categories", description: "A quick scan of the saved arrays before the challenge opens." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Required tags"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, requiredTags.length ? requiredTags.map((tag) => /* @__PURE__ */ React.createElement("span", { key: tag, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-3 py-1.5 text-xs font-semibold text-sky-100" }, tag)) : /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-500" }, "No required tags yet."))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Allowed categories"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, allowedCategories.length ? allowedCategories.map((category) => /* @__PURE__ */ React.createElement("span", { key: category, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-slate-200" }, category)) : /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-500" }, "All categories are allowed unless you add limits."))))))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3 rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "rounded-full border border-sky-300/25 bg-sky-300/12 px-5 py-3 text-sm font-semibold text-sky-100" }, form.processing ? "Saving..." : "Save challenge"), /* @__PURE__ */ React.createElement(xe, { href: indexUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white" }, "Back"), destroyUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: deleteChallenge, className: "rounded-full border border-rose-300/20 bg-rose-300/10 px-5 py-3 text-sm font-semibold text-rose-100" }, "Delete") : null)), /* @__PURE__ */ React.createElement( + ShareToast, + { + key: toast.id, + message: toast.message, + visible: toast.visible, + variant: toast.variant, + duration: toast.variant === "error" ? 3200 : 2200, + onHide: () => setToast((current) => ({ ...current, visible: false })) + } + )); +} +const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + default: ChallengeEditor +}, Symbol.toStringTag, { value: "Module" })); function laneKey(sectionId) { return sectionId == null ? "unsectioned" : `section:${sectionId}`; } @@ -15794,7 +16761,7 @@ function AcademyCourseBuilder({ course, sections = [], courseLessons = [], avail } ), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: attachForm.processing || !attachForm.data.lesson_id, className: "w-full rounded-full border border-amber-300/25 bg-amber-300/12 px-5 py-3 text-sm font-semibold text-amber-100" }, attachForm.processing ? "Attaching..." : "Attach lesson")))))); } -const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AcademyCourseBuilder }, Symbol.toStringTag, { value: "Module" })); @@ -18356,655 +19323,6 @@ function RichTextEditor({ } ))); } -function formatBytes$2(bytes) { - const value = Number(bytes || 0); - if (!Number.isFinite(value) || value <= 0) return null; - if (value < 1024 * 1024) return `${Math.round(value / 1024)} KB`; - return `${(value / (1024 * 1024)).toFixed(1)} MB`; -} -function WorldMediaUploadField({ - label, - slot, - value, - previewUrl, - emptyLabel, - helperText, - uploadUrl, - deleteUrl, - worldId = null, - onChange, - isTemporaryValue = false, - accept = "image/jpeg,image/png,image/webp", - maxFileSizeMb = 6 -}) { - const inputRef = reactExports.useRef(null); - const [dragging, setDragging] = reactExports.useState(false); - const [uploading, setUploading] = reactExports.useState(false); - const [error, setError] = reactExports.useState(""); - const [meta, setMeta] = reactExports.useState(null); - const csrfToken2 = reactExports.useMemo(() => { - if (typeof document === "undefined") { - return ""; - } - return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") || ""; - }, []); - const deleteTemporaryUpload = async (path) => { - if (!deleteUrl || !path) return; - const response = await fetch(deleteUrl, { - method: "DELETE", - headers: { - "Content-Type": "application/json", - "X-CSRF-TOKEN": csrfToken2, - Accept: "application/json" - }, - credentials: "same-origin", - body: JSON.stringify({ - path, - world_id: worldId || void 0 - }) - }); - const payload = await response.json().catch(() => ({})); - if (!response.ok) { - throw new Error(payload?.message || payload?.error || "Could not remove uploaded image."); - } - }; - const handleFile = async (file) => { - if (!file || uploading) return; - const allowed = ["image/jpeg", "image/png", "image/webp"]; - if (!allowed.includes(String(file.type || "").toLowerCase())) { - setError("Use a JPG, PNG, or WEBP image."); - return; - } - if (file.size > maxFileSizeMb * 1024 * 1024) { - setError(`Image is too large. Maximum allowed size is ${maxFileSizeMb} MB.`); - return; - } - setUploading(true); - setError(""); - try { - if (value && isTemporaryValue) { - await deleteTemporaryUpload(value); - } - const body2 = new FormData(); - body2.append("slot", slot); - body2.append("image", file); - if (worldId) { - body2.append("world_id", String(worldId)); - } - const response = await fetch(uploadUrl, { - method: "POST", - headers: { - "X-CSRF-TOKEN": csrfToken2, - Accept: "application/json" - }, - credentials: "same-origin", - body: body2 - }); - const payload = await response.json().catch(() => ({})); - if (!response.ok) { - throw new Error(payload?.message || payload?.error || "Upload failed."); - } - setMeta({ - width: payload?.width || null, - height: payload?.height || null, - size: formatBytes$2(payload?.size_bytes) - }); - onChange?.({ path: payload?.path || "", url: payload?.url || "" }); - } catch (uploadError) { - setError(uploadError?.message || "Upload failed."); - } finally { - setUploading(false); - if (inputRef.current) { - inputRef.current.value = ""; - } - } - }; - return /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, label), value ? /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: async (event) => { - event.stopPropagation(); - setError(""); - setMeta(null); - try { - if (value && isTemporaryValue) { - setUploading(true); - await deleteTemporaryUpload(value); - } - onChange?.({ path: "", url: "" }); - } catch (deleteError) { - setError(deleteError?.message || "Could not remove uploaded image."); - } finally { - setUploading(false); - } - }, - disabled: uploading, - className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-white" - }, - "Clear" - ) : null), /* @__PURE__ */ React.createElement( - "div", - { - role: "button", - tabIndex: 0, - onClick: () => !uploading && inputRef.current?.click(), - onKeyDown: (event) => { - if (uploading) return; - if (event.key === "Enter" || event.key === " ") { - event.preventDefault(); - inputRef.current?.click(); - } - }, - onDragOver: (event) => { - event.preventDefault(); - if (!uploading) setDragging(true); - }, - onDragEnter: (event) => { - event.preventDefault(); - if (!uploading) setDragging(true); - }, - onDragLeave: (event) => { - event.preventDefault(); - setDragging(false); - }, - onDrop: (event) => { - event.preventDefault(); - setDragging(false); - void handleFile(event.dataTransfer?.files?.[0]); - }, - className: [ - "rounded-[24px] border border-dashed px-5 py-5 transition outline-none", - uploading ? "cursor-progress border-sky-300/35 bg-sky-400/10" : dragging ? "cursor-pointer border-sky-300/50 bg-sky-400/12" : "cursor-pointer border-white/10 bg-black/20 hover:border-white/20 hover:bg-white/[0.04]" - ].join(" ") - }, - /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl border border-sky-300/20 bg-sky-400/10 text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${uploading ? "fa-circle-notch fa-spin" : "fa-cloud-arrow-up"}` })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, uploading ? "Uploading image…" : "Drop image here or browse"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-5 text-slate-400" }, helperText), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-2 text-[11px] text-slate-400" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "JPG"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "PNG"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "WEBP"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1" }, "Max ", maxFileSizeMb, " MB")))), /* @__PURE__ */ React.createElement("div", { className: "h-28 w-full overflow-hidden rounded-[20px] border border-white/10 bg-slate-950 lg:w-44" }, previewUrl ? /* @__PURE__ */ React.createElement("img", { src: previewUrl, alt: "", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center px-4 text-center text-sm text-slate-500" }, emptyLabel))), - value ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 truncate rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-xs text-slate-400" }, "Stored path: ", /* @__PURE__ */ React.createElement("span", { className: "text-slate-200" }, value)) : null, - meta ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-xs text-slate-400" }, "Optimized to ", meta.width, "×", meta.height, meta.size ? ` • ${meta.size}` : "") : null, - error ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, error) : null, - /* @__PURE__ */ React.createElement( - "input", - { - ref: inputRef, - type: "file", - accept, - className: "hidden", - disabled: uploading, - onChange: (event) => { - void handleFile(event.target.files?.[0]); - } - } - ) - )); -} -const MONTH_NAMES = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" -]; -const YEAR_MIN = 1900; -const YEAR_MAX = 2105; -const DAY_ABBR = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]; -function pad(value) { - return String(value).padStart(2, "0"); -} -function daysInMonth(year, month) { - return new Date(year, month + 1, 0).getDate(); -} -function firstWeekday(year, month) { - const day = new Date(year, month, 1).getDay(); - return (day + 6) % 7; -} -function toISODate(date) { - return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; -} -function parseDatePart(value) { - if (!value) return null; - const [year, month, day] = value.split("-").map(Number); - if (!year || !month || !day) return null; - return new Date(year, month - 1, day); -} -function normalizeDateTimeInput(value) { - const raw = String(value || "").trim(); - if (!raw) return { date: "", time: "" }; - const match = raw.match(/^(\d{4}-\d{2}-\d{2})(?:[ T](\d{2}:\d{2})(?::\d{2})?)?(?:Z|[+-]\d{2}:?\d{2})?$/); - if (match) { - return { - date: match[1], - time: match[2] || "" - }; - } - const parsed = new Date(raw); - if (Number.isNaN(parsed.getTime())) { - return { date: raw, time: "" }; - } - return { - date: toISODate(parsed), - time: `${pad(parsed.getHours())}:${pad(parsed.getMinutes())}` - }; -} -function splitDateTime(value) { - const normalized = normalizeDateTimeInput(value); - return { - date: normalized.date, - time: normalized.time.slice(0, 5) - }; -} -function mergeDateTime(date, time) { - if (!date) return ""; - return `${date}T${time || "00:00"}`; -} -function maxDateValue(a, b2) { - if (!a) return b2 || ""; - if (!b2) return a || ""; - return a > b2 ? a : b2; -} -function minDateValue(a, b2) { - if (!a) return b2 || ""; - if (!b2) return a || ""; - return a < b2 ? a : b2; -} -function clampTimeToBounds(date, time, minDateTime, maxDateTime) { - const nextTime = time || "00:00"; - const minParts = splitDateTime(minDateTime); - const maxParts = splitDateTime(maxDateTime); - if (date && minParts.date === date && minParts.time && nextTime < minParts.time) { - return minParts.time; - } - if (date && maxParts.date === date && maxParts.time && nextTime > maxParts.time) { - return maxParts.time; - } - return nextTime; -} -function formatDisplay(value) { - if (!value) return ""; - const { date, time } = splitDateTime(value); - const parsed = parseDatePart(date); - if (!parsed) return ""; - return `${MONTH_NAMES[parsed.getMonth()].slice(0, 3)} ${parsed.getDate()}, ${parsed.getFullYear()}${time ? ` at ${time}` : ""}`; -} -function isSameDay(a, b2) { - return a?.getFullYear() === b2?.getFullYear() && a?.getMonth() === b2?.getMonth() && a?.getDate() === b2?.getDate(); -} -function CalendarGrid({ year, month, selectedDate, onSelect, minDate, maxDate }) { - const count = daysInMonth(year, month); - const start = firstWeekday(year, month); - const prevMonth = month - 1 < 0 ? 11 : month - 1; - const prevYear = month - 1 < 0 ? year - 1 : year; - const prevCount = daysInMonth(prevYear, prevMonth); - const cells = []; - for (let index2 = start - 1; index2 >= 0; index2 -= 1) { - cells.push({ - day: prevCount - index2, - current: false, - date: new Date(prevYear, prevMonth, prevCount - index2) - }); - } - for (let day = 1; day <= count; day += 1) { - cells.push({ day, current: true, date: new Date(year, month, day) }); - } - let nextDay = 1; - while (cells.length % 7 !== 0) { - cells.push({ day: nextDay, current: false, date: new Date(year, month + 1, nextDay) }); - nextDay += 1; - } - const today = /* @__PURE__ */ new Date(); - today.setHours(0, 0, 0, 0); - return /* @__PURE__ */ React.createElement("div", { className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "mb-1 grid grid-cols-7" }, DAY_ABBR.map((day) => /* @__PURE__ */ React.createElement("div", { key: day, className: "py-1 text-center text-[10px] font-semibold text-slate-500" }, day))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-7 gap-y-0.5" }, cells.map((cell, index2) => { - const iso = toISODate(cell.date); - const selected = isSameDay(cell.date, selectedDate); - const todayCell = isSameDay(cell.date, today); - const disabled = minDate && iso < minDate || maxDate && iso > maxDate; - return /* @__PURE__ */ React.createElement( - "button", - { - key: `${iso}-${index2}`, - type: "button", - disabled, - onClick: () => onSelect(iso), - className: [ - "relative mx-auto flex h-8 w-8 items-center justify-center rounded-lg text-sm transition-all", - !cell.current ? "text-slate-600" : "", - cell.current && !selected && !disabled ? "text-white hover:bg-white/10" : "", - selected ? "bg-accent font-semibold text-white shadow shadow-accent/30" : "", - todayCell && !selected ? "text-accent ring-1 ring-accent/50" : "", - disabled ? "cursor-not-allowed opacity-30" : "cursor-pointer" - ].join(" ") - }, - cell.day - ); - }))); -} -function DateTimePicker({ - value = "", - onChange, - label, - placeholder, - error, - hint, - required = false, - clearable = false, - id, - disabled = false, - mode = "datetime", - minDate, - maxDate, - minDateTime, - maxDateTime, - className = "" -}) { - const today = /* @__PURE__ */ new Date(); - const initial = splitDateTime(value); - const initialDate = parseDatePart(initial.date) || today; - const [open, setOpen] = reactExports.useState(false); - const [dropPos, setDropPos] = reactExports.useState({ top: 0, left: 0, width: 320 }); - const [viewYear, setViewYear] = reactExports.useState(initialDate.getFullYear()); - const [viewMonth, setViewMonth] = reactExports.useState(initialDate.getMonth()); - const [draftDate, setDraftDate] = reactExports.useState(initial.date); - const nowTime = `${pad(today.getHours())}:${pad(today.getMinutes())}`; - const defaultDraftTime = (function() { - const baseDate = initial.date || toISODate(initialDate); - const candidate = initial.time || nowTime; - return clampTimeToBounds(baseDate, candidate, minDateTime, maxDateTime); - })(); - const [draftTime, setDraftTime] = reactExports.useState(defaultDraftTime); - const effectivePlaceholder = placeholder || (mode === "date" ? "Pick a date" : "Pick a date and time"); - const triggerRef = reactExports.useRef(null); - const inputId = id ?? (label ? `dtp-${label.toLowerCase().replace(/\s+/g, "-")}` : "date-time-picker"); - const panelId = `dtp-panel-${inputId}`; - reactExports.useEffect(() => { - const next = splitDateTime(value); - setDraftDate(next.date); - const fallbackTime = (() => { - const candidate = next.time || `${pad((/* @__PURE__ */ new Date()).getHours())}:${pad((/* @__PURE__ */ new Date()).getMinutes())}`; - const dateForClamp = next.date || toISODate(initialDate); - return clampTimeToBounds(dateForClamp, candidate, minDateTime, maxDateTime); - })(); - setDraftTime(next.time || fallbackTime); - const nextDate = parseDatePart(next.date); - if (nextDate) { - setViewYear(nextDate.getFullYear()); - setViewMonth(nextDate.getMonth()); - } - }, [value]); - const measure = reactExports.useCallback(() => { - if (!triggerRef.current) return; - const rect = triggerRef.current.getBoundingClientRect(); - const panelWidth = Math.max(rect.width, 320); - const panelHeight = 420; - const openUp = window.innerHeight - rect.bottom < panelHeight + 8 && rect.top > panelHeight + 8; - setDropPos({ - top: openUp ? rect.top - panelHeight - 4 : rect.bottom + 4, - left: Math.min(rect.left, window.innerWidth - panelWidth - 8), - width: panelWidth - }); - }, []); - const openPicker = reactExports.useCallback(() => { - if (disabled) return; - measure(); - setOpen(true); - }, [disabled, measure]); - reactExports.useEffect(() => { - if (!open) return void 0; - const handleMouseDown = (event) => { - if (!triggerRef.current?.contains(event.target) && !document.getElementById(panelId)?.contains(event.target)) { - setOpen(false); - } - }; - document.addEventListener("mousedown", handleMouseDown); - return () => document.removeEventListener("mousedown", handleMouseDown); - }, [open, panelId]); - reactExports.useEffect(() => { - if (!open) return void 0; - const handleScroll = (event) => { - if (document.getElementById(panelId)?.contains(event.target)) return; - setOpen(false); - }; - const handleResize = () => setOpen(false); - window.addEventListener("scroll", handleScroll, true); - window.addEventListener("resize", handleResize); - return () => { - window.removeEventListener("scroll", handleScroll, true); - window.removeEventListener("resize", handleResize); - }; - }, [open, panelId]); - const applyValue = reactExports.useCallback((date, time) => { - if (!date) { - onChange?.(""); - return; - } - onChange?.(mode === "date" ? date : mergeDateTime(date, time)); - }, [mode, onChange]); - const handleDateSelect = (nextDate) => { - const nextTime = clampTimeToBounds(nextDate, draftTime, minDateTime, maxDateTime); - setDraftDate(nextDate); - setDraftTime(nextTime); - applyValue(nextDate, nextTime); - }; - const handleTimeChange = (event) => { - const nextTime = clampTimeToBounds(draftDate, event.target.value, minDateTime, maxDateTime); - setDraftTime(nextTime); - applyValue(draftDate, nextTime); - }; - const clearValue = (event) => { - event.stopPropagation(); - const now = `${pad((/* @__PURE__ */ new Date()).getHours())}:${pad((/* @__PURE__ */ new Date()).getMinutes())}`; - setDraftDate(""); - setDraftTime(now); - onChange?.(""); - }; - const prevMonth = () => { - if (viewMonth === 0) { - setViewMonth(11); - setViewYear((current) => current - 1); - return; - } - setViewMonth((current) => current - 1); - }; - const nextMonth = () => { - if (viewMonth === 11) { - setViewMonth(0); - setViewYear((current) => current + 1); - return; - } - setViewMonth((current) => current + 1); - }; - const triggerClass = [ - "relative flex h-[42px] w-full cursor-pointer items-center gap-2 rounded-xl border px-3.5 text-sm transition-all duration-150", - "bg-white/[0.06] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0", - error ? "border-red-500/60 focus-visible:ring-red-500/40" : open ? "border-accent/50 ring-2 ring-accent/40" : "border-white/12 hover:border-white/22", - disabled ? "pointer-events-none cursor-not-allowed opacity-50" : "", - className - ].join(" "); - const selectedDate = parseDatePart(draftDate); - const minDateTimeParts = splitDateTime(minDateTime); - const maxDateTimeParts = splitDateTime(maxDateTime); - const effectiveMinDate = maxDateValue(minDate, minDateTimeParts.date); - const effectiveMaxDate = minDateValue(maxDate, maxDateTimeParts.date); - const minTime = draftDate && draftDate === minDateTimeParts.date ? minDateTimeParts.time || void 0 : void 0; - const maxTime = draftDate && draftDate === maxDateTimeParts.date ? maxDateTimeParts.time || void 0 : void 0; - return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1.5" }, label && /* @__PURE__ */ React.createElement("label", { htmlFor: inputId, className: "text-sm font-medium text-white/85 select-none" }, label, required && /* @__PURE__ */ React.createElement("span", { className: "ml-1 text-red-400" }, "*")), /* @__PURE__ */ React.createElement( - "div", - { - ref: triggerRef, - id: inputId, - role: "button", - tabIndex: disabled ? -1 : 0, - "aria-label": label ?? effectivePlaceholder, - className: triggerClass, - onClick: openPicker, - onKeyDown: (event) => { - if (event.key === "Enter" || event.key === " ") { - event.preventDefault(); - openPicker(); - } - } - }, - /* @__PURE__ */ React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", className: "shrink-0 text-slate-500", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("rect", { x: "1", y: "2.5", width: "12", height: "10.5", rx: "1.5", stroke: "currentColor", strokeWidth: "1.3" }), /* @__PURE__ */ React.createElement("path", { d: "M1 6h12", stroke: "currentColor", strokeWidth: "1.3" }), /* @__PURE__ */ React.createElement("path", { d: "M4 1v3M10 1v3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round" }), /* @__PURE__ */ React.createElement("circle", { cx: "4.5", cy: "9", r: "0.75", fill: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "7", cy: "9", r: "0.75", fill: "currentColor" }), /* @__PURE__ */ React.createElement("circle", { cx: "9.5", cy: "9", r: "0.75", fill: "currentColor" })), - /* @__PURE__ */ React.createElement("span", { className: `flex-1 truncate ${value ? "text-white" : "text-slate-500"}` }, value ? formatDisplay(value) : effectivePlaceholder), - clearable && value && /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - tabIndex: -1, - onClick: clearValue, - className: "flex h-5 w-5 items-center justify-center rounded text-slate-500 transition-colors hover:text-white", - "aria-label": "Clear date and time" - }, - /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M1 1l8 8M9 1L1 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })) - ) - ), error && /* @__PURE__ */ React.createElement("p", { role: "alert", className: "text-xs text-red-400" }, error), !error && hint && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500" }, hint), open && reactDomExports.createPortal( - /* @__PURE__ */ React.createElement( - "div", - { - id: panelId, - className: "fixed z-[500] overflow-hidden rounded-2xl border border-white/12 bg-nova-900 shadow-2xl shadow-black/50", - style: { top: dropPos.top, left: dropPos.left, width: dropPos.width } - }, - /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 px-3 pt-3" }, /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: prevMonth, - className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white", - "aria-label": "Previous month" - }, - /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M7 1L3 5l4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) - ), /* @__PURE__ */ React.createElement("div", { className: "flex min-w-0 flex-1 items-center justify-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "whitespace-nowrap text-sm font-semibold text-white" }, MONTH_NAMES[viewMonth]), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 rounded-xl border border-white/10 bg-white/[0.04] px-1 py-1" }, /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: () => setViewYear((current) => Math.max(YEAR_MIN, current - 1)), - disabled: viewYear <= YEAR_MIN, - className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white disabled:cursor-not-allowed disabled:opacity-30", - "aria-label": "Previous year" - }, - /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-minus text-[11px]", "aria-hidden": "true" }) - ), /* @__PURE__ */ React.createElement("span", { className: "min-w-[72px] px-2 text-center text-sm font-semibold text-white" }, viewYear), /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: () => setViewYear((current) => Math.min(YEAR_MAX, current + 1)), - disabled: viewYear >= YEAR_MAX, - className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white disabled:cursor-not-allowed disabled:opacity-30", - "aria-label": "Next year" - }, - /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-plus text-[11px]", "aria-hidden": "true" }) - ))), /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: nextMonth, - className: "flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition-all hover:bg-white/8 hover:text-white", - "aria-label": "Next month" - }, - /* @__PURE__ */ React.createElement("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M3 1l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) - )), - /* @__PURE__ */ React.createElement( - CalendarGrid, - { - year: viewYear, - month: viewMonth, - selectedDate, - onSelect: handleDateSelect, - minDate: effectiveMinDate, - maxDate: effectiveMaxDate - } - ), - /* @__PURE__ */ React.createElement("div", { className: "border-t border-white/8 px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: `grid gap-3 ${mode === "date" ? "" : "sm:grid-cols-[minmax(0,1fr)_7rem] sm:items-end"}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Selected date"), /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white" }, draftDate ? formatDisplay(draftDate) : "Pick a day")), mode !== "date" ? /* @__PURE__ */ React.createElement("label", { className: "grid gap-1.5 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Time"), /* @__PURE__ */ React.createElement( - "input", - { - type: "time", - value: draftTime, - onChange: handleTimeChange, - min: minTime, - max: maxTime, - className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-white outline-none transition focus:border-accent/50 focus:ring-2 focus:ring-accent/40" - } - )) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex items-center justify-between" }, /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: () => handleDateSelect(toISODate(/* @__PURE__ */ new Date())), - className: "text-xs font-medium text-accent transition-colors hover:text-accent/80" - }, - "Today" - ), /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: () => setOpen(false), - className: "rounded-lg border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-medium text-white transition hover:bg-white/[0.08]" - }, - "Done" - ))) - ), - document.body - )); -} -function ShareToast({ message = "Link copied!", visible = false, onHide, duration = 2e3, variant = "success" }) { - const [show, setShow] = reactExports.useState(false); - const config = variant === "error" ? { - border: "border-rose-300/25", - background: "bg-rose-950/90", - text: "text-rose-50", - icon: "text-rose-300", - role: "alert", - live: "assertive", - iconPath: "M12 9v3.75m0 3.75h.007v.008H12v-.008ZM10.29 3.86 1.82 18a1.875 1.875 0 0 0 1.606 2.813h16.148A1.875 1.875 0 0 0 21.18 18L12.71 3.86a1.875 1.875 0 0 0-3.42 0Z" - } : { - border: "border-white/[0.10]", - background: "bg-nova-800/90", - text: "text-white", - icon: "text-emerald-400", - role: "status", - live: "polite", - iconPath: "M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z" - }; - reactExports.useEffect(() => { - if (visible) { - const enterTimer = requestAnimationFrame(() => setShow(true)); - const hideTimer = setTimeout(() => { - setShow(false); - setTimeout(() => onHide?.(), 200); - }, duration); - return () => { - cancelAnimationFrame(enterTimer); - clearTimeout(hideTimer); - }; - } else { - setShow(false); - } - }, [visible, duration, onHide]); - if (!visible) return null; - return reactDomExports.createPortal( - /* @__PURE__ */ React.createElement( - "div", - { - role: config.role, - "aria-live": config.live, - className: [ - "fixed bottom-24 left-1/2 z-[10001] -translate-x-1/2 rounded-full border px-5 py-2.5 text-sm font-medium shadow-xl backdrop-blur-md transition-all duration-200", - config.border, - config.background, - config.text, - show ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0" - ].join(" ") - }, - /* @__PURE__ */ React.createElement("span", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: `h-4 w-4 ${config.icon}` }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: config.iconPath, clipRule: "evenodd" })), message) - ), - document.body - ); -} const COURSE_EDITOR_TABS = [ { id: "overview", @@ -20230,7 +20548,7 @@ function CourseEditor({ title, subtitle, fields, record, submitUrl, indexUrl, de } )); } -const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CourseEditor }, Symbol.toStringTag, { value: "Module" })); @@ -23057,7 +23375,7 @@ function LessonEditor({ title, subtitle, fields, record, submitUrl, indexUrl, de } )); } -const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: LessonEditor }, Symbol.toStringTag, { value: "Module" })); @@ -24501,6 +24819,22 @@ function AcademyCrudForm({ resource, title, subtitle, fields, record, submitUrl, } ); } + if (resource === "challenges") { + return /* @__PURE__ */ React.createElement( + ChallengeEditor, + { + title, + subtitle, + fields, + record, + submitUrl, + indexUrl, + destroyUrl, + method, + editorContext + } + ); + } return /* @__PURE__ */ React.createElement( GenericEditor, { @@ -24516,7 +24850,7 @@ function AcademyCrudForm({ resource, title, subtitle, fields, record, submitUrl, } ); } -const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AcademyCrudForm }, Symbol.toStringTag, { value: "Module" })); @@ -24811,7 +25145,7 @@ function AcademyCrudIndex({ title, subtitle, items, columns, createUrl }) { At.delete(item.destroy_url, { preserveScroll: true }); }, className: "rounded-full border border-rose-300/20 bg-rose-300/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Delete")))))))); } -const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AcademyCrudIndex }, Symbol.toStringTag, { value: "Module" })); @@ -24821,7 +25155,7 @@ function StatCard$c({ label, value }) { function AcademyDashboard({ stats, links }) { return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Academy Dashboard", subtitle: "Overview of Academy content, challenge activity, and live Academy subscription health." }, /* @__PURE__ */ React.createElement(Se$1, { title: "Admin · Academy Dashboard" }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement(StatCard$c, { label: "Courses", value: stats.courses }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Lessons", value: stats.lessons }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Prompts", value: stats.prompts }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Prompt Packs", value: stats.packs }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Challenges", value: stats.challenges }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Submissions", value: stats.submissions }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Badges", value: stats.badges }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Active Subscribers", value: stats.active_subscribers || 0 }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Creator Subscribers", value: stats.creator_subscribers }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Pro Subscribers", value: stats.pro_subscribers }), /* @__PURE__ */ React.createElement(StatCard$c, { label: "Grace Period", value: stats.grace_period_subscribers || 0 })), /* @__PURE__ */ React.createElement("div", { className: "mt-8 rounded-[28px] border border-white/[0.08] bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500" }, "Modules"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3" }, Object.entries(links).map(([key, href]) => /* @__PURE__ */ React.createElement(xe, { key, href, className: "rounded-2xl border border-white/[0.08] bg-black/20 px-4 py-4 text-sm font-semibold text-white transition hover:border-white/15 hover:bg-white/[0.05]" }, key.replaceAll("_", " ")))))); } -const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AcademyDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -24829,7 +25163,7 @@ function AcademySubmissions({ submissions }) { const flash = X$1().props.flash || {}; return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Academy Challenge Submissions", subtitle: "Approve or reject Academy challenge entries." }, /* @__PURE__ */ React.createElement(Se$1, { title: "Admin · Academy Challenge Submissions" }), flash.success ? /* @__PURE__ */ React.createElement("div", { className: "mb-6 rounded-2xl border border-emerald-300/20 bg-emerald-300/10 px-4 py-3 text-sm text-emerald-100" }, flash.success) : null, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, (submissions?.data || []).map((submission) => /* @__PURE__ */ React.createElement("article", { key: submission.id, className: "rounded-[28px] border border-white/[0.08] bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] text-white/80" }, submission.moderation_status), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-400" }, submission.challenge?.title || "Challenge")), /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, submission.artwork?.title || "Artwork removed"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, submission.user?.name || "Unknown user", " · ", submission.ai_tool_used || "No tool noted"), submission.prompt_used ? /* @__PURE__ */ React.createElement("pre", { className: "whitespace-pre-wrap rounded-2xl border border-white/10 bg-black/20 p-4 text-sm leading-7 text-slate-200" }, submission.prompt_used) : null, submission.workflow_notes ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 p-4 text-sm leading-7 text-slate-300" }, submission.workflow_notes) : null), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3 lg:justify-end" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(submission.approve_url, {}, { preserveScroll: true }), className: "rounded-full border border-emerald-300/20 bg-emerald-300/10 px-4 py-2 text-sm font-semibold text-emerald-100" }, "Approve"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(submission.reject_url, {}, { preserveScroll: true }), className: "rounded-full border border-rose-300/20 bg-rose-300/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Reject"))))))); } -const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AcademySubmissions }, Symbol.toStringTag, { value: "Module" })); @@ -25018,14 +25352,14 @@ function AiBiographyAdmin() { )), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2 text-xs leading-relaxed text-slate-300" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Approved:"), " ", formatDateTime$5(record.approved_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Created:"), " ", formatDateTime$5(record.created_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Updated:"), " ", formatDateTime$5(record.updated_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Source hash:"), " ", record.source_hash || "—"))))); })), records.prev_page_url || records.next_page_url ? /* @__PURE__ */ React.createElement("div", { className: "mt-8 flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, records.prev_page_url ? /* @__PURE__ */ React.createElement(xe, { href: records.prev_page_url, preserveScroll: true, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left text-[10px]" }), "Previous") : null), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, "Showing page ", records.current_page || 1, " of ", records.last_page || 1), /* @__PURE__ */ React.createElement("div", null, records.next_page_url ? /* @__PURE__ */ React.createElement(xe, { href: records.next_page_url, preserveScroll: true, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Next", /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right text-[10px]" })) : null)) : null); } -const __vite_glob_0_93 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_94 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AiBiographyAdmin }, Symbol.toStringTag, { value: "Module" })); function AdminAiBiography() { return /* @__PURE__ */ React.createElement(AdminLayout, null, /* @__PURE__ */ React.createElement(AiBiographyAdmin, null)); } -const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminAiBiography }, Symbol.toStringTag, { value: "Module" })); @@ -25049,7 +25383,7 @@ function AdminArtworks({ artworks }) { } ) : /* @__PURE__ */ React.createElement("span", { key: i, className: "rounded-lg px-3 py-1.5 text-xs text-slate-700", dangerouslySetInnerHTML: { __html: link2.label } })))))); } -const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -25147,7 +25481,7 @@ function AuthAudit({ logs, filters, eventOptions, statusOptions }) { } ) : /* @__PURE__ */ React.createElement("span", { key: `${link2.label}-${index2}`, className: "rounded-lg px-3 py-1.5 text-xs text-slate-700", dangerouslySetInnerHTML: { __html: link2.label } })))) : null)); } -const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AuthAudit }, Symbol.toStringTag, { value: "Module" })); @@ -25281,7 +25615,7 @@ function DailyActivity({ selectedDate, summary, queues, sections }) { } ))))); } -const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_28 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: DailyActivity }, Symbol.toStringTag, { value: "Module" })); @@ -25317,7 +25651,7 @@ function Dashboard({ stats }) { /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white group-hover:text-rose-300 transition" }, item.label), /* @__PURE__ */ React.createElement("p", { className: "mt-0.5 text-xs text-slate-500" }, item.desc)) ))))); } -const __vite_glob_0_28 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_29 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: Dashboard }, Symbol.toStringTag, { value: "Module" })); @@ -26099,14 +26433,14 @@ function FeaturedArtworksAdmin() { } ))))); } -const __vite_glob_0_49 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_50 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: FeaturedArtworksAdmin }, Symbol.toStringTag, { value: "Module" })); function AdminFeaturedArtworks() { return /* @__PURE__ */ React.createElement(AdminLayout, null, /* @__PURE__ */ React.createElement(FeaturedArtworksAdmin, null)); } -const __vite_glob_0_29 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_30 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminFeaturedArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -26785,7 +27119,7 @@ function HomepageAnnouncementForm({ announcement, previewAnnouncement, options, } }, help: "Turn this on to clear the saved background image on the next save." })) : null, activeTab === "behavior" ? /* @__PURE__ */ React.createElement(Section$1, { title: "Behavior", description: "Dismiss controls let you force a fresh surface when the message materially changes." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(TextField, { label: "Dismiss version", value: form.data.dismiss_version, onChange: (event) => form.setData("dismiss_version", event.target.value), error: form.errors.dismiss_version, inputMode: "numeric" }), /* @__PURE__ */ React.createElement(SelectField, { label: "Placement", value: form.data.placement, onChange: (nextValue) => form.setData("placement", nextValue), options: options.placements, error: form.errors.placement })), /* @__PURE__ */ React.createElement(ToggleField, { label: "Users can dismiss this card", checked: Boolean(form.data.is_dismissible), onChange: (event) => form.setData("is_dismissible", event.target.checked), help: "When disabled, the card remains visible and no restore pill is shown." })) : null), /* @__PURE__ */ React.createElement("aside", { className: "space-y-6 xl:sticky xl:top-[7.5rem] xl:self-start" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Section$1, { title: "Preview", description: "Refresh the preview to render the sanitized content and resolved CTA payload exactly as the homepage card sees it." }, /* @__PURE__ */ React.createElement("div", { className: "-mx-6 -mt-6 mb-5 border-b border-white/10 bg-slate-950/92 px-6 py-4 backdrop-blur-xl" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: runPreview, disabled: previewBusy, className: "rounded-full border border-sky-300/20 bg-sky-300/12 px-4 py-2 text-sm font-semibold text-sky-100 transition hover:bg-sky-300/18 disabled:opacity-60" }, previewBusy ? "Refreshing preview…" : "Refresh preview"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => submit(), className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "Save changes")), previewError ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm text-rose-300" }, previewError) : null), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[30px] border border-white/10 bg-black/20 py-2" }, /* @__PURE__ */ React.createElement(HomepageAnnouncement, { announcement: previewWithLocalImage, mode: "preview" }))))))); } -const __vite_glob_0_30 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_31 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HomepageAnnouncementForm }, Symbol.toStringTag, { value: "Module" })); @@ -26824,7 +27158,7 @@ function HomepageAnnouncementsIndex({ announcements, createUrl }) { } ) : /* @__PURE__ */ React.createElement("span", { key: `${link2.label}-${index2}`, className: "rounded-lg px-3 py-1.5 text-xs text-slate-600", dangerouslySetInnerHTML: { __html: link2.label } })))) : null); } -const __vite_glob_0_31 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_32 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HomepageAnnouncementsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -26864,7 +27198,7 @@ function AdminSettings({ settings = {} }) { } )))))), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-600" }, "Full settings management via config files and environment variables."))); } -const __vite_glob_0_32 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_33 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminSettings }, Symbol.toStringTag, { value: "Module" })); @@ -26888,7 +27222,7 @@ function AdminStories({ stories }) { } ) : /* @__PURE__ */ React.createElement("span", { key: i, className: "rounded-lg px-3 py-1.5 text-xs text-slate-700", dangerouslySetInnerHTML: { __html: link2.label } })))))); } -const __vite_glob_0_33 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_34 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminStories }, Symbol.toStringTag, { value: "Module" })); @@ -26954,7 +27288,7 @@ function AdminUploadQueue() { function UploadQueuePage() { return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Upload Queue", subtitle: "Review and moderate pending artwork submissions" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Admin · Upload Queue" }), /* @__PURE__ */ React.createElement(AdminUploadQueue, null)); } -const __vite_glob_0_34 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_35 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadQueuePage }, Symbol.toStringTag, { value: "Module" })); @@ -27018,7 +27352,7 @@ function AdminUsernameQueue() { function UsernameQueuePage() { return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Username Queue", subtitle: "Review and approve pending username change requests" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Admin · Username Queue" }), /* @__PURE__ */ React.createElement(AdminUsernameQueue, null)); } -const __vite_glob_0_35 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_36 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UsernameQueuePage }, Symbol.toStringTag, { value: "Module" })); @@ -27114,7 +27448,7 @@ function UsersIndex({ users, filters, roles }) { } ) : /* @__PURE__ */ React.createElement("span", { key: i, className: "rounded-lg px-3 py-1.5 text-xs text-slate-700", dangerouslySetInnerHTML: { __html: link2.label } })))))); } -const __vite_glob_0_36 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_37 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UsersIndex }, Symbol.toStringTag, { value: "Module" })); @@ -27178,7 +27512,7 @@ function SimilarArtworksHeader({ artwork }) { artwork.content_type_name || "artworks" ))))); } -const __vite_glob_0_37 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_38 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SimilarArtworksHeader }, Symbol.toStringTag, { value: "Module" })); @@ -40521,7 +40855,7 @@ function useWebShare({ onFallback } = {}) { ); return { canNativeShare, share }; } -const ArtworkShareModal = reactExports.lazy(() => import("./assets/ArtworkShareModal-BPM8yel5.js")); +const ArtworkShareModal = reactExports.lazy(() => import("./assets/ArtworkShareModal-BI8kkaqs.js")); function ShareIcon() { return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 1 1 0-2.684m0 2.684 6.632 3.316m-6.632-6 6.632-3.316m0 0a3 3 0 1 0 5.367-2.684 3 3 0 0 0-5.367 2.684Zm0 9.316a3 3 0 1 0 5.368 2.684 3 3 0 0 0-5.368-2.684Z" })); } @@ -42438,7 +42772,7 @@ function ArtworkPage({ artwork: initialArtwork, related: initialRelated, present } )); } -const __vite_glob_0_38 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_39 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ArtworkPage }, Symbol.toStringTag, { value: "Module" })); @@ -74788,7 +75122,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountElement).render(/* @__PURE__ */ React.createElement(CategoriesPage, { ...props })); } } -const __vite_glob_0_39 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_40 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CategoriesPage }, Symbol.toStringTag, { value: "Module" })); @@ -74810,7 +75144,7 @@ function CollectionAnalytics() { const seo = props.seo || {}; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Se$1, null, /* @__PURE__ */ React.createElement("title", null, seo.title || `${collection.title || "Collection"} Analytics — Skinbase`), /* @__PURE__ */ React.createElement("meta", { name: "description", content: seo.description || "Collection analytics overview." }), seo.canonical ? /* @__PURE__ */ React.createElement("link", { rel: "canonical", href: seo.canonical }) : null, /* @__PURE__ */ React.createElement("meta", { name: "robots", content: seo.robots || "noindex,follow" })), /* @__PURE__ */ React.createElement("div", { className: "relative min-h-screen overflow-hidden pb-16" }, /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-0 -z-10 h-[32rem] opacity-95", style: { background: "radial-gradient(circle at 14% 14%, rgba(56,189,248,0.18), transparent 26%), radial-gradient(circle at 86% 18%, rgba(16,185,129,0.16), transparent 24%), linear-gradient(180deg, #07101d 0%, #0a1220 42%, #08111f 100%)" } }), /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10 opacity-[0.05]", style: { backgroundImage: "url(/gfx/noise.png)", backgroundSize: "180px" } }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pt-8 md:px-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-slate-300" }, props.dashboardUrl ? /* @__PURE__ */ React.createElement("a", { href: props.dashboardUrl, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left fa-fw text-[11px]" }), "Dashboard") : null, props.historyUrl ? /* @__PURE__ */ React.createElement("a", { href: props.historyUrl, className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 font-semibold text-sky-100 transition hover:bg-sky-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-timeline fa-fw text-[11px]" }), "History") : null, collection.manage_url ? /* @__PURE__ */ React.createElement("a", { href: collection.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen-to-square fa-fw text-[11px]" }), "Manage") : null), /* @__PURE__ */ React.createElement("section", { className: "mt-6 rounded-[34px] border border-white/10 bg-white/[0.04] p-6 shadow-[0_30px_90px_rgba(2,6,23,0.28)] backdrop-blur-sm md:p-8" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Performance"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-4xl font-semibold tracking-[-0.05em] text-white md:text-5xl" }, collection.title || "Collection analytics"), /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-relaxed text-slate-300 md:text-[15px]" }, "Review activity velocity, audience response, and the artworks carrying the most discovery value over the last ", range2.days || 30, " days.")), /* @__PURE__ */ React.createElement("section", { className: "mt-8 grid gap-5 md:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Views", value: totals.views, delta: range2.views_delta, icon: "fa-eye" }), /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Likes", value: totals.likes, delta: range2.likes_delta, icon: "fa-heart" }), /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Follows", value: totals.follows, delta: range2.follows_delta, icon: "fa-bell" }), /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Saves", value: totals.saves, delta: range2.saves_delta, icon: "fa-bookmark" }), /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Comments", value: totals.comments, delta: range2.comments_delta, icon: "fa-comments" }), /* @__PURE__ */ React.createElement(MetricCard$1, { label: "Submissions", value: totals.submissions, delta: totals.submissions, icon: "fa-inbox" })), /* @__PURE__ */ React.createElement("div", { className: "mt-8 space-y-6" }, /* @__PURE__ */ React.createElement(TimelineChart, { timeline: analytics.timeline }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Artworks"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Top artwork drivers")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, topArtworks.length)), topArtworks.length ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, topArtworks.map((artwork) => /* @__PURE__ */ React.createElement("div", { key: artwork.id, className: "overflow-hidden rounded-[24px] border border-white/10 bg-slate-950/40" }, /* @__PURE__ */ React.createElement("div", { className: "aspect-square bg-slate-950/60" }, artwork.thumb ? /* @__PURE__ */ React.createElement("img", { src: artwork.thumb, alt: artwork.title, className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full w-full items-center justify-center text-slate-500" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image text-3xl" }))), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-sm font-semibold text-white" }, artwork.title), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-2 text-xs text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Views: ", Number(artwork.views || 0).toLocaleString()), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Favs: ", Number(artwork.favourites || 0).toLocaleString()), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Shares: ", Number(artwork.shares || 0).toLocaleString()), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Rank: ", Number(artwork.ranking_score || 0).toFixed(1))))))) : /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-dashed border-white/12 bg-white/[0.03] px-6 py-12 text-sm text-slate-300" }, "Attach or publish more artworks before artwork-level ranking can be surfaced here.")))))); } -const __vite_glob_0_40 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_41 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -75277,7 +75611,7 @@ function CollectionDashboard() { } ), /* @__PURE__ */ React.createElement(SearchResults, { state: searchState, endpoints, selectedIds, onToggleSelected: toggleSelected })), /* @__PURE__ */ React.createElement(WarningList, { warnings: healthWarnings, endpoints }), /* @__PURE__ */ React.createElement(CollectionStrip, { title: "Top Performing", eyebrow: "Momentum", collections: topPerforming, emptyLabel: "No collections have enough activity yet to rank here.", endpoints }), /* @__PURE__ */ React.createElement(CollectionStrip, { title: "Needs Attention", eyebrow: "Quality", collections: needsAttention, emptyLabel: "No collections currently need manual intervention.", endpoints }), /* @__PURE__ */ React.createElement(CollectionStrip, { title: "Expiring Campaigns", eyebrow: "Timing", collections: expiringCampaigns, emptyLabel: "No campaigns are approaching their sunset window.", endpoints }))))); } -const __vite_glob_0_41 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_42 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -75473,7 +75807,7 @@ function CollectionFeaturedIndex() { } ), /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10 opacity-[0.05]", style: { backgroundImage: "url(/gfx/noise.png)", backgroundSize: "180px" } }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pt-8 md:px-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("a", { href: "/", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left fa-fw text-[11px]" }), "Back to home"), /* @__PURE__ */ React.createElement("a", { href: "/collections/featured", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Featured"), /* @__PURE__ */ React.createElement("a", { href: "/collections/trending", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Trending"), /* @__PURE__ */ React.createElement("a", { href: "/collections/community", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Community"), /* @__PURE__ */ React.createElement("a", { href: "/collections/editorial", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Editorial"), /* @__PURE__ */ React.createElement("a", { href: "/collections/seasonal", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Seasonal")), /* @__PURE__ */ React.createElement("section", { className: "mt-6 overflow-hidden rounded-[34px] border border-white/10 bg-white/[0.04] p-6 shadow-[0_30px_90px_rgba(2,6,23,0.28)] backdrop-blur-sm md:p-8" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-8 xl:grid-cols-[minmax(0,1.18fr)_400px] xl:items-end" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, eyebrow), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-4xl font-semibold tracking-[-0.05em] text-white md:text-5xl" }, title), campaign?.badge_label ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 inline-flex items-center rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100" }, campaign.badge_label) : program?.promotion_tier ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 inline-flex items-center rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100" }, "Promotion tier: ", program.promotion_tier) : null, /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-relaxed text-slate-300 md:text-[15px]" }, description), campaign ? /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3 text-xs text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Campaign key: ", campaign.key), campaign.event_label ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Event: ", campaign.event_label) : null, campaign.season_key ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Season: ", campaign.season_key) : null, Array.isArray(campaign.active_surface_keys) && campaign.active_surface_keys.length ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Surfaces: ", campaign.active_surface_keys.join(", ")) : null) : program ? /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3 text-xs text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Program key: ", program.key), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Collections: ", program.collections_count ?? collections.length), program.trust_tier ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Trust: ", program.trust_tier) : null, Array.isArray(program.partner_labels) && program.partner_labels.length ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Partners: ", program.partner_labels.join(", ")) : null, Array.isArray(program.sponsorship_labels) && program.sponsorship_labels.length ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-2" }, "Sponsors: ", program.sponsorship_labels.join(", ")) : null) : null), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 sm:grid-cols-3 xl:grid-cols-1" }, /* @__PURE__ */ React.createElement(HeroStat$2, { icon: "fa-layer-group", label: "Collections", value: collections.length.toLocaleString() }), /* @__PURE__ */ React.createElement(HeroStat$2, { icon: "fa-wand-magic-sparkles", label: "Smart", value: smartCount.toLocaleString() }), /* @__PURE__ */ React.createElement(HeroStat$2, { icon: "fa-images", label: "Artworks", value: totalArtworks.toLocaleString() })))), /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement(SearchPanel, { search: search2 })), /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, collections.length ? /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, collections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: mainSave.context, saveContextMeta: mainSave.meta }))) : /* @__PURE__ */ React.createElement(EmptyState$4, null)), communityCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Community"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Collaborative picks"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, communityCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: "community_row", saveContextMeta: { surface_label: "community collections" } })))) : null, trendingCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Trending"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Momentum right now")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, trendingCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: "trending_row", saveContextMeta: { surface_label: "trending collections" } })))) : null, editorialCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Editorial"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Staff and campaign collections")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, editorialCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: "editorial_row", saveContextMeta: { surface_label: "editorial collections" } })))) : null, seasonalCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Seasonal"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Campaign and event spotlights")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, seasonalCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: "seasonal_row", saveContextMeta: { surface_label: "seasonal collections" } })))) : null, recentCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-10 pb-8" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Recent"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Freshly published collections")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, recentCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false, saveContext: "recent_row", saveContextMeta: { surface_label: "recent collections" } })))) : null))); } -const __vite_glob_0_42 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionFeaturedIndex }, Symbol.toStringTag, { value: "Module" })); @@ -75544,7 +75878,7 @@ function CollectionHistory() { busyId === entry.id ? "Restoring…" : "Restore" ) : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement(FieldChanges, { label: "Before", value: entry.before }), /* @__PURE__ */ React.createElement(FieldChanges, { label: "After", value: entry.after })))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[30px] border border-dashed border-white/12 bg-white/[0.03] px-6 py-14 text-sm text-slate-300" }, "No audit entries have been recorded for this collection yet.")), Number(meta.last_page || 1) > 1 ? /* @__PURE__ */ React.createElement("div", { className: "mt-8 flex flex-wrap items-center justify-between gap-3 rounded-[28px] border border-white/10 bg-white/[0.04] px-5 py-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", null, "Page ", meta.current_page || 1, " of ", meta.last_page || 1), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, (meta.current_page || 1) > 1 ? /* @__PURE__ */ React.createElement("a", { href: buildPageUrl((meta.current_page || 1) - 1), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left fa-fw text-[10px]" }), "Previous") : null, (meta.current_page || 1) < (meta.last_page || 1) ? /* @__PURE__ */ React.createElement("a", { href: buildPageUrl((meta.current_page || 1) + 1), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 font-semibold text-white transition hover:bg-white/[0.07]" }, "Next", /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right fa-fw text-[10px]" })) : null)) : null))); } -const __vite_glob_0_43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionHistory }, Symbol.toStringTag, { value: "Module" })); @@ -77504,7 +77838,7 @@ function CollectionManage() { } )), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("span", null, "Allow comments"), /* @__PURE__ */ React.createElement(Checkbox, { checked: form.allow_comments, onChange: (event) => handleModerationToggle("allow_comments", event.target.checked) })), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("span", null, "Allow submissions"), /* @__PURE__ */ React.createElement(Checkbox, { checked: form.allow_submissions, onChange: (event) => handleModerationToggle("allow_submissions", event.target.checked) })), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("span", null, "Allow saves"), /* @__PURE__ */ React.createElement(Checkbox, { checked: form.allow_saves, onChange: (event) => handleModerationToggle("allow_saves", event.target.checked) })))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.04] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Rapid actions"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: handleAdminUnfeature, className: "rounded-2xl border border-amber-300/25 bg-amber-300/10 px-4 py-3 text-sm font-semibold text-amber-100 transition hover:bg-amber-300/15" }, "Remove featured placement"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleModerationStatusChange("under_review"), className: "rounded-2xl border border-white/12 bg-white/[0.05] px-4 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "Send to review"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleModerationStatusChange("restricted"), className: "rounded-2xl border border-rose-400/20 bg-rose-400/10 px-4 py-3 text-sm font-semibold text-rose-100 transition hover:bg-rose-400/15" }, "Restrict public access")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-4 text-sm leading-relaxed text-slate-300" }, "Current state: ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, (collectionState?.moderation_status || "active").replace("_", " ")))))) : null))); } -const __vite_glob_0_44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionManage }, Symbol.toStringTag, { value: "Module" })); @@ -77521,7 +77855,7 @@ function CollectionSeriesShow() { const stats = props.stats || {}; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SeoHead, { seo, title: seo.title || `${title} — Skinbase`, description: seo.description || description }), /* @__PURE__ */ React.createElement("div", { className: "relative min-h-screen overflow-hidden pb-16" }, /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-0 -z-10 h-[36rem] opacity-95", style: { background: "radial-gradient(circle at 10% 15%, rgba(59,130,246,0.18), transparent 28%), radial-gradient(circle at 84% 18%, rgba(34,197,94,0.16), transparent 24%), linear-gradient(180deg, #07101d 0%, #0a1220 42%, #08111f 100%)" } }), /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10 opacity-[0.05]", style: { backgroundImage: "url(/gfx/noise.png)", backgroundSize: "180px" } }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pt-8 md:px-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("a", { href: "/collections/featured", className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left fa-fw text-[11px]" }), "Back to collections"), leadCollection?.url ? /* @__PURE__ */ React.createElement("a", { href: leadCollection.url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, "Lead collection") : null), /* @__PURE__ */ React.createElement("section", { className: "mt-6 overflow-hidden rounded-[34px] border border-white/10 bg-white/[0.04] p-6 shadow-[0_30px_90px_rgba(2,6,23,0.28)] backdrop-blur-sm md:p-8" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-8 xl:grid-cols-[minmax(0,1.15fr)_400px] xl:items-end" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Series"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-4xl font-semibold tracking-[-0.05em] text-white md:text-5xl" }, title), /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-relaxed text-slate-300 md:text-[15px]" }, description), props.seriesKey ? /* @__PURE__ */ React.createElement("div", { className: "mt-5 inline-flex rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.18em] text-slate-300" }, props.seriesKey) : null), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 sm:grid-cols-3 xl:grid-cols-1" }, /* @__PURE__ */ React.createElement(StatCard$6, { icon: "fa-layer-group", label: "Collections", value: Number(stats.collections || collections.length).toLocaleString() }), /* @__PURE__ */ React.createElement(StatCard$6, { icon: "fa-user-group", label: "Creators", value: Number(stats.owners || 0).toLocaleString() }), /* @__PURE__ */ React.createElement(StatCard$6, { icon: "fa-images", label: "Artworks", value: Number(stats.artworks || 0).toLocaleString() })))), leadCollection ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Lead Entry"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Start with the opening collection")), stats.latest_activity_at ? /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, "Latest activity ", new Date(stats.latest_activity_at).toLocaleDateString()) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-5 max-w-xl" }, /* @__PURE__ */ React.createElement(CollectionCard, { collection: leadCollection, isOwner: false }))) : null, /* @__PURE__ */ React.createElement("section", { className: "mt-8 pb-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Sequence"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Public collections in order"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3" }, collections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false }))))))); } -const __vite_glob_0_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionSeriesShow }, Symbol.toStringTag, { value: "Module" })); @@ -79231,7 +79565,7 @@ function CollectionShow() { const renderedSidebarModules = enabledModules.filter((module) => module.slot === "sidebar").map(renderModule).filter(Boolean); return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SeoHead, { seo, title: metaTitle, description: metaDescription, jsonLd: collectionSchema }), /* @__PURE__ */ React.createElement("div", { className: "relative min-h-screen overflow-hidden pb-16" }, /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-0 -z-10 h-[36rem] opacity-95", style: { background: "radial-gradient(circle at top left, rgba(56,189,248,0.18), transparent 32%), radial-gradient(circle at 82% 10%, rgba(249,115,22,0.18), transparent 26%), linear-gradient(180deg, #07101d 0%, #0a1220 42%, #08111f 100%)" } }), /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10 opacity-[0.05]", style: { backgroundImage: "url(/gfx/noise.png)", backgroundSize: "180px" } }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pt-8 md:px-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("a", { href: profileCollectionsUrl, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left fa-fw text-[11px]" }), "Back to collections"), isOwner && manageUrl ? /* @__PURE__ */ React.createElement("a", { href: manageUrl, className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 font-semibold text-sky-100 transition hover:bg-sky-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-grip fa-fw text-[11px]" }), "Manage artworks") : null, isOwner && editUrl ? /* @__PURE__ */ React.createElement("a", { href: editUrl, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen-to-square fa-fw text-[11px]" }), "Edit details") : null, isOwner && analyticsUrl ? /* @__PURE__ */ React.createElement("a", { href: analyticsUrl, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-chart-column fa-fw text-[11px]" }), "Analytics") : null, isOwner && historyUrl ? /* @__PURE__ */ React.createElement("a", { href: historyUrl, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 transition hover:bg-white/[0.07] hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-timeline fa-fw text-[11px]" }), "History") : null), /* @__PURE__ */ React.createElement("section", { className: "mt-6 overflow-hidden rounded-[34px] border border-white/10 bg-[linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02))] shadow-[0_30px_90px_rgba(2,6,23,0.32)] backdrop-blur-xl" }, /* @__PURE__ */ React.createElement("div", { className: `h-[3px] bg-gradient-to-r ${collection?.type === "editorial" ? "from-amber-400/80 via-amber-400/30 to-transparent" : collection?.type === "community" ? "from-emerald-400/80 via-emerald-400/30 to-transparent" : collection?.mode === "smart" ? "from-sky-400/80 via-sky-400/30 to-transparent" : "from-violet-400/80 via-violet-400/30 to-transparent"}` }), /* @__PURE__ */ React.createElement("div", { className: "grid items-start gap-6 p-5 md:p-7 xl:grid-cols-[minmax(0,1.2fr)_420px]" }, /* @__PURE__ */ React.createElement("div", { className: "relative self-start overflow-hidden rounded-[28px] border border-white/10 bg-slate-950/60" }, /* @__PURE__ */ React.createElement(CollectionCover, { collection }), /* @__PURE__ */ React.createElement("div", { className: "pointer-events-none absolute inset-0 bg-[linear-gradient(to_top,rgba(2,6,23,0.8),rgba(2,6,23,0.08))]" })), /* @__PURE__ */ React.createElement("div", { className: "relative overflow-hidden rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.12),transparent_28%),radial-gradient(circle_at_90%_8%,rgba(251,191,36,0.14),transparent_24%),linear-gradient(180deg,rgba(15,23,42,0.94),rgba(10,18,32,0.92))] px-5 py-6 shadow-[inset_0_1px_0_rgba(255,255,255,0.04)] md:px-6 md:py-7" }, /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute -left-14 top-10 h-36 w-36 rounded-full bg-sky-400/10 blur-3xl" }), /* @__PURE__ */ React.createElement("div", { "aria-hidden": "true", className: "pointer-events-none absolute -right-10 bottom-8 h-32 w-32 rounded-full bg-amber-300/10 blur-3xl" }), /* @__PURE__ */ React.createElement("div", { className: "relative z-10 flex h-full flex-col justify-between" }, collection?.banner_text ? /* @__PURE__ */ React.createElement("div", { className: `mb-4 inline-flex max-w-full items-center gap-2 rounded-[22px] border px-4 py-3 text-sm font-medium shadow-[0_18px_40px_rgba(2,6,23,0.2)] ${spotlightClasses}` }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-sparkles text-[12px]" }), /* @__PURE__ */ React.createElement("span", { className: "truncate" }, collection.banner_text)) : null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, collection?.is_featured ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-amber-300/25 bg-amber-300/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100" }, "Featured Collection") : null, collection?.mode === "smart" ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100" }, "Smart Collection") : null, /* @__PURE__ */ React.createElement(TypeBadge, { collection }), collection?.event_label ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-white" }, collection.event_label) : null, collection?.campaign_label ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-amber-300/20 bg-amber-300/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100" }, collection.campaign_label) : null, collection?.badge_label ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-white" }, collection.badge_label) : null, collection?.series_key ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-white" }, "Series ", collection.series_order ? `#${collection.series_order}` : "") : null, isOwner ? /* @__PURE__ */ React.createElement(CollectionVisibilityBadge, { visibility: collection?.visibility }) : null), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 max-w-3xl text-4xl font-black tracking-[-0.06em] text-white md:text-5xl xl:text-[4rem] xl:leading-[0.92]" }, collection?.title), showIntroBlock ? /* @__PURE__ */ React.createElement(React.Fragment, null, collection?.subtitle ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-lg text-slate-300 md:text-xl" }, collection.subtitle) : null, collection?.summary || collection?.description ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-2xl text-sm leading-relaxed text-slate-300 md:text-[15px]" }, collection?.summary || collection?.description) : /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-2xl text-sm leading-relaxed text-slate-400 md:text-[15px]" }, "A curated selection from @", owner?.username, ", assembled as a focused gallery rather than a simple archive."), collection?.smart_summary ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 max-w-2xl rounded-[22px] border border-sky-300/15 bg-sky-400/[0.07] px-4 py-3 text-sm leading-relaxed text-sky-100/90" }, collection.smart_summary) : null, featuringCreatorsCount > 1 ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm text-slate-300" }, "Featuring artworks by ", featuringCreatorsCount, " creators.") : null) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-7 space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement(CollectionHeroAction, { onClick: handleLike, disabled: state.busy || !engagement?.like_url, icon: "fa-heart", label: state.liked ? "Liked" : "Like", tone: "rose", active: state.liked }), /* @__PURE__ */ React.createElement(CollectionHeroAction, { onClick: handleFollow, disabled: state.busy || !engagement?.follow_url, icon: "fa-bell", label: state.following ? "Following" : "Follow", tone: "emerald", active: state.following }), /* @__PURE__ */ React.createElement(CollectionHeroAction, { onClick: handleSave, disabled: state.busy || !engagement?.save_url && !engagement?.unsave_url, icon: "fa-bookmark", label: state.saved ? "Saved" : "Save", tone: "violet", active: state.saved })), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement(CollectionHeroAction, { onClick: handleShare, icon: "fa-share-nodes", label: "Share", tone: "neutral", compact: true }), featuredCollectionsUrl ? /* @__PURE__ */ React.createElement(CollectionHeroAction, { href: featuredCollectionsUrl, icon: "fa-compass", label: "Explore", tone: "sky", compact: true }) : null, reportEndpoint && !isOwner ? /* @__PURE__ */ React.createElement(CollectionHeroAction, { onClick: () => handleReport("collection", collection?.id), icon: "fa-flag", label: "Report", tone: "amber", compact: true }) : null)), state.notice ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm text-sky-100" }, state.notice) : null, /* @__PURE__ */ React.createElement(OwnerCard, { owner, collectionType: collection?.type }))))), heroMetrics.length || heroSignals.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-6 rounded-[30px] border border-white/10 bg-[linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02))] p-5 shadow-[0_20px_70px_rgba(2,6,23,0.22)] backdrop-blur-xl md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Collection Snapshot"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Stats and placement signals")), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm leading-relaxed text-slate-400" }, "The engagement counters and ranking signals now live outside the hero so the header can stay focused on the artwork, title, and actions.")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 xl:grid-cols-[minmax(0,1.6fr)_minmax(320px,0.95fr)]" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-5" }, heroMetrics.map((item) => /* @__PURE__ */ React.createElement(HeroMetricCard, { key: item.label, icon: item.icon, label: item.label, value: item.value, helper: item.helper, tone: item.tone }))), heroSignals.length ? /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-1" }, heroSignals.map((item) => /* @__PURE__ */ React.createElement(HeroSignalCard, { key: item.label, icon: item.icon, label: item.label, value: item.value, description: item.description, tone: item.tone }))) : null)) : null, seriesContext?.url || seriesContext?.previous || seriesContext?.next || Array.isArray(seriesContext?.siblings) && seriesContext.siblings.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[30px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Series"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, seriesContext?.title || "Connected collection sequence"), seriesContext?.description ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 max-w-3xl text-sm leading-relaxed text-slate-300" }, seriesContext.description) : null), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3" }, collection?.series_key ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, collection.series_key) : null, seriesContext?.url ? /* @__PURE__ */ React.createElement("a", { href: seriesContext.url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-list fa-fw text-[10px]" }), "View full series") : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, seriesContext?.previous ? /* @__PURE__ */ React.createElement("a", { href: seriesContext.previous.url, className: "flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.04] px-5 py-4 transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Previous"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, seriesContext.previous.title)), /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left text-slate-500" })) : null, seriesContext?.next ? /* @__PURE__ */ React.createElement("a", { href: seriesContext.next.url, className: "flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.04] px-5 py-4 transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Next"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, seriesContext.next.title)), /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right text-slate-500" })) : null), Array.isArray(seriesContext?.siblings) && seriesContext.siblings.length ? /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, seriesContext.siblings.slice(0, 2).map((item) => /* @__PURE__ */ React.createElement(CollectionCard, { key: item.id, collection: item, isOwner: false }))) : null)) : null, contextSignals.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[30px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl border border-amber-300/15 bg-amber-400/10 text-amber-300" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-diagram-project text-sm" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200/80" }, "Related Context"), /* @__PURE__ */ React.createElement("h2", { className: "mt-1 text-2xl font-semibold text-white" }, "Campaign, event, and quality context"))), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, contextSignals.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, contextSignals.map((item) => /* @__PURE__ */ React.createElement(ContextSignalCard, { key: `${item.meta}-${item.title}`, item })))) : null, storyLinks.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[30px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl border border-lime-300/15 bg-lime-400/10 text-lime-300" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-book-open text-sm" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-lime-200/80" }, "Stories"), /* @__PURE__ */ React.createElement("h2", { className: "mt-1 text-2xl font-semibold text-white" }, "Stories and editorial references linked to this collection"))), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, storyLinks.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, storyLinks.map((item) => /* @__PURE__ */ React.createElement(EntityLinkCard, { key: `${item.linked_type}-${item.linked_id}-${item.id}`, item })))) : null, taxonomyLinks.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[30px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl border border-violet-300/15 bg-violet-400/10 text-violet-300" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-tags text-sm" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-violet-200/80" }, "Browse The Theme"), /* @__PURE__ */ React.createElement("h2", { className: "mt-1 text-2xl font-semibold text-white" }, "Categories and tags that anchor this collection"))), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, taxonomyLinks.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, taxonomyLinks.map((item) => /* @__PURE__ */ React.createElement(EntityLinkCard, { key: `${item.linked_type}-${item.linked_id}-${item.id}`, item })))) : null, contributorLinks.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[30px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl border border-sky-300/15 bg-sky-400/10 text-sky-300" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user-group text-sm" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Connected Creators"), /* @__PURE__ */ React.createElement("h2", { className: "mt-1 text-2xl font-semibold text-white" }, "Creators and artworks that give the set its shape"))), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, contributorLinks.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, contributorLinks.map((item) => /* @__PURE__ */ React.createElement(EntityLinkCard, { key: `${item.linked_type}-${item.linked_id}-${item.id}`, item })))) : null, renderedFullModules.length ? /* @__PURE__ */ React.createElement("div", { className: "mt-8 space-y-6" }, renderedFullModules) : null, renderedMainModules.length || renderedSidebarModules.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, renderedMainModules), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, renderedSidebarModules)) : null))); } -const __vite_glob_0_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionShow }, Symbol.toStringTag, { value: "Module" })); @@ -79627,7 +79961,7 @@ function CollectionStaffProgramming() { return /* @__PURE__ */ React.createElement("div", { key: `merge-pending-${item.id}`, className: `rounded-[24px] border border-white/10 bg-white/[0.04] p-4 transition ${cardBusy ? "ring-1 ring-sky-300/25" : ""}` }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, (item.comparison?.match_reasons || []).map((reason) => /* @__PURE__ */ React.createElement("span", { key: reason, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.14em] text-slate-300" }, titleize(reason)))), cardBusy ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.14em] text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-circle-notch fa-spin fa-fw text-[10px]" }), "Processing ", titleize(activeQueueAction)) : null), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Source"), item.source ? /* @__PURE__ */ React.createElement(CollectionCard, { collection: item.source, isOwner: true }) : null), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Candidate"), item.target ? /* @__PURE__ */ React.createElement(CollectionCard, { collection: item.target, isOwner: true }) : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-2 md:grid-cols-3 text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Shared artworks: ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, item.comparison?.shared_artworks_count ?? 0)), /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Source count: ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, item.comparison?.source_artworks_count ?? 0)), /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2" }, "Target count: ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, item.comparison?.target_artworks_count ?? 0))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, item.source?.manage_url ? /* @__PURE__ */ React.createElement("a", { href: item.source.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-xs font-semibold text-rose-100 transition hover:bg-rose-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-code-compare fa-fw text-[10px]" }), "Review source") : null, item.target?.manage_url ? /* @__PURE__ */ React.createElement("a", { href: item.target.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square fa-fw text-[10px]" }), "Open target") : null, item.source?.id && historyPattern ? /* @__PURE__ */ React.createElement("a", { href: historyPattern.replace("__COLLECTION__", String(item.source.id)), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-timeline fa-fw text-[10px]" }), "History") : null, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleQueueAction("canonicalize", item), disabled: cardBusy, className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 text-xs font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${activeQueueAction === "canonicalize" ? "fa-circle-notch fa-spin" : "fa-badge-check"} fa-fw text-[10px]` }), activeQueueAction === "canonicalize" ? "Canonicalizing..." : "Canonicalize"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleQueueAction("merge", item), disabled: cardBusy, className: "inline-flex items-center gap-2 rounded-full border border-emerald-300/20 bg-emerald-400/10 px-4 py-2 text-xs font-semibold text-emerald-100 transition hover:bg-emerald-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${activeQueueAction === "merge" ? "fa-circle-notch fa-spin" : "fa-code-merge"} fa-fw text-[10px]` }), activeQueueAction === "merge" ? "Merging..." : "Merge now"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleQueueAction("reject", item), disabled: cardBusy, className: "inline-flex items-center gap-2 rounded-full border border-amber-300/20 bg-amber-400/10 px-4 py-2 text-xs font-semibold text-amber-100 transition hover:bg-amber-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${activeQueueAction === "reject" ? "fa-circle-notch fa-spin" : "fa-ban"} fa-fw text-[10px]` }), activeQueueAction === "reject" ? "Rejecting..." : "Reject"))); }) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/12 bg-white/[0.03] px-5 py-10 text-sm text-slate-300" }, "No pending merge candidates right now."))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Recent Decisions"), /* @__PURE__ */ React.createElement("h3", { className: "mt-2 text-xl font-semibold text-white" }, "Canonical, reject, and merge history")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, mergeQueue?.recent?.length || 0)), /* @__PURE__ */ React.createElement("div", { className: "mt-5 space-y-4" }, (mergeQueue?.recent || []).length ? mergeQueue.recent.map((item) => /* @__PURE__ */ React.createElement("div", { key: `merge-recent-${item.id}`, className: "rounded-[24px] border border-white/10 bg-white/[0.04] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "inline-flex rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, titleize(item.action_type)), item.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-300" }, item.summary) : null, /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-xs text-slate-500" }, item.updated_at ? new Date(item.updated_at).toLocaleString() : "Unknown time", item.actor?.username ? ` • @${item.actor.username}` : ""))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 lg:grid-cols-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Source"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, item.source?.title || "Collection")), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Target"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, item.target?.title || "Collection"))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, item.source?.manage_url ? /* @__PURE__ */ React.createElement("a", { href: item.source.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen-to-square fa-fw text-[10px]" }), "Open source") : null, item.target?.manage_url ? /* @__PURE__ */ React.createElement("a", { href: item.target.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square fa-fw text-[10px]" }), "Open target") : null))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/12 bg-white/[0.03] px-5 py-10 text-sm text-slate-300" }, "No recent merge decisions yet."))))), /* @__PURE__ */ React.createElement("section", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]" }, /* @__PURE__ */ React.createElement("form", { onSubmit: handleAssignmentSubmit, className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Assignment"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Program key and scope")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(Field$2, { label: "Collection" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: String(assignmentForm.collection_id || ""), onChange: (val) => setAssignmentForm((current) => ({ ...current, collection_id: val })), options: collectionOptions.map((o) => ({ value: String(o.id), label: o.title })) })), /* @__PURE__ */ React.createElement(Field$2, { label: "Program Key", help: "Use stable internal names like discover-spring or homepage-hero." }, /* @__PURE__ */ React.createElement("input", { list: "program-key-options", value: assignmentForm.program_key, onChange: (event) => setAssignmentForm((current) => ({ ...current, program_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Placement Scope", help: "Optional placement scope such as homepage.hero or discover.rail." }, /* @__PURE__ */ React.createElement("input", { value: assignmentForm.placement_scope, onChange: (event) => setAssignmentForm((current) => ({ ...current, placement_scope: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Campaign Key" }, /* @__PURE__ */ React.createElement("input", { value: assignmentForm.campaign_key, onChange: (event) => setAssignmentForm((current) => ({ ...current, campaign_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Priority" }, /* @__PURE__ */ React.createElement("input", { type: "number", min: "-100", max: "100", value: assignmentForm.priority, onChange: (event) => setAssignmentForm((current) => ({ ...current, priority: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field$2, { label: "Starts At" }, /* @__PURE__ */ React.createElement(DateTimePicker, { value: assignmentForm.starts_at, onChange: (nextValue) => setAssignmentForm((current) => ({ ...current, starts_at: nextValue })), placeholder: "Start time", clearable: true, className: "bg-white/[0.04]" })), /* @__PURE__ */ React.createElement(Field$2, { label: "Ends At" }, /* @__PURE__ */ React.createElement(DateTimePicker, { value: assignmentForm.ends_at, onChange: (nextValue) => setAssignmentForm((current) => ({ ...current, ends_at: nextValue })), placeholder: "End time", clearable: true, className: "bg-white/[0.04]" }))), /* @__PURE__ */ React.createElement(Field$2, { label: "Notes", help: "Operational note for launch timing, overrides, or review context." }, /* @__PURE__ */ React.createElement("textarea", { value: assignmentForm.notes, onChange: (event) => setAssignmentForm((current) => ({ ...current, notes: event.target.value })), className: "mt-4 min-h-[120px] w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 1e3 })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: busy === "assignment", className: "inline-flex items-center gap-2 rounded-2xl border border-sky-300/20 bg-sky-400/10 px-5 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "assignment" ? "fa-circle-notch fa-spin" : "fa-sliders"} fa-fw` }), assignmentForm.id ? "Update Assignment" : "Save Assignment"), assignmentForm.id ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: resetAssignmentForm, className: "inline-flex items-center gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-rotate-left fa-fw" }), "Cancel Edit") : null), /* @__PURE__ */ React.createElement("datalist", { id: "program-key-options" }, programKeyOptions.map((option) => /* @__PURE__ */ React.createElement("option", { key: option, value: option })))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("form", { onSubmit: handlePreview, className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200/80" }, "Preview"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Inspect a live program pool")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-[minmax(0,1fr)_140px_auto]" }, /* @__PURE__ */ React.createElement(Field$2, { label: "Program Key" }, /* @__PURE__ */ React.createElement("input", { list: "program-key-options", value: previewForm.program_key, onChange: (event) => setPreviewForm((current) => ({ ...current, program_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Limit" }, /* @__PURE__ */ React.createElement("input", { type: "number", min: "1", max: "24", value: previewForm.limit, onChange: (event) => setPreviewForm((current) => ({ ...current, limit: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "flex items-end" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: busy === "preview", className: "inline-flex h-[50px] w-full items-center justify-center gap-2 rounded-2xl border border-amber-300/20 bg-amber-400/10 px-5 text-sm font-semibold text-amber-100 transition hover:bg-amber-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "preview" ? "fa-circle-notch fa-spin" : "fa-binoculars"} fa-fw` }), "Preview"))), previewCollections.length ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 xl:grid-cols-2" }, previewCollections.map((collection) => /* @__PURE__ */ React.createElement("div", { key: collection.id, className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4" }, /* @__PURE__ */ React.createElement(CollectionCard, { collection, isOwner: true })))) : /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-dashed border-white/12 bg-white/[0.03] px-5 py-8 text-sm text-slate-300" }, "Run a preview to inspect which collections currently qualify for a given program key.")), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-lime-200/80" }, "Diagnostics"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Eligibility, duplicate risk, and ranking refresh")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 xl:grid-cols-[320px_minmax(0,1fr)]" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Operations summary"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-1" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] uppercase tracking-[0.16em] text-slate-400" }, "Stale health"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-semibold text-white" }, Number(observabilitySummary?.counts?.stale_health || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] uppercase tracking-[0.16em] text-slate-400" }, "Stale recommendations"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-semibold text-white" }, Number(observabilitySummary?.counts?.stale_recommendations || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] uppercase tracking-[0.16em] text-slate-400" }, "Placement blocked"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-semibold text-white" }, Number(observabilitySummary?.counts?.placement_blocked || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] uppercase tracking-[0.16em] text-slate-400" }, "Duplicate risk"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-semibold text-white" }, Number(observabilitySummary?.counts?.duplicate_risk || 0)))), observabilitySummary?.generated_at ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-xs text-slate-400" }, "Generated ", new Date(observabilitySummary.generated_at).toLocaleString()) : null), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Watchlist"), Array.isArray(observabilitySummary?.watchlist) && observabilitySummary.watchlist.length ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 xl:grid-cols-2" }, observabilitySummary.watchlist.map((collection) => /* @__PURE__ */ React.createElement("div", { key: `watch-${collection.id}`, className: "rounded-[20px] border border-white/10 bg-white/[0.04] p-3" }, /* @__PURE__ */ React.createElement(CollectionCard, { collection, isOwner: true })))) : /* @__PURE__ */ React.createElement("p", { className: "mt-3" }, "No watchlist items are currently flagged."))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]" }, /* @__PURE__ */ React.createElement(Field$2, { label: "Target Collection", help: "Leave a selection in place to inspect one collection. Change it any time before running a diagnostic." }, /* @__PURE__ */ React.createElement(NovaSelect, { value: String(selectedCollectionId || ""), onChange: (val) => setSelectedCollectionId(val), options: collectionOptions.map((o) => ({ value: String(o.id), label: o.title })) })), /* @__PURE__ */ React.createElement("div", { className: "flex items-end gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => runDiagnostic("eligibility"), disabled: busy !== "", className: "inline-flex items-center gap-2 rounded-2xl border border-lime-300/20 bg-lime-400/10 px-4 py-3 text-sm font-semibold text-lime-100 transition hover:bg-lime-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "eligibility" ? "fa-circle-notch fa-spin" : "fa-shield-check"} fa-fw` }), "Eligibility"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => runDiagnostic("duplicates"), disabled: busy !== "", className: "inline-flex items-center gap-2 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm font-semibold text-rose-100 transition hover:bg-rose-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "duplicates" ? "fa-circle-notch fa-spin" : "fa-id-card"} fa-fw` }), "Duplicates"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => runDiagnostic("recommendations"), disabled: busy !== "", className: "inline-flex items-center gap-2 rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "recommendations" ? "fa-circle-notch fa-spin" : "fa-arrows-rotate"} fa-fw` }), "Refresh"))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Eligibility"), diagnostics.eligibility ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, /* @__PURE__ */ React.createElement("p", null, diagnostics.eligibility.status === "queued" ? `${diagnostics.eligibility.count} collection(s) queued.` : `${diagnostics.eligibility.count} collection(s) evaluated.`), diagnostics.eligibility.message ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, diagnostics.eligibility.message) : null, (diagnostics.eligibility.items || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.collection_id, className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, item.health_state || "unknown", " · ", item.readiness_state || "unknown", " · ", item.placement_eligibility ? "eligible" : "blocked"))) : /* @__PURE__ */ React.createElement("p", { className: "mt-3" }, "Run an eligibility refresh to verify readiness and public placement safety.")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Duplicate candidates"), diagnostics.duplicates ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, /* @__PURE__ */ React.createElement("p", null, diagnostics.duplicates.status === "queued" ? `${diagnostics.duplicates.count} collection(s) queued.` : `${diagnostics.duplicates.count} collection(s) with candidates.`), diagnostics.duplicates.message ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, diagnostics.duplicates.message) : null, (diagnostics.duplicates.items || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.collection_id, className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, item.candidates?.length ? item.candidates.map((candidate) => candidate.title).join(", ") : "No candidates"))) : /* @__PURE__ */ React.createElement("p", { className: "mt-3" }, "Run duplicate scan to surface overlap before programming a collection widely.")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Recommendation refresh"), diagnostics.recommendations ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, /* @__PURE__ */ React.createElement("p", null, diagnostics.recommendations.status === "queued" ? `${diagnostics.recommendations.count} collection(s) queued.` : `${diagnostics.recommendations.count} collection(s) refreshed.`), diagnostics.recommendations.message ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, diagnostics.recommendations.message) : null, (diagnostics.recommendations.items || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.collection_id, className: "rounded-2xl border border-white/10 bg-white/[0.04] px-3 py-2" }, titleize(item.recommendation_tier || "unknown"), " · ", titleize(item.ranking_bucket || "unknown"), " · ", titleize(item.search_boost_tier || "unknown")))) : /* @__PURE__ */ React.createElement("p", { className: "mt-3" }, "Run a recommendation refresh to update ranking and search tiers for this collection.")))), /* @__PURE__ */ React.createElement("form", { onSubmit: handleHooksSubmit, className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-fuchsia-200/80" }, "Hooks"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Experiment and program governance"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-relaxed text-slate-300" }, "Control experiment keys, promotion tiers, and staff-only program governance hooks for the selected collection without leaving the programming studio.")), selectedCollection?.program_key && endpoints.publicProgramPattern ? /* @__PURE__ */ React.createElement("a", { href: buildProgramUrl(endpoints.publicProgramPattern, selectedCollection.program_key), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square fa-fw text-[11px]" }), "Open public program landing") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(Field$2, { label: "Experiment Key", help: "Internal test or treatment key for cross-surface collection experiments." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.experiment_key, onChange: (event) => setHooksForm((current) => ({ ...current, experiment_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Treatment", help: "Variant or treatment label tied to the experiment key." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.experiment_treatment, onChange: (event) => setHooksForm((current) => ({ ...current, experiment_treatment: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Placement Variant", help: "Surface-specific placement variant such as homepage_a or search_dense." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.placement_variant, onChange: (event) => setHooksForm((current) => ({ ...current, placement_variant: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Ranking Variant", help: "Override or annotate ranking mode experiments without changing the live pool logic." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.ranking_mode_variant, onChange: (event) => setHooksForm((current) => ({ ...current, ranking_mode_variant: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Pool Version", help: "Snapshot or rollout version for the collection pool definition." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.collection_pool_version, onChange: (event) => setHooksForm((current) => ({ ...current, collection_pool_version: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Test Label", help: "Human-readable campaign or experiment label for operations and diagnostics." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.test_label, onChange: (event) => setHooksForm((current) => ({ ...current, test_label: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 120 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Promotion Tier", help: "Optional internal tier for elevated or restrained programming treatment." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.promotion_tier, onChange: (event) => setHooksForm((current) => ({ ...current, promotion_tier: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 40 })), viewer.isAdmin ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Field$2, { label: "Partner Key", help: "Admin-only internal key for trusted partner or program ownership." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.partner_key, onChange: (event) => setHooksForm((current) => ({ ...current, partner_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Trust Tier", help: "Admin-only trust marker used for internal partner/program review logic." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.trust_tier, onChange: (event) => setHooksForm((current) => ({ ...current, trust_tier: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 40 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Sponsorship State", help: "Admin-only state for sponsored, pending, or cleared program treatment." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.sponsorship_state, onChange: (event) => setHooksForm((current) => ({ ...current, sponsorship_state: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 40 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Ownership Domain", help: "Admin-only internal ownership domain such as editorial, partner, creator_program, or events." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.ownership_domain, onChange: (event) => setHooksForm((current) => ({ ...current, ownership_domain: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Commercial Review", help: "Admin-only commercial review status for future partner and sponsor programs." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.commercial_review_state, onChange: (event) => setHooksForm((current) => ({ ...current, commercial_review_state: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 40 })), /* @__PURE__ */ React.createElement(Field$2, { label: "Legal Review", help: "Admin-only legal review status when collections need compliance approval before wider promotion." }, /* @__PURE__ */ React.createElement("input", { value: hooksForm.legal_review_state, onChange: (event) => setHooksForm((current) => ({ ...current, legal_review_state: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 40 }))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/12 bg-white/[0.03] px-4 py-4 text-sm text-slate-300 md:col-span-2 xl:col-span-3" }, "Partner, sponsorship, ownership, and review metadata remain admin-only. Moderators can still manage experiment and promotion hooks here.")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex items-center gap-3 rounded-[20px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: hooksForm.placement_eligibility, onChange: (event) => setHooksForm((current) => ({ ...current, placement_eligibility: event.target.checked })), label: "Placement eligible override" })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 sm:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Experiment"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.experiment_key || selectedCollection?.experiment_key || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Treatment"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.experiment_treatment || selectedCollection?.experiment_treatment || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Placement Variant"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.placement_variant || selectedCollection?.placement_variant || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Workflow"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, titleize(hooksDiagnostics?.workflow_state || selectedCollection?.workflow_state || "unknown"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Health"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, titleize(hooksDiagnostics?.health_state || selectedCollection?.health_state || "unknown"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Recommendation Tier"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, titleize(hooksDiagnostics?.recommendation_tier || selectedCollection?.recommendation_tier || "unknown"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Ranking Bucket"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, titleize(hooksDiagnostics?.ranking_bucket || selectedCollection?.ranking_bucket || "unknown"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Ranking Variant"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.ranking_mode_variant || selectedCollection?.ranking_mode_variant || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Pool Version"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.collection_pool_version || selectedCollection?.collection_pool_version || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Test Label"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.test_label || selectedCollection?.test_label || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Promotion Tier"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.promotion_tier || selectedCollection?.promotion_tier || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Partner Key"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.partner_key || selectedCollection?.partner_key || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Trust Tier"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.trust_tier || selectedCollection?.trust_tier || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Sponsorship State"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.sponsorship_state || selectedCollection?.sponsorship_state || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Ownership Domain"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.ownership_domain || selectedCollection?.ownership_domain || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Commercial Review"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.commercial_review_state || selectedCollection?.commercial_review_state || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Legal Review"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.legal_review_state || selectedCollection?.legal_review_state || "Not set")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Last Health Check"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.last_health_check_at ? new Date(hooksDiagnostics.last_health_check_at).toLocaleString() : "Not yet")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-slate-950/40 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, "Last Recommendation Refresh"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, hooksDiagnostics?.last_recommendation_refresh_at ? new Date(hooksDiagnostics.last_recommendation_refresh_at).toLocaleString() : "Not yet"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: busy === "hooks" || !selectedCollectionId, className: "inline-flex items-center gap-2 rounded-2xl border border-fuchsia-300/20 bg-fuchsia-400/10 px-5 py-3 text-sm font-semibold text-fuchsia-100 transition hover:bg-fuchsia-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "hooks" ? "fa-circle-notch fa-spin" : "fa-flask-vial"} fa-fw` }), "Save Hooks"), selectedCollection?.manage_url ? /* @__PURE__ */ React.createElement("a", { href: selectedCollection.manage_url, className: "inline-flex items-center gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square fa-fw" }), "Open collection") : null)))), /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Assignments"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Current programming inventory")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, assignments.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-5" }, assignments.length ? assignments.map((assignment) => /* @__PURE__ */ React.createElement("div", { key: assignment.id, className: "rounded-[28px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100" }, assignment.program_key), assignment.placement_scope ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, assignment.placement_scope) : null, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, "priority ", assignment.priority)), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => hydrateAssignment(assignment), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen fa-fw text-[10px]" }), "Edit"), endpoints.managePattern ? /* @__PURE__ */ React.createElement("a", { href: endpoints.managePattern.replace("__COLLECTION__", String(assignment.collection?.id || "")), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square fa-fw text-[10px]" }), "Manage") : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-5 xl:grid-cols-[minmax(0,1fr)_280px]" }, /* @__PURE__ */ React.createElement("div", null, assignment.collection ? /* @__PURE__ */ React.createElement(CollectionCard, { collection: assignment.collection, isOwner: true }) : null), /* @__PURE__ */ React.createElement("div", { className: "space-y-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Campaign: ", assignment.campaign_key || "None"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Starts: ", assignment.starts_at ? new Date(assignment.starts_at).toLocaleString() : "Immediate"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Ends: ", assignment.ends_at ? new Date(assignment.ends_at).toLocaleString() : "Open-ended"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Placement: ", assignment.collection?.placement_eligibility ? "Eligible" : "Blocked"), assignment.notes ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, assignment.notes) : null)))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[26px] border border-dashed border-white/12 bg-white/[0.03] px-6 py-12 text-sm text-slate-300" }, "No programming assignments yet. Create the first one above.")))))); } -const __vite_glob_0_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionStaffProgramming }, Symbol.toStringTag, { value: "Module" })); @@ -79953,7 +80287,7 @@ function CollectionStaffSurfaces() { return /* @__PURE__ */ React.createElement("label", { key: option.id, className: `flex cursor-pointer items-start gap-3 rounded-[22px] border px-4 py-3 transition ${checked ? "border-lime-300/30 bg-lime-400/10" : "border-white/10 bg-white/[0.04] hover:bg-white/[0.07]"}` }, /* @__PURE__ */ React.createElement(Checkbox, { checked, onChange: () => toggleBatchCollection(option.id) }), /* @__PURE__ */ React.createElement("span", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("span", { className: "block truncate text-sm font-semibold text-white" }, option.title), /* @__PURE__ */ React.createElement("span", { className: "mt-1 block text-xs text-slate-400" }, option.type || "collection", " · ", option.visibility || "public"))); }))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[26px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-semibold text-white" }, "Campaign metadata"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(Field$1, { label: "Campaign Key" }, /* @__PURE__ */ React.createElement("input", { value: batchForm.campaign_key, onChange: (event) => setBatchForm((current) => ({ ...current, campaign_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 })), /* @__PURE__ */ React.createElement(Field$1, { label: "Campaign Label" }, /* @__PURE__ */ React.createElement("input", { value: batchForm.campaign_label, onChange: (event) => setBatchForm((current) => ({ ...current, campaign_label: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 120 })), /* @__PURE__ */ React.createElement(Field$1, { label: "Event Label" }, /* @__PURE__ */ React.createElement("input", { value: batchForm.event_label, onChange: (event) => setBatchForm((current) => ({ ...current, event_label: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 120 })), /* @__PURE__ */ React.createElement(Field$1, { label: "Season Key" }, /* @__PURE__ */ React.createElement("input", { value: batchForm.season_key, onChange: (event) => setBatchForm((current) => ({ ...current, season_key: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 80 }))), /* @__PURE__ */ React.createElement(Field$1, { label: "Editorial Notes", help: "Shared context recorded on each selected collection." }, /* @__PURE__ */ React.createElement("textarea", { value: batchForm.editorial_notes, onChange: (event) => setBatchForm((current) => ({ ...current, editorial_notes: event.target.value })), className: "mt-4 min-h-[120px] w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 4e3 })))), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[26px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-semibold text-white" }, "Optional placement plan"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-300" }, "If you set a surface, the preview shows which collections can safely be placed and which ones will be skipped."), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(Field$1, { label: "Surface" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: batchForm.surface_key, onChange: (val) => setBatchForm((current) => ({ ...current, surface_key: val })), placeholder: "No placement", options: surfaceKeyOptions.map((o) => ({ value: o, label: o })) })), /* @__PURE__ */ React.createElement(Field$1, { label: "Placement Type" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: batchForm.placement_type, onChange: (val) => setBatchForm((current) => ({ ...current, placement_type: val })), searchable: false, options: [{ value: "campaign", label: "Campaign" }, { value: "manual", label: "Manual" }, { value: "scheduled_override", label: "Scheduled override" }] })), /* @__PURE__ */ React.createElement(Field$1, { label: "Priority" }, /* @__PURE__ */ React.createElement("input", { type: "number", min: "-100", max: "100", value: batchForm.priority, onChange: (event) => setBatchForm((current) => ({ ...current, priority: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: batchForm.is_active, onChange: (event) => setBatchForm((current) => ({ ...current, is_active: event.target.checked })), label: "Active placement" })), /* @__PURE__ */ React.createElement(Field$1, { label: "Starts At" }, /* @__PURE__ */ React.createElement(DateTimePicker, { value: batchForm.starts_at, onChange: (nextValue) => setBatchForm((current) => ({ ...current, starts_at: nextValue })), placeholder: "Start time", clearable: true, className: "bg-white/[0.04]" })), /* @__PURE__ */ React.createElement(Field$1, { label: "Ends At" }, /* @__PURE__ */ React.createElement(DateTimePicker, { value: batchForm.ends_at, onChange: (nextValue) => setBatchForm((current) => ({ ...current, ends_at: nextValue })), placeholder: "End time", clearable: true, className: "bg-white/[0.04]" }))), /* @__PURE__ */ React.createElement(Field$1, { label: "Placement Notes" }, /* @__PURE__ */ React.createElement("textarea", { value: batchForm.notes, onChange: (event) => setBatchForm((current) => ({ ...current, notes: event.target.value })), className: "mt-4 min-h-[110px] w-full rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-white outline-none", maxLength: 1e3 })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleBatchEditorial("preview"), disabled: busy === "batch-preview", className: "inline-flex items-center gap-2 rounded-2xl border border-lime-300/20 bg-lime-400/10 px-5 py-3 text-sm font-semibold text-lime-100 transition hover:bg-lime-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "batch-preview" ? "fa-circle-notch fa-spin" : "fa-flask"} fa-fw` }), "Preview Batch"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleBatchEditorial("apply"), disabled: busy === "batch-apply", className: "inline-flex items-center gap-2 rounded-2xl border border-amber-300/20 bg-amber-400/10 px-5 py-3 text-sm font-semibold text-amber-100 transition hover:bg-amber-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === "batch-apply" ? "fa-circle-notch fa-spin" : "fa-wand-magic-sparkles"} fa-fw` }), "Apply Batch"))), batchResult ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[26px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-semibold text-white" }, "Preview results"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-300" }, batchResult.collections_count, " collections reviewed, ", batchResult.placement_eligible_count, " placement-ready."))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (batchResult.items || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.collection?.id, className: "rounded-[22px] border border-white/10 bg-white/[0.04] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-semibold text-white" }, item.collection?.title), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs text-slate-400" }, item.collection?.visibility, " · ", item.collection?.lifecycle_state, " · ", item.collection?.moderation_status)), item.placement ? /* @__PURE__ */ React.createElement("span", { className: `rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] ${item.placement.eligible ? "border-lime-300/20 bg-lime-400/10 text-lime-100" : "border-rose-300/20 bg-rose-400/10 text-rose-100"}` }, item.placement.eligible ? `ready for ${item.placement.surface_key}` : "placement skipped") : /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, "metadata only")), item.eligibility?.reasons?.length ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-xs text-amber-100/80" }, "Campaign readiness: ", item.eligibility.reasons.join(" ")) : null, item.placement?.reasons?.length ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-xs text-rose-100/80" }, "Placement: ", item.placement.reasons.join(" ")) : null)))) : null))), /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-sky-200/80" }, "Definitions"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Registered surfaces")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, definitions.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, definitions.map((definition2) => /* @__PURE__ */ React.createElement("div", { key: definition2.id, className: "rounded-[24px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100" }, definition2.surface_key), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, definition2.mode)), /* @__PURE__ */ React.createElement("h3", { className: "mt-4 text-lg font-semibold text-white" }, definition2.title), definition2.description ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-300" }, definition2.description) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2 text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, definition2.ranking_mode), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, "max ", definition2.max_items), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, definition2.is_active ? "active" : "inactive"), definition2.starts_at ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, "starts ", new Date(definition2.starts_at).toLocaleString()) : null, definition2.ends_at ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, "ends ", new Date(definition2.ends_at).toLocaleString()) : null, definition2.fallback_surface_key ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, "fallback ", definition2.fallback_surface_key) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => hydrateDefinition(definition2), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen fa-fw text-[10px]" }), "Edit Definition"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleDeleteDefinition(definition2), disabled: busy === `delete-definition-${definition2.id}`, className: "inline-flex items-center gap-2 rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-xs font-semibold text-rose-100 transition hover:bg-rose-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === `delete-definition-${definition2.id}` ? "fa-circle-notch fa-spin" : "fa-trash"} fa-fw text-[10px]` }), "Delete"))))))), conflicts.length ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-rose-300/20 bg-rose-500/10 p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-rose-100/80" }, "Conflicts"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Schedule overlaps need review")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-3 py-1 text-xs font-semibold text-rose-100" }, conflicts.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, conflicts.map((conflict, index2) => /* @__PURE__ */ React.createElement("div", { key: `${conflict.surface_key}-${index2}`, className: "rounded-[24px] border border-rose-300/20 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-rose-100" }, conflict.surface_key)), /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm text-rose-50" }, conflict.summary), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-xs text-rose-100/70" }, "Window: ", conflict.window?.starts_at ? new Date(conflict.window.starts_at).toLocaleString() : "Immediate", " to ", conflict.window?.ends_at ? new Date(conflict.window.ends_at).toLocaleString() : "Open-ended"))))) : null, /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200/80" }, "Placements"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Active and scheduled slots")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, placements.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-5" }, placements.map((placement) => /* @__PURE__ */ React.createElement("div", { key: placement.id, className: "rounded-[28px] border border-white/10 bg-slate-950/40 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100" }, placement.surface_key), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, placement.placement_type), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300" }, "priority ", placement.priority), conflictPlacementIds.has(placement.id) || placement.has_conflict ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-rose-100" }, "conflict") : null), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => hydratePlacement(placement), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-xs font-semibold text-white transition hover:bg-white/[0.07]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-pen fa-fw text-[10px]" }), "Edit"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleDeletePlacement(placement), disabled: busy === `delete-placement-${placement.id}`, className: "inline-flex items-center gap-2 rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-xs font-semibold text-rose-100 transition hover:bg-rose-400/15 disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${busy === `delete-placement-${placement.id}` ? "fa-circle-notch fa-spin" : "fa-trash"} fa-fw text-[10px]` }), "Delete"))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-5 xl:grid-cols-[minmax(0,1fr)_280px]" }, /* @__PURE__ */ React.createElement("div", null, placement.collection ? /* @__PURE__ */ React.createElement(CollectionCard, { collection: placement.collection, isOwner: true }) : null), /* @__PURE__ */ React.createElement("div", { className: "space-y-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Starts: ", placement.starts_at ? new Date(placement.starts_at).toLocaleString() : "Immediate"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Ends: ", placement.ends_at ? new Date(placement.ends_at).toLocaleString() : "Open-ended"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Campaign: ", placement.campaign_key || "None"), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3" }, "Status: ", placement.is_active ? "Active" : "Inactive"), placement.notes ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-white/[0.04] px-4 py-3 text-slate-300" }, placement.notes) : null))))))))); } -const __vite_glob_0_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_49 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionStaffSurfaces }, Symbol.toStringTag, { value: "Module" })); @@ -80522,7 +80856,7 @@ function NovaCardsAdminIndex() { } )), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Featured"), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(card.featured), onChange: (event) => updateCard(card.id, { featured: event.target.checked }) })), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Allow remix"), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(card.allow_remix), onChange: (event) => updateCard(card.id, { allow_remix: event.target.checked }) }))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-4 text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, card.likes_count || 0, " likes"), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, card.saves_count || 0, " saves"), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, card.remixes_count || 0, " remixes"), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, card.challenge_entries_count || 0, " challenge entries")), card.moderation_reason_labels?.length ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-amber-300/15 bg-amber-400/10 px-4 py-3 text-sm text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Heuristic moderation flags"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-2" }, card.moderation_reason_labels.map((label) => /* @__PURE__ */ React.createElement("span", { key: `${card.id}-${label}`, className: "rounded-full border border-amber-200/20 bg-amber-50/10 px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.14em] text-amber-50" }, label))), card.moderation_source ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-[11px] uppercase tracking-[0.14em] text-amber-100/70" }, "Source ", String(card.moderation_source).replaceAll("_", " ")) : null) : null, card.moderation_override ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-sky-300/15 bg-sky-400/10 px-4 py-3 text-sm text-sky-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100/80" }, "Latest staff override"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-2 text-xs uppercase tracking-[0.14em] text-sky-100/80" }, /* @__PURE__ */ React.createElement("span", null, "Status ", card.moderation_override.moderation_status), card.moderation_override.disposition_label ? /* @__PURE__ */ React.createElement("span", null, card.moderation_override.disposition_label) : null, card.moderation_override.actor_username ? /* @__PURE__ */ React.createElement("span", null, "@", card.moderation_override.actor_username) : null, card.moderation_override.source ? /* @__PURE__ */ React.createElement("span", null, String(card.moderation_override.source).replaceAll("_", " ")) : null), card.moderation_override.note ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm leading-6 text-sky-50" }, card.moderation_override.note) : null) : null, card.moderation_override_history?.length > 1 ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-sky-300/10 bg-sky-400/[0.08] px-4 py-3 text-sm text-sky-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100/75" }, "Recent override history"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, renderOverrideHistoryItems(card.moderation_override_history, `card-${card.id}`))) : null))))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Creator curation"), !featuredCreators.length ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-4 text-sm text-slate-400" }, "No public Nova creators are available for curation yet.") : null, /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, featuredCreators.map((creator) => /* @__PURE__ */ React.createElement("div", { key: creator.id, className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, creator.display_name), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "@", creator.username)), creator.public_url ? /* @__PURE__ */ React.createElement("a", { href: creator.public_url, className: "text-xs font-semibold uppercase tracking-[0.16em] text-sky-300 transition hover:text-sky-200" }, "Open profile") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-3 grid grid-cols-3 gap-2 text-xs text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-[#08111f]/70 px-3 py-3" }, creator.public_cards_count || 0, " public cards"), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-[#08111f]/70 px-3 py-3" }, creator.featured_cards_count || 0, " featured"), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-[#08111f]/70 px-3 py-3" }, creator.total_views_count || 0, " views")), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Feature on editorial page"), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(creator.nova_featured_creator), onChange: (event) => updateCreator(creator.id, { nova_featured_creator: event.target.checked }) })))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Categories"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, categories.map((category) => /* @__PURE__ */ React.createElement("div", { key: category.id, className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, category.name), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, category.slug, " • ", category.cards_count, " cards")), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => saveCategory(category), className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-white transition hover:bg-white/[0.08]" }, "Save")))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Add category"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React.createElement("input", { value: newCategory.name, onChange: (event) => setNewCategory((current) => ({ ...current, name: event.target.value })), placeholder: "Name", className: "w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("input", { value: newCategory.slug, onChange: (event) => setNewCategory((current) => ({ ...current, slug: event.target.value })), placeholder: "Slug", className: "w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("textarea", { value: newCategory.description, onChange: (event) => setNewCategory((current) => ({ ...current, description: event.target.value })), placeholder: "Description", rows: 3, className: "w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => saveCategory(newCategory), className: "w-full rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, "Create category")))))); } -const __vite_glob_0_50 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_51 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsAdminIndex }, Symbol.toStringTag, { value: "Module" })); @@ -80585,7 +80919,7 @@ function NovaCardsAssetPackAdmin() { } }, rows: 10, className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 font-mono text-sm text-white md:col-span-2" })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.active), onChange: (event) => setForm((current) => ({ ...current, active: event.target.checked })), label: "Active" }), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.official), onChange: (event) => setForm((current) => ({ ...current, official: event.target.checked })), label: "Official" })), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: savePack, className: "mt-5 w-full rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, selectedId ? "Update pack" : "Create pack")))); } -const __vite_glob_0_51 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_52 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsAssetPackAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -80651,7 +80985,7 @@ function NovaCardsChallengeAdmin() { } }, rows: 10, className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 font-mono text-sm text-white md:col-span-2" })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.official), onChange: (event) => setForm((current) => ({ ...current, official: event.target.checked })), label: "Official" }), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.featured), onChange: (event) => setForm((current) => ({ ...current, featured: event.target.checked })), label: "Featured" })), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: saveChallenge, className: "mt-5 w-full rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, selectedId ? "Update challenge" : "Create challenge")))); } -const __vite_glob_0_52 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_53 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsChallengeAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -80736,7 +81070,7 @@ function NovaCardsCollectionAdmin() { } return /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pb-20 pt-8 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Nova Cards Collections" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.14),transparent_38%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.88))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/75" }, "Editorial layer"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "Official and public card collections"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 max-w-3xl text-sm leading-7 text-slate-300" }, "Create editorial collections, assign owners, and curate the public card sets that the v2 browse surface links to.")), /* @__PURE__ */ React.createElement("div", { className: "flex gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setSelectedId(null), className: "rounded-2xl border border-white/10 bg-white/[0.05] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "New collection"), /* @__PURE__ */ React.createElement(xe, { href: endpoints.cards || "/cp/cards", className: "rounded-2xl border border-white/10 bg-white/[0.05] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "Back to cards")))), /* @__PURE__ */ React.createElement("div", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Collections"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, collections.map((collection) => /* @__PURE__ */ React.createElement("button", { key: collection.id, type: "button", onClick: () => setSelectedId(collection.id), className: `w-full rounded-[22px] border p-4 text-left transition ${selectedId === collection.id ? "border-sky-300/35 bg-sky-400/10" : "border-white/10 bg-white/[0.03] hover:border-white/20 hover:bg-white/[0.05]"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-base font-semibold tracking-[-0.03em] text-white" }, collection.name), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, collection.featured ? "Featured • " : "", collection.official ? "Official" : "@" + (collection.owner?.username || "creator"))), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-200" }, collection.cards_count, " cards")), collection.description ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, collection.description) : null)))), /* @__PURE__ */ React.createElement("section", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Collection editor"), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Owner"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.user_id, onChange: (val) => setForm((current) => ({ ...current, user_id: Number(val) })), options: admins.map((a) => ({ value: a.id, label: a.name || a.username })) })), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Visibility"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.visibility, onChange: (val) => setForm((current) => ({ ...current, visibility: val })), searchable: false, options: [{ value: "public", label: "public" }, { value: "private", label: "private" }] })), /* @__PURE__ */ React.createElement("input", { value: form.name, onChange: (event) => setForm((current) => ({ ...current, name: event.target.value })), placeholder: "Collection name", className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("input", { value: form.slug, onChange: (event) => setForm((current) => ({ ...current, slug: event.target.value })), placeholder: "Slug", className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("textarea", { value: form.description, onChange: (event) => setForm((current) => ({ ...current, description: event.target.value })), placeholder: "Description", rows: 4, className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white md:col-span-2" })), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-4" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.official), onChange: (event) => setForm((current) => ({ ...current, official: event.target.checked })), label: "Official collection" }), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.featured), onChange: (event) => setForm((current) => ({ ...current, featured: event.target.checked })), label: "Featured collection" })), selected?.public_url ? /* @__PURE__ */ React.createElement("a", { href: selected.public_url, className: "text-sky-100 transition hover:text-white", target: "_blank", rel: "noreferrer" }, "Open public page") : null), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: saveCollection, className: "mt-5 w-full rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, selectedId ? "Update collection" : "Create collection")), /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Curate cards"), !selectedId ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/12 bg-white/[0.03] px-4 py-8 text-center text-sm text-slate-400" }, "Create or select a collection first.") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: String(cardId || ""), onChange: (val) => setCardId(val), placeholder: "Select a card", options: cards.map((c) => ({ value: String(c.id), label: c.title })) }), /* @__PURE__ */ React.createElement("input", { value: cardNote, onChange: (event) => setCardNote(event.target.value), placeholder: "Optional curator note", className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: attachCard, className: "rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, "Add")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 space-y-3" }, (selected?.items || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "flex items-start justify-between gap-4 rounded-[22px] border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-base font-semibold text-white" }, item.card?.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, "#", item.sort_order, " ", item.card?.creator?.username ? `• @${item.card.creator.username}` : ""), item.note ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, item.note) : null), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => detachCard(selectedId, item.card.id), className: "rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm font-semibold text-rose-100 transition hover:bg-rose-400/15" }, "Remove"))))))))); } -const __vite_glob_0_53 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_54 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsCollectionAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -80841,7 +81175,7 @@ function NovaCardsTemplateAdmin() { } return /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl px-4 pb-20 pt-8 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Nova Cards Templates" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.14),transparent_38%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.88))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/75" }, "Template system"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "Official Nova Cards templates"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 max-w-3xl text-sm leading-7 text-slate-300" }, "Keep starter templates config-driven so the editor and render pipeline stay aligned as new card styles ship.")), /* @__PURE__ */ React.createElement("div", { className: "flex gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: resetForm, className: "rounded-2xl border border-white/10 bg-white/[0.05] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "New template"), /* @__PURE__ */ React.createElement(xe, { href: endpoints.cards || "/cp/cards", className: "rounded-2xl border border-white/10 bg-white/[0.05] px-5 py-3 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, "Back to cards")))), /* @__PURE__ */ React.createElement("div", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,1.4fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Existing templates"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, templates.map((template) => /* @__PURE__ */ React.createElement("button", { key: template.id, type: "button", onClick: () => loadTemplate(template), className: `w-full rounded-[22px] border p-4 text-left transition ${selectedId === template.id ? "border-sky-300/35 bg-sky-400/10" : "border-white/10 bg-white/[0.03] hover:border-white/20 hover:bg-white/[0.05]"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-base font-semibold tracking-[-0.03em] text-white" }, template.name), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, template.slug)), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-200" }, template.supported_formats?.join(", "))), template.description ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, template.description) : null)))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] p-5 shadow-[0_20px_50px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400" }, "Template editor"), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("input", { value: form.name, onChange: (event) => setForm((current) => ({ ...current, name: event.target.value })), placeholder: "Template name", className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("input", { value: form.slug, onChange: (event) => setForm((current) => ({ ...current, slug: event.target.value })), placeholder: "Slug", className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white" }), /* @__PURE__ */ React.createElement("textarea", { value: form.description, onChange: (event) => setForm((current) => ({ ...current, description: event.target.value })), placeholder: "Description", rows: 3, className: "rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white md:col-span-2" }), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Font preset"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.config_json?.font_preset || "modern-sans", onChange: (val) => setForm((current) => ({ ...current, config_json: { ...current.config_json, font_preset: val } })), options: fonts.map((f2) => ({ value: f2.key, label: f2.label })), searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Gradient preset"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.config_json?.gradient_preset || "midnight-nova", onChange: (val) => setForm((current) => ({ ...current, config_json: { ...current.config_json, gradient_preset: val } })), options: gradients.map((g2) => ({ value: g2.key, label: g2.label })), searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Layout preset"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.config_json?.layout || "quote_heavy", onChange: (val) => setForm((current) => ({ ...current, config_json: { ...current.config_json, layout: val } })), options: ["quote_heavy", "author_emphasis", "centered", "minimal"].map((v2) => ({ value: v2, label: v2 })), searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Text alignment"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.config_json?.text_align || "center", onChange: (val) => setForm((current) => ({ ...current, config_json: { ...current.config_json, text_align: val } })), options: ["left", "center", "right"].map((v2) => ({ value: v2, label: v2 })), searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Overlay style"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.config_json?.overlay_style || "dark-soft", onChange: (val) => setForm((current) => ({ ...current, config_json: { ...current.config_json, overlay_style: val } })), options: ["none", "dark-soft", "dark-strong", "light-soft"].map((v2) => ({ value: v2, label: v2 })), searchable: false })), /* @__PURE__ */ React.createElement("label", { className: "text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block" }, "Text color"), /* @__PURE__ */ React.createElement("input", { type: "color", value: form.config_json?.text_color || "#ffffff", onChange: (event) => setForm((current) => ({ ...current, config_json: { ...current.config_json, text_color: event.target.value } })), className: "h-12 w-full rounded-2xl border border-white/10 bg-[#0d1726] p-2" }))), /* @__PURE__ */ React.createElement("div", { className: "mt-5" }, /* @__PURE__ */ React.createElement("div", { className: "mb-3 text-sm font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Supported formats"), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, formats2.map((format) => /* @__PURE__ */ React.createElement("div", { key: format.key, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.03] px-3 py-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: form.supported_formats.includes(format.key), onChange: () => toggleFormat(format.key), label: format.label }))))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex items-center justify-between gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.active), onChange: (event) => setForm((current) => ({ ...current, active: event.target.checked })), label: "Active" }), /* @__PURE__ */ React.createElement(Checkbox, { checked: Boolean(form.official), onChange: (event) => setForm((current) => ({ ...current, official: event.target.checked })), label: "Official" })), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: saveTemplate, className: "mt-5 w-full rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, selectedId ? "Update template" : "Create template")))); } -const __vite_glob_0_54 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_55 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsTemplateAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -81127,7 +81461,7 @@ function SavedCollections() { } ))))) : activeFilters.q || activeFilters.filter !== "all" || activeFilters.sort !== "saved_desc" || activeFilters.list ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[32px] border border-dashed border-white/12 bg-white/[0.03] px-6 py-16 text-center text-sm text-slate-300" }, "No saved collections match the current search or filters.") : /* @__PURE__ */ React.createElement(EmptyState$3, { browseUrl })), recommendedCollections.length ? /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-white/[0.04] p-6 backdrop-blur-sm md:p-7" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200/80" }, "Recommended Next"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Because of what you save")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, recommendedCollections.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid grid-cols-1 gap-5 xl:grid-cols-3" }, recommendedCollections.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false })))) : null))))); } -const __vite_glob_0_55 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_56 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SavedCollections }, Symbol.toStringTag, { value: "Module" })); @@ -81465,7 +81799,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(CommunityActivityPage, { ...props })); } } -const __vite_glob_0_56 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_57 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CommunityActivityPage }, Symbol.toStringTag, { value: "Module" })); @@ -81787,7 +82121,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(LatestCommentsPage, { ...props })); } } -const __vite_glob_0_57 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: LatestCommentsPage }, Symbol.toStringTag, { value: "Module" })); @@ -81861,7 +82195,7 @@ function EnhanceCreate() { /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-current/70" }, "Optimized preset") ))), form.errors.mode ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-rose-300" }, form.errors.mode) : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-amber-300/20 bg-amber-400/10 px-4 py-4 text-sm leading-6 text-amber-50" }, "The original file is preserved separately. Completed outputs can be reviewed and downloaded before you decide how to use them."), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "mt-6 inline-flex w-full items-center justify-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/12 px-5 py-3 text-sm font-semibold text-sky-50 transition hover:bg-sky-400/20 disabled:cursor-not-allowed disabled:opacity-60" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-wand-magic-sparkles text-xs" }), form.processing ? "Starting enhance…" : sourceType === "artwork" ? "Enhance artwork image" : "Start enhance")))); } -const __vite_glob_0_58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_59 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: EnhanceCreate }, Symbol.toStringTag, { value: "Module" })); @@ -81929,7 +82263,7 @@ function EnhanceIndex() { const enhanceConfig = props.enhanceConfig || {}; return /* @__PURE__ */ React.createElement("div", { className: "w-full pb-16 pt-8" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Skinbase Enhance" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.16),transparent_36%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/80" }, "Skinbase Enhance"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "Image Upscaler"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-relaxed text-slate-300" }, "Improve older wallpapers, digital art, and photos with a clean upscaled version. Your original file is never replaced automatically.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement(xe, { href: props.createUrl, className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/12 px-5 py-3 text-xs font-semibold uppercase tracking-[0.14em] text-sky-50 transition hover:bg-sky-400/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-sparkles text-[10px]" }), "Start enhance"))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.04] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Daily limit"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-3xl font-semibold tracking-[-0.04em] text-white" }, formatEnhanceInteger(props.dailyLimit || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.04] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Total jobs"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-3xl font-semibold tracking-[-0.04em] text-white" }, formatEnhanceInteger(props.jobs?.total || jobs.length))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.04] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Completed outputs"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-3xl font-semibold tracking-[-0.04em] text-white" }, formatEnhanceInteger(latestCompleted.length))))), /* @__PURE__ */ React.createElement(EnhanceStubWarning, { config: enhanceConfig, className: "mt-6" }), flash.success ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, flash.success) : null, flash.error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, flash.error) : null, latestCompleted.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Latest completed"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold tracking-[-0.03em] text-white" }, "Recent enhanced outputs"))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, latestCompleted.map((job) => /* @__PURE__ */ React.createElement(xe, { key: job.id, href: job.show_url, className: "overflow-hidden rounded-[28px] border border-white/10 bg-[#08111d] transition hover:border-sky-300/30 hover:bg-[#0b1524]" }, /* @__PURE__ */ React.createElement("div", { className: "aspect-square bg-black/20" }, job.output_url ? /* @__PURE__ */ React.createElement("img", { src: job.output_url, alt: `Enhance job ${job.id}`, className: "h-full w-full object-cover" }) : null), /* @__PURE__ */ React.createElement("div", { className: "p-4" }, /* @__PURE__ */ React.createElement(EnhanceStatusBadge, { status: job.status }), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-sm font-semibold text-white" }, "Job #", job.id), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, job.scale, "x • ", job.mode)))))) : null, /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "History"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold tracking-[-0.03em] text-white" }, "Your enhance jobs")), jobs.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-white/10 bg-white/[0.04] px-6 py-12 text-center text-slate-300" }, "No enhance jobs yet. Upload an image to start your first upscale.") : /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, jobs.map((job) => /* @__PURE__ */ React.createElement(JobCard, { key: job.id, job }))))); } -const __vite_glob_0_59 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_60 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: EnhanceIndex }, Symbol.toStringTag, { value: "Module" })); @@ -81988,7 +82322,7 @@ function EnhanceShow() { At.delete(job.delete_url); }, className: "inline-flex items-center gap-2 rounded-full border border-rose-300/20 bg-rose-400/12 px-5 py-3 text-xs font-semibold uppercase tracking-[0.14em] text-rose-100 transition hover:bg-rose-400/20" }, "Delete") : null))), /* @__PURE__ */ React.createElement(EnhanceStubWarning, { config: props.enhanceConfig, className: "mt-6" }), flash.success ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, flash.success) : null, flash.error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, flash.error) : null, errors.job ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, errors.job) : null, job.error_message ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, job.error_message) : null, canCompare ? /* @__PURE__ */ React.createElement("div", { className: "mt-8" }, /* @__PURE__ */ React.createElement(BeforeAfterSlider, { beforeUrl: job.source_url, afterUrl: job.output_url })) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_380px]" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-3 text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Original source"), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20" }, job.source_url ? /* @__PURE__ */ React.createElement("img", { src: job.source_url, alt: "Original source", className: "w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex min-h-[280px] items-center justify-center text-white/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image text-4xl" })))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-3 text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Enhanced result"), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20" }, job.output_url ? /* @__PURE__ */ React.createElement("img", { src: job.output_url, alt: "Enhanced output", className: "w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex min-h-[280px] items-center justify-center text-white/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-hourglass-half text-4xl" })))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Metadata"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("pre", { className: "overflow-x-auto whitespace-pre-wrap break-words" }, JSON.stringify(job.metadata || {}, null, 2))))), /* @__PURE__ */ React.createElement("aside", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Job details"), /* @__PURE__ */ React.createElement("dl", { className: "mt-4" }, /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Created", value: formatDate$g(job.created_at) }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Queued", value: formatDate$g(job.queued_at) }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Started", value: formatDate$g(job.started_at) }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Finished", value: formatDate$g(job.finished_at) }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Expires", value: formatDate$g(job.expires_at) }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Input size", value: job.input_filesize ? `${(job.input_filesize / 1024 / 1024).toFixed(2)} MB` : "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Input mime", value: job.input_mime || "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Input dimensions", value: job.input_width && job.input_height ? `${job.input_width} × ${job.input_height}` : "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Output size", value: job.output_filesize ? `${(job.output_filesize / 1024 / 1024).toFixed(2)} MB` : "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Output mime", value: job.output_mime || "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Output dimensions", value: job.output_width && job.output_height ? `${job.output_width} × ${job.output_height}` : "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Processing seconds", value: job.processing_seconds ?? "—" }), /* @__PURE__ */ React.createElement(DetailRow$1, { label: "Artwork", value: job.artwork?.title ? /* @__PURE__ */ React.createElement("a", { href: job.artwork.url, className: "text-sky-300 hover:text-sky-200" }, job.artwork.title) : "Standalone upload" }))))); } -const __vite_glob_0_60 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_61 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: EnhanceShow }, Symbol.toStringTag, { value: "Module" })); @@ -82659,7 +82993,7 @@ function FollowingFeed() { loading ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-spinner fa-spin mr-2" }), "Loading…") : "Load more" ))))); } -const __vite_glob_0_61 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_62 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: FollowingFeed }, Symbol.toStringTag, { value: "Module" })); @@ -82719,7 +83053,7 @@ function HashtagFeed() { loading ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-spinner fa-spin mr-2" }), "Loading…") : "Load more" )))))); } -const __vite_glob_0_62 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_63 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HashtagFeed }, Symbol.toStringTag, { value: "Module" })); @@ -82777,7 +83111,7 @@ function SavedFeed() { loading ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-spinner fa-spin mr-2" }), "Loading…") : "Load more" )))))); } -const __vite_glob_0_63 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_64 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SavedFeed }, Symbol.toStringTag, { value: "Module" })); @@ -82902,7 +83236,7 @@ function SearchFeed() { "Load more" ))), /* @__PURE__ */ React.createElement("aside", { className: "hidden lg:block w-64 shrink-0 space-y-4 pt-14" }, /* @__PURE__ */ React.createElement(TrendingHashtagsSidebar$1, { hashtags: trendingHashtags }), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/[0.07] bg-white/[0.03] px-4 py-4 text-center" }, /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500 leading-relaxed" }, "Tip: search ", /* @__PURE__ */ React.createElement("span", { className: "text-sky-400/80" }, "#hashtag"), " to find posts by topic."))))))); } -const __vite_glob_0_64 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_65 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SearchFeed }, Symbol.toStringTag, { value: "Module" })); @@ -82964,7 +83298,7 @@ function TrendingFeed() { loading ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-spinner fa-spin mr-2" }), "Loading…") : "Load more" ))), /* @__PURE__ */ React.createElement("aside", { className: "hidden lg:block w-64 shrink-0 space-y-4 pt-14" }, /* @__PURE__ */ React.createElement(TrendingHashtagsSidebar, { hashtags: trendingHashtags }), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/[0.07] bg-white/[0.03] px-4 py-4 text-center" }, /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500 leading-relaxed" }, "Posts are ranked by likes, comments & engagement over the last 7 days."))))))); } -const __vite_glob_0_65 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_66 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: TrendingFeed }, Symbol.toStringTag, { value: "Module" })); @@ -83049,7 +83383,7 @@ function ForumCategory({ category, parentCategory = null, threads = [], paginati "New topic" ))), /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-2xl border border-white/[0.06] bg-nova-800/50 backdrop-blur" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 border-b border-white/[0.06] px-5 py-3" }, /* @__PURE__ */ React.createElement("span", { className: "flex-1 text-xs font-semibold uppercase tracking-widest text-white/30" }, "Topics"), /* @__PURE__ */ React.createElement("span", { className: "w-16 text-center text-xs font-semibold uppercase tracking-widest text-white/30" }, "Replies")), threads.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "px-5 py-12 text-center" }, /* @__PURE__ */ React.createElement("svg", { className: "mx-auto mb-4 text-zinc-600", width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" })), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-zinc-500" }, "No topics in this board yet."), isAuthenticated && slug && /* @__PURE__ */ React.createElement("a", { href: `/forum/${slug}/new`, className: "mt-3 inline-block text-sm text-sky-300 hover:text-sky-200" }, "Be the first to start a discussion →")) : /* @__PURE__ */ React.createElement("div", null, threads.map((thread, i) => /* @__PURE__ */ React.createElement(ThreadRow, { key: thread.topic_id ?? thread.id ?? i, thread, isFirst: i === 0 })))), pagination?.last_page > 1 && /* @__PURE__ */ React.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React.createElement(Pagination$1, { meta: pagination })))); } -const __vite_glob_0_66 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_67 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumCategory }, Symbol.toStringTag, { value: "Module" })); @@ -83313,7 +83647,7 @@ function ForumEditPost({ post: post2, thread, csrfToken: csrfToken2, errors = {} ), /* @__PURE__ */ React.createElement(Button$1, { type: "submit", variant: "primary", size: "md", loading: submitting }, "Save changes")) ))); } -const __vite_glob_0_67 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_68 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumEditPost }, Symbol.toStringTag, { value: "Module" })); @@ -83404,7 +83738,7 @@ function formatLastActivity(value) { } return `Updated ${date.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })}`; } -const __vite_glob_0_68 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_69 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumIndex }, Symbol.toStringTag, { value: "Module" })); @@ -83525,7 +83859,7 @@ function ForumNewThread({ category, csrfToken: csrfToken2, errors = {}, oldValue /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between pt-2" }, /* @__PURE__ */ React.createElement("a", { href: `/forum/${slug}`, className: "text-sm text-zinc-500 hover:text-zinc-300 transition-colors" }, "← Cancel"), /* @__PURE__ */ React.createElement(Button$1, { type: "submit", variant: "primary", size: "md", loading: submitting }, "Publish topic")) ))); } -const __vite_glob_0_69 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_70 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumNewThread }, Symbol.toStringTag, { value: "Module" })); @@ -83540,7 +83874,7 @@ function ForumSection({ category, boards = [], seo = {} }) { ]; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SeoHead, { seo }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-6xl px-4 pb-20 pt-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(Breadcrumbs, { items: breadcrumbs }), /* @__PURE__ */ React.createElement("section", { className: "mt-5 overflow-hidden rounded-3xl border border-white/10 bg-nova-800/55 shadow-xl backdrop-blur" }, /* @__PURE__ */ React.createElement("div", { className: "relative h-56 overflow-hidden sm:h-64" }, /* @__PURE__ */ React.createElement("img", { src: preview, alt: `${name2} preview`, className: "h-full w-full object-cover object-center" }), /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 bg-gradient-to-t from-black/85 via-black/35 to-transparent" }), /* @__PURE__ */ React.createElement("div", { className: "absolute inset-x-0 bottom-0 p-6 sm:p-8" }, /* @__PURE__ */ React.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.18em] text-cyan-200/85" }, "Forum Section"), /* @__PURE__ */ React.createElement("h1", { className: "mt-2 text-3xl font-black text-white sm:text-4xl" }, name2), description && /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm text-white/70 sm:text-base" }, description)))), /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-2xl border border-white/8 bg-nova-800/45 p-5 backdrop-blur sm:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-end justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.16em] text-white/40" }, "Subcategories"), /* @__PURE__ */ React.createElement("h2", { className: "mt-1 text-2xl font-bold text-white" }, "Browse boards")), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-white/45 sm:text-sm" }, "Select a board to open its thread list.")), boards.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "py-12 text-center text-sm text-white/45" }, "No boards are available in this section yet.") : /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 md:grid-cols-2" }, boards.map((board) => /* @__PURE__ */ React.createElement("a", { key: board.id ?? board.slug, href: `/forum/${board.slug}`, className: "rounded-2xl border border-white/8 bg-white/[0.02] p-5 transition hover:border-cyan-400/25 hover:bg-white/[0.04] block" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-white" }, board.title), board.description && /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-white/55" }, board.description)), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-cyan-300/20 bg-cyan-300/10 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-cyan-200" }, "Open")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-4 text-xs text-white/50" }, /* @__PURE__ */ React.createElement("span", null, board.topics_count ?? 0, " topics"), /* @__PURE__ */ React.createElement("span", null, board.posts_count ?? 0, " posts"), board.latest_topic?.title && /* @__PURE__ */ React.createElement("span", null, "Latest: ", board.latest_topic.title)))))))); } -const __vite_glob_0_70 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_71 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumSection }, Symbol.toStringTag, { value: "Module" })); @@ -83878,7 +84212,7 @@ function formatDate$d(dateStr) { return ""; } } -const __vite_glob_0_71 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_72 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumThread }, Symbol.toStringTag, { value: "Module" })); @@ -84122,7 +84456,7 @@ function GroupChallengeShow() { const outcomeSections = challenge.outcome_sections || {}; return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(234,179,8,0.15),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${challenge.title || group.name} - Skinbase`, description: challenge.summary || challenge.description || "Group challenge" }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-6xl space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-[32px] border border-white/10 bg-white/[0.03]" }, challenge.cover_url ? /* @__PURE__ */ React.createElement("img", { src: challenge.cover_url, alt: challenge.title, className: "h-56 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "h-40 bg-white/[0.03]" }), /* @__PURE__ */ React.createElement("div", { className: "p-6" }, /* @__PURE__ */ React.createElement("a", { href: group.urls?.public, className: "text-sm font-semibold text-amber-200" }, group.name), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold text-white" }, challenge.title), /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-7 text-slate-300" }, challenge.summary || challenge.description || "Group challenge"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3 text-xs uppercase tracking-[0.16em] text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, challenge.status), /* @__PURE__ */ React.createElement("span", null, challenge.visibility), /* @__PURE__ */ React.createElement("span", null, String(challenge.participation_scope || "").replace("_", " ")), challenge.start_at ? /* @__PURE__ */ React.createElement("span", null, "Starts ", new Date(challenge.start_at).toLocaleDateString()) : null, challenge.end_at ? /* @__PURE__ */ React.createElement("span", null, "Ends ", new Date(challenge.end_at).toLocaleDateString()) : null), /* @__PURE__ */ React.createElement(ChallengeWorldLinkBadge, { world: linkedWorld, className: "mt-5" }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-8 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Challenge brief"), /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm leading-7 text-slate-300" }, challenge.description || "No extended challenge brief yet."), challenge.rules_text ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Rules"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-7 text-slate-300" }, challenge.rules_text)) : null, challenge.submission_instructions ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Submission instructions"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-7 text-slate-300" }, challenge.submission_instructions)) : null), /* @__PURE__ */ React.createElement("div", { className: "space-y-8" }, /* @__PURE__ */ React.createElement(OutcomeSection, { section: outcomeSections.winner }), /* @__PURE__ */ React.createElement(OutcomeSection, { section: outcomeSections.finalist }), /* @__PURE__ */ React.createElement(OutcomeSection, { section: outcomeSections.runner_up }), /* @__PURE__ */ React.createElement(OutcomeSection, { section: outcomeSections.honorable_mention }), /* @__PURE__ */ React.createElement(OutcomeSection, { section: outcomeSections.featured }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Entries"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 sm:grid-cols-2 xl:grid-cols-1" }, Array.isArray(challenge.artworks) && challenge.artworks.length > 0 ? challenge.artworks.map((artwork) => /* @__PURE__ */ React.createElement("a", { key: artwork.id, href: artwork.url, className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20" }, artwork.thumb ? /* @__PURE__ */ React.createElement("img", { src: artwork.thumb, alt: artwork.title, className: "aspect-[4/3] w-full object-cover" }) : null, /* @__PURE__ */ React.createElement("div", { className: "p-4 text-white" }, artwork.title))) : /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, "No entries linked yet."))))))); } -const __vite_glob_0_72 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_73 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupChallengeShow }, Symbol.toStringTag, { value: "Module" })); @@ -84132,7 +84466,7 @@ function GroupEventShow() { const event = props.event || {}; return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(16,185,129,0.15),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${event.title || group.name} - Skinbase`, description: event.summary || event.description || "Group event" }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-5xl space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-[32px] border border-white/10 bg-white/[0.03]" }, event.cover_url ? /* @__PURE__ */ React.createElement("img", { src: event.cover_url, alt: event.title, className: "h-56 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "h-40 bg-white/[0.03]" }), /* @__PURE__ */ React.createElement("div", { className: "p-6" }, /* @__PURE__ */ React.createElement("a", { href: group.urls?.public, className: "text-sm font-semibold text-emerald-200" }, group.name), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold text-white" }, event.title), /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-7 text-slate-300" }, event.summary || event.description || "Group event"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Starts"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-white" }, event.start_at ? new Date(event.start_at).toLocaleString() : "Not scheduled")), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Details"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-white" }, event.event_type, " • ", event.visibility), event.location ? /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, event.location) : null)), event.external_url ? /* @__PURE__ */ React.createElement("a", { href: event.external_url, className: "mt-5 inline-flex rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Open external link") : null)), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "About this event"), /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm leading-7 text-slate-300" }, event.description || "No extended event details yet.")))); } -const __vite_glob_0_73 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_74 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupEventShow }, Symbol.toStringTag, { value: "Module" })); @@ -84822,7 +85156,7 @@ function GroupFaqPage() { /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("a", { href: links.contact_support, className: "rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Contact"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Contact support"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, "Use this if your question is not answered here or if you need help with an account or workflow issue.")), /* @__PURE__ */ React.createElement("a", { href: links.report_issue, className: "rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Report"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Report a problem"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, "Use this if a route, role, contributor record, or Group workflow appears broken rather than just unclear."))) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Support flow"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.quickstart, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Quickstart"), /* @__PURE__ */ React.createElement("a", { href: links.full_documentation, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read full documentation"), /* @__PURE__ */ React.createElement("a", { href: links.group_studio, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Group Studio"), /* @__PURE__ */ React.createElement("a", { href: links.create_group, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Create a Group"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Quick troubleshooting rule"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "If something feels wrong, check three things first: are you in the right Group context, do you have the right role, and is the content public or internal?"))))))); } -const __vite_glob_0_74 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_75 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupFaqPage }, Symbol.toStringTag, { value: "Module" })); @@ -85370,7 +85704,7 @@ function GroupHelpPage() { /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement("a", { href: links.create_group, className: "rounded-[28px] border border-sky-300/20 bg-sky-300/10 p-5 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-100/80" }, "Create"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Create your first Group"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-sky-50/80" }, "Start with branding, visibility, and your first member invites.")), /* @__PURE__ */ React.createElement("a", { href: links.group_studio, className: "rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Manage"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Open Group Studio"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, "Check members, workflow, releases, recruitment, and review status.")), /* @__PURE__ */ React.createElement("a", { href: links.contact_support, className: "rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Contact"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Contact support"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, "Use the general support flow if you need help untangling an account or workflow issue.")), /* @__PURE__ */ React.createElement("a", { href: links.report_issue, className: "rounded-[28px] border border-white/10 bg-black/20 p-5 transition hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Report"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, "Report a problem"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, "Use this if a route, permission, credit record, or workflow appears broken."))) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick actions"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.groups_directory, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Browse public Groups"), /* @__PURE__ */ React.createElement("a", { href: links.group_studio, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Group Studio"), links.faq ? /* @__PURE__ */ React.createElement("a", { href: links.faq, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Groups FAQ") : null, /* @__PURE__ */ React.createElement("a", { href: "#publishing-as-a-group", className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Review publishing guidance"), /* @__PURE__ */ React.createElement("a", { href: "#contributor-credit", className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Check contributor credit rules"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Read this before launch day"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "Before the first public release or artwork, confirm the Group context, contributor credit, and review expectations. Those three checks prevent most avoidable confusion."))))))); } -const __vite_glob_0_75 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_76 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -85445,7 +85779,7 @@ function GroupIndex() { } )), leaderboardItems.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.02em] text-white" }, "Monthly group leaderboard"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-6 text-slate-400" }, "A fast view of the collaborative teams moving the most attention and publishing energy right now.")), /* @__PURE__ */ React.createElement("a", { href: "/leaderboard?type=groups&period=monthly", className: "text-sm font-semibold text-sky-200 transition hover:text-white" }, "View leaderboard")), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 xl:grid-cols-3" }, leaderboardItems.slice(0, 3).map((item) => /* @__PURE__ */ React.createElement(GroupLeaderboardCard, { key: item.entity?.id || item.rank, item })))) : null, /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.02em] text-white" }, "Browse groups"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-6 text-slate-400" }, "Filter the directory by discovery surface, then jump into each group’s public page for artworks, releases, projects, events, and activity.")), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-500" }, Number(props.groups?.meta?.total || 0).toLocaleString(), " public groups")), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, groups.map((group) => /* @__PURE__ */ React.createElement(GroupDiscoveryCard, { key: group.slug || group.id, group })))))); } -const __vite_glob_0_76 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_77 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupIndex }, Symbol.toStringTag, { value: "Module" })); @@ -85475,7 +85809,7 @@ function GroupPostShow() { }; return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.16),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${post2.title || group.name} - Skinbase`, description: post2.excerpt || group.headline || group.bio || "Group post" }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-5xl" }, /* @__PURE__ */ React.createElement("article", { className: "rounded-[32px] border border-white/10 bg-white/[0.03] p-6 sm:p-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("a", { href: group.urls?.public, className: "text-sm font-semibold text-sky-200" }, "← Back to ", group.name), props.reportEndpoint ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: submitReport, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-2 text-sm font-semibold text-white" }, "Report") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2 text-xs uppercase tracking-[0.16em] text-slate-400" }, post2.type ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1" }, post2.type) : null, post2.is_pinned ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-400/10 px-3 py-1 text-amber-100" }, "Pinned") : null), /* @__PURE__ */ React.createElement("h1", { className: "mt-5 text-4xl font-semibold text-white" }, post2.title), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-sm text-slate-400" }, post2.author?.name || post2.author?.username || group.name, " • ", post2.published_at ? new Date(post2.published_at).toLocaleString() : "Recently"), post2.excerpt ? /* @__PURE__ */ React.createElement("p", { className: "mt-6 text-lg leading-8 text-slate-200" }, post2.excerpt) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8 whitespace-pre-wrap text-sm leading-7 text-slate-300" }, post2.content || "")), recentPosts.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "More from ", group.name), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2" }, recentPosts.filter((item) => item.id !== post2.id).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.url, className: "rounded-[24px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, item.type), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, item.excerpt || "Read the full post."))))) : null)); } -const __vite_glob_0_77 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_78 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupPostShow }, Symbol.toStringTag, { value: "Module" })); @@ -85491,7 +85825,7 @@ function GroupProjectShow() { const project = props.project || {}; return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.16),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${project.title || group.name} - Skinbase`, description: project.summary || project.description || group.headline || "Group project" }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-6xl space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-[32px] border border-white/10 bg-white/[0.03]" }, project.cover_url ? /* @__PURE__ */ React.createElement("img", { src: project.cover_url, alt: project.title, className: "h-56 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "h-40 bg-white/[0.03]" }), /* @__PURE__ */ React.createElement("div", { className: "p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React.createElement("a", { href: group.urls?.public, className: "text-sm font-semibold text-sky-200" }, group.name), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, project.status), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, project.visibility)), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold text-white" }, project.title), project.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-7 text-slate-300" }, project.summary) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-4 text-xs text-slate-400" }, project.start_date ? /* @__PURE__ */ React.createElement("span", null, "Started ", new Date(project.start_date).toLocaleDateString()) : null, project.target_date ? /* @__PURE__ */ React.createElement("span", null, "Target ", new Date(project.target_date).toLocaleDateString()) : null, project.released_at ? /* @__PURE__ */ React.createElement("span", null, "Released ", new Date(project.released_at).toLocaleDateString()) : null, project.lead?.name || project.lead?.username ? /* @__PURE__ */ React.createElement("span", null, "Lead: ", project.lead?.name || project.lead?.username) : null))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-8 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Overview"), /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm leading-7 text-slate-300" }, project.description || "No long-form description yet."), Array.isArray(project.milestones) && project.milestones.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-3" }, project.milestones.map((milestone) => /* @__PURE__ */ React.createElement("div", { key: milestone.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, milestone.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, milestone.status)), milestone.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, milestone.summary) : null, milestone.owner?.name || milestone.owner?.username ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs text-slate-500" }, "Owner: ", milestone.owner?.name || milestone.owner?.username) : null))) : null, /* @__PURE__ */ React.createElement(ArtworkGrid$2, { artworks: project.artworks })), /* @__PURE__ */ React.createElement("div", { className: "space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Pipeline"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-sm leading-7 text-slate-300" }, "This project currently has ", project.counts?.milestones || 0, " milestones and is linked to ", project.release_count || project.counts?.releases || 0, " releases.")), Array.isArray(project.assets) && project.assets.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Assets"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, project.assets.map((asset) => /* @__PURE__ */ React.createElement("a", { key: asset.id, href: asset.download_url, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, asset.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, asset.category, " • ", asset.visibility))))) : null, Array.isArray(project.team) && project.team.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Team"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, project.team.map((member) => /* @__PURE__ */ React.createElement("div", { key: member.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, member.name || member.username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, member.role_label || (member.is_lead ? "Lead" : "Contributor")))))) : null, project.pinned_post ? /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Pinned update"), /* @__PURE__ */ React.createElement("a", { href: project.pinned_post.url, className: "mt-4 inline-block text-sm font-semibold text-sky-200" }, project.pinned_post.title)) : null)))); } -const __vite_glob_0_78 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_79 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupProjectShow }, Symbol.toStringTag, { value: "Module" })); @@ -85790,7 +86124,7 @@ function GroupQuickstartPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: nextSteps }) ))))); } -const __vite_glob_0_79 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_80 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupQuickstartPage }, Symbol.toStringTag, { value: "Module" })); @@ -85808,7 +86142,7 @@ function GroupReleaseShow() { const milestones = Array.isArray(release.milestones) ? release.milestones : []; return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.16),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${release.title || group.name} - Skinbase`, description: release.summary || release.description || group.headline || "Group release" }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-6xl space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "overflow-hidden rounded-[32px] border border-white/10 bg-white/[0.03]" }, release.cover_url ? /* @__PURE__ */ React.createElement("img", { src: release.cover_url, alt: release.title, className: "h-64 w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "h-44 bg-white/[0.03]" }), /* @__PURE__ */ React.createElement("div", { className: "p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React.createElement("a", { href: group.urls?.public, className: "text-sm font-semibold text-sky-200" }, group.name), release.status ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, release.status) : null, release.current_stage ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, release.current_stage) : null), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold text-white" }, release.title), release.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-3xl text-sm leading-7 text-slate-300" }, release.summary) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-4 text-xs text-slate-400" }, release.released_at ? /* @__PURE__ */ React.createElement("span", null, "Released ", new Date(release.released_at).toLocaleDateString()) : null, release.planned_release_at ? /* @__PURE__ */ React.createElement("span", null, "Planned ", new Date(release.planned_release_at).toLocaleDateString()) : null, release.lead?.name || release.lead?.username ? /* @__PURE__ */ React.createElement("span", null, "Lead: ", release.lead?.name || release.lead?.username) : null, /* @__PURE__ */ React.createElement("span", null, release.counts?.artworks || 0, " artworks"), /* @__PURE__ */ React.createElement("span", null, release.counts?.contributors || 0, " contributors"), /* @__PURE__ */ React.createElement("span", null, release.counts?.milestones || 0, " milestones")))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-8 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Overview"), /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm leading-7 text-slate-300" }, release.description || "No long-form release description yet."), release.release_notes ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Release notes"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 whitespace-pre-wrap text-sm leading-7 text-slate-300" }, release.release_notes)) : null, /* @__PURE__ */ React.createElement(ArtworkGrid$1, { artworks: release.artworks })), /* @__PURE__ */ React.createElement("div", { className: "space-y-8" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Links"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, release.linked_project?.url ? /* @__PURE__ */ React.createElement("a", { href: release.linked_project.url, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, release.linked_project.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, "Linked project")) : null, release.linked_collection?.url ? /* @__PURE__ */ React.createElement("a", { href: release.linked_collection.url, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, release.linked_collection.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, "Linked collection")) : null, release.featured_artwork ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, release.featured_artwork.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, "Featured artwork")) : null)), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Contributors"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, contributors.length > 0 ? contributors.map((contributor) => /* @__PURE__ */ React.createElement("div", { key: contributor.id, className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, contributor.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: contributor.avatar_url, alt: contributor.name || contributor.username, className: "h-11 w-11 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate font-semibold text-white" }, contributor.name || contributor.username), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, contributor.role_label || "Contributor")))) : /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, "No contributor credits yet."))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "Milestones"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, milestones.length > 0 ? milestones.map((milestone) => /* @__PURE__ */ React.createElement("div", { key: milestone.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, milestone.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, milestone.status)), milestone.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, milestone.summary) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs text-slate-500" }, milestone.owner?.name || milestone.owner?.username || "No owner", milestone.due_date ? ` • due ${milestone.due_date}` : ""))) : /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, "No milestones defined yet."))))))); } -const __vite_glob_0_80 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_81 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupReleaseShow }, Symbol.toStringTag, { value: "Module" })); @@ -86188,7 +86522,7 @@ function GroupShow() { if (!currentJoinRequest?.id || !group.urls?.join_request_withdraw_pattern) return; At.delete(group.urls.join_request_withdraw_pattern.replace("__JOIN_REQUEST__", String(currentJoinRequest.id))); }; - return /* @__PURE__ */ React.createElement("div", { className: "relative min-h-screen overflow-hidden pb-16" }, /* @__PURE__ */ React.createElement(SeoHead, { title: `${group.name} - Skinbase`, description: group.headline || group.bio || "Skinbase group" }), /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ React.createElement("div", { className: "relative min-h-screen overflow-hidden pb-16" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${group.name} - Skinbase`, description: group.headline || group.bio || "Skinbase group" }), /* @__PURE__ */ React.createElement( "div", { "aria-hidden": "true", @@ -86236,7 +86570,7 @@ function GroupShow() { return /* @__PURE__ */ React.createElement("section", { key: label, className: "relative overflow-hidden rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: `absolute inset-x-0 top-0 h-[3px] rounded-t-[30px] bg-gradient-to-r ${roleKey === "owner" ? "from-amber-400/70 to-transparent" : roleKey === "admin" ? "from-sky-400/70 to-transparent" : roleKey === "editor" ? "from-violet-400/70 to-transparent" : "from-emerald-400/70 to-transparent"}` }), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("span", { className: `inline-flex h-8 w-8 items-center justify-center rounded-xl border ${roleStyle.badge}` }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${roleStyle.icon} fa-fw text-sm ${roleStyle.iconColor}` })), /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-white" }, label), /* @__PURE__ */ React.createElement("span", { className: "ml-auto rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-slate-300" }, bucket.length)), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3" }, bucket.map((member) => /* @__PURE__ */ React.createElement("a", { key: member.id, href: member.user?.profile_url || "#", className: "group flex items-center gap-3 rounded-[24px] border border-white/10 bg-black/20 px-4 py-4 transition hover:border-white/20 hover:bg-white/[0.04]" }, member.user?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: member.user.avatar_url, alt: member.user.name || member.user.username, className: "h-12 w-12 shrink-0 rounded-2xl object-cover ring-1 ring-white/10 transition group-hover:ring-white/20" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate font-semibold text-white" }, member.user?.name || member.user?.username), /* @__PURE__ */ React.createElement("div", { className: `mt-1 inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.14em] ${roleStyle.badge}` }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${roleStyle.icon} fa-fw text-[9px]` }), member.role_label || member.role)))))); }))) : null, section === "about" ? /* @__PURE__ */ React.createElement("section", { className: "mt-8 relative overflow-hidden rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "absolute inset-x-0 top-0 h-[3px] rounded-t-[30px] bg-gradient-to-r from-slate-400/50 to-transparent" }), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "inline-flex h-10 w-10 items-center justify-center rounded-[14px] border border-white/10 bg-white/[0.05] text-slate-300" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-id-card fa-fw" })), /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold text-white" }, "About")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 space-y-4 text-sm leading-7 text-slate-300" }, /* @__PURE__ */ React.createElement("p", null, group.bio || "No long-form description yet."), group.website_url ? /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("a", { href: group.website_url, className: "inline-flex items-center gap-1.5 text-sky-200 underline underline-offset-4 transition hover:text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-link" }), group.website_url)) : null, Array.isArray(group.links) && group.links.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, group.links.map((link2) => /* @__PURE__ */ React.createElement("a", { key: `${link2.label}-${link2.url}`, href: link2.url, className: "inline-flex items-center gap-2 rounded-[14px] border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white transition hover:bg-white/[0.08]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square text-slate-400" }), link2.label))) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-4 border-t border-white/8 pt-4 text-xs text-slate-400" }, group.founded_at ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center gap-2" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-calendar-days text-slate-500" }), "Founded ", new Date(group.founded_at).toLocaleDateString()) : null, group.type ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center gap-2" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-tag text-slate-500" }), group.type) : null))) : null)); } -const __vite_glob_0_81 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_82 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupShow }, Symbol.toStringTag, { value: "Module" })); @@ -86494,7 +86828,7 @@ function AccountHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-emerald-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: signedIn ? links.profile_settings : links.login, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, signedIn ? "Open account settings" : "Open login"), /* @__PURE__ */ React.createElement("a", { href: links.help_auth, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read auth help"), /* @__PURE__ */ React.createElement("a", { href: links.help_profile, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Profile help"), /* @__PURE__ */ React.createElement("a", { href: links.help_troubleshooting, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open troubleshooting"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-emerald-300/20 bg-emerald-400/10 p-4 text-emerald-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-emerald-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-emerald-50/85" }, "The healthiest account is the one with a current email, a manageable password, and settings reviewed before they become emergency work."))))))); } -const __vite_glob_0_82 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_83 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AccountHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -86850,7 +87184,7 @@ function AuthHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.login, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open login"), /* @__PURE__ */ React.createElement("a", { href: links.register, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Create account"), /* @__PURE__ */ React.createElement("a", { href: links.password_request, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Reset password"), /* @__PURE__ */ React.createElement("a", { href: links.help_account, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read account settings help"), /* @__PURE__ */ React.createElement("a", { href: links.help_troubleshooting, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open troubleshooting hub"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "If access breaks, check four things first: the email, the password, the inbox, and whether the problem is really permissions rather than login."))))))); } -const __vite_glob_0_83 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_84 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AuthHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -87276,7 +87610,7 @@ function CardsHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.create_card, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Create a Card"), /* @__PURE__ */ React.createElement("a", { href: links.studio_cards, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Cards workspace"), /* @__PURE__ */ React.createElement("a", { href: links.cards_index, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Browse public Cards"), /* @__PURE__ */ React.createElement("a", { href: links.studio_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Studio help"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "If the content feels unclear, ask one question first: is this a Card, an artwork, a post, or a collection? The answer usually fixes the workflow too."))))))); } -const __vite_glob_0_84 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_85 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CardsHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -88185,7 +88519,7 @@ function HelpCenterPage() { /* @__PURE__ */ React.createElement(HelpSupportCta, { items: supportItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Help architecture"), /* @__PURE__ */ React.createElement("ul", { className: "mt-4 space-y-3 text-sm leading-6 text-slate-300" }, /* @__PURE__ */ React.createElement("li", null, "Use ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, "/help"), " as the main hub."), /* @__PURE__ */ React.createElement("li", null, "Use ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, "/help/topic"), " for overview pages."), /* @__PURE__ */ React.createElement("li", null, "Use ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, "/help/topic/subpage"), " for quickstarts, FAQs, and troubleshooting."))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Current coverage"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-300" }, "Groups is the first complete multi-page topic family, and Studio, Upload, Cards, Profile, Signup / Login, Account Settings, and Troubleshooting are now live topic guides. The rest of the Help Center still follows the same predictable expansion path."))))))); } -const __vite_glob_0_85 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_86 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HelpCenterPage }, Symbol.toStringTag, { value: "Module" })); @@ -88574,7 +88908,7 @@ function ProfileHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.profile_settings, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open profile settings"), /* @__PURE__ */ React.createElement("a", { href: links.groups_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Groups help"), /* @__PURE__ */ React.createElement("a", { href: links.studio_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Studio help"), /* @__PURE__ */ React.createElement("a", { href: links.upload_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Upload help"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "A better profile usually starts with three things: a recognizable avatar, a clearer bio, and a stronger sense of what you want people to remember about you."))))))); } -const __vite_glob_0_86 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_87 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ProfileHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -89029,7 +89363,7 @@ function StudioHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.open_studio, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Studio"), /* @__PURE__ */ React.createElement("a", { href: links.studio_drafts, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open drafts"), /* @__PURE__ */ React.createElement("a", { href: links.group_studio, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Group Studio"), /* @__PURE__ */ React.createElement("a", { href: links.groups_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Groups help"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "If something feels missing, check context first. Personal Studio and Group Studio are connected, but they are not identical workspaces."))))))); } -const __vite_glob_0_87 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_88 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -89271,7 +89605,7 @@ function TroubleshootingHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-rose-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.help_auth, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read auth help"), /* @__PURE__ */ React.createElement("a", { href: links.help_account, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read account settings help"), /* @__PURE__ */ React.createElement("a", { href: links.upload_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Upload help"), /* @__PURE__ */ React.createElement("a", { href: links.groups_faq, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Groups FAQ"), /* @__PURE__ */ React.createElement("a", { href: links.report_issue, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Report a problem"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-rose-300/20 bg-rose-400/10 p-4 text-rose-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-rose-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-rose-50/85" }, "A clear problem statement beats frantic guessing. Name the route, the context, and what changed before you decide the product is broken."))))))); } -const __vite_glob_0_88 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_89 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: TroubleshootingHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -89689,7 +90023,7 @@ function UploadHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.upload, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Start upload"), /* @__PURE__ */ React.createElement("a", { href: links.studio_drafts, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open drafts"), /* @__PURE__ */ React.createElement("a", { href: links.studio_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Studio help"), /* @__PURE__ */ React.createElement("a", { href: links.groups_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Groups help"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-amber-300/20 bg-amber-400/10 p-4 text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-amber-50/85" }, "If an upload feels wrong, check three things first: context, draft state, and contributor credit."))))))); } -const __vite_glob_0_89 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_90 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -90152,7 +90486,7 @@ function WorldsHelpPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: relatedHelpItems }) )), /* @__PURE__ */ React.createElement("aside", { className: "hidden xl:block xl:sticky xl:top-24 xl:self-start" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4 rounded-[28px] border border-white/10 bg-white/[0.03] p-5 shadow-[0_18px_50px_rgba(2,6,23,0.22)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Quick route map"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, /* @__PURE__ */ React.createElement("a", { href: links.create_world, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Create a World"), /* @__PURE__ */ React.createElement("a", { href: links.studio_worlds, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Open Worlds workspace"), /* @__PURE__ */ React.createElement("a", { href: links.worlds_index, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Browse public Worlds"), /* @__PURE__ */ React.createElement("a", { href: links.studio_help, className: "block rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm font-semibold text-white transition hover:border-white/20 hover:bg-white/[0.05]" }, "Read Studio help"))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-sky-300/20 bg-sky-400/10 p-4 text-sky-50" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100/80" }, "Fast reminder"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-sky-50/85" }, "A World should feel like an editorial decision, not a container. If the page feels cluttered, the usual fix is stronger curation, fewer modules, and clearer promotion intent."))))))); } -const __vite_glob_0_90 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_91 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldsHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -90263,7 +90597,7 @@ function LeaderboardPage() { const items = Array.isArray(data?.items) ? data.items : []; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SeoHead, { seo, title: seo?.title || "Leaderboard — Skinbase", description: seo?.description || "Top creators, groups, artworks, stories, and Worlds on Skinbase." }), /* @__PURE__ */ React.createElement("div", { className: "min-h-screen bg-[radial-gradient(circle_at_top,rgba(14,165,233,0.14),transparent_34%),linear-gradient(180deg,#020617_0%,#0f172a_48%,#020617_100%)] pb-16 text-slate-100" }, /* @__PURE__ */ React.createElement("div", { className: "mx-auto w-full max-w-7xl px-4 py-8 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("header", { className: "rounded-[2rem] border border-white/10 bg-slate-950/70 px-6 py-8 shadow-[0_35px_120px_rgba(2,6,23,0.75)] backdrop-blur" }, /* @__PURE__ */ React.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.28em] text-sky-300" }, "Skinbase Competition Board"), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 max-w-3xl text-4xl font-black tracking-tight text-white sm:text-5xl" }, "Top creators, groups, standout artworks, stories, and Worlds with momentum."), /* @__PURE__ */ React.createElement("p", { className: "mt-4 max-w-2xl text-sm leading-6 text-slate-300 sm:text-base" }, "Switch between creators, groups, artworks, stories, and Worlds, then filter by daily, weekly, monthly, or all-time performance.")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-4" }, /* @__PURE__ */ React.createElement(LeaderboardTabs, { items: TYPE_TABS, active: type2, onChange: setType, sticky: true, label: "Leaderboard type" }), /* @__PURE__ */ React.createElement(LeaderboardTabs, { items: PERIOD_TABS, active: period, onChange: setPeriod, label: "Leaderboard period" })), loading ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-3xl border border-white/10 bg-white/[0.03] px-6 py-5 text-sm text-slate-400" }, "Refreshing leaderboard...") : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8" }, /* @__PURE__ */ React.createElement(LeaderboardList, { items, type: type2 }))))); } -const __vite_glob_0_91 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_92 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: LeaderboardPage }, Symbol.toStringTag, { value: "Module" })); @@ -92201,7 +92535,7 @@ if (typeof document !== "undefined") { ); } } -const __vite_glob_0_92 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_93 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: MessagesPage }, Symbol.toStringTag, { value: "Module" })); @@ -92368,7 +92702,7 @@ function ArtworkMaturityQueue() { } )); } -const __vite_glob_0_94 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_95 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ArtworkMaturityQueue }, Symbol.toStringTag, { value: "Module" })); @@ -92389,7 +92723,7 @@ function ModerationEnhanceIndex() { } return /* @__PURE__ */ React.createElement("div", { className: "w-full px-6 pb-16 pt-8" }, /* @__PURE__ */ React.createElement(Se$1, { title: "Enhance Jobs" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.16),transparent_36%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/80" }, "Moderation surface"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "Enhance Jobs"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-relaxed text-slate-300" }, "Review queued, processing, failed, and completed image upscale jobs without changing original artwork assets.")), /* @__PURE__ */ React.createElement("form", { onSubmit: applyFilters, className: "mt-6 grid gap-3 md:grid-cols-2 xl:grid-cols-7" }, /* @__PURE__ */ React.createElement("select", { value: filters.status || "all", onChange: (event) => setFilters((current) => ({ ...current, status: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }, (props.options?.statuses || []).map((option) => /* @__PURE__ */ React.createElement("option", { key: option, value: option }, option === "all" ? "All statuses" : option))), /* @__PURE__ */ React.createElement("select", { value: filters.engine || "all", onChange: (event) => setFilters((current) => ({ ...current, engine: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }, (props.options?.engines || []).map((option) => /* @__PURE__ */ React.createElement("option", { key: option, value: option }, option === "all" ? "All engines" : option))), /* @__PURE__ */ React.createElement("select", { value: filters.mode || "all", onChange: (event) => setFilters((current) => ({ ...current, mode: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }, (props.options?.modes || []).map((option) => /* @__PURE__ */ React.createElement("option", { key: option, value: option }, option === "all" ? "All modes" : option))), /* @__PURE__ */ React.createElement("select", { value: filters.scale || "all", onChange: (event) => setFilters((current) => ({ ...current, scale: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }, (props.options?.scales || []).map((option) => /* @__PURE__ */ React.createElement("option", { key: String(option), value: option }, option === "all" ? "All scales" : `${option}x`))), /* @__PURE__ */ React.createElement("input", { value: filters.user || "", onChange: (event) => setFilters((current) => ({ ...current, user: event.target.value })), placeholder: "User name or username", className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { type: "date", value: filters.date_from || "", onChange: (event) => setFilters((current) => ({ ...current, date_from: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { type: "date", value: filters.date_to || "", onChange: (event) => setFilters((current) => ({ ...current, date_to: event.target.value })), className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-2xl border border-white/10 bg-white/[0.06] px-5 py-3 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.1] xl:col-span-7" }, "Apply filters"))), /* @__PURE__ */ React.createElement(EnhanceStubWarning, { config: props.enhanceConfig, moderation: true, className: "mt-6" }), flash.success ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, flash.success) : null, flash.error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, flash.error) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8 overflow-hidden rounded-[28px] border border-white/10 bg-[#08111d] shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React.createElement("table", { className: "w-full text-sm" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", { className: "border-b border-white/[0.07] text-left text-xs font-semibold uppercase tracking-wider text-slate-500" }, /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Preview"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Job"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "User"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Artwork"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Status"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Mode"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Scale"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Dimensions"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5" }, "Created"), /* @__PURE__ */ React.createElement("th", { className: "px-5 py-3.5 text-right" }, "Actions"))), /* @__PURE__ */ React.createElement("tbody", { className: "divide-y divide-white/[0.04]" }, jobs.length === 0 ? /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", { colSpan: 10, className: "px-5 py-12 text-center text-slate-400" }, "No enhance jobs match the current filters.")) : null, jobs.map((job) => /* @__PURE__ */ React.createElement("tr", { key: job.id, className: "transition hover:bg-white/[0.025]" }, /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "h-16 w-16 overflow-hidden rounded-xl border border-white/10 bg-black/20" }, job.preview_url || job.source_url ? /* @__PURE__ */ React.createElement("img", { src: job.preview_url || job.source_url, alt: `Enhance job ${job.id}`, className: "h-full w-full object-cover" }) : null)), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-white" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, "#", job.id), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, job.engine)), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-300" }, job.user?.name || "—", job.user?.username ? /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, "@", job.user.username) : null), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-300" }, job.artwork?.title ? /* @__PURE__ */ React.createElement("a", { href: job.artwork.url, className: "text-sky-300 hover:text-sky-200" }, job.artwork.title) : "—"), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4" }, /* @__PURE__ */ React.createElement(EnhanceStatusBadge, { status: job.status })), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-300" }, job.mode), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-300" }, job.scale, "x"), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-300" }, job.input_width, " × ", job.input_height, job.output_width && job.output_height ? /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, "→ ", job.output_width, " × ", job.output_height) : null), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-slate-400" }, formatDate$c(job.created_at)), /* @__PURE__ */ React.createElement("td", { className: "px-5 py-4 text-right" }, /* @__PURE__ */ React.createElement(xe, { href: job.show_url, className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Open"))))))))); } -const __vite_glob_0_95 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_96 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ModerationEnhanceIndex }, Symbol.toStringTag, { value: "Module" })); @@ -92409,7 +92743,7 @@ function ModerationEnhanceShow() { At.delete(job.delete_url); }, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-5 py-3 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Delete")))), /* @__PURE__ */ React.createElement(EnhanceStubWarning, { config: props.enhanceConfig, moderation: true, className: "mt-6" }), flash.success ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, flash.success) : null, flash.error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, flash.error) : null, errors.job ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, errors.job) : null, job.source_url && job.output_url ? /* @__PURE__ */ React.createElement("div", { className: "mt-8" }, /* @__PURE__ */ React.createElement(BeforeAfterSlider, { beforeUrl: job.source_url, afterUrl: job.output_url })) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8 grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_380px]" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 lg:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-3 text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Source image"), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20" }, job.source_url ? /* @__PURE__ */ React.createElement("img", { src: job.source_url, alt: "Enhance source", className: "w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex min-h-[280px] items-center justify-center text-white/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image text-4xl" })))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mb-3 text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Output image"), /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20" }, job.output_url ? /* @__PURE__ */ React.createElement("img", { src: job.output_url, alt: "Enhance output", className: "w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex min-h-[280px] items-center justify-center text-white/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-hourglass-half text-4xl" })))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Metadata"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("pre", { className: "overflow-x-auto whitespace-pre-wrap break-words" }, JSON.stringify(job.metadata || {}, null, 2)))), job.error_message ? /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-rose-300/20 bg-rose-400/10 p-6 text-sm text-rose-100 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, job.error_message) : null), /* @__PURE__ */ React.createElement("aside", { className: "rounded-[30px] border border-white/10 bg-[#08111d] p-6 shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400" }, "Processing details"), /* @__PURE__ */ React.createElement("dl", { className: "mt-4" }, /* @__PURE__ */ React.createElement(DetailRow, { label: "Created", value: formatDate$b(job.created_at) }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Queued", value: formatDate$b(job.queued_at) }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Started", value: formatDate$b(job.started_at) }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Finished", value: formatDate$b(job.finished_at) }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Expires", value: formatDate$b(job.expires_at) }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Input mime", value: job.input_mime || "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Input size", value: job.input_filesize ? `${(job.input_filesize / 1024 / 1024).toFixed(2)} MB` : "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Input dimensions", value: job.input_width && job.input_height ? `${job.input_width} × ${job.input_height}` : "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Output mime", value: job.output_mime || "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Output size", value: job.output_filesize ? `${(job.output_filesize / 1024 / 1024).toFixed(2)} MB` : "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Output dimensions", value: job.output_width && job.output_height ? `${job.output_width} × ${job.output_height}` : "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Processing seconds", value: job.processing_seconds ?? "—" }), /* @__PURE__ */ React.createElement(DetailRow, { label: "Artwork", value: job.artwork?.title ? /* @__PURE__ */ React.createElement("a", { href: job.artwork.url, className: "text-sky-300 hover:text-sky-200" }, job.artwork.title) : "Standalone upload" }))))); } -const __vite_glob_0_96 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_97 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ModerationEnhanceShow }, Symbol.toStringTag, { value: "Module" })); @@ -92544,7 +92878,7 @@ function WorldWebStoriesIndex() { } ), /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: generator.force, onChange: (event) => setGenerator((current) => ({ ...current, force: event.target.checked })) }), "Force"), /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2 rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: generator.publish, onChange: (event) => setGenerator((current) => ({ ...current, publish: event.target.checked })) }), "Publish"), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: busyKey === "generate", className: "rounded-2xl border border-sky-300/20 bg-sky-400/12 px-5 py-3 text-xs font-semibold uppercase tracking-[0.14em] text-sky-50 transition hover:bg-sky-400/20 disabled:opacity-60" }, "Generate")))), notice ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, notice) : null, error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, error) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-8 grid gap-4 xl:grid-cols-2" }, (stories.data || []).map((story) => /* @__PURE__ */ React.createElement("article", { key: story.id, className: "overflow-hidden rounded-[28px] border border-white/10 bg-[#08111d] shadow-[0_18px_48px_rgba(2,6,23,0.2)]" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-[180px_1fr]" }, /* @__PURE__ */ React.createElement("div", { className: "aspect-[3/4] bg-black/30" }, story.poster_portrait_url ? /* @__PURE__ */ React.createElement("img", { src: story.poster_portrait_url, alt: story.title, className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center text-white/20" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-book-open-reader text-4xl" }))), /* @__PURE__ */ React.createElement("div", { className: "p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement(StatusBadge, { story }), !story.active ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex rounded-full border border-amber-300/20 bg-amber-400/12 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-amber-100" }, "inactive") : null, story.noindex ? /* @__PURE__ */ React.createElement("span", { className: "inline-flex rounded-full border border-rose-300/20 bg-rose-400/12 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-rose-100" }, "noindex") : null), /* @__PURE__ */ React.createElement("h2", { className: "mt-3 text-2xl font-semibold tracking-[-0.03em] text-white" }, story.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-300" }, "/", story.slug, story.world ? ` • ${story.world.title}` : ""), story.excerpt ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, story.excerpt) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2 text-xs uppercase tracking-[0.16em] text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, story.page_count, " pages"), story.published_at ? /* @__PURE__ */ React.createElement("span", null, new Date(story.published_at).toLocaleDateString()) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement(xe, { href: replacePattern$1(endpoints.editPattern, story.id), className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Edit"), /* @__PURE__ */ React.createElement("a", { href: story.public_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Open"), story.status === "published" ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => performAction(`unpublish-${story.id}`, replacePattern$1(endpoints.unpublishPattern, story.id)), className: "inline-flex items-center gap-2 rounded-full border border-amber-300/20 bg-amber-400/12 px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-amber-100 transition hover:bg-amber-400/18" }, "Unpublish") : /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => performAction(`publish-${story.id}`, replacePattern$1(endpoints.publishPattern, story.id)), className: "inline-flex items-center gap-2 rounded-full border border-emerald-300/20 bg-emerald-400/12 px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-emerald-100 transition hover:bg-emerald-400/18" }, "Publish"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => performAction(`delete-${story.id}`, replacePattern$1(endpoints.destroyPattern, story.id), "DELETE"), className: "inline-flex items-center gap-2 rounded-full border border-rose-300/20 bg-rose-400/12 px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-rose-100 transition hover:bg-rose-400/18" }, "Delete")))))))); } -const __vite_glob_0_97 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_98 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldWebStoriesIndex }, Symbol.toStringTag, { value: "Module" })); @@ -92766,7 +93100,7 @@ function WorldWebStoryEditor() { } return /* @__PURE__ */ React.createElement("div", { className: "w-full pb-16 pt-8" }, /* @__PURE__ */ React.createElement(Se$1, { title: isNew ? "New World Web Story" : `Edit ${story.title}` }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/80" }, "Moderation surface"), /* @__PURE__ */ React.createElement("h1", { className: "mt-2 text-3xl font-semibold tracking-[-0.04em] text-white" }, isNew ? "Create World Web Story" : story.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-relaxed text-slate-300" }, "Build a standalone AMP story companion for a Skinbase World without changing the canonical World route.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement(xe, { href: endpoints.index, className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Back"), !isNew && story.public_url ? /* @__PURE__ */ React.createElement("a", { href: story.public_url, className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Open story") : null, !isNew ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => performStoryAction(endpoints.publish), className: "rounded-full border border-emerald-300/20 bg-emerald-400/12 px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-emerald-100 transition hover:bg-emerald-400/18" }, "Publish") : null, !isNew ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => performStoryAction(endpoints.unpublish), className: "rounded-full border border-amber-300/20 bg-amber-400/12 px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-amber-100 transition hover:bg-amber-400/18" }, "Unpublish") : null)), notice ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50" }, notice) : null, error ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, error) : null, /* @__PURE__ */ React.createElement("form", { onSubmit: submit, className: "mt-6 rounded-[32px] border border-white/10 bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement(Field, { label: "Related World" }, /* @__PURE__ */ React.createElement("select", { value: form.data.world_id, onChange: (event) => form.setData("world_id", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" }, /* @__PURE__ */ React.createElement("option", { value: "" }, "No related World"), worldOptions.map((world) => /* @__PURE__ */ React.createElement("option", { key: world.value, value: world.value }, world.label)))), /* @__PURE__ */ React.createElement(Field, { label: "Slug" }, /* @__PURE__ */ React.createElement("input", { value: form.data.slug, onChange: (event) => form.setData("slug", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Title" }, /* @__PURE__ */ React.createElement("input", { value: form.data.title, onChange: (event) => form.setData("title", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Subtitle" }, /* @__PURE__ */ React.createElement("input", { value: form.data.subtitle, onChange: (event) => form.setData("subtitle", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Excerpt" }, /* @__PURE__ */ React.createElement("textarea", { value: form.data.excerpt, onChange: (event) => form.setData("excerpt", event.target.value), rows: 3, className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Description" }, /* @__PURE__ */ React.createElement("textarea", { value: form.data.description, onChange: (event) => form.setData("description", event.target.value), rows: 3, className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "SEO title" }, /* @__PURE__ */ React.createElement("input", { value: form.data.seo_title, onChange: (event) => form.setData("seo_title", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "SEO description" }, /* @__PURE__ */ React.createElement("textarea", { value: form.data.seo_description, onChange: (event) => form.setData("seo_description", event.target.value), rows: 3, className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Poster portrait path" }, /* @__PURE__ */ React.createElement("input", { value: form.data.poster_portrait_path, onChange: (event) => form.setData("poster_portrait_path", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Poster square path" }, /* @__PURE__ */ React.createElement("input", { value: form.data.poster_square_path, onChange: (event) => form.setData("poster_square_path", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Publisher logo path" }, /* @__PURE__ */ React.createElement("input", { value: form.data.publisher_logo_path, onChange: (event) => form.setData("publisher_logo_path", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Status" }, /* @__PURE__ */ React.createElement("select", { value: form.data.status, onChange: (event) => form.setData("status", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" }, ["draft", "published", "archived"].map((value) => /* @__PURE__ */ React.createElement("option", { key: value, value }, value)))), /* @__PURE__ */ React.createElement(Field, { label: "Starts at" }, /* @__PURE__ */ React.createElement("input", { type: "datetime-local", value: form.data.starts_at ? form.data.starts_at.slice(0, 16) : "", onChange: (event) => form.setData("starts_at", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Ends at" }, /* @__PURE__ */ React.createElement("input", { type: "datetime-local", value: form.data.ends_at ? form.data.ends_at.slice(0, 16) : "", onChange: (event) => form.setData("ends_at", event.target.value), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" }))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-4" }, /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: Boolean(form.data.featured), onChange: (event) => form.setData("featured", event.target.checked) }), " Featured"), /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: Boolean(form.data.active), onChange: (event) => form.setData("active", event.target.checked) }), " Active"), /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: Boolean(form.data.noindex), onChange: (event) => form.setData("noindex", event.target.checked) }), " Noindex")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "rounded-full border border-sky-300/20 bg-sky-400/12 px-5 py-2.5 text-xs font-semibold uppercase tracking-[0.14em] text-sky-50 transition hover:bg-sky-400/20 disabled:opacity-60" }, "Save story"), !isNew ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: generateFromWorld, className: "rounded-full border border-white/10 bg-white/[0.05] px-5 py-2.5 text-xs font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Regenerate from World") : null)), !isNew ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.03em] text-white" }, "Validation"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-300" }, "Publish only when poster, logo, page count, alt text, and CTA rules are satisfied.")), /* @__PURE__ */ React.createElement("div", { className: `rounded-full border px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] ${story.validation?.valid ? "border-emerald-300/20 bg-emerald-400/12 text-emerald-100" : "border-amber-300/20 bg-amber-400/12 text-amber-100"}` }, story.validation?.valid ? "Ready to publish" : "Needs fixes")), (story.validation?.errors || []).length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-amber-300/20 bg-amber-400/10 px-4 py-4 text-sm text-amber-50" }, /* @__PURE__ */ React.createElement("ul", { className: "space-y-2" }, (story.validation.errors || []).map((item) => /* @__PURE__ */ React.createElement("li", { key: item }, item)))) : null), /* @__PURE__ */ React.createElement("section", { className: "mt-8 rounded-[32px] border border-white/10 bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.03em] text-white" }, "Story pages"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-300" }, "Keep each page short, visual, and clearly tied back to the World narrative."))), /* @__PURE__ */ React.createElement("form", { onSubmit: createPage, className: "mt-6 grid gap-3 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement(Field, { label: "New page headline" }, /* @__PURE__ */ React.createElement("input", { value: newPage.headline, onChange: (event) => setNewPage((current) => ({ ...current, headline: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "New page caption" }, /* @__PURE__ */ React.createElement("input", { value: newPage.caption, onChange: (event) => setNewPage((current) => ({ ...current, caption: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "New page body" }, /* @__PURE__ */ React.createElement("textarea", { value: newPage.body, onChange: (event) => setNewPage((current) => ({ ...current, body: event.target.value })), rows: 3, className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Alt text" }, /* @__PURE__ */ React.createElement("input", { value: newPage.alt_text, onChange: (event) => setNewPage((current) => ({ ...current, alt_text: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Layout" }, /* @__PURE__ */ React.createElement("select", { value: newPage.layout, onChange: (event) => setNewPage((current) => ({ ...current, layout: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" }, ["cover", "artwork", "creator", "mood", "collection", "cta"].map((value) => /* @__PURE__ */ React.createElement("option", { key: value, value }, value)))), /* @__PURE__ */ React.createElement(Field, { label: "Background type" }, /* @__PURE__ */ React.createElement("select", { value: newPage.background_type, onChange: (event) => setNewPage((current) => ({ ...current, background_type: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" }, ["image", "video", "gradient"].map((value) => /* @__PURE__ */ React.createElement("option", { key: value, value }, value)))), /* @__PURE__ */ React.createElement(Field, { label: "Background path" }, /* @__PURE__ */ React.createElement("input", { value: newPage.background_path, onChange: (event) => setNewPage((current) => ({ ...current, background_path: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement(Field, { label: "Mobile background path" }, /* @__PURE__ */ React.createElement("input", { value: newPage.background_mobile_path, onChange: (event) => setNewPage((current) => ({ ...current, background_mobile_path: event.target.value })), className: "w-full rounded-xl border border-white/10 bg-slate-950/70 px-3 py-2 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "xl:col-span-2 flex justify-end" }, /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-sky-300/20 bg-sky-400/12 px-5 py-2.5 text-xs font-semibold uppercase tracking-[0.14em] text-sky-50 transition hover:bg-sky-400/20" }, "Add page"))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-4" }, pages2.sort((left, right) => left.position - right.position).map((page) => /* @__PURE__ */ React.createElement("div", { key: page.id }, /* @__PURE__ */ React.createElement("div", { className: "mb-2 flex justify-end gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => reorder(page.id, -1), className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Move up"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => reorder(page.id, 1), className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-white/[0.09]" }, "Move down")), /* @__PURE__ */ React.createElement(StoryPageCard, { page, endpoints, onChanged: reloadEditor })))))) : null); } -const __vite_glob_0_98 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_99 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldWebStoryEditor }, Symbol.toStringTag, { value: "Module" })); @@ -93187,7 +93521,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(NewsComments, { ...props })); } } -const __vite_glob_0_99 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_100 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NewsComments }, Symbol.toStringTag, { value: "Module" })); @@ -93274,7 +93608,7 @@ if (typeof document !== "undefined") { document.addEventListener("keydown", handleKeyDown); } const NewsImagePreview = null; -const __vite_glob_0_100 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_101 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NewsImagePreview }, Symbol.toStringTag, { value: "Module" })); @@ -94238,7 +94572,7 @@ function ProfileGallery() { } )))); } -const __vite_glob_0_101 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_102 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ProfileGallery }, Symbol.toStringTag, { value: "Module" })); @@ -97088,7 +97422,7 @@ function ProfileShow() { } )))); } -const __vite_glob_0_102 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_103 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ProfileShow }, Symbol.toStringTag, { value: "Module" })); @@ -98516,7 +98850,7 @@ function ProfileEdit() { ) ); } -const __vite_glob_0_103 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_104 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ProfileEdit }, Symbol.toStringTag, { value: "Module" })); @@ -99029,7 +99363,7 @@ function StudioActivity() { /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "New since last read"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.new_items || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Unread notifications"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.unread_notifications || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Last inbox reset"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-base font-semibold text-white" }, summary.last_read_at ? formatDate$7(summary.last_read_at) : "Not yet"))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.14),_transparent_35%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 lg:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Search activity"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilters({ q: event.target.value }), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white", placeholder: "Message, actor, or module" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Type"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.type || "all", onChange: (val) => updateFilters({ type: val }), options: typeOptions, searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Content type"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.module || "all", onChange: (val) => updateFilters({ module: val }), options: moduleOptions, searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "flex items-end" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => updateFilters({ q: "", type: "all", module: "all" }), className: "w-full rounded-2xl border border-white/10 px-4 py-3 text-sm text-slate-200" }, "Reset")))), /* @__PURE__ */ React.createElement("section", { className: "space-y-4" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: `rounded-[28px] border p-5 ${item.is_new ? "border-sky-300/25 bg-sky-300/10" : "border-white/10 bg-white/[0.03]"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4" }, item.actor?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: item.actor.avatar_url, alt: item.actor.name || "Activity actor", className: "h-12 w-12 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 items-center justify-center rounded-2xl bg-black/20 text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-bell" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, /* @__PURE__ */ React.createElement("span", null, item.module_label), /* @__PURE__ */ React.createElement("span", null, formatDate$7(item.created_at)), item.is_new && /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-sky-300/20 px-2 py-1 text-sky-100" }, "New")), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-lg font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, item.body), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap items-center gap-3 text-sm text-slate-400" }, item.actor?.name && /* @__PURE__ */ React.createElement("span", null, item.actor.name), /* @__PURE__ */ React.createElement("a", { href: item.url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-1.5 text-slate-200" }, "Open")))))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/15 px-6 py-16 text-center text-slate-400" }, "No activity matches this filter.")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) <= 1, onClick: () => updateFilters({ page: Math.max(1, (meta.current_page || 1) - 1) }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Previous"), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Page ", meta.current_page || 1, " of ", meta.last_page || 1), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) >= (meta.last_page || 1), onClick: () => updateFilters({ page: (meta.current_page || 1) + 1 }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Next"))) ); } -const __vite_glob_0_104 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_105 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioActivity }, Symbol.toStringTag, { value: "Module" })); @@ -99120,7 +99454,7 @@ function StudioAnalytics() { return /* @__PURE__ */ React.createElement("div", { key: item.key, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-slate-200" }, /* @__PURE__ */ React.createElement("i", { className: item.icon }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, item.label), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-400" }, Number(item.published_count || 0).toLocaleString(), " published"))), /* @__PURE__ */ React.createElement("a", { href: moduleBreakdown?.find((entry) => entry.key === item.key)?.index_url, className: "text-xs font-semibold uppercase tracking-[0.18em] text-sky-100" }, "Open")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, "Views"), /* @__PURE__ */ React.createElement("span", null, Number(item.views || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "mt-2 h-2 overflow-hidden rounded-full bg-white/5" }, /* @__PURE__ */ React.createElement("div", { className: "h-full rounded-full bg-emerald-400/60", style: { width: `${Math.max(4, Math.round(Number(item.views || 0) / viewMax * 100))}%` } }))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, "Engagement"), /* @__PURE__ */ React.createElement("span", null, Number(item.engagement || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "mt-2 h-2 overflow-hidden rounded-full bg-white/5" }, /* @__PURE__ */ React.createElement("div", { className: "h-full rounded-full bg-pink-400/60", style: { width: `${Math.max(4, Math.round(Number(item.engagement || 0) / engagementMax * 100))}%` } }))))); }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Readable insights"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3 text-sm text-slate-400" }, (insightBlocks || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.key, href: item.href, className: "block rounded-[22px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-white/[0.04] text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: item.icon })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 leading-6 text-slate-400" }, item.body), /* @__PURE__ */ React.createElement("span", { className: "mt-3 inline-flex items-center gap-2 text-sm font-medium text-sky-100" }, item.cta, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }))))))))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Top content"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 overflow-x-auto" }, /* @__PURE__ */ React.createElement("table", { className: "w-full text-sm" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", { className: "border-b border-white/5 text-left text-[11px] uppercase tracking-[0.18em] text-slate-500" }, /* @__PURE__ */ React.createElement("th", { className: "pb-3 pr-4" }, "Module"), /* @__PURE__ */ React.createElement("th", { className: "pb-3 pr-4" }, "Title"), /* @__PURE__ */ React.createElement("th", { className: "pb-3 pr-4 text-right" }, "Views"), /* @__PURE__ */ React.createElement("th", { className: "pb-3 pr-4 text-right" }, "Reactions"), /* @__PURE__ */ React.createElement("th", { className: "pb-3 pr-4 text-right" }, "Comments"), /* @__PURE__ */ React.createElement("th", { className: "pb-3 text-right" }, "Open"))), /* @__PURE__ */ React.createElement("tbody", { className: "divide-y divide-white/5" }, (topContent || []).map((item) => /* @__PURE__ */ React.createElement("tr", { key: item.id }, /* @__PURE__ */ React.createElement("td", { className: "py-3 pr-4 text-slate-300" }, item.module_label), /* @__PURE__ */ React.createElement("td", { className: "py-3 pr-4 text-white" }, item.title), /* @__PURE__ */ React.createElement("td", { className: "py-3 pr-4 text-right text-slate-300" }, Number(item.metrics?.views || 0).toLocaleString()), /* @__PURE__ */ React.createElement("td", { className: "py-3 pr-4 text-right text-slate-300" }, Number(item.metrics?.appreciation || 0).toLocaleString()), /* @__PURE__ */ React.createElement("td", { className: "py-3 pr-4 text-right text-slate-300" }, Number(item.metrics?.comments || 0).toLocaleString()), /* @__PURE__ */ React.createElement("td", { className: "py-3 text-right" }, /* @__PURE__ */ React.createElement("a", { href: item.analytics_url || item.view_url, className: "text-sky-100" }, "Open")))))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Recent comments"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (recentComments || []).map((comment) => /* @__PURE__ */ React.createElement("article", { key: comment.id, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/70" }, comment.module_label), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-white" }, comment.author_name, " on ", comment.item_title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, comment.body))))))); } -const __vite_glob_0_105 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_106 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -99965,7 +100299,7 @@ function StudioArchived() { } )); } -const __vite_glob_0_106 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_107 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArchived }, Symbol.toStringTag, { value: "Module" })); @@ -100001,7 +100335,7 @@ function StudioArtworkAnalytics() { } ), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-bold text-white" }, artwork?.title), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500 mt-1" }, "/", artwork?.slug))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4 mb-8" }, kpiItems$1.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.key, className: "bg-nova-900/60 border border-white/10 rounded-2xl p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${item.icon} ${item.color}` }), /* @__PURE__ */ React.createElement("span", { className: "text-xs font-medium text-slate-400 uppercase tracking-wider" }, item.label)), /* @__PURE__ */ React.createElement("p", { className: "text-2xl font-bold text-white tabular-nums" }, (analytics?.[item.key] ?? 0).toLocaleString())))), /* @__PURE__ */ React.createElement("h3", { className: "text-base font-bold text-white mb-4" }, "Performance Metrics"), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8" }, metricCards.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.key, className: "bg-nova-900/60 border border-white/10 rounded-2xl p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 mb-3" }, /* @__PURE__ */ React.createElement("div", { className: `w-10 h-10 rounded-xl bg-white/5 flex items-center justify-center ${item.color}` }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${item.icon} text-lg` })), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-slate-300" }, item.label)), /* @__PURE__ */ React.createElement("p", { className: "text-3xl font-bold text-white tabular-nums" }, (analytics?.[item.key] ?? 0).toFixed(1))))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "bg-nova-900/40 border border-white/10 rounded-2xl p-6" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white mb-3" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-chart-line mr-2 text-slate-500" }), "Traffic Sources"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-center py-8" }, /* @__PURE__ */ React.createElement("div", { className: "text-center" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-chart-pie text-3xl text-slate-700 mb-3" }), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500" }, "Coming soon"), /* @__PURE__ */ React.createElement("p", { className: "text-[10px] text-slate-600 mt-1" }, "Traffic source tracking is on the roadmap")))), /* @__PURE__ */ React.createElement("div", { className: "bg-nova-900/40 border border-white/10 rounded-2xl p-6" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white mb-3" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-share-from-square mr-2 text-slate-500" }), "Shares by Platform"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-center py-8" }, /* @__PURE__ */ React.createElement("div", { className: "text-center" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-share-nodes text-3xl text-slate-700 mb-3" }), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500" }, "Coming soon"), /* @__PURE__ */ React.createElement("p", { className: "text-[10px] text-slate-600 mt-1" }, "Per-platform breakdown coming in a future update")))), /* @__PURE__ */ React.createElement("div", { className: "bg-nova-900/40 border border-white/10 rounded-2xl p-6 lg:col-span-2" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white mb-3" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-trophy mr-2 text-slate-500" }), "Ranking History"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-center py-8" }, /* @__PURE__ */ React.createElement("div", { className: "text-center" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-chart-area text-3xl text-slate-700 mb-3" }), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-slate-500" }, "Coming soon"), /* @__PURE__ */ React.createElement("p", { className: "text-[10px] text-slate-600 mt-1" }, "Historical ranking data will be tracked in a future update")))))); } -const __vite_glob_0_107 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_108 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArtworkAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -102778,7 +103112,7 @@ function StudioArtworkEdit() { )), historyData.versions.length === 0 && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500 text-center py-8" }, "No version history yet.")) )); } -const __vite_glob_0_108 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_109 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArtworkEdit }, Symbol.toStringTag, { value: "Module" })); @@ -102799,7 +103133,7 @@ function StudioArtworks() { } )); } -const __vite_glob_0_109 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_110 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -102925,7 +103259,7 @@ function StudioAssets() { /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }) )))); } -const __vite_glob_0_110 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_111 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioAssets }, Symbol.toStringTag, { value: "Module" })); @@ -103097,7 +103431,7 @@ function StudioCalendar() { }, [selectedDay]); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Scheduled"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.scheduled_total || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Unscheduled"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.unscheduled_total || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Overloaded days"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.overloaded_days || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Next publish"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-base font-semibold text-white" }, formatReleaseCountdown(summary.next_publish_at, nowMs)), summary.next_publish_at && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, formatScheduledDate(summary.next_publish_at)))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.14),_transparent_35%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 lg:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-5" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 xl:col-span-2" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Search planning queue"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilters({ q: event.target.value }), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white", placeholder: "Title or module" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "View"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.view || "month", onChange: (val) => updateFilters({ view: val }), options: calendar.view_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Module"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.module || "all", onChange: (val) => updateFilters({ module: val }), options: calendar.module_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Queue"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.status || "scheduled", onChange: (val) => updateFilters({ status: val }), options: calendar.status_options || [], searchable: false })))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_340px]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, filters.view === "week" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, calendar.week?.label), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, "Week planning")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => shiftCalendar(-1), className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Prev week"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: resetCalendarFocus, className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Today"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => shiftCalendar(1), className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Next week"))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-7" }, (calendar.week?.days || []).map((day) => /* @__PURE__ */ React.createElement("div", { key: day.date, className: "rounded-[22px] border border-white/10 bg-black/20 p-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, day.label), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, day.items.length > 0 ? day.items.map((item) => /* @__PURE__ */ React.createElement(CalendarInlineItem, { key: item.id, item })) : /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, "No scheduled items")))))) : filters.view === "agenda" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Agenda"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-4" }, (calendar.agenda || []).map((group) => /* @__PURE__ */ React.createElement("div", { key: group.date, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-base font-semibold text-white" }, group.label), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, group.count, " items")), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, group.items.map((item) => /* @__PURE__ */ React.createElement(CalendarInlineItem, { key: item.id, item }))))))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, calendar.month?.label), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, "Month planning")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => shiftCalendar(-1), className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Prev month"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: resetCalendarFocus, className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Today"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => shiftCalendar(1), className: "rounded-full border border-white/10 px-3 py-1.5 text-sm text-slate-200 transition hover:border-sky-300/20 hover:bg-sky-300/10 hover:text-sky-100" }, "Next month"))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid grid-cols-7 gap-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((label) => /* @__PURE__ */ React.createElement("div", { key: label, className: "px-2 py-1" }, label))), /* @__PURE__ */ React.createElement("div", { className: "mt-2 grid grid-cols-7 gap-2" }, (calendar.month?.days || []).map((day) => /* @__PURE__ */ React.createElement(CalendarMonthDay, { key: day.date, day, onOpenDetail: setSelectedDay }))))), /* @__PURE__ */ React.createElement("aside", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Coverage gaps"), /* @__PURE__ */ React.createElement("a", { href: "/studio/drafts", className: "text-sm font-medium text-sky-100" }, "Open drafts")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (calendar.gaps || []).length > 0 ? (calendar.gaps || []).map((gap) => /* @__PURE__ */ React.createElement("div", { key: gap.date, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-200" }, gap.label)) : /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/15 px-4 py-8 text-sm text-slate-500" }, "No empty days in the next two weeks."))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Unscheduled queue"), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, (calendar.unscheduled_items || []).length)), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (calendar.unscheduled_items || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.edit_url || item.manage_url, className: "block rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, item.module_label, " · ", item.workflow?.readiness?.label || "Needs review"))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Upcoming actions"), /* @__PURE__ */ React.createElement("a", { href: "/studio/scheduled", className: "text-sm font-medium text-sky-100" }, "Open list")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (calendar.scheduled_items || []).slice(0, 5).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs font-medium text-sky-200" }, formatReleaseCountdown(item.scheduled_at, nowMs)), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, formatScheduledDate(item.scheduled_at)), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", disabled: busyKey === `publish:${item.id}`, onClick: () => runAction(props.endpoints.publishNowPattern, item, "publish"), className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-3 py-1.5 text-xs text-sky-100 disabled:opacity-50" }, "Publish now"), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: busyKey === `unschedule:${item.id}`, onClick: () => runAction(props.endpoints.unschedulePattern, item, "unschedule"), className: "rounded-full border border-white/10 px-3 py-1.5 text-xs text-slate-200 disabled:opacity-50" }, "Unschedule")))))))), /* @__PURE__ */ React.createElement(CalendarDayModal, { day: selectedDay, busyKey, endpoints: props.endpoints, onAction: runAction, onClose: () => setSelectedDay(null), nowMs }))); } -const __vite_glob_0_111 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_112 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCalendar }, Symbol.toStringTag, { value: "Module" })); @@ -103119,7 +103453,7 @@ function StudioCardAnalytics() { const { card, analytics } = props; return /* @__PURE__ */ React.createElement(StudioLayout, { title: `Analytics: ${card?.title || "Nova Card"}` }, /* @__PURE__ */ React.createElement(xe, { href: "/studio/cards", className: "mb-6 inline-flex items-center gap-2 text-sm text-slate-400 transition-colors hover:text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left" }), "Back to Cards"), /* @__PURE__ */ React.createElement("div", { className: "mb-8 flex items-center gap-4 rounded-2xl border border-white/10 bg-nova-900/60 p-4" }, card?.preview_url ? /* @__PURE__ */ React.createElement("img", { src: card.preview_url, alt: card.title, className: "h-20 w-20 rounded-xl object-cover bg-nova-800" }) : null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-bold text-white" }, card?.title), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs text-slate-500" }, "/", card?.slug), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-xs uppercase tracking-[0.18em] text-slate-400" }, card?.status, " • ", card?.visibility))), /* @__PURE__ */ React.createElement("div", { className: "mb-8 grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-6" }, kpiItems.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.key, className: "rounded-2xl border border-white/10 bg-nova-900/60 p-5" }, /* @__PURE__ */ React.createElement("div", { className: "mb-2 flex items-center gap-2" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${item.icon} ${item.color}` }), /* @__PURE__ */ React.createElement("span", { className: "text-xs font-medium uppercase tracking-wider text-slate-400" }, item.label)), /* @__PURE__ */ React.createElement("p", { className: "text-2xl font-bold tabular-nums text-white" }, (analytics?.[item.key] ?? 0).toLocaleString())))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-nova-900/40 p-6" }, /* @__PURE__ */ React.createElement("h3", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.18em] text-slate-300" }, "Ranking signals"), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-400" }, "Trending score"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-bold tabular-nums text-white" }, Number(analytics?.trending_score ?? 0).toFixed(2))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-400" }, "Last engaged"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-white" }, analytics?.last_engaged_at || "No activity yet")))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-nova-900/40 p-6" }, /* @__PURE__ */ React.createElement("h3", { className: "mb-4 text-sm font-semibold uppercase tracking-[0.18em] text-slate-300" }, "Secondary metrics"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, secondaryItems.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.key, className: "flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${item.icon} text-slate-500` }), item.label), /* @__PURE__ */ React.createElement("div", { className: "text-base font-semibold tabular-nums text-white" }, (analytics?.[item.key] ?? 0).toLocaleString()))))))); } -const __vite_glob_0_112 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_113 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCardAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -104263,7 +104597,7 @@ function StudioCardEditor() { fmt2.label ))), exportStatus && /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex items-center gap-3 rounded-[18px] border border-white/10 bg-white/[0.03] p-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-xs font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Export status"), /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold capitalize text-white" }, exportStatus.status)), exportStatus.status === "ready" && exportStatus.output_url && /* @__PURE__ */ React.createElement("a", { href: exportStatus.output_url, download: true, className: "ml-auto rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-1.5 text-xs font-semibold text-emerald-200 transition hover:bg-emerald-400/15" }, "Download"))))), /* @__PURE__ */ React.createElement("nav", { className: "sticky bottom-0 z-20 mt-6 border-t border-white/10 bg-[rgba(2,6,23,0.92)] px-4 py-3 backdrop-blur xl:hidden" }, /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex max-w-7xl items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => goToNextTab(-1), disabled: tabIndex === 0, className: "rounded-2xl border border-white/10 bg-white/[0.05] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-white/[0.08] disabled:opacity-50" }, "Back"), /* @__PURE__ */ React.createElement("div", { className: "text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Step ", tabIndex + 1, " / ", editorTabs.length), /* @__PURE__ */ React.createElement("div", { className: "mt-0.5 text-sm font-semibold text-white" }, editorTabs[tabIndex]?.label)), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => goToNextTab(1), disabled: tabIndex >= editorTabs.length - 1, className: "rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-2.5 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-50" }, "Next")))); } -const __vite_glob_0_113 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_114 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCardEditor }, Symbol.toStringTag, { value: "Module" })); @@ -104285,7 +104619,7 @@ function StudioCardsIndex() { } ))); } -const __vite_glob_0_114 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_115 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCardsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -104358,7 +104692,7 @@ function StudioChallenges() { "Challenge" ), /* @__PURE__ */ React.createElement("a", { href: entry.card.edit_url, className: "text-slate-300" }, "Edit card"), /* @__PURE__ */ React.createElement("a", { href: entry.card.analytics_url, className: "text-slate-300" }, "Analytics")))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Cards with challenge traction"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (cardLeaders || []).map((card) => /* @__PURE__ */ React.createElement("div", { key: card.id, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, card.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, card.status, " • ", card.challenge_entries_count, " challenge entries")), /* @__PURE__ */ React.createElement("a", { href: card.edit_url, className: "text-xs font-semibold uppercase tracking-[0.16em] text-sky-100" }, "Open")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid grid-cols-2 gap-3 text-sm text-slate-400" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Views"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, Number(card.views_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Comments"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, Number(card.comments_count || 0).toLocaleString()))))))))); } -const __vite_glob_0_115 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_116 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioChallenges }, Symbol.toStringTag, { value: "Module" })); @@ -104378,7 +104712,7 @@ function StudioCollections() { } )); } -const __vite_glob_0_116 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_117 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCollections }, Symbol.toStringTag, { value: "Module" })); @@ -104665,7 +104999,7 @@ function StudioComments() { /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }) ))))); } -const __vite_glob_0_117 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_118 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioComments }, Symbol.toStringTag, { value: "Module" })); @@ -104681,7 +105015,7 @@ function StudioContentIndex() { } )); } -const __vite_glob_0_118 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_119 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioContentIndex }, Symbol.toStringTag, { value: "Module" })); @@ -104807,7 +105141,7 @@ function StudioDashboard() { ["Comments", analytics.totals?.comments] ].map(([label, value]) => /* @__PURE__ */ React.createElement("div", { key: label, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", null, label), /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, Number(value || 0).toLocaleString()))))))), showWidget("stale_drafts") && /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Stale drafts"), /* @__PURE__ */ React.createElement("a", { href: "/studio/content?bucket=drafts&stale=only&module=stories", className: "text-sm font-medium text-sky-100" }, "Filter stale work")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-4" }, (overview.stale_drafts || []).map((item) => /* @__PURE__ */ React.createElement(ContinueWorkingCard, { key: item.id, item }))))); } -const __vite_glob_0_119 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_120 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -104824,7 +105158,7 @@ function StudioDrafts() { } )); } -const __vite_glob_0_120 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_121 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioDrafts }, Symbol.toStringTag, { value: "Module" })); @@ -104907,7 +105241,7 @@ function StudioFeatured() { })) : /* @__PURE__ */ React.createElement("div", { className: "mt-5 rounded-[24px] border border-dashed border-white/15 px-6 py-10 text-center text-sm text-slate-400" }, "No published ", module.label.toLowerCase(), " candidates yet.")); }))); } -const __vite_glob_0_121 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_122 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioFeatured }, Symbol.toStringTag, { value: "Module" })); @@ -104933,7 +105267,7 @@ function StudioFollowers() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React.createElement(SummaryCard$1, { label: "Total followers", value: summary.total_followers, icon: "fa-solid fa-user-group" }), /* @__PURE__ */ React.createElement(SummaryCard$1, { label: "Following back", value: summary.following_back, icon: "fa-solid fa-arrows-rotate" }), /* @__PURE__ */ React.createElement(SummaryCard$1, { label: "Not followed yet", value: summary.not_followed, icon: "fa-solid fa-user-plus" })), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 lg:grid-cols-[minmax(0,1fr)_220px_220px]" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500" }, "Search"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateQuery({ q: event.target.value, page: 1 }), placeholder: "Search followers", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500" }, "Sort"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.sort || "recent", onChange: (val) => updateQuery({ sort: val, page: 1 }), options: listing.sort_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500" }, "Relationship"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.relationship || "all", onChange: (val) => updateQuery({ relationship: val, page: 1 }), options: listing.relationship_options || [], searchable: false }))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-3" }, items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: "flex flex-col gap-4 rounded-[24px] border border-white/10 bg-black/20 p-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React.createElement("a", { href: item.profile_url, className: "flex min-w-0 items-center gap-4" }, item.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: item.avatar_url, alt: item.username, className: "h-14 w-14 rounded-[18px] object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-14 w-14 items-center justify-center rounded-[18px] bg-white/5 text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-base font-semibold text-white" }, item.name), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "@", item.username))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 text-sm text-slate-400 md:grid-cols-4 md:text-right" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Uploads"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, Number(item.uploads_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Followers"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, Number(item.followers_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Followed"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, item.followed_at ? new Date(item.followed_at).toLocaleDateString() : "—")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Status"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, item.is_following_back ? "Following back" : "Not followed")))))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) <= 1, onClick: () => updateQuery({ page: Math.max(1, (meta.current_page || 1) - 1) }), className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-left" }), "Previous"), /* @__PURE__ */ React.createElement("span", null, "Page ", meta.current_page || 1, " of ", meta.last_page || 1), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) >= (meta.last_page || 1), onClick: () => updateQuery({ page: (meta.current_page || 1) + 1 }), className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Next", /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }))))); } -const __vite_glob_0_122 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_123 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioFollowers }, Symbol.toStringTag, { value: "Module" })); @@ -104942,7 +105276,7 @@ function StudioGroupActivity() { const items = Array.isArray(props.activity) ? props.activity : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("h2", { className: "text-base font-semibold text-white" }, item.headline), item.is_pinned ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-300/10 px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-amber-100" }, "Pinned") : null, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, item.visibility)), item.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, item.summary) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-xs text-slate-500" }, item.actor?.name || item.actor?.username || "System", " • ", item.occurred_at ? new Date(item.occurred_at).toLocaleString() : "Recently"), item.subject?.url ? /* @__PURE__ */ React.createElement("a", { href: item.subject.url, className: "mt-3 inline-flex text-sm font-semibold text-sky-200" }, "Open subject") : null), props.pinPattern ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.pinPattern.replace("__ITEM__", String(item.id)), { is_pinned: !item.is_pinned }), className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-sm font-semibold text-white" }, item.is_pinned ? "Unpin" : "Pin") : null))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No activity yet."))); } -const __vite_glob_0_123 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_124 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupActivity }, Symbol.toStringTag, { value: "Module" })); @@ -104950,7 +105284,7 @@ function StudioGroupArtworks() { const { props } = X$1(); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 rounded-[28px] border border-sky-300/20 bg-sky-300/10 p-5 text-sky-100" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em]" }, "Group publish flow"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-semibold" }, "Upload into ", props.studioGroup?.name), /* @__PURE__ */ React.createElement("a", { href: props.uploadUrl, className: "mt-4 inline-flex rounded-full border border-sky-200/20 bg-sky-200/10 px-4 py-2 text-sm font-semibold text-sky-50" }, "New group artwork")), /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: [{ key: "artworks", label: "Artwork", icon: "fa-solid fa-cloud-arrow-up", url: props.uploadUrl }], hideModuleFilter: true })); } -const __vite_glob_0_124 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_125 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -104991,7 +105325,7 @@ function StudioGroupAssets() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, props.storeUrl ? /* @__PURE__ */ React.createElement("form", { onSubmit: submit, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-6" }, /* @__PURE__ */ React.createElement("input", { value: form.data.title, onChange: (event) => form.setData("title", event.target.value), placeholder: "Asset title", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none lg:col-span-2" }), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.category, onChange: (val) => form.setData("category", val), options: props.categoryOptions || [], searchable: false }), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.visibility, onChange: (val) => form.setData("visibility", val), options: props.visibilityOptions || [], searchable: false }), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.status, onChange: (val) => form.setData("status", val), options: props.statusOptions || [], searchable: false }), /* @__PURE__ */ React.createElement("input", { type: "file", onChange: (event) => form.setData("file", event.target.files?.[0] || null), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("textarea", { value: form.data.description, onChange: (event) => form.setData("description", event.target.value), placeholder: "What is this asset for?", rows: 3, className: "mt-4 w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: String(form.data.linked_project_id || ""), onChange: (val) => form.setData("linked_project_id", val), placeholder: "No linked project", options: (props.projectOptions || []).map((o) => ({ value: String(o.id), label: o.title })) }), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: form.data.is_featured, onChange: (event) => form.setData("is_featured", event.target.checked), label: "Featured asset" }))), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "mt-4 rounded-full border border-white/10 bg-white/[0.05] px-5 py-2.5 text-sm font-semibold text-white" }, "Upload asset")) : null, /* @__PURE__ */ React.createElement("form", { onSubmit: applyFilters, className: "mt-6 rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-end justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Browse library"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Search and filter shared assets by visibility and category.")), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm font-semibold text-white" }, "Apply filters")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 lg:grid-cols-3" }, /* @__PURE__ */ React.createElement("input", { value: filters.data.q, onChange: (event) => filters.setData("q", event.target.value), placeholder: "Search title, description, or filename", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.data.category, onChange: (val) => filters.setData("category", val), options: [{ value: "all", label: "All categories" }, ...props.categoryOptions || []], searchable: false }), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.data.bucket, onChange: (val) => filters.setData("bucket", val), options: [{ value: "all", label: "All visibility levels" }, ...(props.listing?.bucket_options || []).filter((option) => option.value !== "all")], searchable: false }))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, items.length > 0 ? items.map((asset) => /* @__PURE__ */ React.createElement("div", { key: asset.id, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, asset.title), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, asset.category, " • ", asset.visibility, " • ", asset.status)), /* @__PURE__ */ React.createElement("a", { href: asset.download_url, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-sm font-semibold text-white" }, "Download")), asset.description ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, asset.description) : null, props.updatePattern ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.patch(props.updatePattern.replace("__ASSET__", String(asset.id)), { title: asset.title, description: asset.description || "", category: asset.category, visibility: asset.visibility, status: asset.status === "active" ? "archived" : "active", linked_project_id: asset.linked_project?.id || "", is_featured: asset.is_featured }), className: "mt-4 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, asset.status === "active" ? "Archive" : "Reactivate") : null)) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No assets yet."))); } -const __vite_glob_0_125 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_126 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupAssets }, Symbol.toStringTag, { value: "Module" })); @@ -105063,7 +105397,7 @@ function StudioGroupChallengeEditor() { attachForm.post(props.attachArtworkUrl, { preserveScroll: true }); }, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Attach artwork"), /* @__PURE__ */ React.createElement(NovaSelect, { value: String(attachForm.data.artwork_id || ""), onChange: (val) => attachForm.setData("artwork_id", val), placeholder: "Choose artwork", options: (props.artworkOptions || []).map((o) => ({ value: String(o.id), label: o.title })) }), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "mt-4 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm font-semibold text-white" }, "Attach")) : null))); } -const __vite_glob_0_126 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_127 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupChallengeEditor }, Symbol.toStringTag, { value: "Module" })); @@ -105072,7 +105406,7 @@ function StudioGroupChallenges() { const items = Array.isArray(props.listing?.items) ? props.listing.items : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Challenges keep the group active between releases and give members a focused creative prompt."), props.createUrl ? /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Create challenge") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, items.length > 0 ? items.map((challenge) => /* @__PURE__ */ React.createElement("a", { key: challenge.id, href: challenge.urls?.edit || challenge.url, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, challenge.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, challenge.status)), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, challenge.summary || "Challenge page"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-xs text-slate-500" }, challenge.entry_count || 0, " linked entries"))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No challenges yet."))); } -const __vite_glob_0_127 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_128 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupChallenges }, Symbol.toStringTag, { value: "Module" })); @@ -105080,7 +105414,7 @@ function StudioGroupCollections() { const { props } = X$1(); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 rounded-[28px] border border-sky-300/20 bg-sky-300/10 p-5 text-sky-100" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em]" }, "Shared curation"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-semibold" }, "Create collections for ", props.studioGroup?.name), /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "mt-4 inline-flex rounded-full border border-sky-200/20 bg-sky-200/10 px-4 py-2 text-sm font-semibold text-sky-50" }, "New group collection")), /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: [{ key: "collections", label: "Collection", icon: "fa-solid fa-layer-group", url: props.createUrl }], hideModuleFilter: true })); } -const __vite_glob_0_128 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_129 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupCollections }, Symbol.toStringTag, { value: "Module" })); @@ -105194,7 +105528,7 @@ function StudioGroupCreate() { } )), /* @__PURE__ */ React.createElement("section", { className: "mx-auto max-w-3xl rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-5" }, /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Name"), /* @__PURE__ */ React.createElement("input", { value: form.name, onChange: handleNameChange, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Slug"), /* @__PURE__ */ React.createElement("input", { value: form.slug, onChange: handleSlugChange, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Short description"), /* @__PURE__ */ React.createElement("input", { value: form.headline, onChange: (event) => setForm((current) => ({ ...current, headline: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "About"), /* @__PURE__ */ React.createElement("textarea", { value: form.bio, onChange: (event) => setForm((current) => ({ ...current, bio: event.target.value })), rows: 6, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Type / category"), /* @__PURE__ */ React.createElement("input", { value: form.type, onChange: (event) => setForm((current) => ({ ...current, type: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Founded date"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: form.founded_at, onChange: (nextValue) => setForm((current) => ({ ...current, founded_at: nextValue })), mode: "date", placeholder: "Pick the founding date", clearable: true, className: "bg-black/20" }))), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Website"), /* @__PURE__ */ React.createElement("input", { value: form.website_url, onChange: (event) => setForm((current) => ({ ...current, website_url: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, "Avatar / logo"), /* @__PURE__ */ React.createElement("div", { className: "flex h-28 w-28 items-center justify-center overflow-hidden rounded-[24px] border border-white/10 bg-white/[0.04]" }, resolvedAvatarPreview ? /* @__PURE__ */ React.createElement("img", { src: resolvedAvatarPreview, alt: "Avatar preview", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image text-slate-500" })), /* @__PURE__ */ React.createElement("input", { ref: avatarInputRef, type: "file", accept: "image/png,image/jpeg,image/webp", onChange: handleFileSelected("avatar_file", setAvatarPreview), className: "hidden" }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => avatarInputRef.current?.click(), className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Upload avatar"), form.avatar_file ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => clearSelectedFile("avatar_file", setAvatarPreview, avatarInputRef), className: "rounded-full border border-white/10 bg-transparent px-4 py-2 text-sm font-semibold text-slate-300" }, "Use URL instead") : null), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Or paste an image URL"), /* @__PURE__ */ React.createElement("input", { value: form.avatar_path, onChange: (event) => setForm((current) => ({ ...current, avatar_path: event.target.value })), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, "Cover image"), /* @__PURE__ */ React.createElement("div", { className: "flex h-28 w-full items-center justify-center overflow-hidden rounded-[24px] border border-white/10 bg-white/[0.04]" }, resolvedBannerPreview ? /* @__PURE__ */ React.createElement("img", { src: resolvedBannerPreview, alt: "Cover preview", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-panorama text-slate-500" })), /* @__PURE__ */ React.createElement("input", { ref: bannerInputRef, type: "file", accept: "image/png,image/jpeg,image/webp", onChange: handleFileSelected("banner_file", setBannerPreview), className: "hidden" }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => bannerInputRef.current?.click(), className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Upload cover"), form.banner_file ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => clearSelectedFile("banner_file", setBannerPreview, bannerInputRef), className: "rounded-full border border-white/10 bg-transparent px-4 py-2 text-sm font-semibold text-slate-300" }, "Use URL instead") : null), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Or paste an image URL"), /* @__PURE__ */ React.createElement("input", { value: form.banner_path, onChange: (event) => setForm((current) => ({ ...current, banner_path: event.target.value })), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Visibility"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.visibility, onChange: (val) => setForm((current) => ({ ...current, visibility: val })), options: props.visibilityOptions || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Membership policy"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.membership_policy, onChange: (val) => setForm((current) => ({ ...current, membership_policy: val })), options: props.membershipPolicyOptions || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-200" }, "Links"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: addLink, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-white" }, "Add link")), form.links_json.map((item, index2) => /* @__PURE__ */ React.createElement("div", { key: `link-${index2}`, className: "grid gap-3 md:grid-cols-[0.8fr_1.2fr_auto]" }, /* @__PURE__ */ React.createElement("input", { value: item.label, onChange: (event) => updateLink(index2, "label", event.target.value), placeholder: "Label", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { value: item.url, onChange: (event) => updateLink(index2, "url", event.target.value), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => removeLink(index2), className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Remove")))), /* @__PURE__ */ React.createElement("div", { className: "flex justify-end gap-3" }, /* @__PURE__ */ React.createElement("a", { href: "/studio/groups", className: "rounded-full border border-white/10 bg-white/[0.03] px-4 py-2 text-sm font-semibold text-white" }, "Cancel"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: submit, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100" }, "Create group"))))); } -const __vite_glob_0_129 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_130 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupCreate }, Symbol.toStringTag, { value: "Module" })); @@ -105259,7 +105593,7 @@ function StudioGroupDashboard() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-3 xl:grid-cols-6" }, /* @__PURE__ */ React.createElement(StatCard, { label: "Artworks", value: group?.counts?.artworks, icon: "fa-solid fa-images" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Collections", value: group?.counts?.collections, icon: "fa-solid fa-layer-group" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Followers", value: group?.counts?.followers, icon: "fa-solid fa-user-group" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Active members", value: dashboard?.active_members_count || group?.counts?.members, icon: "fa-solid fa-people-group" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Projects", value: dashboard?.projects_count, icon: "fa-solid fa-diagram-project" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Releases", value: dashboard?.published_releases_count || dashboard?.releases_count, icon: "fa-solid fa-rocket" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Assets", value: dashboard?.assets_count, icon: "fa-solid fa-box-archive" })), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Quick actions"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Run the most common group tasks without leaving the dashboard."))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, quickActions.map((action) => /* @__PURE__ */ React.createElement("a", { key: action.label, href: action.href, className: `rounded-[24px] border px-4 py-4 transition hover:translate-y-[-1px] hover:border-white/20 ${toneClasses2[action.tone] || toneClasses2.sky}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "inline-flex h-11 w-11 items-center justify-center rounded-2xl border border-current/20 bg-black/10" }, /* @__PURE__ */ React.createElement("i", { className: action.icon })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold" }, action.label), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs opacity-80" }, action.detail)))))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-white" }, "Pending action"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Drafts and scheduled items that still need a publishing decision.")), /* @__PURE__ */ React.createElement("div", { className: "text-right text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", null, Number(dashboard?.draft_artworks_count || 0), " drafts"), /* @__PURE__ */ React.createElement("div", null, Number(dashboard?.scheduled_artworks_count || 0), " scheduled"))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, draftsPendingAction.length > 0 ? draftsPendingAction.map((artwork) => /* @__PURE__ */ React.createElement(ContentCard, { key: artwork.id, item: artwork, fallbackLabel: "Draft" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No drafts waiting", description: "This group has no draft artworks waiting for review or completion right now." }))), pendingJoinRequests.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-white" }, "Pending join requests"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Applicants waiting for a review decision.")), group?.urls?.studio_join_requests ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_join_requests, className: "text-sm font-semibold text-sky-200" }, "Open queue") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, pendingJoinRequests.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, item.user?.name || item.user?.username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, item.desired_role_label || item.desired_role || "Contributor", " • ", item.created_at ? new Date(item.created_at).toLocaleDateString() : "New"))))) : null), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Members"), /* @__PURE__ */ React.createElement("a", { href: group?.urls?.studio_members, className: "text-sm font-semibold text-sky-200" }, "Manage")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-2 sm:grid-cols-2" }, Object.entries(roleSummary).map(([role, count]) => /* @__PURE__ */ React.createElement("div", { key: role, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, role), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xl font-semibold text-white" }, Number(count))))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, members.slice(0, 6).map((member) => /* @__PURE__ */ React.createElement("div", { key: member.id, className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, member.user?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: member.user.avatar_url, alt: member.user.name || member.user.username, className: "h-11 w-11 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "truncate font-semibold text-white" }, member.user?.name || member.user?.username), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, member.role))))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Recruitment"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-lg font-semibold text-white" }, recruitment?.is_recruiting ? recruitment.headline || "Recruiting is active" : "Recruitment is off"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, recruitment?.description || "Set open roles, skills, and contact instructions from the recruitment page.")))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Releases"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Track featured drops and current release pipelines.")), group?.urls?.studio_releases ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_releases, className: "text-sm font-semibold text-sky-200" }, "Manage") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentReleases.length > 0 ? recentReleases.map((release) => /* @__PURE__ */ React.createElement(ContentCard, { key: release.id, item: release, fallbackLabel: "Release" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No releases yet", description: "Create a release to track milestones, contributors, and publication status." }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Projects"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Recent structured releases and collaboration hubs.")), group?.urls?.studio_projects ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_projects, className: "text-sm font-semibold text-sky-200" }, "Manage") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentProjects.length > 0 ? recentProjects.map((project) => /* @__PURE__ */ React.createElement(ContentCard, { key: project.id, item: project, fallbackLabel: "Project" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No projects yet", description: "Create a project to bundle shared assets, linked artworks, and a release state." }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Challenges"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Current creative prompts and challenge arcs.")), group?.urls?.studio_challenges ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_challenges, className: "text-sm font-semibold text-sky-200" }, "Manage") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentChallenges.length > 0 ? recentChallenges.map((challenge) => /* @__PURE__ */ React.createElement(ContentCard, { key: challenge.id, item: challenge, fallbackLabel: "Challenge" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No challenges yet", description: "Launch a challenge to keep the group active between major releases." })))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Trust summary"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Public-facing trust labels and internal contributor health snapshot.")), group?.urls?.studio_reputation ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_reputation, className: "text-sm font-semibold text-sky-200" }, "Open dashboard") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, trustSignals.map((signal) => /* @__PURE__ */ React.createElement("span", { key: signal.key, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-2 text-sm font-semibold text-white" }, signal.label))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Contributors"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-semibold text-white" }, Number(reputationSummary?.counts?.contributors || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Group badges"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-semibold text-white" }, Number(reputationSummary?.counts?.group_badges || 0))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Contributor highlights"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Recent high-trust contributors and badge unlocks."))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, Array.isArray(reputationSummary?.top_contributors) && reputationSummary.top_contributors.length > 0 ? reputationSummary.top_contributors.slice(0, 4).map((entry) => /* @__PURE__ */ React.createElement("div", { key: entry.user?.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, entry.user?.name || entry.user?.username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, entry.summary || "Contributor"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs text-slate-500" }, entry.counts?.releases || 0, " releases • ", entry.counts?.credited_artworks || 0, " artworks"))) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No contributor signals yet", description: "Release and milestone activity will populate contributor reputation here." })))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent artworks"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Latest published work released under this group identity.")), /* @__PURE__ */ React.createElement("a", { href: group?.urls?.studio_artworks, className: "text-sm font-semibold text-sky-200" }, "View all")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentArtworks.length > 0 ? recentArtworks.map((artwork) => /* @__PURE__ */ React.createElement(ContentCard, { key: artwork.id, item: artwork, fallbackLabel: "Published" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No published artworks yet", description: "Publish the first group artwork to start building this feed." }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Events"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Upcoming or recently updated moments on the group timeline.")), group?.urls?.studio_events ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_events, className: "text-sm font-semibold text-sky-200" }, "Manage") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentEvents.length > 0 ? recentEvents.map((event) => /* @__PURE__ */ React.createElement(ContentCard, { key: event.id, item: event, fallbackLabel: "Event" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No events yet", description: "Schedule a launch, stream, or milestone to start the group timeline." })))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent collections"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Collections most recently updated in this group workspace.")), /* @__PURE__ */ React.createElement("a", { href: group?.urls?.studio_collections, className: "text-sm font-semibold text-sky-200" }, "View all")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentCollections.length > 0 ? recentCollections.map((collection) => /* @__PURE__ */ React.createElement(ContentCard, { key: collection.id, item: collection, fallbackLabel: "Collection" })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No collections yet", description: "Create a collection to organize group work into campaigns, series, or themed sets." }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Activity feed"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Pinned and recent internal or public timeline items.")), group?.urls?.studio_activity ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_activity, className: "text-sm font-semibold text-sky-200" }, "Open feed") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, recentActivity.length > 0 ? recentActivity.map((item) => /* @__PURE__ */ React.createElement(ActivityCard, { key: item.id, item })) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No activity items yet", description: "Publishing projects, events, posts, and member milestones will populate this feed." })))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Review queue"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Latest artwork submissions waiting for moderation.")), group?.urls?.studio_review ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_review, className: "text-sm font-semibold text-sky-200" }, "Open queue") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, reviewQueuePreview.length > 0 ? reviewQueuePreview.map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.urls?.edit, className: "rounded-[24px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, item.group_review_status))) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No pending reviews", description: "Contributor submissions will appear here when they are sent for review." }))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent posts"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Announcements and updates published from the group.")), group?.urls?.studio_posts ? /* @__PURE__ */ React.createElement("a", { href: group.urls.studio_posts, className: "text-sm font-semibold text-sky-200" }, "Manage posts") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, recentPosts.length > 0 ? recentPosts.map((post2) => /* @__PURE__ */ React.createElement("a", { key: post2.id, href: post2.url, className: "rounded-[24px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, post2.type), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-base font-semibold text-white" }, post2.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, post2.excerpt || "Open post"))) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No posts yet", description: "Create the first group announcement to add a public news feed." })))), /* @__PURE__ */ React.createElement("section", { className: "mt-6 rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent history"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3" }, recentHistory.length > 0 ? recentHistory.map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.summary || item.action_type), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs text-slate-400" }, item.actor?.name || item.actor?.username || "System", " • ", item.created_at ? new Date(item.created_at).toLocaleString() : "Recently"))) : /* @__PURE__ */ React.createElement(EmptyCard, { title: "No history yet", description: "Audit events will appear here as members review requests, posts, and submissions." })))); } -const __vite_glob_0_130 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_131 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -105298,7 +105632,7 @@ function StudioGroupEventEditor() { form.post(props.publishUrl, { preserveScroll: true }); }, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-white/10 bg-white/[0.05] px-5 py-2.5 text-sm font-semibold text-white" }, "Publish event")) : null)); } -const __vite_glob_0_131 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_132 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupEventEditor }, Symbol.toStringTag, { value: "Module" })); @@ -105307,7 +105641,7 @@ function StudioGroupEvents() { const items = Array.isArray(props.listing?.items) ? props.listing.items : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Events let the group announce launches, sessions, milestones, and time-based updates."), props.createUrl ? /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Create event") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, items.length > 0 ? items.map((event) => /* @__PURE__ */ React.createElement("a", { key: event.id, href: event.urls?.edit || event.url, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, event.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, event.status)), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, event.summary || "Event page"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-xs text-slate-500" }, event.start_at ? new Date(event.start_at).toLocaleString() : "Unscheduled", " • ", event.event_type))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No events yet."))); } -const __vite_glob_0_132 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_133 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupEvents }, Symbol.toStringTag, { value: "Module" })); @@ -105334,7 +105668,7 @@ function StudioGroupInvitations() { ); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("section", { className: "mb-6 rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/75" }, "Group invitations"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-semibold text-white" }, "Invite collaborators into ", props.studioGroup?.name), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-2xl text-sm leading-6 text-slate-300" }, "Pending invites stay separate from active members here, so owners and admins can review who was invited, when the invite expires, and revoke access before acceptance.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement(xe, { href: props.studioGroup?.urls?.studio_members, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Members"), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100" }, pendingInvites.length, " pending"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 md:grid-cols-[1.1fr_0.8fr_1fr_0.7fr_auto]" }, /* @__PURE__ */ React.createElement("input", { value: invite.username, onChange: (event) => setInvite((current) => ({ ...current, username: event.target.value })), placeholder: "Username", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement(NovaSelect, { value: invite.role, onChange: (val) => setInvite((current) => ({ ...current, role: val })), searchable: false, options: [{ value: "contributor", label: "Contributor" }, { value: "editor", label: "Editor" }, { value: "admin", label: "Admin" }] }), /* @__PURE__ */ React.createElement("input", { value: invite.note, onChange: (event) => setInvite((current) => ({ ...current, note: event.target.value })), placeholder: "Optional note", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { value: invite.expires_in_days, onChange: (event) => setInvite((current) => ({ ...current, expires_in_days: event.target.value })), type: "number", min: "1", max: "30", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.endpoints?.invite, { ...invite, expires_in_days: Number(invite.expires_in_days || 7) || 7 }), className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100" }, "Send invite"))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Pending invitations"), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-400" }, pendingInvites.length, " outstanding")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, pendingInvites.length > 0 ? pendingInvites.map((inviteRow) => /* @__PURE__ */ React.createElement("article", { key: inviteRow.id, className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, inviteRow.user?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: inviteRow.user.avatar_url, alt: inviteRow.user.name || inviteRow.user.username, className: "h-12 w-12 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, inviteRow.user?.name || inviteRow.user?.username), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, inviteRow.role_label || inviteRow.role))), /* @__PURE__ */ React.createElement("div", { className: "md:ml-auto flex flex-wrap items-center gap-3 text-xs text-slate-400" }, inviteRow.invited_by ? /* @__PURE__ */ React.createElement("span", null, "Invited by ", inviteRow.invited_by.name || inviteRow.invited_by.username) : null, inviteRow.invited_at ? /* @__PURE__ */ React.createElement("span", null, "Sent ", formatInviteTimestamp(inviteRow.invited_at)) : null, inviteRow.expires_at ? /* @__PURE__ */ React.createElement("span", null, "Expires ", formatInviteTimestamp(inviteRow.expires_at)) : null)), inviteRow.note ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm text-slate-300" }, inviteRow.note) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, inviteRow.can_revoke && inviteRow.revoke_url ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.delete(inviteRow.revoke_url), className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-3 py-2 text-sm font-semibold text-rose-100" }, "Revoke invite") : null))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 px-6 py-12 text-center text-slate-400" }, "No pending invites for this group."))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Recent invite history"), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-400" }, revokedInvites.length, " revoked or expired")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, revokedInvites.length > 0 ? revokedInvites.map((inviteRow) => /* @__PURE__ */ React.createElement("article", { key: inviteRow.id, className: "rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, inviteRow.user?.name || inviteRow.user?.username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-400" }, inviteRow.is_expired ? "Expired" : "Revoked", " • ", inviteRow.role_label || inviteRow.role), inviteRow.invited_at ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, "Originally sent ", formatInviteTimestamp(inviteRow.invited_at)) : null)) : /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/10 px-4 py-8 text-center text-slate-400" }, "No recent invite history yet."))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Active members"), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-400" }, activeMembers.length, " active")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, activeMembers.slice(0, 6).map((member) => /* @__PURE__ */ React.createElement("div", { key: member.id, className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, member.user?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: member.user.avatar_url, alt: member.user.name || member.user.username, className: "h-11 w-11 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "truncate font-semibold text-white" }, member.user?.name || member.user?.username), /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.16em] text-slate-400" }, member.role_label || member.role))))))))); } -const __vite_glob_0_133 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_134 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupInvitations }, Symbol.toStringTag, { value: "Module" })); @@ -105363,7 +105697,7 @@ function routeUrl(baseUrl, id, action) { if (!baseUrl) return ""; return `${String(baseUrl).replace(/\/$/, "")}/${id}/${action}`; } -const __vite_glob_0_134 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_135 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupJoinRequests }, Symbol.toStringTag, { value: "Module" })); @@ -105430,7 +105764,7 @@ function StudioGroupMembers() { return /* @__PURE__ */ React.createElement("div", { key: option.value, className: "rounded-2xl border border-white/10 bg-white/[0.03] p-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, option.label), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setPermissionState(member.id, option.value, "inherit"), className: `rounded-full border px-3 py-1.5 text-xs font-semibold ${current === "inherit" ? "border-white/20 bg-white/[0.08] text-white" : "border-white/10 bg-transparent text-slate-300"}` }, "Inherit"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setPermissionState(member.id, option.value, "allow"), className: `rounded-full border px-3 py-1.5 text-xs font-semibold ${current === "allow" ? "border-emerald-300/20 bg-emerald-400/10 text-emerald-100" : "border-white/10 bg-transparent text-slate-300"}` }, "Allow"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setPermissionState(member.id, option.value, "deny"), className: `rounded-full border px-3 py-1.5 text-xs font-semibold ${current === "deny" ? "border-rose-300/20 bg-rose-400/10 text-rose-100" : "border-white/10 bg-transparent text-slate-300"}` }, "Deny"))); }))) : null)), filteredMembers.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "px-4 py-8 text-sm text-slate-400" }, "No members match the current search.") : null)))); } -const __vite_glob_0_135 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_136 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupMembers }, Symbol.toStringTag, { value: "Module" })); @@ -105454,7 +105788,7 @@ function StudioGroupPostEditor() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("form", { onSubmit: submit, className: "grid gap-6 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Type"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.type, onChange: (val) => form.setData("type", val), options: Array.isArray(props.typeOptions) ? props.typeOptions : [], searchable: false })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Title"), /* @__PURE__ */ React.createElement("input", { value: form.data.title, onChange: (event) => form.setData("title", event.target.value), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Excerpt"), /* @__PURE__ */ React.createElement("textarea", { value: form.data.excerpt, onChange: (event) => form.setData("excerpt", event.target.value), rows: 3, className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Content"), /* @__PURE__ */ React.createElement("textarea", { value: form.data.content, onChange: (event) => form.setData("content", event.target.value), rows: 12, className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Post controls"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 space-y-3" }, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "w-full rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-3 text-sm font-semibold text-sky-100 disabled:opacity-60" }, "Save"), props.publishUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.publishUrl), className: "w-full rounded-full border border-emerald-300/20 bg-emerald-400/10 px-4 py-3 text-sm font-semibold text-emerald-100" }, "Publish") : null, props.pinUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.pinUrl), className: "w-full rounded-full border border-amber-300/20 bg-amber-400/10 px-4 py-3 text-sm font-semibold text-amber-100" }, "Toggle pinned") : null, props.archiveUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.archiveUrl), className: "w-full rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm font-semibold text-rose-100" }, "Archive") : null)))); } -const __vite_glob_0_136 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_137 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupPostEditor }, Symbol.toStringTag, { value: "Module" })); @@ -105463,7 +105797,7 @@ function StudioGroupPosts() { const items = Array.isArray(props.listing?.items) ? props.listing.items : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Post library"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Draft, publish, pin, and archive public group posts.")), props.createUrl ? /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100" }, "New post") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 md:grid-cols-2" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, item.type), /* @__PURE__ */ React.createElement("h3", { className: "mt-2 text-lg font-semibold text-white" }, item.title)), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col items-end gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-300" }, item.status), item.is_pinned ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-400/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-amber-100" }, "Pinned") : null)), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-300" }, item.excerpt || item.content || "No excerpt yet."), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("a", { href: item.urls?.edit, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Edit"), item.urls?.public ? /* @__PURE__ */ React.createElement("a", { href: item.urls.public, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "View") : null))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-5 text-sm text-slate-400" }, "No posts yet.")))); } -const __vite_glob_0_137 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_138 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupPosts }, Symbol.toStringTag, { value: "Module" })); @@ -105512,7 +105846,7 @@ function StudioGroupProjectEditor() { milestoneForm.post(props.storeMilestoneUrl, { preserveScroll: true, onSuccess: () => milestoneForm.reset("title", "summary", "due_date", "owner_user_id", "notes") }); }, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Milestones"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, /* @__PURE__ */ React.createElement("input", { value: milestoneForm.data.title, onChange: (event) => milestoneForm.setData("title", event.target.value), placeholder: "Milestone title", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("textarea", { value: milestoneForm.data.summary, onChange: (event) => milestoneForm.setData("summary", event.target.value), placeholder: "Summary", rows: 3, className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: milestoneForm.data.status, onChange: (val) => milestoneForm.setData("status", val), searchable: false, options: ["pending", "active", "blocked", "completed", "cancelled"].map((s2) => ({ value: s2, label: s2 })) }), /* @__PURE__ */ React.createElement(DateTimePicker, { value: milestoneForm.data.due_date, onChange: (nextValue) => milestoneForm.setData("due_date", nextValue), mode: "date", placeholder: "Due date", clearable: true, className: "bg-black/20" })), /* @__PURE__ */ React.createElement(NovaSelect, { value: String(milestoneForm.data.owner_user_id || ""), onChange: (val) => milestoneForm.setData("owner_user_id", val), placeholder: "No owner", options: (props.memberOptions || []).map((o) => ({ value: String(o.id), label: o.name || o.username })) }), /* @__PURE__ */ React.createElement("textarea", { value: milestoneForm.data.notes, onChange: (event) => milestoneForm.setData("notes", event.target.value), placeholder: "Notes", rows: 3, className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm font-semibold text-white" }, "Add milestone")), Array.isArray(project?.milestones) && project.milestones.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-3" }, project.milestones.map((milestone) => /* @__PURE__ */ React.createElement("div", { key: milestone.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, milestone.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, milestone.owner?.name || milestone.owner?.username || "No owner", milestone.due_date ? ` • due ${milestone.due_date}` : "")), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.patch(props.updateMilestonePattern.replace("__MILESTONE__", String(milestone.id)), { title: milestone.title, summary: milestone.summary || "", status: milestone.status === "completed" ? "active" : "completed", due_date: milestone.due_date || "", owner_user_id: milestone.owner?.id || "", notes: milestone.notes || "" }, { preserveScroll: true }), className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-xs font-semibold text-white" }, "Mark ", milestone.status === "completed" ? "active" : "complete")), milestone.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, milestone.summary) : null))) : null) : null))); } -const __vite_glob_0_138 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_139 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupProjectEditor }, Symbol.toStringTag, { value: "Module" })); @@ -105522,7 +105856,7 @@ function StudioGroupProjects() { const items = Array.isArray(listing.items) ? listing.items : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Projects give the group a structured place for releases, teams, and linked outputs."), props.createUrl ? /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Create project") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, items.length > 0 ? items.map((project) => /* @__PURE__ */ React.createElement("a", { key: project.id, href: project.urls?.edit || project.url, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, project.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, project.status)), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, project.summary || "Project page"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-xs text-slate-500" }, project.counts?.artworks || 0, " artworks • ", project.counts?.assets || 0, " assets • ", project.counts?.team || 0, " team • ", project.counts?.milestones || 0, " milestones • ", project.counts?.releases || 0, " releases"))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No projects yet."))); } -const __vite_glob_0_139 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_140 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupProjects }, Symbol.toStringTag, { value: "Module" })); @@ -105553,7 +105887,7 @@ function StudioGroupRecruitment() { return /* @__PURE__ */ React.createElement("button", { key: option.value, type: "button", onClick: () => form.setData("skills_json", toggleItem(form.data.skills_json, option.value)), className: `rounded-full border px-3 py-1.5 text-xs font-semibold ${selected ? "border-sky-300/20 bg-sky-300/10 text-sky-100" : "border-white/10 bg-white/[0.03] text-slate-300"}` }, option.label); }))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Application settings"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Contact mode"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.contact_mode, onChange: (val) => form.setData("contact_mode", val), options: Array.isArray(props.contactModes) ? props.contactModes : [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Visibility"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.data.visibility, onChange: (val) => form.setData("visibility", val), options: Array.isArray(props.visibilityOptions) ? props.visibilityOptions : [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-white" }, "Public preview"), /* @__PURE__ */ React.createElement("p", { className: "mt-2" }, form.data.headline || "No headline yet."), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-slate-400" }, form.data.description || "Recruitment copy will show here once you add it."), form.data.roles_json.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, form.data.roles_json.map((role) => /* @__PURE__ */ React.createElement("span", { key: role, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-white" }, role))) : null), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-3 text-sm font-semibold text-sky-100 disabled:opacity-60" }, "Save recruitment profile"))))); } -const __vite_glob_0_140 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_141 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupRecruitment }, Symbol.toStringTag, { value: "Module" })); @@ -105606,7 +105940,7 @@ function StudioGroupReleaseEditor() { milestoneForm.post(props.storeMilestoneUrl, { preserveScroll: true, onSuccess: () => milestoneForm.reset("title", "summary", "due_date", "owner_user_id", "notes") }); }, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Milestones"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, /* @__PURE__ */ React.createElement("input", { value: milestoneForm.data.title, onChange: (event) => milestoneForm.setData("title", event.target.value), placeholder: "Milestone title", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("textarea", { value: milestoneForm.data.summary, onChange: (event) => milestoneForm.setData("summary", event.target.value), placeholder: "Summary", rows: 3, className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: milestoneForm.data.status, onChange: (val) => milestoneForm.setData("status", val), searchable: false, options: ["pending", "active", "blocked", "completed", "cancelled"].map((s2) => ({ value: s2, label: s2 })) }), /* @__PURE__ */ React.createElement(DateTimePicker, { value: milestoneForm.data.due_date, onChange: (nextValue) => milestoneForm.setData("due_date", nextValue), mode: "date", placeholder: "Due date", clearable: true, className: "bg-black/20" })), /* @__PURE__ */ React.createElement(NovaSelect, { value: String(milestoneForm.data.owner_user_id || ""), onChange: (val) => milestoneForm.setData("owner_user_id", val), placeholder: "No owner", options: (props.memberOptions || []).map((o) => ({ value: String(o.id), label: o.name || o.username })) }), /* @__PURE__ */ React.createElement("textarea", { value: milestoneForm.data.notes, onChange: (event) => milestoneForm.setData("notes", event.target.value), placeholder: "Notes", rows: 3, className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm font-semibold text-white" }, "Add milestone")), Array.isArray(release?.milestones) && release.milestones.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-3" }, release.milestones.map((milestone) => /* @__PURE__ */ React.createElement("div", { key: milestone.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, milestone.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, milestone.owner?.name || milestone.owner?.username || "No owner", milestone.due_date ? ` • due ${milestone.due_date}` : "")), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.patch(props.updateMilestonePattern.replace("__MILESTONE__", String(milestone.id)), { title: milestone.title, summary: milestone.summary || "", status: milestone.status === "completed" ? "active" : "completed", due_date: milestone.due_date || "", owner_user_id: milestone.owner?.id || "", notes: milestone.notes || "" }, { preserveScroll: true }), className: "rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-xs font-semibold text-white" }, "Mark ", milestone.status === "completed" ? "active" : "complete")), milestone.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, milestone.summary) : null))) : null) : null))); } -const __vite_glob_0_141 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_142 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReleaseEditor }, Symbol.toStringTag, { value: "Module" })); @@ -105618,7 +105952,7 @@ function StudioGroupReleases() { const currentBucket = listing.filters?.bucket || "all"; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Track the release pipeline from draft through public launch, with milestones and contributor credits."), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: currentBucket, onChange: (val) => At.get(window.location.pathname, { bucket: val }, { preserveScroll: true, preserveState: true }), options: bucketOptions, searchable: false }), props.createUrl ? /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Create release") : null)), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-2" }, items.length > 0 ? items.map((release) => /* @__PURE__ */ React.createElement("div", { key: release.id, className: "overflow-hidden rounded-[24px] border border-white/10 bg-white/[0.03]" }, release.cover_url ? /* @__PURE__ */ React.createElement("img", { src: release.cover_url, alt: release.title, className: "aspect-[4/3] w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex aspect-[4/3] items-center justify-center bg-white/[0.03] text-slate-500" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-rocket text-2xl" })), /* @__PURE__ */ React.createElement("div", { className: "p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, release.status), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, release.current_stage), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, release.visibility)), /* @__PURE__ */ React.createElement("h2", { className: "mt-3 text-xl font-semibold text-white" }, release.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, release.summary || "Release page"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-xs text-slate-500" }, release.counts?.artworks || 0, " artworks • ", release.counts?.contributors || 0, " contributors • ", release.counts?.milestones || 0, " milestones"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("a", { href: release.urls?.edit || release.url, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Manage"), release.urls?.public ? /* @__PURE__ */ React.createElement("a", { href: release.urls.public, className: "rounded-full border border-white/10 bg-black/20 px-4 py-2 text-sm font-semibold text-white" }, "View public") : null)))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No releases yet."))); } -const __vite_glob_0_142 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_143 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReleases }, Symbol.toStringTag, { value: "Module" })); @@ -105635,7 +105969,7 @@ function StudioGroupReputation() { const memberBadgeUnlocks = Array.isArray(reputation.member_badge_unlocks) ? reputation.member_badge_unlocks : []; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-5" }, /* @__PURE__ */ React.createElement(MetricCard, { label: "Freshness", value: metrics.freshness_score }), /* @__PURE__ */ React.createElement(MetricCard, { label: "Activity", value: metrics.activity_score }), /* @__PURE__ */ React.createElement(MetricCard, { label: "Release", value: metrics.release_score }), /* @__PURE__ */ React.createElement(MetricCard, { label: "Trust", value: metrics.trust_score }), /* @__PURE__ */ React.createElement(MetricCard, { label: "Collaboration", value: metrics.collaboration_score })), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Trust signals"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Public-safe labels that shape discovery and confidence."))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, trustSignals.map((signal) => /* @__PURE__ */ React.createElement("span", { key: signal.key, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-2 text-sm font-semibold text-white" }, signal.label))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Contributors"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-semibold text-white" }, Number(reputation.counts?.contributors || 0))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Member badges"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-semibold text-white" }, Number(reputation.counts?.member_badges || 0)))), metrics.last_calculated_at ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-xs text-slate-500" }, "Last calculated ", new Date(metrics.last_calculated_at).toLocaleString()) : null), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Top contributors"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Reputation summaries derived from visible collaboration history."))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, topContributors.length > 0 ? topContributors.map((entry) => /* @__PURE__ */ React.createElement("div", { key: entry.user?.id, className: "rounded-[24px] border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, entry.user?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: entry.user.avatar_url, alt: entry.user?.name || entry.user?.username, className: "h-11 w-11 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "truncate font-semibold text-white" }, entry.user?.name || entry.user?.username), entry.trusted_indicator ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-emerald-300/20 bg-emerald-300/10 px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-emerald-100" }, "Trusted") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, entry.summary || "Contributor"))), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-xs text-slate-500" }, entry.counts?.releases || 0, " releases • ", entry.counts?.projects || 0, " projects • ", entry.counts?.credited_artworks || 0, " artworks • ", entry.counts?.review_actions || 0, " reviews"), Array.isArray(entry.badges) && entry.badges.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, entry.badges.map((badge) => /* @__PURE__ */ React.createElement("span", { key: `${entry.user?.id}-${badge.key}`, className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-300" }, badge.label))) : null)) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No contributor reputation signals yet.")))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Group badges"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, recentBadges.length > 0 ? recentBadges.map((badge) => /* @__PURE__ */ React.createElement("div", { key: badge.key, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, badge.label), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, badge.reason))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No group badges awarded yet."))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent member badge unlocks"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, memberBadgeUnlocks.length > 0 ? memberBadgeUnlocks.map((entry) => /* @__PURE__ */ React.createElement("div", { key: `${entry.user?.id}-${entry.badge?.key}`, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, entry.user?.name || entry.user?.username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-sky-200" }, entry.badge?.label), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, entry.badge?.reason))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No member badge unlocks yet."))))); } -const __vite_glob_0_143 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_144 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReputation }, Symbol.toStringTag, { value: "Module" })); @@ -105652,7 +105986,7 @@ function StudioGroupReviewQueue() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Submission queue"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Review artwork drafts before they publish under the group identity.")), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-300" }, listing.filters?.bucket || "submitted")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-4" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start gap-4" }, item.thumb ? /* @__PURE__ */ React.createElement("img", { src: item.thumb, alt: item.title, className: "h-24 w-24 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-24 w-24 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-slate-300" }, item.group_review_status)), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-3 text-xs text-slate-400" }, item.primary_author ? /* @__PURE__ */ React.createElement("span", null, "Author: ", item.primary_author.name || item.primary_author.username) : null, item.uploader ? /* @__PURE__ */ React.createElement("span", null, "Uploader: ", item.uploader.name || item.uploader.username) : null, item.submitted_at ? /* @__PURE__ */ React.createElement("span", null, "Submitted ", new Date(item.submitted_at).toLocaleString()) : null), item.group_review_notes ? /* @__PURE__ */ React.createElement("p", { className: "mt-3 rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2 text-sm text-slate-300" }, item.group_review_notes) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("a", { href: item.urls?.edit, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Open draft"), item.can_review ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => sendAction(item, "approve"), className: "rounded-full border border-emerald-300/20 bg-emerald-400/10 px-4 py-2 text-sm font-semibold text-emerald-100" }, "Approve") : null, item.can_review ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => sendAction(item, "needs_changes"), className: "rounded-full border border-amber-300/20 bg-amber-400/10 px-4 py-2 text-sm font-semibold text-amber-100" }, "Needs changes") : null, item.can_review ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => sendAction(item, "reject"), className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Reject") : null))))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-dashed border-white/10 bg-white/[0.02] p-5 text-sm text-slate-400" }, "No submissions in this bucket."))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-white" }, "Recent history"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (Array.isArray(props.recentHistory) ? props.recentHistory : []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.id, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.summary || item.action_type), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-400" }, item.actor?.name || item.actor?.username || "System", " • ", item.created_at ? new Date(item.created_at).toLocaleString() : "Recently"))))))); } -const __vite_glob_0_144 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_145 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReviewQueue }, Symbol.toStringTag, { value: "Module" })); @@ -105745,7 +106079,7 @@ function StudioGroupSettings() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("section", { className: "mx-auto max-w-3xl rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-5" }, /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Name"), /* @__PURE__ */ React.createElement("input", { value: form.name, onChange: (event) => setForm((current) => ({ ...current, name: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Slug"), /* @__PURE__ */ React.createElement("input", { value: form.slug, onChange: (event) => setForm((current) => ({ ...current, slug: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Short description"), /* @__PURE__ */ React.createElement("input", { value: form.headline, onChange: (event) => setForm((current) => ({ ...current, headline: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "About"), /* @__PURE__ */ React.createElement("textarea", { value: form.bio, onChange: (event) => setForm((current) => ({ ...current, bio: event.target.value })), rows: 6, className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Type / category"), /* @__PURE__ */ React.createElement("input", { value: form.type, onChange: (event) => setForm((current) => ({ ...current, type: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Founded date"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: form.founded_at, onChange: (nextValue) => setForm((current) => ({ ...current, founded_at: nextValue })), mode: "date", placeholder: "Pick the founding date", clearable: true, className: "bg-black/20" }))), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Website"), /* @__PURE__ */ React.createElement("input", { value: form.website_url, onChange: (event) => setForm((current) => ({ ...current, website_url: event.target.value })), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-5 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, "Avatar / logo"), /* @__PURE__ */ React.createElement("div", { className: "flex h-28 w-28 items-center justify-center overflow-hidden rounded-[24px] border border-white/10 bg-white/[0.04]" }, resolvedAvatarPreview ? /* @__PURE__ */ React.createElement("img", { src: resolvedAvatarPreview, alt: "Avatar preview", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-image text-slate-500" })), /* @__PURE__ */ React.createElement("input", { ref: avatarInputRef, type: "file", accept: "image/png,image/jpeg,image/webp", onChange: handleFileSelected("avatar_file", setAvatarPreview), className: "hidden" }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => avatarInputRef.current?.click(), className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Upload avatar"), form.avatar_file ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => clearSelectedFile("avatar_file", setAvatarPreview, avatarInputRef), className: "rounded-full border border-white/10 bg-transparent px-4 py-2 text-sm font-semibold text-slate-300" }, "Use current path") : null), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Or paste an image URL"), /* @__PURE__ */ React.createElement("input", { value: form.avatar_path, onChange: (event) => setForm((current) => ({ ...current, avatar_path: event.target.value })), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, "Cover image"), /* @__PURE__ */ React.createElement("div", { className: "flex h-28 w-full items-center justify-center overflow-hidden rounded-[24px] border border-white/10 bg-white/[0.04]" }, resolvedBannerPreview ? /* @__PURE__ */ React.createElement("img", { src: resolvedBannerPreview, alt: "Cover preview", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-panorama text-slate-500" })), /* @__PURE__ */ React.createElement("input", { ref: bannerInputRef, type: "file", accept: "image/png,image/jpeg,image/webp", onChange: handleFileSelected("banner_file", setBannerPreview), className: "hidden" }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => bannerInputRef.current?.click(), className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, "Upload cover"), form.banner_file ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => clearSelectedFile("banner_file", setBannerPreview, bannerInputRef), className: "rounded-full border border-white/10 bg-transparent px-4 py-2 text-sm font-semibold text-slate-300" }, "Use current path") : null), /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Or paste an image URL"), /* @__PURE__ */ React.createElement("input", { value: form.banner_path, onChange: (event) => setForm((current) => ({ ...current, banner_path: event.target.value })), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Featured artwork"), /* @__PURE__ */ React.createElement(NovaSelect, { value: String(form.featured_artwork_id || ""), onChange: (val) => setForm((current) => ({ ...current, featured_artwork_id: val })), placeholder: "Use latest published artwork", options: featuredArtworkOptions.map((item) => ({ value: String(item.id), label: item.title })) })), selectedFeaturedArtwork ? /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 rounded-[20px] border border-white/10 bg-white/[0.04] p-3" }, selectedFeaturedArtwork.thumb ? /* @__PURE__ */ React.createElement("img", { src: selectedFeaturedArtwork.thumb, alt: selectedFeaturedArtwork.title, className: "h-16 w-16 rounded-2xl object-cover" }) : null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, selectedFeaturedArtwork.title), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, selectedFeaturedArtwork.author || "Group member"))) : /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, "When this is empty, the public overview falls back to the latest published works automatically.")), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Visibility"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.visibility, onChange: (val) => setForm((current) => ({ ...current, visibility: val })), options: props.visibilityOptions || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("span", null, "Membership policy"), /* @__PURE__ */ React.createElement(NovaSelect, { value: form.membership_policy, onChange: (val) => setForm((current) => ({ ...current, membership_policy: val })), options: props.membershipPolicyOptions || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm text-slate-200" }, "Links"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: addLink, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold text-white" }, "Add link")), form.links_json.map((item, index2) => /* @__PURE__ */ React.createElement("div", { key: `link-${index2}`, className: "grid gap-3 md:grid-cols-[0.8fr_1.2fr_auto]" }, /* @__PURE__ */ React.createElement("input", { value: item.label, onChange: (event) => updateLink(index2, "label", event.target.value), placeholder: "Label", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { value: item.url, onChange: (event) => updateLink(index2, "url", event.target.value), placeholder: "https://", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => removeLink(index2), className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Remove")))), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between gap-3" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: archiveGroup, className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Archive group"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: submit, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100" }, "Save settings"))))); } -const __vite_glob_0_145 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_146 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupSettings }, Symbol.toStringTag, { value: "Module" })); @@ -105773,7 +106107,7 @@ function StudioGroupsIndex() { } ), /* @__PURE__ */ React.createElement("div", { className: "mb-6 flex items-center justify-between gap-3 rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/80" }, "Collective publishing"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-semibold text-white" }, "Launch and manage shared identities")), /* @__PURE__ */ React.createElement(xe, { href: props.endpoints?.create, className: "rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, "Create group")), pendingInvites.length > 0 ? /* @__PURE__ */ React.createElement("section", { className: "mb-6 rounded-[28px] border border-amber-300/20 bg-amber-400/10 p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-amber-50" }, "Pending invites"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, pendingInvites.map((invite) => /* @__PURE__ */ React.createElement("article", { key: invite.id, className: "rounded-2xl border border-white/10 bg-black/20 p-4 text-white" }, /* @__PURE__ */ React.createElement("h3", { className: "text-base font-semibold" }, invite.group?.name), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-amber-50/80" }, "Role: ", invite.role), invite.invited_by ? /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-amber-50/70" }, "Invited by ", invite.invited_by.name || invite.invited_by.username) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(invite.accept_url), className: "rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-2 text-sm font-semibold text-emerald-100" }, "Accept"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(invite.decline_url), className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-2 text-sm font-semibold text-white" }, "Decline")))))) : null, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 xl:grid-cols-2" }, groups.length > 0 ? groups.map((group) => /* @__PURE__ */ React.createElement(GroupCard, { key: group.slug, group })) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/10 px-6 py-16 text-center text-slate-400" }, "No groups yet. Create one to start publishing collaboratively."))); } -const __vite_glob_0_146 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_147 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -105874,7 +106208,7 @@ function StudioGrowth() { /* @__PURE__ */ React.createElement("div", { className: "mt-3 grid grid-cols-3 gap-3 text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Views"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm font-semibold text-white" }, Number(item.metrics?.views || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Reactions"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm font-semibold text-white" }, Number(item.metrics?.appreciation || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, "Comments"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm font-semibold text-white" }, Number(item.metrics?.comments || 0).toLocaleString()))) )))))); } -const __vite_glob_0_147 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_148 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGrowth }, Symbol.toStringTag, { value: "Module" })); @@ -105934,7 +106268,7 @@ function StudioInbox() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description, actions: /* @__PURE__ */ React.createElement("button", { type: "button", onClick: markAllRead, disabled: marking, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-slate-100 disabled:opacity-50" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-check-double" }), marking ? "Updating..." : "Mark all read") }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Unread"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.unread_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "High priority"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.high_priority_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Comments"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.comment_count || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Followers"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.follower_count || 0).toLocaleString()))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[320px_minmax(0,1fr)]" }, /* @__PURE__ */ React.createElement("aside", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Filters"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Search"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilters({ q: event.target.value }), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white", placeholder: "Actor, title, or module" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Type"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.type || "all", onChange: (val) => updateFilters({ type: val }), options: inbox.type_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Module"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.module || "all", onChange: (val) => updateFilters({ module: val }), options: inbox.module_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Read state"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.read_state || "all", onChange: (val) => updateFilters({ read_state: val }), options: inbox.read_state_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Priority"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.priority || "all", onChange: (val) => updateFilters({ priority: val }), options: inbox.priority_options || [], searchable: false })))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Attention now"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (inbox.panels?.attention_now || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.url, className: "block rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, item.module_label)))))), /* @__PURE__ */ React.createElement("section", { className: "space-y-4" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: `rounded-[28px] border p-5 ${item.is_new ? "border-sky-300/20 bg-sky-300/10" : "border-white/10 bg-white/[0.03]"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4" }, item.actor?.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: item.actor.avatar_url, alt: item.actor.name || "Actor", className: "h-12 w-12 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 items-center justify-center rounded-2xl bg-black/20 text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-bell" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, /* @__PURE__ */ React.createElement("span", null, item.module_label), /* @__PURE__ */ React.createElement("span", { className: `inline-flex items-center rounded-full border px-2 py-1 ${priorityClasses[item.priority] || priorityClasses.low}` }, item.priority), item.is_new && /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-sky-300/20 px-2 py-1 text-sky-100" }, "Unread")), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-lg font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-400" }, item.body), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap items-center gap-3 text-sm text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, formatDate$2(item.created_at)), item.actor?.name && /* @__PURE__ */ React.createElement("span", null, item.actor.name), /* @__PURE__ */ React.createElement("a", { href: item.url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-1.5 text-slate-200" }, "Open")))))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/15 px-6 py-16 text-center text-slate-400" }, "No inbox items match this filter."), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) <= 1, onClick: () => updateFilters({ page: Math.max(1, (meta.current_page || 1) - 1) }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Previous"), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Page ", meta.current_page || 1, " of ", meta.last_page || 1), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) >= (meta.last_page || 1), onClick: () => updateFilters({ page: (meta.current_page || 1) + 1 }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Next")))))); } -const __vite_glob_0_148 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_149 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioInbox }, Symbol.toStringTag, { value: "Module" })); @@ -106369,7 +106703,7 @@ function getDraftValue(source, key, fallback = "") { } return fallback; } -function buildInitialFormData(article, defaultAuthor, typeOptions, oldInput = {}) { +function buildInitialFormData(article, defaultAuthor, defaultPublishedAt, typeOptions, oldInput = {}) { return { title: String(getDraftValue(oldInput, "title", article.title || "")), slug: String(getDraftValue(oldInput, "slug", article.slug || "")), @@ -106380,7 +106714,7 @@ function buildInitialFormData(article, defaultAuthor, typeOptions, oldInput = {} category_id: String(getDraftValue(oldInput, "category_id", article.category_id ? String(article.category_id) : "")), author_id: getDraftValue(oldInput, "author_id", article.author_id || defaultAuthor?.id || ""), editorial_status: String(getDraftValue(oldInput, "editorial_status", article.editorial_status || "draft")), - published_at: String(getDraftValue(oldInput, "published_at", article.published_at ? String(article.published_at).slice(0, 16) : "")), + published_at: String(getDraftValue(oldInput, "published_at", article.published_at ? String(article.published_at).slice(0, 16) : defaultPublishedAt || "")), is_featured: parseBooleanish(getDraftValue(oldInput, "is_featured", Boolean(article.is_featured))), is_pinned: parseBooleanish(getDraftValue(oldInput, "is_pinned", Boolean(article.is_pinned))), comments_enabled: parseBooleanish(getDraftValue(oldInput, "comments_enabled", article.id ? Boolean(article.comments_enabled) : true)), @@ -106577,8 +106911,7 @@ async function loadNewsMarkdownTurndown() { newsMarkdownTurndownPromise = import("./assets/turndown.es-8lfE8z0s.js").then(({ default: TurndownService }) => new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced", - bulletListMarker: "-", - emDelimiter: "*" + bulletListMarker: "-" })).then((service) => { newsMarkdownTurndown = service; return service; @@ -107269,7 +107602,7 @@ function StudioNewsEditor() { const { props } = X$1(); const { toasts, push: pushToast, dismiss: dismissToast } = useToast(); const article = props.article || {}; - const initialFormData = reactExports.useMemo(() => buildInitialFormData(article, props.defaultAuthor, props.typeOptions, props.oldInput || {}), [article, props.defaultAuthor, props.oldInput, props.typeOptions]); + const initialFormData = reactExports.useMemo(() => buildInitialFormData(article, props.defaultAuthor, props.defaultPublishedAt, props.typeOptions, props.oldInput || {}), [article, props.defaultAuthor, props.defaultPublishedAt, props.oldInput, props.typeOptions]); const articleSyncKey = reactExports.useMemo(() => JSON.stringify(initialFormData), [initialFormData]); const [authorResults, setAuthorResults] = reactExports.useState([]); const [authorQuery, setAuthorQuery] = reactExports.useState(article.author?.title || article.author?.subtitle?.replace(/^@/, "") || ""); @@ -107623,8 +107956,8 @@ function StudioNewsEditor() { advancedNews: true, searchEntities, mediaSupport: { - uploadUrl: props.coverUploadUrl, - deleteUrl: props.coverDeleteUrl, + uploadUrl: props.bodyMediaUploadUrl || props.coverUploadUrl, + deleteUrl: props.bodyMediaDeleteUrl || props.coverDeleteUrl, slot: "body" } } @@ -107692,7 +108025,7 @@ function StudioNewsEditor() { } )); } -const __vite_glob_0_149 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_150 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioNewsEditor }, Symbol.toStringTag, { value: "Module" })); @@ -107878,7 +108211,7 @@ function StudioNewsIndex() { "Next" ))) : null); } -const __vite_glob_0_150 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_151 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioNewsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -107911,7 +108244,7 @@ function StudioNewsTaxonomies() { tagForm.post(props.storeTagUrl); }, className: "mt-5 grid gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto] md:items-center" }, /* @__PURE__ */ React.createElement("input", { value: tagForm.data.name, onChange: (event) => tagForm.setData("name", event.target.value), placeholder: "Tag name", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { value: tagForm.data.slug, onChange: (event) => tagForm.setData("slug", event.target.value), placeholder: "optional slug", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "submit", className: "rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100" }, "Create tag")), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-3" }, tags.map((tag, index2) => /* @__PURE__ */ React.createElement("div", { key: tag.id, className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto_auto] md:items-center" }, /* @__PURE__ */ React.createElement("input", { value: tag.name, onChange: (event) => updateTag(index2, "name", event.target.value), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("input", { value: tag.slug, onChange: (event) => updateTag(index2, "slug", event.target.value), className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.14em] text-slate-500" }, Number(tag.published_count || 0).toLocaleString(), " published"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => saveTag(tag), className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm font-semibold text-white" }, "Save")))))))); } -const __vite_glob_0_151 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_152 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioNewsTaxonomies }, Symbol.toStringTag, { value: "Module" })); @@ -108061,7 +108394,7 @@ function StudioPreferences() { return /* @__PURE__ */ React.createElement("div", { key: widgetKey, className: "flex flex-col gap-3 rounded-[22px] border border-white/10 bg-black/20 p-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, option.label), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, "Position ", index2 + 1)), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => toggleWidget(widgetKey), className: `rounded-full border px-3 py-1.5 text-xs ${enabled ? "border-sky-300/25 bg-sky-300/10 text-sky-100" : "border-white/10 text-slate-300"}` }, enabled ? "Visible" : "Hidden"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => moveWidget(widgetKey, "up"), className: "rounded-full border border-white/10 px-3 py-1.5 text-xs text-slate-300" }, "Up"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => moveWidget(widgetKey, "down"), className: "rounded-full border border-white/10 px-3 py-1.5 text-xs text-slate-300" }, "Down"))); })))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Related surfaces"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (props.links || []).map((link2) => /* @__PURE__ */ React.createElement("a", { key: link2.url, href: link2.url, className: "block rounded-[22px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: link2.icon }), /* @__PURE__ */ React.createElement("span", { className: "text-base font-semibold text-white" }, link2.label)))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Preference notes"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3 text-sm text-slate-400" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, "Landing page and widget order are stored in the shared Studio preference record, so new Creator Studio surfaces can plug into the same contract without another migration."), /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, "Analytics range and card density stay here so Analytics, Growth, and the main dashboard can stay visually consistent.")))))); } -const __vite_glob_0_152 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_153 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioPreferences }, Symbol.toStringTag, { value: "Module" })); @@ -108241,7 +108574,7 @@ function StudioProfile() { /* @__PURE__ */ React.createElement("div", { className: "p-6 pt-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-end gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, profile.avatar_url ? /* @__PURE__ */ React.createElement("img", { src: profile.avatar_url, alt: profile.username, className: "h-24 w-24 rounded-[28px] border border-white/10 object-cover shadow-lg" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-24 w-24 items-center justify-center rounded-[28px] border border-white/10 bg-black/30 text-slate-400 shadow-lg" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-user text-2xl" })), /* @__PURE__ */ React.createElement("input", { ref: avatarInputRef, type: "file", accept: "image/png,image/jpeg,image/webp", onChange: handleAvatarSelected, className: "hidden" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => avatarInputRef.current?.click(), disabled: uploadingAvatar, className: "absolute -bottom-2 -right-2 inline-flex h-10 w-10 items-center justify-center rounded-full border border-sky-300/25 bg-sky-300/15 text-sky-100 disabled:opacity-50" }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${uploadingAvatar ? "fa-spinner fa-spin" : "fa-camera"}` }))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-3xl font-semibold text-white" }, profile.name), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-300" }, "@", profile.username), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap gap-4 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", null, Number(profile.followers || 0).toLocaleString(), " followers"), profile.location && /* @__PURE__ */ React.createElement("span", null, profile.location)))), profile.cover_url && /* @__PURE__ */ React.createElement("div", { className: "w-full max-w-sm rounded-[24px] border border-white/10 bg-black/30 p-4" }, /* @__PURE__ */ React.createElement("label", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Banner position"), /* @__PURE__ */ React.createElement("input", { type: "range", min: "0", max: "100", value: coverPosition, onChange: (event) => setCoverPosition(Number(event.target.value)), className: "mt-3 w-full" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: saveCoverPosition, disabled: savingCoverPosition, className: "mt-3 inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-white disabled:opacity-50" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrows-up-down" }), savingCoverPosition ? "Saving..." : "Save banner position")))) )), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Public profile details"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Update the creator information that supports your public presence across Nova.")), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: saveProfile, disabled: savingProfile, className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100 disabled:opacity-50" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-floppy-disk" }), savingProfile ? "Saving..." : "Save profile")), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 md:col-span-2" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Display name"), /* @__PURE__ */ React.createElement("input", { value: form.display_name, onChange: (event) => setForm((current) => ({ ...current, display_name: event.target.value })), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none" })), /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 md:col-span-2" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Tagline"), /* @__PURE__ */ React.createElement("input", { value: form.tagline, onChange: (event) => setForm((current) => ({ ...current, tagline: event.target.value })), placeholder: "One-line creator summary", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none placeholder:text-slate-500" })), /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 md:col-span-2" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Bio"), /* @__PURE__ */ React.createElement("textarea", { value: form.bio, onChange: (event) => setForm((current) => ({ ...current, bio: event.target.value })), rows: 5, placeholder: "Tell visitors what you create and what makes your work distinct.", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none placeholder:text-slate-500" })), /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 md:col-span-2" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Website"), /* @__PURE__ */ React.createElement("input", { value: form.website, onChange: (event) => setForm((current) => ({ ...current, website: event.target.value })), placeholder: "https://example.com", className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none placeholder:text-slate-500" }))), /* @__PURE__ */ React.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { className: "text-base font-semibold text-white" }, "Social links"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, "Add the channels that matter for your creator identity.")), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: addSocialLink, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-white" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-plus" }), "Add link")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, form.social_links.map((link2, index2) => /* @__PURE__ */ React.createElement("div", { key: `${index2}-${link2.platform}`, className: "grid gap-3 rounded-[24px] border border-white/10 bg-black/20 p-4 md:grid-cols-[180px_minmax(0,1fr)_auto]" }, /* @__PURE__ */ React.createElement("input", { value: link2.platform, onChange: (event) => updateSocialLink(index2, "platform", event.target.value), placeholder: "instagram", className: "rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm text-white outline-none placeholder:text-slate-500" }), /* @__PURE__ */ React.createElement("input", { value: link2.url, onChange: (event) => updateSocialLink(index2, "url", event.target.value), placeholder: "https://...", className: "rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm text-white outline-none placeholder:text-slate-500" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => removeSocialLink(index2), className: "inline-flex items-center justify-center rounded-2xl border border-rose-300/20 bg-rose-300/10 px-4 py-3 text-sm text-rose-100" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-trash" }))))))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Publishing footprint"), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4" }, (props.moduleSummaries || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.key, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-slate-200" }, /* @__PURE__ */ React.createElement("i", { className: item.icon }), /* @__PURE__ */ React.createElement("span", null, item.label)), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-3xl font-semibold text-white" }, Number(item.count || 0).toLocaleString()), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-slate-400" }, Number(item.published_count || 0).toLocaleString(), " published, ", Number(item.draft_count || 0).toLocaleString(), " drafts"))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Featured identity"), /* @__PURE__ */ React.createElement("a", { href: "/studio/featured", className: "text-sm font-medium text-sky-100" }, "Manage featured")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, featuredModules.length > 0 ? featuredModules.map((module) => /* @__PURE__ */ React.createElement("span", { key: module, className: "inline-flex items-center rounded-full border border-sky-300/20 bg-sky-300/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-sky-100" }, socialPlatformLabel(module))) : /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-400" }, "No featured modules selected yet.")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, Object.entries(featuredContent).map(([module, item]) => item ? /* @__PURE__ */ React.createElement("a", { key: module, href: item.view_url || item.preview_url || "/studio/featured", className: "flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 p-3" }, item.image_url ? /* @__PURE__ */ React.createElement("img", { src: item.image_url, alt: item.title, className: "h-14 w-14 rounded-2xl object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-14 w-14 items-center justify-center rounded-2xl bg-white/5 text-slate-400" }, /* @__PURE__ */ React.createElement("i", { className: item.module_icon || "fa-solid fa-star" })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, socialPlatformLabel(module)), /* @__PURE__ */ React.createElement("div", { className: "truncate text-sm font-semibold text-white" }, item.title))) : null))))))); } -const __vite_glob_0_153 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_154 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioProfile }, Symbol.toStringTag, { value: "Module" })); @@ -108318,7 +108651,7 @@ function StudioScheduled() { }, [items, summary.next_publish_at]); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "grid gap-4 xl:grid-cols-[minmax(0,1fr)_340px]" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Scheduled total"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-semibold text-white" }, Number(summary.total || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4 md:col-span-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Next publish slot"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xl font-semibold text-white" }, formatReleaseCountdown(summary.next_publish_at, nowMs)), summary.next_publish_at && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, formatScheduledDate(summary.next_publish_at)))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4" }, (summary.by_module || []).map((entry) => /* @__PURE__ */ React.createElement("div", { key: entry.key, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-slate-300" }, /* @__PURE__ */ React.createElement("i", { className: entry.icon }), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-white" }, entry.label)), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-2xl font-semibold text-white" }, Number(entry.count || 0).toLocaleString()))))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Agenda"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, agenda.length > 0 ? agenda.slice(0, 6).map((day) => /* @__PURE__ */ React.createElement("div", { key: day.date, className: "rounded-[22px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, day.label), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, day.count, " items")), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-400" }, day.items.slice(0, 2).map((item) => item.title).join(" • ")))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] border border-dashed border-white/15 px-4 py-8 text-sm text-slate-400" }, "No scheduled items yet.")))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.14),_transparent_35%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 lg:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-5" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Search scheduled work"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilters({ q: event.target.value }), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white", placeholder: "Title or module" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Module"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.module || "all", onChange: (val) => updateFilters({ module: val }), options: listing.module_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Date range"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.range || "upcoming", onChange: (val) => updateFilters({ range: val }), options: rangeOptions2, searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Start date"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: filters.start_date || "", onChange: (nextValue) => updateFilters({ range: "custom", start_date: nextValue }), mode: "date", placeholder: "Start date", clearable: true, className: "bg-black/20" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "End date"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: filters.end_date || "", onChange: (nextValue) => updateFilters({ range: "custom", end_date: nextValue }), mode: "date", placeholder: "End date", clearable: true, className: "bg-black/20" })), /* @__PURE__ */ React.createElement("div", { className: "flex items-end" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => updateFilters({ q: "", module: "all", range: "upcoming", start_date: "", end_date: "" }), className: "w-full rounded-2xl border border-white/10 px-4 py-3 text-sm text-slate-200" }, "Reset")))), /* @__PURE__ */ React.createElement("section", { className: "space-y-4" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-3 text-[11px] font-semibold uppercase tracking-[0.18em] text-sky-200/70" }, /* @__PURE__ */ React.createElement("span", null, item.module_label), /* @__PURE__ */ React.createElement("span", null, item.status)), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex flex-wrap items-center gap-4 text-sm text-slate-400" }, /* @__PURE__ */ React.createElement("span", null, formatReleaseCountdown(item.scheduled_at || item.published_at, nowMs)), /* @__PURE__ */ React.createElement("span", null, formatScheduledDate(item.scheduled_at || item.published_at)), item.visibility && /* @__PURE__ */ React.createElement("span", null, "Visibility: ", item.visibility), item.updated_at && /* @__PURE__ */ React.createElement("span", null, "Last edited ", formatScheduledDate(item.updated_at)), item.schedule_timezone && /* @__PURE__ */ React.createElement("span", null, item.schedule_timezone))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("a", { href: item.edit_url || item.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-slate-200" }, "Edit"), /* @__PURE__ */ React.createElement("a", { href: item.edit_url || item.manage_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-slate-200" }, "Reschedule"), item.preview_url && /* @__PURE__ */ React.createElement("a", { href: item.preview_url, className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-slate-200" }, "Preview"), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: busyId === `publish:${item.id}`, onClick: () => runAction(item, "publish"), className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm text-sky-100 disabled:opacity-50" }, "Publish now"), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: busyId === `unschedule:${item.id}`, onClick: () => runAction(item, "unschedule"), className: "inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 text-sm text-slate-200 disabled:opacity-50" }, "Unschedule"))))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/15 px-6 py-16 text-center text-slate-400" }, "No scheduled content matches this view.")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) <= 1, onClick: () => updateFilters({ page: Math.max(1, (meta.current_page || 1) - 1) }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Previous"), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Page ", meta.current_page || 1, " of ", meta.last_page || 1), /* @__PURE__ */ React.createElement("button", { type: "button", disabled: (meta.current_page || 1) >= (meta.last_page || 1), onClick: () => updateFilters({ page: (meta.current_page || 1) + 1 }), className: "rounded-full border border-white/10 px-4 py-2 disabled:opacity-40" }, "Next")))); } -const __vite_glob_0_154 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_155 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioScheduled }, Symbol.toStringTag, { value: "Module" })); @@ -108336,7 +108669,7 @@ function StudioSearch() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(56,189,248,0.14),_transparent_35%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 lg:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-5" }, /* @__PURE__ */ React.createElement("label", { className: "space-y-2 text-sm text-slate-300 xl:col-span-3" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Search Studio"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilters({ q: event.target.value }), className: "w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white", placeholder: "Search content, comments, inbox, or assets" })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Surface"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.type || "all", onChange: (val) => updateFilters({ type: val }), options: search2.type_options || [], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "space-y-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "block text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Module"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.module || "all", onChange: (val) => updateFilters({ module: val }), options: search2.module_options || [], searchable: false })))), filters.q ? /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Found ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, Number(search2.summary?.total || 0).toLocaleString()), " matches for ", /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, search2.summary?.query)), sections.length > 0 ? sections.map((section) => /* @__PURE__ */ React.createElement("section", { key: section.key, className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, section.label), /* @__PURE__ */ React.createElement("span", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, section.count, " matches")), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3" }, section.items.map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.href, className: "block rounded-[24px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-white/[0.04] text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: item.icon })), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-base font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-slate-500" }, item.subtitle), /* @__PURE__ */ React.createElement("p", { className: "mt-3 line-clamp-3 text-sm leading-6 text-slate-400" }, item.description)))))))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/15 px-6 py-16 text-center text-slate-400" }, "No results matched this search yet.")) : /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_320px]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Continue working"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:grid-cols-2" }, (search2.empty_state?.continue_working || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.edit_url || item.manage_url, className: "block rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, item.module_label, " · ", item.workflow?.readiness?.label))))), /* @__PURE__ */ React.createElement("aside", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Stale drafts"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3" }, (search2.empty_state?.stale_drafts || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.id, href: item.edit_url || item.manage_url, className: "block rounded-2xl border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, item.module_label))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "Quick create"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3" }, (props.quickCreate || []).map((item) => /* @__PURE__ */ React.createElement("a", { key: item.key, href: item.url, className: "inline-flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-100" }, /* @__PURE__ */ React.createElement("i", { className: item.icon }), /* @__PURE__ */ React.createElement("span", null, "New ", item.label))))))))); } -const __vite_glob_0_155 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_156 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioSearch }, Symbol.toStringTag, { value: "Module" })); @@ -108344,7 +108677,7 @@ function StudioSettings() { const { props } = X$1(); return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, "System handoff"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-2xl text-sm leading-6 text-slate-400" }, "Studio now keeps creator workflow preferences in their own surface. This page stays focused on links out to adjacent dashboards and the control points that do not belong in the day-to-day workflow UI."), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-3 md:grid-cols-2" }, (props.links || []).map((link2) => /* @__PURE__ */ React.createElement("a", { key: link2.url, href: link2.url, className: "rounded-[22px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20 hover:bg-black/30" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-sky-100" }, /* @__PURE__ */ React.createElement("i", { className: link2.icon }), /* @__PURE__ */ React.createElement("span", { className: "text-base font-semibold text-white" }, link2.label)), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, "Open the linked dashboard or settings surface without losing the Studio navigation shell as the default control plane."))))), /* @__PURE__ */ React.createElement("section", { className: "space-y-6" }, (props.sections || []).map((section) => /* @__PURE__ */ React.createElement("div", { key: section.title, className: "rounded-[30px] border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, section.title), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6 text-slate-400" }, section.body), /* @__PURE__ */ React.createElement("a", { href: section.href, className: "mt-4 inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-sm font-semibold text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, section.cta, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }))))))); } -const __vite_glob_0_156 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_157 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioSettings }, Symbol.toStringTag, { value: "Module" })); @@ -108365,7 +108698,7 @@ function StudioStories() { } )); } -const __vite_glob_0_157 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_158 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioStories }, Symbol.toStringTag, { value: "Module" })); @@ -109028,7 +109361,7 @@ function StudioUploadQueue() { ))))); }))))); } -const __vite_glob_0_158 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_159 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioUploadQueue }, Symbol.toStringTag, { value: "Module" })); @@ -110760,7 +111093,7 @@ function StudioWorldEditor() { )) : null )); } -const __vite_glob_0_159 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_160 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioWorldEditor }, Symbol.toStringTag, { value: "Module" })); @@ -110846,7 +111179,7 @@ function StudioWorldsIndex() { }; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-6" }, /* @__PURE__ */ React.createElement(WorldAnalyticsPortfolioPanel, { analytics: props.analytics }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-[minmax(0,1fr)_12rem_12rem_auto] lg:items-end" }, /* @__PURE__ */ React.createElement("label", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Search"), /* @__PURE__ */ React.createElement("input", { value: filters.q || "", onChange: (event) => updateFilter("q", event.target.value), placeholder: "Search title, slug, or summary", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Status"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.status || "", onChange: (val) => updateFilter("status", val), options: [{ value: "", label: "All statuses" }, ...props.statusOptions || []], searchable: false })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Type"), /* @__PURE__ */ React.createElement(NovaSelect, { value: filters.type || "", onChange: (val) => updateFilter("type", val), options: [{ value: "", label: "All types" }, ...props.typeOptions || []], searchable: false })), /* @__PURE__ */ React.createElement("a", { href: props.createUrl, className: "inline-flex items-center justify-center gap-2 rounded-2xl border border-sky-300/20 bg-sky-400/10 px-5 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-plus" }), "New world"))), /* @__PURE__ */ React.createElement("section", { className: "grid gap-4 xl:grid-cols-2" }, items.length > 0 ? items.map((world) => /* @__PURE__ */ React.createElement("a", { key: world.id, href: world.edit_url, className: "rounded-[28px] border border-white/10 bg-white/[0.03] p-5 transition hover:-translate-y-1 hover:border-white/20 hover:bg-white/[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, /* @__PURE__ */ React.createElement(WorldStatusBadge, { badge: { label: world.status, tone: "slate" } }), /* @__PURE__ */ React.createElement(WorldStatusBadge, { badge: { label: world.type, tone: "slate" } }), (Array.isArray(world.status_badges) ? world.status_badges : []).map((badge) => /* @__PURE__ */ React.createElement(WorldStatusBadge, { key: `${world.id}-${badge.label}`, badge }))), /* @__PURE__ */ React.createElement("h2", { className: "mt-4 text-2xl font-semibold tracking-[-0.03em] text-white" }, world.title), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-500" }, "/", world.slug), world.summary ? /* @__PURE__ */ React.createElement("p", { className: "mt-4 text-sm leading-6 text-slate-300" }, world.summary) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-4 text-sm text-slate-400" }, world.timeframe_label ? /* @__PURE__ */ React.createElement("span", null, world.timeframe_label) : null, world.promotion_window_label ? /* @__PURE__ */ React.createElement("span", null, world.promotion_window_label) : null, /* @__PURE__ */ React.createElement("span", null, world.relation_count, " relations"), world.live_submission_count > 0 ? /* @__PURE__ */ React.createElement("span", null, world.live_submission_count, " live submissions") : null, world.theme_key ? /* @__PURE__ */ React.createElement("span", null, world.theme_key) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-3 text-sm font-semibold" }, /* @__PURE__ */ React.createElement("span", { className: "text-sky-100" }, "Edit"), /* @__PURE__ */ React.createElement("span", { className: "text-slate-500" }, "Preview"), world.public_url ? /* @__PURE__ */ React.createElement("span", { className: "text-slate-500" }, "Public") : null))) : /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] border border-dashed border-white/10 bg-white/[0.02] p-6 text-sm text-slate-400" }, "No worlds match this filter yet.")))); } -const __vite_glob_0_160 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_161 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioWorldsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -115480,7 +115813,7 @@ function UploadPage({ draftId = null, filesCdnUrl = "", chunkSize, chunkRequestT "Reset" )))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/5 p-6" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold" }, "Pipeline status"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-white/60" }, "Stage: ", /* @__PURE__ */ React.createElement("span", { className: "text-white" }, statusLabel2)), /* @__PURE__ */ React.createElement("div", { className: "mt-4 h-2 w-full overflow-hidden rounded-full bg-white/10" }, /* @__PURE__ */ React.createElement("div", { className: "h-full bg-sky-400 transition-all", style: { width: `${state.progress}%` } })), state.failureReason && /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-sm text-red-200" }, "Failure: ", state.failureReason), state.previewUrl && state.phase === phases.success && /* @__PURE__ */ React.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white/80" }, "CDN preview"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 overflow-hidden rounded-xl border border-white/10" }, /* @__PURE__ */ React.createElement("img", { src: state.previewUrl, alt: "CDN preview", className: "h-56 w-full object-cover" }))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-xs text-white/60" }, "Session: ", state.sessionId ?? "—")), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/5 p-6" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold" }, "Draft resume"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-white/60" }, "Use the draft link to resume an interrupted upload."), draftId ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-sm text-white/80" }, "Draft ID: ", draftId) : /* @__PURE__ */ React.createElement("div", { className: "mt-4 text-sm text-white/50" }, "No draft loaded.")))))); } -const __vite_glob_0_161 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_162 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadPage }, Symbol.toStringTag, { value: "Module" })); @@ -115658,7 +115991,7 @@ function WorldIndex() { const { props } = X$1(); const hasSpotlight = Boolean(props.spotlightWorld); const featuredFallback = !hasSpotlight && Array.isArray(props.featuredWorlds) ? props.featuredWorlds : []; - return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(249,115,22,0.12),_transparent_28%),radial-gradient(circle_at_top_right,_rgba(56,189,248,0.12),_transparent_32%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { title: props.seo?.title || "Worlds - Skinbase", description: props.seo?.description || props.description, image: props.seo?.image }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[36px] border border-white/10 bg-white/[0.03] p-6 sm:p-8" }, /* @__PURE__ */ React.createElement("div", { className: "max-w-4xl" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/70" }, "Skinbase Worlds"), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold tracking-[-0.05em] text-white sm:text-5xl" }, "Curated spaces for seasonal culture, scene moments, and editorial campaigns."), /* @__PURE__ */ React.createElement("p", { className: "mt-5 max-w-3xl text-base leading-7 text-slate-300" }, "Worlds bundle together artworks, collections, creators, groups, cards, releases, events, challenges, and newsroom context into a single themed destination. They are not filters. They are editorial environments."))), hasSpotlight ? /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ React.createElement("main", { className: "min-h-screen bg-[radial-gradient(circle_at_top_left,_rgba(249,115,22,0.12),_transparent_28%),radial-gradient(circle_at_top_right,_rgba(56,189,248,0.12),_transparent_32%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: "Worlds - Skinbase", description: props.description }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl" }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[36px] border border-white/10 bg-white/[0.03] p-6 sm:p-8" }, /* @__PURE__ */ React.createElement("div", { className: "max-w-4xl" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/70" }, "Skinbase Worlds"), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-4xl font-semibold tracking-[-0.05em] text-white sm:text-5xl" }, "Curated spaces for seasonal culture, scene moments, and editorial campaigns."), /* @__PURE__ */ React.createElement("p", { className: "mt-5 max-w-3xl text-base leading-7 text-slate-300" }, "Worlds bundle together artworks, collections, creators, groups, cards, releases, events, challenges, and newsroom context into a single themed destination. They are not filters. They are editorial environments."))), hasSpotlight ? /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement( ActiveWorldSpotlight, { spotlight: props.spotlightWorld, @@ -115724,7 +116057,7 @@ function WorldIndex() { } ))); } -const __vite_glob_0_162 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_163 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldIndex }, Symbol.toStringTag, { value: "Module" })); @@ -115999,7 +116332,7 @@ function WorldShow() { container.removeEventListener("click", clickHandler); }; }, [previewMode, world?.id]); - return /* @__PURE__ */ React.createElement("main", { ref: rootRef, className: "min-h-screen bg-[radial-gradient(circle_at_top,_rgba(56,189,248,0.12),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { title: props.seo?.title || `${world?.title || "World"} - Skinbase`, description: props.seo?.description || world?.summary, image: props.seo?.image }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl" }, previewMode ? /* @__PURE__ */ React.createElement("section", { className: "mb-6 rounded-[28px] border border-amber-300/20 bg-amber-400/10 px-5 py-4 text-sm text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100/75" }, "Studio preview"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, "You are viewing the editorial preview version of this world before or alongside public release.")), world?.public_url ? /* @__PURE__ */ React.createElement("a", { href: world.public_url, className: "inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white" }, "Open canonical page ", /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-up-right-from-square" })) : null)) : null, /* @__PURE__ */ React.createElement(WorldArchiveNotice, { notice: archiveNotice }), recap ? /* @__PURE__ */ React.createElement(WorldRecapHero, { world, recap, previewMode }) : /* @__PURE__ */ React.createElement(WorldHero, { world, previewMode }), recap ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(WorldRecapSummaryCard, { recap }), /* @__PURE__ */ React.createElement(WorldRecapStatsGrid, { stats: recap.stats }), /* @__PURE__ */ React.createElement(WorldRecapArticleCard, { article: recap.article }), /* @__PURE__ */ React.createElement(WorldRecapFeaturedArtworks, { section: recap.featured_artworks }), /* @__PURE__ */ React.createElement(WorldChallengePanel, { section: linkedChallenge })) : /* @__PURE__ */ React.createElement(WorldChallengePanel, { section: linkedChallenge }), familySummary ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.03em] text-white" }, "Recurring Family"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-6 text-slate-400" }, "Each edition stays public, but the family route always resolves to the canonical current or latest edition.")), /* @__PURE__ */ React.createElement(WorldFamilyCard, { family: familySummary, sourceSurface: "navigation", sourceDetail: "family_summary" })) : null, /* @__PURE__ */ React.createElement(WebStoryCard, { story: webStory, worldTitle: world?.title || "this World" }), sections.length > 0 ? sections.map((section) => /* @__PURE__ */ React.createElement(WorldSection, { key: section.key, section })) : null, /* @__PURE__ */ React.createElement(WorldChallengeEntriesRail, { section: linkedChallengeEntries, challengeId: linkedChallenge?.id || null }), /* @__PURE__ */ React.createElement(WorldChallengeWinnersPanel, { section: linkedChallengeWinners, challengeId: linkedChallenge?.id || null }), /* @__PURE__ */ React.createElement(WorldChallengeFinalistsGrid, { panel: linkedChallenge, section: linkedChallengeFinalists }), recap ? /* @__PURE__ */ React.createElement(WorldRecapCommunityHighlights, { section: recap.community_highlights }) : /* @__PURE__ */ React.createElement(RewardedContributors, { section: rewardedContributors, world }), recap ? /* @__PURE__ */ React.createElement(WorldRecapCreatorsPanel, { section: recap.creators }) : /* @__PURE__ */ React.createElement(WorldCommunitySubmissionsSection, { section: communitySubmissions }), currentEdition ? /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ React.createElement("main", { ref: rootRef, className: "min-h-screen bg-[radial-gradient(circle_at_top,_rgba(56,189,248,0.12),_transparent_28%),linear-gradient(180deg,_#020617_0%,_#02040a_100%)] px-4 py-10 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement(SeoHead, { seo: props.seo || {}, title: `${world?.title || "World"} - Skinbase`, description: world?.summary }), /* @__PURE__ */ React.createElement("div", { className: "mx-auto max-w-7xl" }, previewMode ? /* @__PURE__ */ React.createElement("section", { className: "mb-6 rounded-[28px] border border-amber-300/20 bg-amber-400/10 px-5 py-4 text-sm text-amber-50" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-100/75" }, "Studio preview"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 font-semibold text-white" }, "You are viewing the editorial preview version of this world before or alongside public release.")), world?.public_url ? /* @__PURE__ */ React.createElement("a", { href: world.public_url, className: "inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white" }, "Open canonical page ", /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-up-right-from-square" })) : null)) : null, /* @__PURE__ */ React.createElement(WorldArchiveNotice, { notice: archiveNotice }), recap ? /* @__PURE__ */ React.createElement(WorldRecapHero, { world, recap, previewMode }) : /* @__PURE__ */ React.createElement(WorldHero, { world, previewMode }), recap ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(WorldRecapSummaryCard, { recap }), /* @__PURE__ */ React.createElement(WorldRecapStatsGrid, { stats: recap.stats }), /* @__PURE__ */ React.createElement(WorldRecapArticleCard, { article: recap.article }), /* @__PURE__ */ React.createElement(WorldRecapFeaturedArtworks, { section: recap.featured_artworks }), /* @__PURE__ */ React.createElement(WorldChallengePanel, { section: linkedChallenge })) : /* @__PURE__ */ React.createElement(WorldChallengePanel, { section: linkedChallenge }), familySummary ? /* @__PURE__ */ React.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-semibold tracking-[-0.03em] text-white" }, "Recurring Family"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-6 text-slate-400" }, "Each edition stays public, but the family route always resolves to the canonical current or latest edition.")), /* @__PURE__ */ React.createElement(WorldFamilyCard, { family: familySummary, sourceSurface: "navigation", sourceDetail: "family_summary" })) : null, /* @__PURE__ */ React.createElement(WebStoryCard, { story: webStory, worldTitle: world?.title || "this World" }), sections.length > 0 ? sections.map((section) => /* @__PURE__ */ React.createElement(WorldSection, { key: section.key, section })) : null, /* @__PURE__ */ React.createElement(WorldChallengeEntriesRail, { section: linkedChallengeEntries, challengeId: linkedChallenge?.id || null }), /* @__PURE__ */ React.createElement(WorldChallengeWinnersPanel, { section: linkedChallengeWinners, challengeId: linkedChallenge?.id || null }), /* @__PURE__ */ React.createElement(WorldChallengeFinalistsGrid, { panel: linkedChallenge, section: linkedChallengeFinalists }), recap ? /* @__PURE__ */ React.createElement(WorldRecapCommunityHighlights, { section: recap.community_highlights }) : /* @__PURE__ */ React.createElement(RewardedContributors, { section: rewardedContributors, world }), recap ? /* @__PURE__ */ React.createElement(WorldRecapCreatorsPanel, { section: recap.creators }) : /* @__PURE__ */ React.createElement(WorldCommunitySubmissionsSection, { section: communitySubmissions }), currentEdition ? /* @__PURE__ */ React.createElement( SupportingRail, { title: "Current Edition", @@ -116025,7 +116358,7 @@ function WorldShow() { } ))); } -const __vite_glob_0_163 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_164 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldShow }, Symbol.toStringTag, { value: "Module" })); @@ -141633,153 +141966,154 @@ const pages = /* @__PURE__ */ Object.assign({ "./Pages/Admin/Academy/AnalyticsOverview.jsx": __vite_glob_0_14, "./Pages/Admin/Academy/AnalyticsSearch.jsx": __vite_glob_0_15, "./Pages/Admin/Academy/Billing.jsx": __vite_glob_0_16, - "./Pages/Admin/Academy/CourseBuilder.jsx": __vite_glob_0_17, - "./Pages/Admin/Academy/CourseEditor.jsx": __vite_glob_0_18, - "./Pages/Admin/Academy/CrudForm.jsx": __vite_glob_0_19, - "./Pages/Admin/Academy/CrudIndex.jsx": __vite_glob_0_20, - "./Pages/Admin/Academy/Dashboard.jsx": __vite_glob_0_21, - "./Pages/Admin/Academy/LessonEditor.jsx": __vite_glob_0_22, - "./Pages/Admin/Academy/Submissions.jsx": __vite_glob_0_23, - "./Pages/Admin/AiBiography.jsx": __vite_glob_0_24, - "./Pages/Admin/Artworks.jsx": __vite_glob_0_25, - "./Pages/Admin/AuthAudit.jsx": __vite_glob_0_26, - "./Pages/Admin/DailyActivity.jsx": __vite_glob_0_27, - "./Pages/Admin/Dashboard.jsx": __vite_glob_0_28, - "./Pages/Admin/FeaturedArtworks.jsx": __vite_glob_0_29, - "./Pages/Admin/HomepageAnnouncements/Form.jsx": __vite_glob_0_30, - "./Pages/Admin/HomepageAnnouncements/Index.jsx": __vite_glob_0_31, - "./Pages/Admin/Settings.jsx": __vite_glob_0_32, - "./Pages/Admin/Stories.jsx": __vite_glob_0_33, - "./Pages/Admin/UploadQueue.jsx": __vite_glob_0_34, - "./Pages/Admin/UsernameQueue.jsx": __vite_glob_0_35, - "./Pages/Admin/Users/Index.jsx": __vite_glob_0_36, - "./Pages/Artwork/SimilarArtworksHeader.jsx": __vite_glob_0_37, - "./Pages/ArtworkPage.jsx": __vite_glob_0_38, - "./Pages/CategoriesPage.jsx": __vite_glob_0_39, - "./Pages/Collection/CollectionAnalytics.jsx": __vite_glob_0_40, - "./Pages/Collection/CollectionDashboard.jsx": __vite_glob_0_41, - "./Pages/Collection/CollectionFeaturedIndex.jsx": __vite_glob_0_42, - "./Pages/Collection/CollectionHistory.jsx": __vite_glob_0_43, - "./Pages/Collection/CollectionManage.jsx": __vite_glob_0_44, - "./Pages/Collection/CollectionSeriesShow.jsx": __vite_glob_0_45, - "./Pages/Collection/CollectionShow.jsx": __vite_glob_0_46, - "./Pages/Collection/CollectionStaffProgramming.jsx": __vite_glob_0_47, - "./Pages/Collection/CollectionStaffSurfaces.jsx": __vite_glob_0_48, - "./Pages/Collection/FeaturedArtworksAdmin.jsx": __vite_glob_0_49, - "./Pages/Collection/NovaCardsAdminIndex.jsx": __vite_glob_0_50, - "./Pages/Collection/NovaCardsAssetPackAdmin.jsx": __vite_glob_0_51, - "./Pages/Collection/NovaCardsChallengeAdmin.jsx": __vite_glob_0_52, - "./Pages/Collection/NovaCardsCollectionAdmin.jsx": __vite_glob_0_53, - "./Pages/Collection/NovaCardsTemplateAdmin.jsx": __vite_glob_0_54, - "./Pages/Collection/SavedCollections.jsx": __vite_glob_0_55, - "./Pages/Community/CommunityActivityPage.jsx": __vite_glob_0_56, - "./Pages/Community/LatestCommentsPage.jsx": __vite_glob_0_57, - "./Pages/Enhance/Create.jsx": __vite_glob_0_58, - "./Pages/Enhance/Index.jsx": __vite_glob_0_59, - "./Pages/Enhance/Show.jsx": __vite_glob_0_60, - "./Pages/Feed/FollowingFeed.jsx": __vite_glob_0_61, - "./Pages/Feed/HashtagFeed.jsx": __vite_glob_0_62, - "./Pages/Feed/SavedFeed.jsx": __vite_glob_0_63, - "./Pages/Feed/SearchFeed.jsx": __vite_glob_0_64, - "./Pages/Feed/TrendingFeed.jsx": __vite_glob_0_65, - "./Pages/Forum/ForumCategory.jsx": __vite_glob_0_66, - "./Pages/Forum/ForumEditPost.jsx": __vite_glob_0_67, - "./Pages/Forum/ForumIndex.jsx": __vite_glob_0_68, - "./Pages/Forum/ForumNewThread.jsx": __vite_glob_0_69, - "./Pages/Forum/ForumSection.jsx": __vite_glob_0_70, - "./Pages/Forum/ForumThread.jsx": __vite_glob_0_71, - "./Pages/Group/GroupChallengeShow.jsx": __vite_glob_0_72, - "./Pages/Group/GroupEventShow.jsx": __vite_glob_0_73, - "./Pages/Group/GroupFaqPage.jsx": __vite_glob_0_74, - "./Pages/Group/GroupHelpPage.jsx": __vite_glob_0_75, - "./Pages/Group/GroupIndex.jsx": __vite_glob_0_76, - "./Pages/Group/GroupPostShow.jsx": __vite_glob_0_77, - "./Pages/Group/GroupProjectShow.jsx": __vite_glob_0_78, - "./Pages/Group/GroupQuickstartPage.jsx": __vite_glob_0_79, - "./Pages/Group/GroupReleaseShow.jsx": __vite_glob_0_80, - "./Pages/Group/GroupShow.jsx": __vite_glob_0_81, - "./Pages/Help/AccountHelpPage.jsx": __vite_glob_0_82, - "./Pages/Help/AuthHelpPage.jsx": __vite_glob_0_83, - "./Pages/Help/CardsHelpPage.jsx": __vite_glob_0_84, - "./Pages/Help/HelpCenterPage.jsx": __vite_glob_0_85, - "./Pages/Help/ProfileHelpPage.jsx": __vite_glob_0_86, - "./Pages/Help/StudioHelpPage.jsx": __vite_glob_0_87, - "./Pages/Help/TroubleshootingHelpPage.jsx": __vite_glob_0_88, - "./Pages/Help/UploadHelpPage.jsx": __vite_glob_0_89, - "./Pages/Help/WorldsHelpPage.jsx": __vite_glob_0_90, - "./Pages/Leaderboard/LeaderboardPage.jsx": __vite_glob_0_91, - "./Pages/Messages/Index.jsx": __vite_glob_0_92, - "./Pages/Moderation/AiBiographyAdmin.jsx": __vite_glob_0_93, - "./Pages/Moderation/ArtworkMaturityQueue.jsx": __vite_glob_0_94, - "./Pages/Moderation/Enhance/Index.jsx": __vite_glob_0_95, - "./Pages/Moderation/Enhance/Show.jsx": __vite_glob_0_96, - "./Pages/Moderation/WorldWebStoriesIndex.jsx": __vite_glob_0_97, - "./Pages/Moderation/WorldWebStoryEditor.jsx": __vite_glob_0_98, - "./Pages/News/NewsComments.jsx": __vite_glob_0_99, - "./Pages/News/NewsImagePreview.jsx": __vite_glob_0_100, - "./Pages/Profile/ProfileGallery.jsx": __vite_glob_0_101, - "./Pages/Profile/ProfileShow.jsx": __vite_glob_0_102, - "./Pages/Settings/ProfileEdit.jsx": __vite_glob_0_103, - "./Pages/Studio/StudioActivity.jsx": __vite_glob_0_104, - "./Pages/Studio/StudioAnalytics.jsx": __vite_glob_0_105, - "./Pages/Studio/StudioArchived.jsx": __vite_glob_0_106, - "./Pages/Studio/StudioArtworkAnalytics.jsx": __vite_glob_0_107, - "./Pages/Studio/StudioArtworkEdit.jsx": __vite_glob_0_108, - "./Pages/Studio/StudioArtworks.jsx": __vite_glob_0_109, - "./Pages/Studio/StudioAssets.jsx": __vite_glob_0_110, - "./Pages/Studio/StudioCalendar.jsx": __vite_glob_0_111, - "./Pages/Studio/StudioCardAnalytics.jsx": __vite_glob_0_112, - "./Pages/Studio/StudioCardEditor.jsx": __vite_glob_0_113, - "./Pages/Studio/StudioCardsIndex.jsx": __vite_glob_0_114, - "./Pages/Studio/StudioChallenges.jsx": __vite_glob_0_115, - "./Pages/Studio/StudioCollections.jsx": __vite_glob_0_116, - "./Pages/Studio/StudioComments.jsx": __vite_glob_0_117, - "./Pages/Studio/StudioContentIndex.jsx": __vite_glob_0_118, - "./Pages/Studio/StudioDashboard.jsx": __vite_glob_0_119, - "./Pages/Studio/StudioDrafts.jsx": __vite_glob_0_120, - "./Pages/Studio/StudioFeatured.jsx": __vite_glob_0_121, - "./Pages/Studio/StudioFollowers.jsx": __vite_glob_0_122, - "./Pages/Studio/StudioGroupActivity.jsx": __vite_glob_0_123, - "./Pages/Studio/StudioGroupArtworks.jsx": __vite_glob_0_124, - "./Pages/Studio/StudioGroupAssets.jsx": __vite_glob_0_125, - "./Pages/Studio/StudioGroupChallengeEditor.jsx": __vite_glob_0_126, - "./Pages/Studio/StudioGroupChallenges.jsx": __vite_glob_0_127, - "./Pages/Studio/StudioGroupCollections.jsx": __vite_glob_0_128, - "./Pages/Studio/StudioGroupCreate.jsx": __vite_glob_0_129, - "./Pages/Studio/StudioGroupDashboard.jsx": __vite_glob_0_130, - "./Pages/Studio/StudioGroupEventEditor.jsx": __vite_glob_0_131, - "./Pages/Studio/StudioGroupEvents.jsx": __vite_glob_0_132, - "./Pages/Studio/StudioGroupInvitations.jsx": __vite_glob_0_133, - "./Pages/Studio/StudioGroupJoinRequests.jsx": __vite_glob_0_134, - "./Pages/Studio/StudioGroupMembers.jsx": __vite_glob_0_135, - "./Pages/Studio/StudioGroupPostEditor.jsx": __vite_glob_0_136, - "./Pages/Studio/StudioGroupPosts.jsx": __vite_glob_0_137, - "./Pages/Studio/StudioGroupProjectEditor.jsx": __vite_glob_0_138, - "./Pages/Studio/StudioGroupProjects.jsx": __vite_glob_0_139, - "./Pages/Studio/StudioGroupRecruitment.jsx": __vite_glob_0_140, - "./Pages/Studio/StudioGroupReleaseEditor.jsx": __vite_glob_0_141, - "./Pages/Studio/StudioGroupReleases.jsx": __vite_glob_0_142, - "./Pages/Studio/StudioGroupReputation.jsx": __vite_glob_0_143, - "./Pages/Studio/StudioGroupReviewQueue.jsx": __vite_glob_0_144, - "./Pages/Studio/StudioGroupSettings.jsx": __vite_glob_0_145, - "./Pages/Studio/StudioGroupsIndex.jsx": __vite_glob_0_146, - "./Pages/Studio/StudioGrowth.jsx": __vite_glob_0_147, - "./Pages/Studio/StudioInbox.jsx": __vite_glob_0_148, - "./Pages/Studio/StudioNewsEditor.jsx": __vite_glob_0_149, - "./Pages/Studio/StudioNewsIndex.jsx": __vite_glob_0_150, - "./Pages/Studio/StudioNewsTaxonomies.jsx": __vite_glob_0_151, - "./Pages/Studio/StudioPreferences.jsx": __vite_glob_0_152, - "./Pages/Studio/StudioProfile.jsx": __vite_glob_0_153, - "./Pages/Studio/StudioScheduled.jsx": __vite_glob_0_154, - "./Pages/Studio/StudioSearch.jsx": __vite_glob_0_155, - "./Pages/Studio/StudioSettings.jsx": __vite_glob_0_156, - "./Pages/Studio/StudioStories.jsx": __vite_glob_0_157, - "./Pages/Studio/StudioUploadQueue.jsx": __vite_glob_0_158, - "./Pages/Studio/StudioWorldEditor.jsx": __vite_glob_0_159, - "./Pages/Studio/StudioWorldsIndex.jsx": __vite_glob_0_160, - "./Pages/Upload/Index.jsx": __vite_glob_0_161, - "./Pages/World/WorldIndex.jsx": __vite_glob_0_162, - "./Pages/World/WorldShow.jsx": __vite_glob_0_163 + "./Pages/Admin/Academy/ChallengeEditor.jsx": __vite_glob_0_17, + "./Pages/Admin/Academy/CourseBuilder.jsx": __vite_glob_0_18, + "./Pages/Admin/Academy/CourseEditor.jsx": __vite_glob_0_19, + "./Pages/Admin/Academy/CrudForm.jsx": __vite_glob_0_20, + "./Pages/Admin/Academy/CrudIndex.jsx": __vite_glob_0_21, + "./Pages/Admin/Academy/Dashboard.jsx": __vite_glob_0_22, + "./Pages/Admin/Academy/LessonEditor.jsx": __vite_glob_0_23, + "./Pages/Admin/Academy/Submissions.jsx": __vite_glob_0_24, + "./Pages/Admin/AiBiography.jsx": __vite_glob_0_25, + "./Pages/Admin/Artworks.jsx": __vite_glob_0_26, + "./Pages/Admin/AuthAudit.jsx": __vite_glob_0_27, + "./Pages/Admin/DailyActivity.jsx": __vite_glob_0_28, + "./Pages/Admin/Dashboard.jsx": __vite_glob_0_29, + "./Pages/Admin/FeaturedArtworks.jsx": __vite_glob_0_30, + "./Pages/Admin/HomepageAnnouncements/Form.jsx": __vite_glob_0_31, + "./Pages/Admin/HomepageAnnouncements/Index.jsx": __vite_glob_0_32, + "./Pages/Admin/Settings.jsx": __vite_glob_0_33, + "./Pages/Admin/Stories.jsx": __vite_glob_0_34, + "./Pages/Admin/UploadQueue.jsx": __vite_glob_0_35, + "./Pages/Admin/UsernameQueue.jsx": __vite_glob_0_36, + "./Pages/Admin/Users/Index.jsx": __vite_glob_0_37, + "./Pages/Artwork/SimilarArtworksHeader.jsx": __vite_glob_0_38, + "./Pages/ArtworkPage.jsx": __vite_glob_0_39, + "./Pages/CategoriesPage.jsx": __vite_glob_0_40, + "./Pages/Collection/CollectionAnalytics.jsx": __vite_glob_0_41, + "./Pages/Collection/CollectionDashboard.jsx": __vite_glob_0_42, + "./Pages/Collection/CollectionFeaturedIndex.jsx": __vite_glob_0_43, + "./Pages/Collection/CollectionHistory.jsx": __vite_glob_0_44, + "./Pages/Collection/CollectionManage.jsx": __vite_glob_0_45, + "./Pages/Collection/CollectionSeriesShow.jsx": __vite_glob_0_46, + "./Pages/Collection/CollectionShow.jsx": __vite_glob_0_47, + "./Pages/Collection/CollectionStaffProgramming.jsx": __vite_glob_0_48, + "./Pages/Collection/CollectionStaffSurfaces.jsx": __vite_glob_0_49, + "./Pages/Collection/FeaturedArtworksAdmin.jsx": __vite_glob_0_50, + "./Pages/Collection/NovaCardsAdminIndex.jsx": __vite_glob_0_51, + "./Pages/Collection/NovaCardsAssetPackAdmin.jsx": __vite_glob_0_52, + "./Pages/Collection/NovaCardsChallengeAdmin.jsx": __vite_glob_0_53, + "./Pages/Collection/NovaCardsCollectionAdmin.jsx": __vite_glob_0_54, + "./Pages/Collection/NovaCardsTemplateAdmin.jsx": __vite_glob_0_55, + "./Pages/Collection/SavedCollections.jsx": __vite_glob_0_56, + "./Pages/Community/CommunityActivityPage.jsx": __vite_glob_0_57, + "./Pages/Community/LatestCommentsPage.jsx": __vite_glob_0_58, + "./Pages/Enhance/Create.jsx": __vite_glob_0_59, + "./Pages/Enhance/Index.jsx": __vite_glob_0_60, + "./Pages/Enhance/Show.jsx": __vite_glob_0_61, + "./Pages/Feed/FollowingFeed.jsx": __vite_glob_0_62, + "./Pages/Feed/HashtagFeed.jsx": __vite_glob_0_63, + "./Pages/Feed/SavedFeed.jsx": __vite_glob_0_64, + "./Pages/Feed/SearchFeed.jsx": __vite_glob_0_65, + "./Pages/Feed/TrendingFeed.jsx": __vite_glob_0_66, + "./Pages/Forum/ForumCategory.jsx": __vite_glob_0_67, + "./Pages/Forum/ForumEditPost.jsx": __vite_glob_0_68, + "./Pages/Forum/ForumIndex.jsx": __vite_glob_0_69, + "./Pages/Forum/ForumNewThread.jsx": __vite_glob_0_70, + "./Pages/Forum/ForumSection.jsx": __vite_glob_0_71, + "./Pages/Forum/ForumThread.jsx": __vite_glob_0_72, + "./Pages/Group/GroupChallengeShow.jsx": __vite_glob_0_73, + "./Pages/Group/GroupEventShow.jsx": __vite_glob_0_74, + "./Pages/Group/GroupFaqPage.jsx": __vite_glob_0_75, + "./Pages/Group/GroupHelpPage.jsx": __vite_glob_0_76, + "./Pages/Group/GroupIndex.jsx": __vite_glob_0_77, + "./Pages/Group/GroupPostShow.jsx": __vite_glob_0_78, + "./Pages/Group/GroupProjectShow.jsx": __vite_glob_0_79, + "./Pages/Group/GroupQuickstartPage.jsx": __vite_glob_0_80, + "./Pages/Group/GroupReleaseShow.jsx": __vite_glob_0_81, + "./Pages/Group/GroupShow.jsx": __vite_glob_0_82, + "./Pages/Help/AccountHelpPage.jsx": __vite_glob_0_83, + "./Pages/Help/AuthHelpPage.jsx": __vite_glob_0_84, + "./Pages/Help/CardsHelpPage.jsx": __vite_glob_0_85, + "./Pages/Help/HelpCenterPage.jsx": __vite_glob_0_86, + "./Pages/Help/ProfileHelpPage.jsx": __vite_glob_0_87, + "./Pages/Help/StudioHelpPage.jsx": __vite_glob_0_88, + "./Pages/Help/TroubleshootingHelpPage.jsx": __vite_glob_0_89, + "./Pages/Help/UploadHelpPage.jsx": __vite_glob_0_90, + "./Pages/Help/WorldsHelpPage.jsx": __vite_glob_0_91, + "./Pages/Leaderboard/LeaderboardPage.jsx": __vite_glob_0_92, + "./Pages/Messages/Index.jsx": __vite_glob_0_93, + "./Pages/Moderation/AiBiographyAdmin.jsx": __vite_glob_0_94, + "./Pages/Moderation/ArtworkMaturityQueue.jsx": __vite_glob_0_95, + "./Pages/Moderation/Enhance/Index.jsx": __vite_glob_0_96, + "./Pages/Moderation/Enhance/Show.jsx": __vite_glob_0_97, + "./Pages/Moderation/WorldWebStoriesIndex.jsx": __vite_glob_0_98, + "./Pages/Moderation/WorldWebStoryEditor.jsx": __vite_glob_0_99, + "./Pages/News/NewsComments.jsx": __vite_glob_0_100, + "./Pages/News/NewsImagePreview.jsx": __vite_glob_0_101, + "./Pages/Profile/ProfileGallery.jsx": __vite_glob_0_102, + "./Pages/Profile/ProfileShow.jsx": __vite_glob_0_103, + "./Pages/Settings/ProfileEdit.jsx": __vite_glob_0_104, + "./Pages/Studio/StudioActivity.jsx": __vite_glob_0_105, + "./Pages/Studio/StudioAnalytics.jsx": __vite_glob_0_106, + "./Pages/Studio/StudioArchived.jsx": __vite_glob_0_107, + "./Pages/Studio/StudioArtworkAnalytics.jsx": __vite_glob_0_108, + "./Pages/Studio/StudioArtworkEdit.jsx": __vite_glob_0_109, + "./Pages/Studio/StudioArtworks.jsx": __vite_glob_0_110, + "./Pages/Studio/StudioAssets.jsx": __vite_glob_0_111, + "./Pages/Studio/StudioCalendar.jsx": __vite_glob_0_112, + "./Pages/Studio/StudioCardAnalytics.jsx": __vite_glob_0_113, + "./Pages/Studio/StudioCardEditor.jsx": __vite_glob_0_114, + "./Pages/Studio/StudioCardsIndex.jsx": __vite_glob_0_115, + "./Pages/Studio/StudioChallenges.jsx": __vite_glob_0_116, + "./Pages/Studio/StudioCollections.jsx": __vite_glob_0_117, + "./Pages/Studio/StudioComments.jsx": __vite_glob_0_118, + "./Pages/Studio/StudioContentIndex.jsx": __vite_glob_0_119, + "./Pages/Studio/StudioDashboard.jsx": __vite_glob_0_120, + "./Pages/Studio/StudioDrafts.jsx": __vite_glob_0_121, + "./Pages/Studio/StudioFeatured.jsx": __vite_glob_0_122, + "./Pages/Studio/StudioFollowers.jsx": __vite_glob_0_123, + "./Pages/Studio/StudioGroupActivity.jsx": __vite_glob_0_124, + "./Pages/Studio/StudioGroupArtworks.jsx": __vite_glob_0_125, + "./Pages/Studio/StudioGroupAssets.jsx": __vite_glob_0_126, + "./Pages/Studio/StudioGroupChallengeEditor.jsx": __vite_glob_0_127, + "./Pages/Studio/StudioGroupChallenges.jsx": __vite_glob_0_128, + "./Pages/Studio/StudioGroupCollections.jsx": __vite_glob_0_129, + "./Pages/Studio/StudioGroupCreate.jsx": __vite_glob_0_130, + "./Pages/Studio/StudioGroupDashboard.jsx": __vite_glob_0_131, + "./Pages/Studio/StudioGroupEventEditor.jsx": __vite_glob_0_132, + "./Pages/Studio/StudioGroupEvents.jsx": __vite_glob_0_133, + "./Pages/Studio/StudioGroupInvitations.jsx": __vite_glob_0_134, + "./Pages/Studio/StudioGroupJoinRequests.jsx": __vite_glob_0_135, + "./Pages/Studio/StudioGroupMembers.jsx": __vite_glob_0_136, + "./Pages/Studio/StudioGroupPostEditor.jsx": __vite_glob_0_137, + "./Pages/Studio/StudioGroupPosts.jsx": __vite_glob_0_138, + "./Pages/Studio/StudioGroupProjectEditor.jsx": __vite_glob_0_139, + "./Pages/Studio/StudioGroupProjects.jsx": __vite_glob_0_140, + "./Pages/Studio/StudioGroupRecruitment.jsx": __vite_glob_0_141, + "./Pages/Studio/StudioGroupReleaseEditor.jsx": __vite_glob_0_142, + "./Pages/Studio/StudioGroupReleases.jsx": __vite_glob_0_143, + "./Pages/Studio/StudioGroupReputation.jsx": __vite_glob_0_144, + "./Pages/Studio/StudioGroupReviewQueue.jsx": __vite_glob_0_145, + "./Pages/Studio/StudioGroupSettings.jsx": __vite_glob_0_146, + "./Pages/Studio/StudioGroupsIndex.jsx": __vite_glob_0_147, + "./Pages/Studio/StudioGrowth.jsx": __vite_glob_0_148, + "./Pages/Studio/StudioInbox.jsx": __vite_glob_0_149, + "./Pages/Studio/StudioNewsEditor.jsx": __vite_glob_0_150, + "./Pages/Studio/StudioNewsIndex.jsx": __vite_glob_0_151, + "./Pages/Studio/StudioNewsTaxonomies.jsx": __vite_glob_0_152, + "./Pages/Studio/StudioPreferences.jsx": __vite_glob_0_153, + "./Pages/Studio/StudioProfile.jsx": __vite_glob_0_154, + "./Pages/Studio/StudioScheduled.jsx": __vite_glob_0_155, + "./Pages/Studio/StudioSearch.jsx": __vite_glob_0_156, + "./Pages/Studio/StudioSettings.jsx": __vite_glob_0_157, + "./Pages/Studio/StudioStories.jsx": __vite_glob_0_158, + "./Pages/Studio/StudioUploadQueue.jsx": __vite_glob_0_159, + "./Pages/Studio/StudioWorldEditor.jsx": __vite_glob_0_160, + "./Pages/Studio/StudioWorldsIndex.jsx": __vite_glob_0_161, + "./Pages/Upload/Index.jsx": __vite_glob_0_162, + "./Pages/World/WorldIndex.jsx": __vite_glob_0_163, + "./Pages/World/WorldShow.jsx": __vite_glob_0_164 }); const ClientOnlyPlaceholder = () => null; d( diff --git a/resources/js/Pages/Admin/Academy/ChallengeEditor.jsx b/resources/js/Pages/Admin/Academy/ChallengeEditor.jsx new file mode 100644 index 00000000..4453e964 --- /dev/null +++ b/resources/js/Pages/Admin/Academy/ChallengeEditor.jsx @@ -0,0 +1,639 @@ +import React, { useMemo, useRef, useState } from 'react' +import { Head, Link, router, useForm } from '@inertiajs/react' +import AdminLayout from '../../../Layouts/AdminLayout' +import DateTimePicker from '../../../components/ui/DateTimePicker' +import NovaSelect from '../../../components/ui/NovaSelect' +import ShareToast from '../../../components/ui/ShareToast' +import WorldMediaUploadField from '../../../components/worlds/editor/WorldMediaUploadField' + +const CHALLENGE_EDITOR_TABS = [ + { + id: 'overview', + label: 'Overview', + description: 'Title, slug, access, and the compact summary shown in academy challenge lists.', + icon: 'fa-compass-drafting', + sections: ['challenge-identity'], + }, + { + id: 'brief', + label: 'Brief', + description: 'Write the creative objective, rules, prizes, required tags, and eligible categories.', + icon: 'fa-bullseye', + sections: ['challenge-brief', 'challenge-rules'], + }, + { + id: 'media', + label: 'Media', + description: 'Upload the hero cover and tune the visual used on challenge cards.', + icon: 'fa-image', + sections: ['challenge-media'], + }, + { + id: 'timeline', + label: 'Timeline', + description: 'Manage submission and voting windows without mixing them into editorial copy.', + icon: 'fa-calendar-days', + sections: ['challenge-timeline'], + }, + { + id: 'publish', + label: 'Publish', + description: 'Control status, visibility, featured placement, and the final public preview.', + icon: 'fa-rocket-launch', + sections: ['challenge-publishing', 'challenge-preview'], + }, +] + +const CHALLENGE_FIELD_TAB_MAP = { + title: 'overview', + slug: 'overview', + excerpt: 'overview', + access_level: 'overview', + description: 'brief', + brief: 'brief', + rules: 'brief', + prize_text: 'brief', + required_tags: 'brief', + allowed_categories: 'brief', + cover_image: 'media', + starts_at: 'timeline', + ends_at: 'timeline', + voting_starts_at: 'timeline', + voting_ends_at: 'timeline', + status: 'publish', + featured: 'publish', + active: 'publish', +} + +function getField(fields, name) { + return fields.find((field) => field.name === name) || null +} + +function FieldError({ message }) { + if (!message) return null + return

{message}

+} + +function SectionCard({ id, eyebrow, title, description, actions, children, tone = 'default', className = '' }) { + const toneClass = tone === 'feature' + ? 'bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.15),transparent_38%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] shadow-[0_24px_70px_rgba(2,6,23,0.28)]' + : 'bg-white/[0.03]' + + return ( +
+
+
+ {eyebrow ?

{eyebrow}

: null} +

{title}

+ {description ?

{description}

: null} +
+ {actions ?
{actions}
: null} +
+
{children}
+
+ ) +} + +function EditorWorkspaceTabs({ activeTab, onChange, errorCounts }) { + const activeMeta = CHALLENGE_EDITOR_TABS.find((tab) => tab.id === activeTab) || CHALLENGE_EDITOR_TABS[0] + + return ( +
+
+ {CHALLENGE_EDITOR_TABS.map((tab) => { + const isActive = tab.id === activeTab + const errorCount = Number(errorCounts?.[tab.id] || 0) + + return ( + + ) + })} +
+
+

{activeMeta.description}

+
+ {activeMeta.sections.map((section) => ( + {section.replace('challenge-', '').replace(/-/g, ' ')} + ))} +
+
+
+ ) +} + +function TextField({ label, value, onChange, error, hint, ...rest }) { + return ( + + ) +} + +function TextAreaField({ label, value, onChange, error, rows = 4, hint, placeholder }) { + return ( +