diff --git a/app/Http/Controllers/Admin/AdminController.php b/app/Http/Controllers/Admin/AdminController.php index 817fc1fd..fa27d71f 100644 --- a/app/Http/Controllers/Admin/AdminController.php +++ b/app/Http/Controllers/Admin/AdminController.php @@ -8,10 +8,17 @@ use App\Enums\UserRole; use App\Http\Controllers\Controller; use App\Models\AuthAuditLog; use App\Models\Artwork; +use App\Models\Report; use App\Models\Story; +use App\Models\Upload; use App\Models\User; +use App\Support\Moderation\ReportTargetResolver; +use Illuminate\Database\Query\Builder; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Schema; use Inertia\Inertia; use Inertia\Response; @@ -33,6 +40,252 @@ final class AdminController extends Controller ]); } + public function dailyActivity(Request $request, ReportTargetResolver $reportTargets): Response + { + $selectedDate = $this->resolveActivityDate($request); + $periodStart = $selectedDate->copy()->startOfDay(); + $periodEnd = $selectedDate->copy()->endOfDay(); + + $users = User::query() + ->select('id', 'name', 'username', 'email', 'role', 'created_at') + ->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orderByDesc('created_at') + ->limit(25) + ->get() + ->map(fn (User $user): array => [ + 'id' => (int) $user->id, + 'name' => (string) $user->name, + 'username' => $user->username, + 'email' => (string) $user->email, + 'role' => (string) $user->role, + 'created_at' => optional($user->created_at)?->toISOString(), + ]) + ->values(); + + $artworks = Artwork::query() + ->with('user:id,name,username') + ->select('id', 'title', 'artwork_status', 'created_at', 'user_id', 'hash', 'thumb_ext') + ->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orderByDesc('created_at') + ->limit(25) + ->get() + ->map(fn (Artwork $artwork): array => [ + 'id' => (int) $artwork->id, + 'title' => (string) ($artwork->title ?? 'Untitled artwork'), + 'status' => (string) ($artwork->artwork_status ?? 'unknown'), + 'thumb' => $artwork->thumbUrl('sm') ?? null, + 'created_at' => optional($artwork->created_at)?->toISOString(), + 'user' => $artwork->user ? [ + 'id' => (int) $artwork->user->id, + 'name' => (string) $artwork->user->name, + 'username' => $artwork->user->username, + ] : null, + ]) + ->values(); + + $stories = Story::query() + ->with('creator:id,name,username') + ->select('id', 'title', 'status', 'created_at', 'published_at', 'creator_id') + ->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orderByDesc('created_at') + ->limit(25) + ->get() + ->map(fn (Story $story): array => [ + 'id' => (int) $story->id, + 'title' => (string) ($story->title ?? 'Untitled story'), + 'status' => (string) ($story->status ?? 'draft'), + 'created_at' => optional($story->created_at)?->toISOString(), + 'published_at' => optional($story->published_at)?->toISOString(), + 'creator' => $story->creator ? [ + 'id' => (int) $story->creator->id, + 'name' => (string) $story->creator->name, + 'username' => $story->creator->username, + ] : null, + ]) + ->values(); + + $uploads = Schema::hasTable('uploads') + ? Upload::query() + ->select('id', 'user_id', 'type', 'status', 'processing_state', 'title', 'created_at', 'moderation_status', 'moderated_at', 'moderated_by', 'moderation_note') + ->where(function ($query) use ($periodStart, $periodEnd): void { + $query->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orWhereBetween('moderated_at', [$periodStart, $periodEnd]); + }) + ->orderByDesc('created_at') + ->limit(40) + ->get() + ->map(fn (Upload $upload): array => [ + 'id' => (string) $upload->id, + 'user_id' => $upload->user_id !== null ? (int) $upload->user_id : null, + 'title' => (string) ($upload->title ?? 'Untitled upload'), + 'type' => (string) ($upload->type ?? 'unknown'), + 'status' => (string) ($upload->status ?? 'unknown'), + 'processing_state' => (string) ($upload->processing_state ?? 'unknown'), + 'moderation_status' => (string) ($upload->moderation_status ?? 'unknown'), + 'created_at' => optional($upload->created_at)?->toISOString(), + 'moderated_at' => optional($upload->moderated_at)?->toISOString(), + 'moderated_by' => $upload->moderated_by !== null ? (int) $upload->moderated_by : null, + 'moderation_note' => $upload->moderation_note, + ]) + ->values() + : collect(); + + $reports = Schema::hasTable('reports') + ? Report::query() + ->with(['reporter:id,username', 'lastModeratedBy:id,username']) + ->where(function ($query) use ($periodStart, $periodEnd): void { + $query->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orWhereBetween('last_moderated_at', [$periodStart, $periodEnd]); + }) + ->orderByDesc('created_at') + ->limit(30) + ->get() + ->map(fn (Report $report): array => [ + 'id' => (int) $report->id, + 'status' => (string) $report->status, + 'reason' => (string) $report->reason, + 'target_type' => (string) $report->target_type, + 'target_id' => (int) $report->target_id, + 'created_at' => optional($report->created_at)?->toISOString(), + 'last_moderated_at' => optional($report->last_moderated_at)?->toISOString(), + 'moderator_note' => $report->moderator_note, + 'reporter' => $report->reporter ? [ + 'id' => (int) $report->reporter->id, + 'username' => (string) $report->reporter->username, + ] : null, + 'last_moderated_by' => $report->lastModeratedBy ? [ + 'id' => (int) $report->lastModeratedBy->id, + 'username' => (string) $report->lastModeratedBy->username, + ] : null, + 'target' => $reportTargets->summarize($report), + ]) + ->values() + : collect(); + + $usernameRequests = Schema::hasTable('username_approval_requests') + ? (function () use ($periodStart, $periodEnd) { + $requestColumns = Schema::getColumnListing('username_approval_requests'); + $selects = [ + 'requests.id', + 'requests.user_id', + 'requests.requested_username', + 'requests.status', + 'requests.created_at', + 'users.username as current_username', + 'users.name as current_name', + ]; + + if (in_array('context', $requestColumns, true)) { + $selects[] = 'requests.context'; + } + + if (in_array('similar_to', $requestColumns, true)) { + $selects[] = 'requests.similar_to'; + } + + if (in_array('review_note', $requestColumns, true)) { + $selects[] = 'requests.review_note'; + } + + if (in_array('reviewed_at', $requestColumns, true)) { + $selects[] = 'requests.reviewed_at'; + } + + $query = DB::table('username_approval_requests as requests') + ->leftJoin('users', 'users.id', '=', 'requests.user_id') + ->select($selects) + ->where(function (Builder $query) use ($periodStart, $periodEnd, $requestColumns): void { + $query->whereBetween('requests.created_at', [$periodStart, $periodEnd]); + + if (in_array('reviewed_at', $requestColumns, true)) { + $query->orWhereBetween('requests.reviewed_at', [$periodStart, $periodEnd]); + } + }) + ->orderByDesc('requests.created_at') + ->limit(30); + + return $query + ->get() + ->map(fn ($row): array => [ + 'id' => (int) $row->id, + 'user_id' => $row->user_id !== null ? (int) $row->user_id : null, + 'requested_username' => (string) $row->requested_username, + 'status' => (string) ($row->status ?? 'pending'), + 'context' => $row->context ?? null, + 'similar_to' => $row->similar_to ?? null, + 'reason' => $row->review_note ?? null, + 'created_at' => $this->serializeDatabaseTimestamp($row->created_at), + 'reviewed_at' => $this->serializeDatabaseTimestamp($row->reviewed_at ?? null), + 'current_username' => $row->current_username, + 'current_name' => $row->current_name, + ]) + ->values(); + })() + : collect(); + + $authEvents = Schema::hasTable('auth_audit_logs') + ? AuthAuditLog::query() + ->with('user:id,name,username,email,role') + ->select('id', 'user_id', 'event_type', 'identifier', 'status', 'reason', 'ip', 'created_at') + ->whereBetween('created_at', [$periodStart, $periodEnd]) + ->orderByDesc('created_at') + ->limit(30) + ->get() + ->map(fn (AuthAuditLog $log): array => [ + 'id' => (int) $log->id, + 'event_type' => (string) $log->event_type, + 'identifier' => $log->identifier, + 'status' => (string) $log->status, + 'reason' => $log->reason, + 'ip' => $log->ip, + 'created_at' => optional($log->created_at)?->toISOString(), + 'user' => $log->user ? [ + 'id' => (int) $log->user->id, + 'name' => (string) $log->user->name, + 'username' => $log->user->username, + 'email' => (string) $log->user->email, + 'role' => (string) $log->user->role, + ] : null, + ]) + ->values() + : collect(); + + return Inertia::render('Admin/DailyActivity', [ + 'selectedDate' => $selectedDate->toDateString(), + 'summary' => [ + 'new_users' => $users->count(), + 'new_artworks' => $artworks->count(), + 'new_stories' => $stories->count(), + 'upload_events' => $uploads->count(), + 'report_events' => $reports->count(), + 'username_events' => $usernameRequests->count(), + 'auth_events' => $authEvents->count(), + 'moderated_uploads' => $uploads->filter(fn (array $upload): bool => ! empty($upload['moderated_at']))->count(), + 'moderated_reports' => $reports->filter(fn (array $report): bool => ! empty($report['last_moderated_at']))->count(), + ], + 'queues' => [ + 'pending_uploads' => Schema::hasTable('uploads') + ? Upload::query()->where('status', 'draft')->where('moderation_status', 'pending')->count() + : 0, + 'open_reports' => Schema::hasTable('reports') + ? Report::query()->where('status', 'open')->count() + : 0, + 'pending_username_requests' => Schema::hasTable('username_approval_requests') + ? DB::table('username_approval_requests')->where('status', 'pending')->count() + : 0, + ], + 'sections' => [ + 'users' => $users, + 'artworks' => $artworks, + 'stories' => $stories, + 'uploads' => $uploads, + 'reports' => $reports, + 'username_requests' => $usernameRequests, + 'auth_events' => $authEvents, + ], + ]); + } + // ── Users ───────────────────────────────────────────────────────────────── public function users(Request $request): Response @@ -237,4 +490,36 @@ final class AdminController extends Controller ], ]); } + + private function resolveActivityDate(Request $request): Carbon + { + $date = $request->string('date')->trim()->toString(); + + if ($date === '') { + return today(); + } + + try { + return Carbon::createFromFormat('Y-m-d', $date)->startOfDay(); + } catch (\Throwable) { + return today(); + } + } + + private function serializeDatabaseTimestamp(mixed $value): ?string + { + if ($value === null || $value === '') { + return null; + } + + if ($value instanceof Carbon) { + return $value->toISOString(); + } + + try { + return Carbon::parse((string) $value)->toISOString(); + } catch (\Throwable) { + return null; + } + } } diff --git a/app/Http/Controllers/StoryController.php b/app/Http/Controllers/StoryController.php index ded8ceec..cb26e0ca 100644 --- a/app/Http/Controllers/StoryController.php +++ b/app/Http/Controllers/StoryController.php @@ -751,24 +751,42 @@ class StoryController extends Controller ], 422); } - $disk = Storage::disk('public'); - $base = 'stories/' . now()->format('Y/m') . '/' . Str::uuid(); - $extension = strtolower((string) ($file->guessExtension() ?: $file->extension() ?: 'jpg')); - $originalPath = $base . '/original.' . $extension; - $thumbnailPath = $base . '/thumbnail.webp'; - $mediumPath = $base . '/medium.webp'; + try { + $this->assertStoryMediaStorageIsAllowed(); + } catch (\RuntimeException $e) { + return response()->json([ + 'message' => $e->getMessage(), + ], 422); + } - $stream = fopen($sourcePath, 'rb'); - if ($stream === false) { + $raw = file_get_contents($sourcePath); + if ($raw === false || $raw === '') { return response()->json([ 'message' => 'Unable to process uploaded image. Please try again.', ], 422); } - try { - $disk->put($originalPath, $stream); - } finally { - fclose($stream); + $hash = hash('sha256', $raw); + $originalExtension = strtolower((string) ($file->guessExtension() ?: $file->extension() ?: 'jpg')); + if ($originalExtension === 'jpeg') { + $originalExtension = 'jpg'; + } + + $originalPath = $this->storyMediaPath('original', $hash, $hash . '.' . $originalExtension); + $thumbnailPath = $this->storyMediaPath('sm', $hash); + $mediumPath = $this->storyMediaPath('md', $hash); + $disk = Storage::disk($this->storyMediaDiskName()); + + $written = $disk->put($originalPath, $raw, [ + 'visibility' => 'public', + 'CacheControl' => 'public, max-age=31536000, immutable', + 'ContentType' => (string) ($file->getMimeType() ?: 'application/octet-stream'), + ]); + + if ($written !== true) { + return response()->json([ + 'message' => 'Unable to store uploaded image. Please try again.', + ], 500); } $storedThumbnails = false; @@ -781,10 +799,20 @@ class StoryController extends Controller $image = $manager->read($sourcePath); $thumb = $image->scaleDown(width: 420); - $disk->put($thumbnailPath, (string) $thumb->encode(new WebpEncoder(82))); + $thumbEncoded = (string) $thumb->encode(new WebpEncoder(82)); + $disk->put($thumbnailPath, $thumbEncoded, [ + 'visibility' => 'public', + 'CacheControl' => 'public, max-age=31536000, immutable', + 'ContentType' => 'image/webp', + ]); $medium = $image->scaleDown(width: 1200); - $disk->put($mediumPath, (string) $medium->encode(new WebpEncoder(85))); + $mediumEncoded = (string) $medium->encode(new WebpEncoder(85)); + $disk->put($mediumPath, $mediumEncoded, [ + 'visibility' => 'public', + 'CacheControl' => 'public, max-age=31536000, immutable', + 'ContentType' => 'image/webp', + ]); $storedThumbnails = true; } catch (\Throwable) { $storedThumbnails = false; @@ -792,17 +820,62 @@ class StoryController extends Controller } if (! $storedThumbnails) { - $disk->copy($originalPath, $thumbnailPath); - $disk->copy($originalPath, $mediumPath); + $disk->put($thumbnailPath, $raw, [ + 'visibility' => 'public', + 'CacheControl' => 'public, max-age=31536000, immutable', + 'ContentType' => (string) ($file->getMimeType() ?: 'application/octet-stream'), + ]); + $disk->put($mediumPath, $raw, [ + 'visibility' => 'public', + 'CacheControl' => 'public, max-age=31536000, immutable', + 'ContentType' => (string) ($file->getMimeType() ?: 'application/octet-stream'), + ]); } return response()->json([ - 'thumbnail_url' => $disk->url($thumbnailPath), - 'medium_url' => $disk->url($mediumPath), - 'original_url' => $disk->url($originalPath), + 'thumbnail_url' => $this->storyMediaPublicUrl($thumbnailPath), + 'medium_url' => $this->storyMediaPublicUrl($mediumPath), + 'original_url' => $this->storyMediaPublicUrl($originalPath), ]); } + private function storyMediaDiskName(): string + { + return (string) config('uploads.object_storage.disk', 's3'); + } + + private function storyMediaPath(string $variant, string $hash, ?string $filename = null): string + { + $cleanVariant = trim($variant, '/'); + $cleanHash = strtolower((string) preg_replace('/[^a-f0-9]/', '', $hash)); + $file = $filename ?? ($cleanHash . '.webp'); + + return sprintf( + 'stories/%s/%s/%s/%s', + $cleanVariant, + substr($cleanHash, 0, 2), + substr($cleanHash, 2, 2), + ltrim($file, '/') + ); + } + + private function storyMediaPublicUrl(string $path): string + { + return rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/') . '/' . ltrim($path, '/'); + } + + private function assertStoryMediaStorageIsAllowed(): void + { + if (! app()->environment('production')) { + return; + } + + $diskName = $this->storyMediaDiskName(); + if (in_array($diskName, ['local', 'public'], true)) { + throw new \RuntimeException('Production story media storage must use object storage, not local/public disks.'); + } + } + public function tag(string $tag): View { $storyTag = StoryTag::query()->where('slug', $tag)->firstOrFail(); diff --git a/app/Models/Story.php b/app/Models/Story.php index 18f6138a..bd5a764f 100644 --- a/app/Models/Story.php +++ b/app/Models/Story.php @@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Storage; /** * Creator Story model. @@ -143,11 +144,12 @@ class Story extends Model public function getCoverUrlAttribute(): ?string { - if (! $this->cover_image) { - return null; - } + return $this->resolveStoryMediaUrl($this->cover_image); + } - return str_starts_with($this->cover_image, 'http') ? $this->cover_image : asset($this->cover_image); + public function getOgImageUrlAttribute(): ?string + { + return $this->resolveStoryMediaUrl($this->og_image); } /** @@ -174,4 +176,30 @@ class Story extends Model return \Illuminate\Support\Str::limit($text, 160); } + + private function resolveStoryMediaUrl(?string $value): ?string + { + if (! $value) { + return null; + } + + if (str_starts_with($value, 'http')) { + return $value; + } + + $path = ltrim($value, '/'); + if (str_starts_with($path, 'storage/')) { + $path = substr($path, strlen('storage/')); + } + + if (preg_match('#^stories/(sm|md|original)/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]+\.(webp|jpg|jpeg|png)$#', $path) === 1) { + $cdnBase = rtrim((string) config('cdn.files_url', ''), '/'); + + return $cdnBase !== '' + ? $cdnBase . '/' . $path + : Storage::disk('public')->url($path); + } + + return asset($value); + } } diff --git a/bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js b/bootstrap/ssr/assets/ArtworkShareModal-LimHRcZ1.js similarity index 99% rename from bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js rename to bootstrap/ssr/assets/ArtworkShareModal-LimHRcZ1.js index 3663af63..f148bc12 100644 --- a/bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js +++ b/bootstrap/ssr/assets/ArtworkShareModal-LimHRcZ1.js @@ -18,7 +18,7 @@ import "node:process"; import "node:path"; import "node:url"; import "./vendor-tooltip-CIQaDNlG.js"; -import "./vendor-realtime-cgmg5qQY.js"; +import "./vendor-realtime-5YdDOIKO.js"; import "buffer"; import "child_process"; import "net"; diff --git a/bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js b/bootstrap/ssr/assets/vendor-realtime-5YdDOIKO.js similarity index 100% rename from bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js rename to bootstrap/ssr/assets/vendor-realtime-5YdDOIKO.js index 015a0ffe..5bd5f978 100644 --- a/bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js +++ b/bootstrap/ssr/assets/vendor-realtime-5YdDOIKO.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-DSw66HfW.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 e670a6a4..48596a2c 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-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000D:/Sites/Skinbase26/node_modules/pusher-js/dist/node/pusher.js?commonjs-module": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.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-DSw66HfW.js" ], "\u0000assert?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000buffer?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000child_process?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000commonjsHelpers.js": [ "/build/assets/vendor-tiptap-DSw66HfW.js" ], "\u0000crypto?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000events?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000fs?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000http?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000https?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000net?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000stream?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000tls?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000url?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "\u0000util?commonjs-external": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "node_modules/@emoji-mart/data/sets/15/native.json": [ "/build/assets/emoji-data-4xGXbtDn.js" @@ -999,7 +999,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-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "node_modules/linkifyjs/dist/linkify.mjs": [ "/build/assets/vendor-tiptap-DSw66HfW.js" @@ -1895,7 +1895,7 @@ ], "node_modules/proxy-from-env/index.js": [], "node_modules/pusher-js/dist/node/pusher.js": [ - "/build/assets/vendor-realtime-cgmg5qQY.js" + "/build/assets/vendor-realtime-5YdDOIKO.js" ], "node_modules/qs/lib/formats.js": [], "node_modules/qs/lib/index.js": [], @@ -1998,6 +1998,7 @@ "resources/js/Pages/Admin/AiBiography.jsx": [], "resources/js/Pages/Admin/Artworks.jsx": [], "resources/js/Pages/Admin/AuthAudit.jsx": [], + "resources/js/Pages/Admin/DailyActivity.jsx": [], "resources/js/Pages/Admin/Dashboard.jsx": [], "resources/js/Pages/Admin/FeaturedArtworks.jsx": [], "resources/js/Pages/Admin/HomepageAnnouncements/Form.jsx": [], @@ -2193,7 +2194,7 @@ "resources/js/components/artwork/ArtworkRecommendationsRails.jsx": [], "resources/js/components/artwork/ArtworkShareButton.jsx": [], "resources/js/components/artwork/ArtworkShareModal.jsx": [ - "/build/assets/ArtworkShareModal-DEVyX6r2.js" + "/build/assets/ArtworkShareModal-LimHRcZ1.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 a70a5ce3..43cf08ec 100644 --- a/bootstrap/ssr/ssr.js +++ b/bootstrap/ssr/ssr.js @@ -17,7 +17,7 @@ import minproc from "node:process"; import minpath from "node:path"; import { fileURLToPath } from "node:url"; import { t as tippy } from "./assets/vendor-tooltip-CIQaDNlG.js"; -import { P as Pusher, E as E$1 } from "./assets/vendor-realtime-cgmg5qQY.js"; +import { P as Pusher, E as E$1 } from "./assets/vendor-realtime-5YdDOIKO.js"; import { u as useReducedMotion, m as motion, A as AnimatePresence } from "./assets/vendor-motion-yDK3iGlC.js"; import * as s from "process"; import require$$2 from "async_hooks"; @@ -12384,7 +12384,8 @@ const buildAdminNavGroups = (isAdmin) => [ { label: "Overview", items: [ - { label: "Dashboard", href: "/moderation", icon: "fa-solid fa-gauge-high", exact: true } + { label: "Dashboard", href: "/moderation", icon: "fa-solid fa-gauge-high", exact: true }, + { label: "Daily Activity", href: "/moderation/activity", icon: "fa-solid fa-calendar-day" } ] }, { @@ -12763,7 +12764,7 @@ async function requestJson$o(url, { method = "POST", body: body2 } = {}) { } return payload; } -function formatDateTime$4(value) { +function formatDateTime$5(value) { if (!value) return "—"; const date = new Date(value); if (Number.isNaN(date.getTime())) return "—"; @@ -12782,7 +12783,7 @@ function Badge$3({ children, tone = "slate" }) { }; return /* @__PURE__ */ React.createElement("span", { className: `inline-flex items-center rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] ${tones2[tone] || tones2.slate}` }, children); } -function StatCard$a({ label, value, tone = "sky" }) { +function StatCard$b({ label, value, tone = "sky" }) { const tones2 = { sky: "border-sky-300/15 bg-sky-400/10 text-sky-100", amber: "border-amber-300/15 bg-amber-400/10 text-amber-100", @@ -12861,7 +12862,7 @@ function AiBiographyAdmin() { setBusyKey(""); } } - return /* @__PURE__ */ React.createElement("div", { className: "w-full pb-16 pt-8" }, /* @__PURE__ */ React.createElement(Se, { title: "AI Biography Review" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.2),transparent_32%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.9))] 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" }, "Moderator surface"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "AI biography review"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-relaxed text-slate-300" }, "Browse active biographies and historical generations, inspect review flags and failures, and rebuild a creator biography directly from cPad.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3 text-xs uppercase tracking-[0.16em] text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2" }, "Page ", records.current_page || 1, " / ", records.last_page || 1), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2" }, Number(records.total || 0).toLocaleString(), " records"))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(StatCard$a, { label: "Total records", value: stats.total_records, tone: "sky" }), /* @__PURE__ */ React.createElement(StatCard$a, { label: "Active", value: stats.active_records, tone: "emerald" }), /* @__PURE__ */ React.createElement(StatCard$a, { label: "Needs review", value: stats.needs_review, tone: "amber" }), /* @__PURE__ */ React.createElement(StatCard$a, { label: "Hidden active", value: stats.hidden_active, tone: "slate" }), /* @__PURE__ */ React.createElement(StatCard$a, { label: "Failed", value: stats.failed, tone: "rose" }), /* @__PURE__ */ React.createElement(StatCard$a, { label: "User edited", value: stats.user_edited_active, tone: "sky" })), /* @__PURE__ */ React.createElement("form", { onSubmit: applyFilters, className: "mt-6 grid gap-3 lg:grid-cols-[2fr_repeat(5,minmax(0,1fr))]" }, /* @__PURE__ */ React.createElement("label", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Search creator"), /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ React.createElement("div", { className: "w-full pb-16 pt-8" }, /* @__PURE__ */ React.createElement(Se, { title: "AI Biography Review" }), /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.2),transparent_32%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.9))] 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" }, "Moderator surface"), /* @__PURE__ */ React.createElement("h1", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "AI biography review"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-3xl text-sm leading-relaxed text-slate-300" }, "Browse active biographies and historical generations, inspect review flags and failures, and rebuild a creator biography directly from cPad.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3 text-xs uppercase tracking-[0.16em] text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2" }, "Page ", records.current_page || 1, " / ", records.last_page || 1), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.05] px-4 py-2" }, Number(records.total || 0).toLocaleString(), " records"))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(StatCard$b, { label: "Total records", value: stats.total_records, tone: "sky" }), /* @__PURE__ */ React.createElement(StatCard$b, { label: "Active", value: stats.active_records, tone: "emerald" }), /* @__PURE__ */ React.createElement(StatCard$b, { label: "Needs review", value: stats.needs_review, tone: "amber" }), /* @__PURE__ */ React.createElement(StatCard$b, { label: "Hidden active", value: stats.hidden_active, tone: "slate" }), /* @__PURE__ */ React.createElement(StatCard$b, { label: "Failed", value: stats.failed, tone: "rose" }), /* @__PURE__ */ React.createElement(StatCard$b, { label: "User edited", value: stats.user_edited_active, tone: "sky" })), /* @__PURE__ */ React.createElement("form", { onSubmit: applyFilters, className: "mt-6 grid gap-3 lg:grid-cols-[2fr_repeat(5,minmax(0,1fr))]" }, /* @__PURE__ */ React.createElement("label", { className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400" }, "Search creator"), /* @__PURE__ */ React.createElement( "input", { value: filters.q || "", @@ -12893,7 +12894,7 @@ function AiBiographyAdmin() { }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-rotate text-[10px]" }), busyKey === rebuildKey ? "Rebuilding…" : "Rebuild" - ))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__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" }, "Prompt"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, record.prompt_version || "—")), /* @__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" }, "Model"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, record.model || "—")), /* @__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" }, "Generated"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, formatDateTime$4(record.generated_at))), /* @__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" }, "Last attempted"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, formatDateTime$4(record.last_attempted_at)))), record.last_error_code || record.last_error_reason ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm leading-relaxed text-rose-100" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-rose-100/80" }, "Last error"), /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, record.last_error_code || "generation_failed", record.last_error_reason ? ` • ${record.last_error_reason}` : "")) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 xl:grid-cols-[minmax(0,1fr)_320px]" }, /* @__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-400" }, "Biography text"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 max-h-[320px] overflow-y-auto whitespace-pre-wrap rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-4 text-sm leading-relaxed text-slate-100" }, record.text || "No biography text stored for this record.")), /* @__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-400" }, "Review actions"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3" }, /* @__PURE__ */ React.createElement( + ))), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__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" }, "Prompt"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, record.prompt_version || "—")), /* @__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" }, "Model"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, record.model || "—")), /* @__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" }, "Generated"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, formatDateTime$5(record.generated_at))), /* @__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" }, "Last attempted"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-sm text-slate-200" }, formatDateTime$5(record.last_attempted_at)))), record.last_error_code || record.last_error_reason ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm leading-relaxed text-rose-100" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-rose-100/80" }, "Last error"), /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, record.last_error_code || "generation_failed", record.last_error_reason ? ` • ${record.last_error_reason}` : "")) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-4 xl:grid-cols-[minmax(0,1fr)_320px]" }, /* @__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-400" }, "Biography text"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 max-h-[320px] overflow-y-auto whitespace-pre-wrap rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-4 text-sm leading-relaxed text-slate-100" }, record.text || "No biography text stored for this record.")), /* @__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-400" }, "Review actions"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3" }, /* @__PURE__ */ React.createElement( "button", { type: "button", @@ -12923,10 +12924,10 @@ function AiBiographyAdmin() { }, /* @__PURE__ */ React.createElement("i", { className: `fa-solid ${record.is_hidden ? "fa-eye" : "fa-eye-slash"} text-[10px]` }), busyKey === visibilityKey ? "Saving…" : record.is_hidden ? "Show publicly" : "Hide publicly" - )), /* @__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$4(record.approved_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Created:"), " ", formatDateTime$4(record.created_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Updated:"), " ", formatDateTime$4(record.updated_at)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-slate-100" }, "Source hash:"), " ", record.source_hash || "—"))))); + )), /* @__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_84 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_85 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AiBiographyAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -13059,6 +13060,140 @@ const __vite_glob_0_2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def __proto__: null, default: AuthAudit }, Symbol.toStringTag, { value: "Module" })); +function formatDateTime$4(value) { + if (!value) return "—"; + try { + return new Intl.DateTimeFormat(void 0, { + year: "numeric", + month: "short", + day: "numeric", + hour: "2-digit", + minute: "2-digit" + }).format(new Date(value)); + } catch { + return String(value); + } +} +function StatCard$a({ icon, label, value, tone = "sky" }) { + const tones2 = { + sky: "border-sky-400/20 bg-sky-400/10 text-sky-200", + rose: "border-rose-400/20 bg-rose-400/10 text-rose-200", + amber: "border-amber-400/20 bg-amber-400/10 text-amber-200", + emerald: "border-emerald-400/20 bg-emerald-400/10 text-emerald-200" + }; + return /* @__PURE__ */ React.createElement("div", { className: `rounded-2xl border p-5 ${tones2[tone]}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-white/65" }, label), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-3xl font-bold text-white" }, Number(value || 0).toLocaleString())), /* @__PURE__ */ React.createElement("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-white/10 bg-black/20 text-lg text-white/80" }, /* @__PURE__ */ React.createElement("i", { className: icon })))); +} +function SectionCard$3({ title, subtitle, actionHref, actionLabel, children }) { + return /* @__PURE__ */ React.createElement("section", { className: "rounded-3xl border border-white/10 bg-white/[0.04] p-5 shadow-[0_24px_80px_rgba(2,6,23,0.35)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4 border-b border-white/8 pb-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-semibold text-white" }, title), subtitle ? /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-400" }, subtitle) : null), actionHref ? /* @__PURE__ */ React.createElement("a", { href: actionHref, className: "inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.05] px-3 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-slate-200 transition hover:bg-white/[0.08]" }, /* @__PURE__ */ React.createElement("span", null, actionLabel || "Open queue"), /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-up-right-from-square text-[10px]" })) : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4" }, children)); +} +function EmptyState$6({ label }) { + return /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/10 bg-black/10 px-4 py-6 text-sm text-slate-400" }, label); +} +function DataTable({ columns, rows, emptyLabel }) { + if (!rows?.length) { + return /* @__PURE__ */ React.createElement(EmptyState$6, { label: emptyLabel }); + } + return /* @__PURE__ */ React.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React.createElement("table", { className: "min-w-full divide-y divide-white/10 text-sm text-slate-200" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", { className: "text-left text-[11px] uppercase tracking-[0.18em] text-slate-500" }, columns.map((column) => /* @__PURE__ */ React.createElement("th", { key: column.key, className: "px-3 py-3 font-semibold" }, column.label)))), /* @__PURE__ */ React.createElement("tbody", { className: "divide-y divide-white/6" }, rows.map((row, index2) => /* @__PURE__ */ React.createElement("tr", { key: row.id || `${index2}-${row.created_at || row.updated_at || "row"}`, className: "align-top" }, columns.map((column) => /* @__PURE__ */ React.createElement("td", { key: column.key, className: "px-3 py-3 text-slate-200/90" }, column.render ? column.render(row) : row[column.key]))))))); +} +function DailyActivity({ selectedDate, summary, queues, sections }) { + const onDateChange = (event) => { + At.get("/moderation/activity", { date: event.target.value }, { preserveState: true, replace: true }); + }; + return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Daily Activity", subtitle: "A day-by-day moderation cockpit for reviewing new content, queue movement, and staff actions." }, /* @__PURE__ */ React.createElement(Se, { title: "Admin · Daily Activity" }), /* @__PURE__ */ React.createElement("div", { className: "rounded-3xl border border-white/10 bg-[linear-gradient(135deg,rgba(244,63,94,0.18),rgba(15,23,42,0.75))] p-6 shadow-[0_30px_120px_rgba(15,23,42,0.5)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-end justify-between gap-5" }, /* @__PURE__ */ React.createElement("div", { className: "max-w-2xl" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.26em] text-rose-200/80" }, "Moderation review"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-2xl font-bold text-white" }, "Selected day: ", selectedDate), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-slate-200/80" }, "This view pulls together the moderation-adjacent activity for the selected day so admins can triage queues and jump into the right review surface quickly.")), /* @__PURE__ */ React.createElement("label", { className: "block" }, /* @__PURE__ */ React.createElement("span", { className: "mb-2 block text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-300" }, "Day"), /* @__PURE__ */ React.createElement( + "input", + { + type: "date", + value: selectedDate, + onChange: onDateChange, + className: "rounded-2xl border border-white/10 bg-slate-950/70 px-4 py-3 text-sm text-white outline-none transition focus:border-rose-400/50" + } + )))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 sm:grid-cols-2 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-user-plus", label: "New Users", value: summary.new_users, tone: "sky" }), /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-images", label: "New Artworks", value: summary.new_artworks, tone: "rose" }), /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-feather-pointed", label: "New Stories", value: summary.new_stories, tone: "amber" }), /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-cloud-arrow-up", label: "Upload Events", value: summary.upload_events, tone: "emerald" }), /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-flag", label: "Report Events", value: summary.report_events, tone: "rose" }), /* @__PURE__ */ React.createElement(StatCard$a, { icon: "fa-solid fa-fingerprint", label: "Auth Events", value: summary.auth_events, tone: "sky" })), /* @__PURE__ */ React.createElement("div", { className: "mt-6 grid gap-4 lg:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-500" }, "Queues right now"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-3 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-white/8 bg-black/10 px-4 py-3" }, /* @__PURE__ */ React.createElement("span", null, "Pending uploads"), /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, queues.pending_uploads)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-white/8 bg-black/10 px-4 py-3" }, /* @__PURE__ */ React.createElement("span", null, "Open reports"), /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, queues.open_reports)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-white/8 bg-black/10 px-4 py-3" }, /* @__PURE__ */ React.createElement("span", null, "Pending username requests"), /* @__PURE__ */ React.createElement("span", { className: "font-semibold text-white" }, queues.pending_username_requests)))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.04] p-5 lg:col-span-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-500" }, "Moderation throughput on this day"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 sm:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/8 bg-black/10 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Moderated uploads"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-bold text-white" }, summary.moderated_uploads)), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/8 bg-black/10 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Moderated reports"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-bold text-white" }, summary.moderated_reports)), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/8 bg-black/10 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs uppercase tracking-[0.18em] text-slate-500" }, "Username events"), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-2xl font-bold text-white" }, summary.username_events))))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 space-y-6" }, /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Uploads", subtitle: "New uploads and same-day moderation decisions.", actionHref: "/moderation/uploads", actionLabel: "Open uploads" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No upload activity on this day.", + rows: sections.uploads, + columns: [ + { key: "title", label: "Upload", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, row.type, " · ", row.status, " · ", row.processing_state)) }, + { key: "moderation_status", label: "Moderation", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, row.moderation_status), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.moderation_note || "No note")) }, + { key: "created_at", label: "Created", render: (row) => formatDateTime$4(row.created_at) }, + { key: "moderated_at", label: "Moderated", render: (row) => formatDateTime$4(row.moderated_at) } + ] + } + )), /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Reports", subtitle: "User reports created or reviewed during the selected day." }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No report activity on this day.", + rows: sections.reports, + columns: [ + { key: "reason", label: "Report", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.reason), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.16em] text-slate-500" }, row.status, " · ", row.target_type, " #", row.target_id)) }, + { key: "reporter", label: "Reporter", render: (row) => row.reporter ? `@${row.reporter.username}` : "—" }, + { key: "target", label: "Target", render: (row) => row.target?.title || row.target?.context || "Resolved via moderation target" }, + { key: "last_moderated_at", label: "Reviewed", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, formatDateTime$4(row.last_moderated_at)), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.last_moderated_by ? `@${row.last_moderated_by.username}` : "Unassigned")) } + ] + } + )), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-2" }, /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Username Requests", subtitle: "Requests created or reviewed on this day.", actionHref: "/moderation/usernames/moderation", actionLabel: "Open usernames" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No username activity on this day.", + rows: sections.username_requests, + columns: [ + { key: "requested_username", label: "Request", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.requested_username), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, "Current: ", row.current_username || row.current_name || "Unknown user")) }, + { key: "status", label: "Status" }, + { key: "created_at", label: "Created", render: (row) => formatDateTime$4(row.created_at) }, + { key: "reviewed_at", label: "Reviewed", render: (row) => formatDateTime$4(row.reviewed_at) } + ] + } + )), /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Auth Audit", subtitle: "Authentication events for the selected day.", actionHref: "/moderation/auth-audit", actionLabel: "Open audit" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No auth audit events on this day.", + rows: sections.auth_events, + columns: [ + { key: "event_type", label: "Event", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.event_type), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.status, " · ", row.ip || "No IP")) }, + { key: "user", label: "User", render: (row) => row.user ? `@${row.user.username || row.user.name}` : row.identifier || "Guest" }, + { key: "reason", label: "Reason", render: (row) => row.reason || "—" }, + { key: "created_at", label: "When", render: (row) => formatDateTime$4(row.created_at) } + ] + } + ))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-6 xl:grid-cols-3" }, /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Users", subtitle: "Accounts created on this day.", actionHref: "/moderation/users", actionLabel: "Open users" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No new users on this day.", + rows: sections.users, + columns: [ + { key: "username", label: "User", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.username ? `@${row.username}` : row.name), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.email)) }, + { key: "role", label: "Role" }, + { key: "created_at", label: "Joined", render: (row) => formatDateTime$4(row.created_at) } + ] + } + )), /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Artworks", subtitle: "Artwork records created on this day.", actionHref: "/moderation/artworks", actionLabel: "Open artworks" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No artwork activity on this day.", + rows: sections.artworks, + columns: [ + { key: "title", label: "Artwork", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.user?.username ? `@${row.user.username}` : "Unknown artist")) }, + { key: "status", label: "Status" }, + { key: "created_at", label: "Created", render: (row) => formatDateTime$4(row.created_at) } + ] + } + )), /* @__PURE__ */ React.createElement(SectionCard$3, { title: "Stories", subtitle: "Creator stories created on this day.", actionHref: "/moderation/stories", actionLabel: "Open stories" }, /* @__PURE__ */ React.createElement( + DataTable, + { + emptyLabel: "No story activity on this day.", + rows: sections.stories, + columns: [ + { key: "title", label: "Story", render: (row) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-semibold text-white" }, row.title), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.creator?.username ? `@${row.creator.username}` : "Unknown creator")) }, + { key: "status", label: "Status" }, + { key: "created_at", label: "Created", render: (row) => formatDateTime$4(row.created_at) } + ] + } + ))))); +} +const __vite_glob_0_3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + default: DailyActivity +}, Symbol.toStringTag, { value: "Module" })); function StatCard$9({ icon, label, value, color: color2 = "sky" }) { const colors = { sky: "from-sky-500/20 to-sky-500/5 border-sky-500/20 text-sky-400", @@ -13070,6 +13205,7 @@ function StatCard$9({ icon, label, value, color: color2 = "sky" }) { } function Dashboard({ stats }) { return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Dashboard", subtitle: "Overview of your Skinbase platform" }, /* @__PURE__ */ React.createElement(Se, { title: "Admin Dashboard" }), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4" }, /* @__PURE__ */ React.createElement(StatCard$9, { icon: "fa-solid fa-users", label: "Total Users", value: stats.total_users, color: "sky" }), /* @__PURE__ */ React.createElement(StatCard$9, { icon: "fa-solid fa-user-plus", label: "New Today", value: stats.new_users_today, color: "violet" }), /* @__PURE__ */ React.createElement(StatCard$9, { icon: "fa-solid fa-shield-halved", label: "Staff Members", value: stats.staff_count, color: "rose" }), /* @__PURE__ */ React.createElement(StatCard$9, { icon: "fa-solid fa-user-shield", label: "Moderators", value: stats.moderator_count, color: "amber" })), /* @__PURE__ */ React.createElement("div", { className: "mt-10" }, /* @__PURE__ */ React.createElement("h2", { className: "mb-4 text-sm font-semibold uppercase tracking-wider text-slate-500" }, "Quick Actions"), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-3" }, [ + { label: "Daily Activity", href: "/moderation/activity", icon: "fa-solid fa-calendar-day", desc: "Review everything created or moderated on a selected day" }, { label: "Manage Users", href: "/moderation/users", icon: "fa-solid fa-users", desc: "Search, promote or demote users" }, { label: "Staff Roles", href: "/moderation/users?role=admin", icon: "fa-solid fa-shield-halved", desc: "View all admins, managers and editorial staff" }, { label: "Username Queue", href: "/moderation/usernames/moderation", icon: "fa-solid fa-id-badge", desc: "Review pending username requests" }, @@ -13089,7 +13225,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_3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: Dashboard }, Symbol.toStringTag, { value: "Module" })); @@ -13905,14 +14041,14 @@ function FeaturedArtworksAdmin() { } ), /* @__PURE__ */ React.createElement(NovaSelect, { value: filter2, onChange: (val) => setFilter(val), searchable: false, options: [{ value: "all", label: "All rows" }, { value: "active", label: "Active" }, { value: "inactive", label: "Inactive" }, { value: "expired", label: "Expired" }, { value: "winner", label: "Winner" }, { value: "eligible", label: "Eligible" }, { value: "ineligible", label: "Not eligible" }] }), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-[1fr_auto] gap-3" }, /* @__PURE__ */ React.createElement(NovaSelect, { value: sortKey, onChange: (val) => setSortKey(val), searchable: false, options: [{ value: "priority", label: "Priority" }, { value: "featured_at", label: "Featured Since" }, { value: "expires_at", label: "Expires" }, { value: "score_30d", label: "Medal Score (30d)" }] }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setSortDirection((current) => current === "desc" ? "asc" : "desc"), className: "rounded-2xl border border-white/10 px-4 py-3 text-sm font-semibold text-slate-100 transition hover:border-white/20 hover:bg-white/5" }, sortDirection === "desc" ? "Desc" : "Asc")))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 overflow-hidden rounded-[24px] border border-white/10" }, /* @__PURE__ */ React.createElement("div", { className: "hidden grid-cols-[1.2fr_1fr_0.5fr_0.9fr_0.9fr_0.7fr_1.5fr_0.9fr] gap-4 border-b border-white/10 bg-black/20 px-5 py-4 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400 lg:grid" }, /* @__PURE__ */ React.createElement("div", null, "Artwork"), /* @__PURE__ */ React.createElement("div", null, "Artist / Owner"), /* @__PURE__ */ React.createElement("div", null, "Priority"), /* @__PURE__ */ React.createElement("div", null, "Featured Since"), /* @__PURE__ */ React.createElement("div", null, "Expires"), /* @__PURE__ */ React.createElement("div", null, "Score (30d)"), /* @__PURE__ */ React.createElement("div", null, "Status"), /* @__PURE__ */ React.createElement("div", null, "Actions")), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-white/10" }, filteredEntries.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "px-5 py-10 text-center text-sm text-slate-400" }, "No featured entries match the current filter.") : filteredEntries.map((entry) => /* @__PURE__ */ React.createElement("div", { key: entry.id, className: "grid gap-5 bg-white/[0.02] px-5 py-5 lg:grid-cols-[1.2fr_1fr_0.5fr_0.9fr_0.9fr_0.7fr_1.5fr_0.9fr] lg:items-center" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 sm:grid-cols-[92px_1fr]" }, /* @__PURE__ */ React.createElement("a", { href: entry.artwork?.canonical_url || "#", target: "_blank", rel: "noreferrer", className: "overflow-hidden rounded-2xl border border-white/10 bg-[#08111d]" }, /* @__PURE__ */ React.createElement("img", { src: entry.artwork?.thumbnail?.url, alt: entry.artwork?.title || "Artwork preview", className: "h-24 w-full object-cover" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-white" }, entry.artwork?.title || "Missing artwork"), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-slate-400" }, "#", entry.artwork?.id || entry.artwork_id)), /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs leading-6 text-slate-400" }, "Visibility: ", entry.artwork?.visibility || "—", " • Published: ", entry.artwork?.published_at ? "Yes" : "No"), entry.is_winner && entry.winner_reason ? /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-xs leading-6 text-amber-100" }, entry.winner_reason) : null)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, entry.artwork?.owner?.display_name || "Unknown"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-400" }, entry.artwork?.owner?.type === "group" ? "Group publisher" : `@${entry.artwork?.owner?.username || ""}`)), /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, entry.priority), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-200" }, formatDateTime$3(entry.featured_at)), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-200" }, formatDateTime$3(entry.expires_at)), /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-white" }, entry.medals?.score_30d || 0), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, (entry.status_badges || []).map((badge, index2) => /* @__PURE__ */ React.createElement(Badge$2, { key: `${entry.id}-${badge.label}-${index2}`, label: badge.label, tone: badge.tone }))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2 lg:justify-end" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => editEntry(entry), className: "rounded-full border border-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-slate-100 transition hover:border-white/20 hover:bg-white/5" }, "Edit"), capabilities.forceHeroEnabled ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleForceHero(entry), disabled: busy === `force-${entry.id}`, className: `rounded-full border px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] transition disabled:cursor-not-allowed disabled:opacity-60 ${entry.is_force_hero ? "border-amber-300/25 text-amber-100 hover:border-amber-300/40 hover:bg-amber-400/10" : "border-amber-300/15 text-amber-50 hover:border-amber-300/30 hover:bg-amber-400/5"}` }, busy === `force-${entry.id}` ? "Saving…" : entry.is_force_hero ? "Disable Force Hero" : "Force Hero") : null, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleToggle(entry), disabled: busy === `toggle-${entry.id}`, className: "rounded-full border border-sky-300/20 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-sky-100 transition hover:border-sky-300/40 hover:bg-sky-400/10 disabled:cursor-not-allowed disabled:opacity-60" }, busy === `toggle-${entry.id}` ? "Saving…" : entry.is_active ? "Deactivate" : "Activate"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => handleDelete(entry), disabled: busy === `delete-${entry.id}`, className: "rounded-full border border-rose-300/20 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-rose-100 transition hover:border-rose-300/40 hover:bg-rose-400/10 disabled:cursor-not-allowed disabled:opacity-60" }, busy === `delete-${entry.id}` ? "Deleting…" : "Delete")))))))))); } -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: FeaturedArtworksAdmin }, Symbol.toStringTag, { value: "Module" })); function AdminFeaturedArtworks() { return /* @__PURE__ */ React.createElement(AdminLayout, null, /* @__PURE__ */ React.createElement(FeaturedArtworksAdmin, null)); } -const __vite_glob_0_4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminFeaturedArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -14645,7 +14781,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_5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HomepageAnnouncementForm }, Symbol.toStringTag, { value: "Module" })); @@ -14684,7 +14820,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_6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HomepageAnnouncementsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -14724,7 +14860,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_7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminSettings }, Symbol.toStringTag, { value: "Module" })); @@ -14748,7 +14884,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_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AdminStories }, Symbol.toStringTag, { value: "Module" })); @@ -14814,7 +14950,7 @@ function AdminUploadQueue() { function UploadQueuePage() { return /* @__PURE__ */ React.createElement(AdminLayout, { title: "Upload Queue", subtitle: "Review and moderate pending artwork submissions" }, /* @__PURE__ */ React.createElement(Se, { title: "Admin · Upload Queue" }), /* @__PURE__ */ React.createElement(AdminUploadQueue, null)); } -const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadQueuePage }, Symbol.toStringTag, { value: "Module" })); @@ -14878,7 +15014,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, { title: "Admin · Username Queue" }), /* @__PURE__ */ React.createElement(AdminUsernameQueue, null)); } -const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UsernameQueuePage }, Symbol.toStringTag, { value: "Module" })); @@ -14974,7 +15110,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_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UsersIndex }, Symbol.toStringTag, { value: "Module" })); @@ -15038,7 +15174,7 @@ function SimilarArtworksHeader({ artwork }) { artwork.content_type_name || "artworks" ))))); } -const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SimilarArtworksHeader }, Symbol.toStringTag, { value: "Module" })); @@ -28486,7 +28622,7 @@ function useWebShare({ onFallback } = {}) { ); return { canNativeShare, share }; } -const ArtworkShareModal = reactExports.lazy(() => import("./assets/ArtworkShareModal-DEVyX6r2.js")); +const ArtworkShareModal = reactExports.lazy(() => import("./assets/ArtworkShareModal-LimHRcZ1.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" })); } @@ -30416,7 +30552,7 @@ function ArtworkPage({ artwork: initialArtwork, related: initialRelated, present } )); } -const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_14 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ArtworkPage }, Symbol.toStringTag, { value: "Module" })); @@ -62766,7 +62902,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountElement).render(/* @__PURE__ */ React.createElement(CategoriesPage, { ...props })); } } -const __vite_glob_0_14 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CategoriesPage }, Symbol.toStringTag, { value: "Module" })); @@ -62788,7 +62924,7 @@ function CollectionAnalytics() { const seo = props.seo || {}; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Se, 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_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -63255,7 +63391,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_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -63451,7 +63587,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_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionFeaturedIndex }, Symbol.toStringTag, { value: "Module" })); @@ -63522,7 +63658,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_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionHistory }, Symbol.toStringTag, { value: "Module" })); @@ -65482,7 +65618,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_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionManage }, Symbol.toStringTag, { value: "Module" })); @@ -65499,7 +65635,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_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionSeriesShow }, Symbol.toStringTag, { value: "Module" })); @@ -67209,7 +67345,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_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionShow }, Symbol.toStringTag, { value: "Module" })); @@ -67605,7 +67741,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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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$1, { 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_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionStaffProgramming }, Symbol.toStringTag, { value: "Module" })); @@ -67931,7 +68067,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, { 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, { 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, { 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, { 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, { 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, { 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, { 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, { 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, { 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, { 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, { 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_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CollectionStaffSurfaces }, Symbol.toStringTag, { value: "Module" })); @@ -68500,7 +68636,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_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsAdminIndex }, Symbol.toStringTag, { value: "Module" })); @@ -68563,7 +68699,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_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsAssetPackAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -68629,7 +68765,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_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_28 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsChallengeAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -68714,7 +68850,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, { 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_28 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_29 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsCollectionAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -68819,7 +68955,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, { 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((v) => ({ value: v, label: v })), 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((v) => ({ value: v, label: v })), 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((v) => ({ value: v, label: v })), 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_29 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_30 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: NovaCardsTemplateAdmin }, Symbol.toStringTag, { value: "Module" })); @@ -69105,7 +69241,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_30 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_31 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SavedCollections }, Symbol.toStringTag, { value: "Module" })); @@ -69443,7 +69579,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(CommunityActivityPage, { ...props })); } } -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: CommunityActivityPage }, Symbol.toStringTag, { value: "Module" })); @@ -69761,7 +69897,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(LatestCommentsPage, { ...props })); } } -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: LatestCommentsPage }, Symbol.toStringTag, { value: "Module" })); @@ -70437,7 +70573,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_33 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_34 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: FollowingFeed }, Symbol.toStringTag, { value: "Module" })); @@ -70497,7 +70633,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_34 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_35 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HashtagFeed }, Symbol.toStringTag, { value: "Module" })); @@ -70555,7 +70691,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_35 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_36 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SavedFeed }, Symbol.toStringTag, { value: "Module" })); @@ -70680,7 +70816,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_36 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_37 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: SearchFeed }, Symbol.toStringTag, { value: "Module" })); @@ -70742,7 +70878,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_37 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_38 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: TrendingFeed }, Symbol.toStringTag, { value: "Module" })); @@ -70827,7 +70963,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_38 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_39 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumCategory }, Symbol.toStringTag, { value: "Module" })); @@ -71549,7 +71685,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_39 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_40 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumEditPost }, Symbol.toStringTag, { value: "Module" })); @@ -71640,7 +71776,7 @@ function formatLastActivity(value) { } return `Updated ${date.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })}`; } -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: ForumIndex }, Symbol.toStringTag, { value: "Module" })); @@ -71761,7 +71897,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_41 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_42 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumNewThread }, Symbol.toStringTag, { value: "Module" })); @@ -71776,7 +71912,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]" }, /* @__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_42 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ForumSection }, Symbol.toStringTag, { value: "Module" })); @@ -72114,7 +72250,7 @@ function formatDate$c(dateStr) { return ""; } } -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: ForumThread }, Symbol.toStringTag, { value: "Module" })); @@ -72358,7 +72494,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_44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupChallengeShow }, Symbol.toStringTag, { value: "Module" })); @@ -72368,7 +72504,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_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupEventShow }, Symbol.toStringTag, { value: "Module" })); @@ -73058,7 +73194,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_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupFaqPage }, Symbol.toStringTag, { value: "Module" })); @@ -73606,7 +73742,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_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -73681,7 +73817,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_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_49 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupIndex }, Symbol.toStringTag, { value: "Module" })); @@ -73711,7 +73847,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_49 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_50 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupPostShow }, Symbol.toStringTag, { value: "Module" })); @@ -73727,7 +73863,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_50 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_51 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupProjectShow }, Symbol.toStringTag, { value: "Module" })); @@ -74026,7 +74162,7 @@ function GroupQuickstartPage() { /* @__PURE__ */ React.createElement(QuickstartNextSteps, { items: nextSteps }) ))))); } -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: GroupQuickstartPage }, Symbol.toStringTag, { value: "Module" })); @@ -74044,7 +74180,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_52 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_53 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupReleaseShow }, Symbol.toStringTag, { value: "Module" })); @@ -74472,7 +74608,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_53 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_54 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: GroupShow }, Symbol.toStringTag, { value: "Module" })); @@ -74730,7 +74866,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_54 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_55 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AccountHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -75086,7 +75222,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_55 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_56 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: AuthHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -75512,7 +75648,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_56 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_57 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: CardsHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -76421,7 +76557,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_57 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: HelpCenterPage }, Symbol.toStringTag, { value: "Module" })); @@ -76810,7 +76946,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_58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_59 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: ProfileHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -77265,7 +77401,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_59 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_60 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -77507,7 +77643,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_60 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_61 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: TroubleshootingHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -77925,7 +78061,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_61 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_62 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -78388,7 +78524,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_62 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_63 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: WorldsHelpPage }, Symbol.toStringTag, { value: "Module" })); @@ -78440,7 +78576,7 @@ function HomeBecauseYouLike$1({ items, preferences }) { "See all →" )), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5" }, items.map((item) => /* @__PURE__ */ React.createElement(ArtCard$2, { key: item.id, item })))); } -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: HomeBecauseYouLike$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78462,7 +78598,7 @@ function HomeCTA$1({ isLoggedIn }) { "Create account" ))))); } -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: HomeCTA$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78533,7 +78669,7 @@ function CategoryTile({ cat }) { function HomeCategories$1() { return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "🗂️ Explore Categories"), /* @__PURE__ */ React.createElement("a", { href: "/browse", className: "text-sm text-nova-300 hover:text-white transition" }, "Browse all →")), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5" }, CATEGORIES.map((cat) => /* @__PURE__ */ React.createElement(CategoryTile, { key: cat.href, cat })))); } -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: HomeCategories$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78559,7 +78695,7 @@ function HomeCollections$1({ } return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "Trending Collections"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 max-w-2xl text-sm text-nova-300" }, "Collections getting the strongest mix of follows, saves, and engagement right now.")), /* @__PURE__ */ React.createElement("a", { href: "/collections/trending", className: "shrink-0 text-sm text-nova-300 transition hover:text-white" }, "All collections →")), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-2 xl:grid-cols-3" }, displayItems.map((collection) => /* @__PURE__ */ React.createElement(CollectionCard, { key: collection.id, collection, isOwner: false })))); } -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: HomeCollections$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78600,7 +78736,7 @@ function HomeCreators$1({ creators }) { if (!Array.isArray(creators) || creators.length === 0) return null; return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "👤 Creator Spotlight"), /* @__PURE__ */ React.createElement("a", { href: "/members", className: "text-sm text-nova-300 hover:text-white transition" }, "All creators →")), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6" }, creators.map((c) => /* @__PURE__ */ React.createElement(CreatorCard$1, { key: c.id, creator: c })))); } -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: HomeCreators$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78641,7 +78777,7 @@ function HomeFresh$1({ items }) { } )); } -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: HomeFresh$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78694,7 +78830,7 @@ function HomeFromFollowing$1({ items }) { } return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "👥 From Creators You Follow"), /* @__PURE__ */ React.createElement("a", { href: "/discover/following", className: "text-sm text-nova-300 hover:text-white transition" }, "See all →")), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5" }, items.map((item) => /* @__PURE__ */ React.createElement(ArtCard$1, { key: item.id, item })))); } -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: HomeFromFollowing$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78746,7 +78882,7 @@ function HomeGroups$1({ groups }) { } return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "Group Spotlight"), /* @__PURE__ */ React.createElement("a", { href: "/groups", className: "text-sm text-nova-300 transition hover:text-white" }, "All groups ->")), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4" }, uniqueGroups.map((group) => /* @__PURE__ */ React.createElement(GroupSpotlightCard, { key: group.id, group })))); } -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: HomeGroups$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78789,7 +78925,7 @@ function HomeHero({ artwork }) { "View Artwork" )))); } -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: HomeHero }, Symbol.toStringTag, { value: "Module" })); @@ -78797,7 +78933,7 @@ function HomeMedalHighlights$1({ title, href = null, items, description = "" }) if (!Array.isArray(items) || items.length === 0) return null; return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__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-xl font-bold text-white" }, title), description ? /* @__PURE__ */ React.createElement("p", { className: "mt-2 max-w-2xl text-sm text-slate-400" }, description) : null), href ? /* @__PURE__ */ React.createElement("a", { href, className: "text-sm text-nova-300 transition hover:text-white" }, "See all →") : null), /* @__PURE__ */ React.createElement(ArtworkGalleryGrid, { items, className: "xl:grid-cols-4" })); } -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: HomeMedalHighlights$1 }, Symbol.toStringTag, { value: "Module" })); @@ -78826,27 +78962,27 @@ function HomeNews$1({ items }) { item.date ? /* @__PURE__ */ React.createElement("span", { className: "flex-shrink-0 text-xs text-soft" }, formatDate$b(item.date)) : null )))); } -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: HomeNews$1 }, Symbol.toStringTag, { value: "Module" })); -const HomeWelcomeRow$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_80)); -const HomeFromFollowing = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_69)); -const HomeTrendingForYou$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_79)); -const HomeBecauseYouLike = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_63)); -const HomeSuggestedCreators$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_76)); -const HomeTrending$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_78)); -const HomeMedalHighlights = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_72)); -const HomeRising$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_75)); -const HomeFresh = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_68)); -const HomeCollections = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_66)); -const HomeWorldSpotlight$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_81)); -const HomeGroups = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_70)); -const HomeCategories = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_65)); -const HomeTags$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_77)); -const HomeCreators = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_67)); -const HomeNews = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_73)); -const HomeCTA = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_64)); +const HomeWelcomeRow$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_81)); +const HomeFromFollowing = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_70)); +const HomeTrendingForYou$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_80)); +const HomeBecauseYouLike = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_64)); +const HomeSuggestedCreators$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_77)); +const HomeTrending$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_79)); +const HomeMedalHighlights = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_73)); +const HomeRising$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_76)); +const HomeFresh = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_69)); +const HomeCollections = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_67)); +const HomeWorldSpotlight$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_82)); +const HomeGroups = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_71)); +const HomeCategories = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_66)); +const HomeTags$1 = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_78)); +const HomeCreators = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_68)); +const HomeNews = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_74)); +const HomeCTA = reactExports.lazy(() => Promise.resolve().then(() => __vite_glob_0_65)); function cx$5(...parts) { return parts.filter(Boolean).join(" "); } @@ -79001,7 +79137,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(HomePage, { ...props })); } } -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: HomePage }, Symbol.toStringTag, { value: "Module" })); @@ -79045,7 +79181,7 @@ function HomeRising({ items }) { if (!Array.isArray(items) || items.length === 0) return null; return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white flex items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "text-emerald-400" }, "🚀"), " Rising Now"), /* @__PURE__ */ React.createElement("a", { href: "/discover/rising", className: "text-sm text-nova-300 hover:text-white transition" }, "See all →")), /* @__PURE__ */ React.createElement("div", { className: "flex snap-x snap-mandatory gap-4 overflow-x-auto pb-3 lg:grid lg:grid-cols-5 lg:overflow-visible" }, items.map((item) => /* @__PURE__ */ React.createElement(ArtCard, { key: item.id, item })))); } -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: HomeRising }, Symbol.toStringTag, { value: "Module" })); @@ -79075,7 +79211,7 @@ function HomeSuggestedCreators({ creators }) { if (!Array.isArray(creators) || creators.length === 0) return null; return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-white" }, "💡 Suggested Creators"), /* @__PURE__ */ React.createElement("p", { className: "mt-0.5 text-xs text-nova-400" }, "Creators you might enjoy following")), /* @__PURE__ */ React.createElement("a", { href: "/creators/top", className: "text-sm text-nova-300 hover:text-white transition" }, "Explore all →")), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4" }, creators.map((creator) => /* @__PURE__ */ React.createElement(CreatorCard, { key: creator.id, creator })))); } -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: HomeSuggestedCreators }, Symbol.toStringTag, { value: "Module" })); @@ -79092,7 +79228,7 @@ function HomeTags({ tags }) { tag.count > 0 && /* @__PURE__ */ React.createElement("span", { className: "ml-1.5 text-xs text-soft" }, tag.count.toLocaleString()) )))); } -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: HomeTags }, Symbol.toStringTag, { value: "Module" })); @@ -79106,7 +79242,7 @@ function HomeTrending({ items }) { } )); } -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: HomeTrending }, Symbol.toStringTag, { value: "Module" })); @@ -79118,7 +79254,7 @@ function HomeTrendingForYou({ items, preferences }) { const link2 = "/discover/for-you"; return /* @__PURE__ */ React.createElement("section", { className: "mt-14 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-5 flex flex-col gap-3 md:flex-row md:items-end md:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[0.7rem] font-semibold uppercase tracking-[0.28em] text-sky-200/70" }, "Personalized feed"), /* @__PURE__ */ React.createElement("h2", { className: "mt-2 text-xl font-bold text-white" }, heading2), /* @__PURE__ */ React.createElement("p", { className: "mt-1 max-w-2xl text-sm text-slate-300" }, subheading)), /* @__PURE__ */ React.createElement("a", { href: link2, className: "text-sm text-nova-300 transition hover:text-white" }, "Open full feed →")), /* @__PURE__ */ React.createElement(ArtworkGalleryGrid, { items, compact: true })); } -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: HomeTrendingForYou }, Symbol.toStringTag, { value: "Module" })); @@ -79164,7 +79300,7 @@ function HomeWelcomeRow({ user_data }) { "Upload" ))))); } -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: HomeWelcomeRow }, Symbol.toStringTag, { value: "Module" })); @@ -79336,7 +79472,7 @@ function HomeWorldSpotlight({ world }) { } )); } -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: HomeWorldSpotlight }, Symbol.toStringTag, { value: "Module" })); @@ -79447,7 +79583,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_82 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_83 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: LeaderboardPage }, Symbol.toStringTag, { value: "Module" })); @@ -81385,7 +81521,7 @@ if (typeof document !== "undefined") { ); } } -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: MessagesPage }, Symbol.toStringTag, { value: "Module" })); @@ -81552,7 +81688,7 @@ function ArtworkMaturityQueue() { } )); } -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: ArtworkMaturityQueue }, Symbol.toStringTag, { value: "Module" })); @@ -81973,7 +82109,7 @@ if (typeof document !== "undefined") { clientExports.createRoot(mountEl).render(/* @__PURE__ */ React.createElement(NewsComments, { ...props })); } } -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: NewsComments }, Symbol.toStringTag, { value: "Module" })); @@ -82937,7 +83073,7 @@ function ProfileGallery() { } )))); } -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: ProfileGallery }, Symbol.toStringTag, { value: "Module" })); @@ -85788,7 +85924,7 @@ function ProfileShow() { } )))); } -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: ProfileShow }, Symbol.toStringTag, { value: "Module" })); @@ -87216,7 +87352,7 @@ function ProfileEdit() { ) ); } -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: ProfileEdit }, Symbol.toStringTag, { value: "Module" })); @@ -87729,7 +87865,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_90 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_91 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioActivity }, Symbol.toStringTag, { value: "Module" })); @@ -87820,7 +87956,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_91 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_92 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -88636,7 +88772,7 @@ function StudioArchived() { } )); } -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: StudioArchived }, Symbol.toStringTag, { value: "Module" })); @@ -88672,7 +88808,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_93 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_94 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArtworkAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -88970,7 +89106,7 @@ function PastedTagsDialog$1({ open, preview, maxTags, onClose, onConfirm }) { document.body ); } -function TagPicker$1({ +function TagPicker({ value = [], onChange, suggestedTags = [], @@ -91129,7 +91265,7 @@ function StudioArtworkEdit() { typeof item.confidence === "number" && /* @__PURE__ */ React.createElement("span", { className: "ml-1 text-[10px] text-white/60" }, Math.round(item.confidence * 100), "%") ); })), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyTagSuggestions(selectedAiTags, "add"), className: "text-xs text-sky-200 transition hover:text-white" }, "Add selected"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyTagSuggestions(aiSuggestedTags, "add"), className: "text-xs text-slate-300 transition hover:text-white" }, "Add all"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyTagSuggestions(aiSuggestedTags, "remove"), className: "text-xs text-slate-400 transition hover:text-white" }, "Remove suggested")))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4 space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white" }, "Category suggestions"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => requestAiIntent("category", "regenerate"), className: "text-xs text-slate-400 transition hover:text-white" }, "Regenerate")), !aiData?.content_type && !aiData?.category && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "AI content-type and category candidates appear here after analysis."), aiData?.content_type && /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] p-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Suggested content type"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm font-medium text-white" }, aiData.content_type.label), /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyCategorySuggestion(aiData.category || { content_type_id: aiData.content_type.id }, "content_type"), className: "text-xs text-sky-200 transition hover:text-white" }, "Apply content type"))), aiData?.category && /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-white/10 bg-white/[0.04] p-3 space-y-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500" }, "Suggested category"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm font-medium text-white" }, aiData.category.label)), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyCategorySuggestion(aiData.category, "category"), className: "text-xs text-sky-200 transition hover:text-white" }, "Apply category"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => applyCategorySuggestion(aiData.category, "both"), className: "text-xs text-slate-300 transition hover:text-white" }, "Apply both")), (aiData.category.alternatives || []).length > 0 && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, aiData.category.alternatives.map((item) => /* @__PURE__ */ React.createElement("button", { key: item.id, type: "button", onClick: () => applyCategorySuggestion(item, "both"), className: "rounded-full border border-white/10 bg-white/[0.03] px-3 py-1 text-xs text-slate-300 transition hover:text-white" }, item.label)))))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4 space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white" }, "Similar / duplicate candidates"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => requestAiIntent("similar", "regenerate"), className: "text-xs text-slate-400 transition hover:text-white" }, "Refresh")), (aiData?.similar_candidates || []).length === 0 && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "Possible duplicates or visually similar artworks will appear here."), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-3" }, (aiData?.similar_candidates || []).map((item) => /* @__PURE__ */ React.createElement("div", { key: item.artwork_id, className: "rounded-xl border border-white/10 bg-white/[0.04] p-3" }, /* @__PURE__ */ React.createElement("div", { className: "aspect-[4/3] overflow-hidden rounded-lg bg-white/5" }, item.thumbnail_url ? /* @__PURE__ */ React.createElement("img", { src: item.thumbnail_url, alt: item.title || "Similar artwork", className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center text-xs text-slate-500" }, "No preview")), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-medium text-white" }, item.title || `Artwork #${item.artwork_id}`), /* @__PURE__ */ React.createElement("div", { className: "text-[11px] text-slate-500" }, "#", item.artwork_id, " · ", item.match_type, " · ", typeof item.score === "number" ? `${Math.round(item.score * 100)}%` : "n/a"), item.owner && /* @__PURE__ */ React.createElement("div", { className: "text-[11px] text-slate-500" }, item.owner), item.review_state && /* @__PURE__ */ React.createElement("div", { className: "text-[11px] text-emerald-300 uppercase tracking-[0.18em]" }, item.review_state)), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-2" }, item.url && /* @__PURE__ */ React.createElement("a", { href: item.url, target: "_blank", rel: "noreferrer", onClick: () => trackAiEvent("duplicate_candidate_viewed", { candidate_artwork_id: item.artwork_id, match_type: item.match_type }), className: "text-xs text-sky-200 transition hover:text-white" }, "Open"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => persistAiAction({ similar_actions: [{ artwork_id: item.artwork_id, state: "ignored" }] }), className: "text-xs text-slate-300 transition hover:text-white" }, "Ignore"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => persistAiAction({ similar_actions: [{ artwork_id: item.artwork_id, state: "reviewed" }] }), className: "text-xs text-slate-400 transition hover:text-white" }, "Mark as reviewed")))))))), activeTab === "tags" && /* @__PURE__ */ React.createElement(Section, { id: "tags", className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement(SectionTitle, { icon: "fa-solid fa-tags" }, "Tags"), /* @__PURE__ */ React.createElement(InlineAiButton, { onClick: () => requestAiIntent("tags"), disabled: aiAction !== "", loading: aiAction === "analyze" || aiAction === "regenerate" }, "Tags")), /* @__PURE__ */ React.createElement( - TagPicker$1, + TagPicker, { value: tagSlugs, onChange: handleTagChange, @@ -91214,7 +91350,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_94 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_95 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioArtworkEdit }, Symbol.toStringTag, { value: "Module" })); @@ -91226,7 +91362,7 @@ function StudioArtworks() { const summary = props.summary || {}; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 grid gap-4 md:grid-cols-4" }, /* @__PURE__ */ React.createElement(SummaryCard$3, { label: "Artworks", value: summary.count, icon: "fa-solid fa-images" }), /* @__PURE__ */ React.createElement(SummaryCard$3, { label: "Drafts", value: summary.draft_count, icon: "fa-solid fa-file-pen" }), /* @__PURE__ */ React.createElement(SummaryCard$3, { label: "Published", value: summary.published_count, icon: "fa-solid fa-rocket" }), /* @__PURE__ */ React.createElement("a", { href: "/upload", className: "rounded-[24px] border border-sky-300/20 bg-sky-300/10 p-5 text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.2em]" }, "Upload artwork"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6" }, "Start a new visual upload flow without leaving Creator Studio."))), /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: props.quickCreate, hideModuleFilter: true })); } -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: StudioArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -91352,7 +91488,7 @@ function StudioAssets() { /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }) )))); } -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: StudioAssets }, Symbol.toStringTag, { value: "Module" })); @@ -91524,7 +91660,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_97 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_98 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCalendar }, Symbol.toStringTag, { value: "Module" })); @@ -91546,7 +91682,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_98 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_99 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCardAnalytics }, Symbol.toStringTag, { value: "Module" })); @@ -92690,7 +92826,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_99 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_100 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioCardEditor }, Symbol.toStringTag, { value: "Module" })); @@ -92702,7 +92838,7 @@ function StudioCardsIndex() { const summary = props.summary || {}; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("section", { className: "rounded-[32px] border border-white/10 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.88))] p-6 shadow-[0_24px_70px_rgba(2,6,23,0.32)]" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "max-w-3xl" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.28em] text-sky-200/75" }, "Creation surface"), /* @__PURE__ */ React.createElement("h2", { className: "mt-3 text-3xl font-semibold tracking-[-0.04em] text-white" }, "Build quote cards, mood cards, and visual text art."), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-7 text-slate-300" }, "Cards now live inside the same shared Creator Studio queue as artworks, collections, and stories, while keeping the dedicated editor and analytics flow.")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, /* @__PURE__ */ React.createElement("a", { href: "/studio/cards/create", 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" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-plus" }), "New card"), /* @__PURE__ */ React.createElement("a", { href: props.publicBrowseUrl, className: "inline-flex items-center gap-2 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]" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-compass" }), "Browse public cards")))), /* @__PURE__ */ React.createElement("section", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4" }, /* @__PURE__ */ React.createElement(StatCard$1, { label: "All cards", value: summary.count || 0, icon: "fa-layer-group" }), /* @__PURE__ */ React.createElement(StatCard$1, { label: "Drafts", value: summary.draft_count || 0, icon: "fa-file-lines" }), /* @__PURE__ */ React.createElement(StatCard$1, { label: "Archived", value: summary.archived_count || 0, icon: "fa-box-archive" }), /* @__PURE__ */ React.createElement(StatCard$1, { label: "Published", value: summary.published_count || 0, icon: "fa-earth-americas" })), /* @__PURE__ */ React.createElement("section", { className: "mt-8" }, /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: props.quickCreate, hideModuleFilter: true, emptyTitle: "No cards yet", emptyBody: "Create your first Nova card and it will appear here alongside your other Creator Studio content." }))); } -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: StudioCardsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -92775,7 +92911,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_101 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_102 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioChallenges }, Symbol.toStringTag, { value: "Module" })); @@ -92787,7 +92923,7 @@ function StudioCollections() { const summary = props.summary || {}; return /* @__PURE__ */ React.createElement(StudioLayout, { title: props.title, subtitle: props.description }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 grid gap-4 md:grid-cols-4" }, /* @__PURE__ */ React.createElement(SummaryCard$2, { label: "Collections", value: summary.count, icon: "fa-solid fa-layer-group" }), /* @__PURE__ */ React.createElement(SummaryCard$2, { label: "Drafts", value: summary.draft_count, icon: "fa-solid fa-file-pen" }), /* @__PURE__ */ React.createElement(SummaryCard$2, { label: "Published", value: summary.published_count, icon: "fa-solid fa-rocket" }), /* @__PURE__ */ React.createElement("a", { href: props.dashboardUrl, className: "rounded-[24px] border border-sky-300/20 bg-sky-300/10 p-5 text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.2em]" }, "Collection dashboard"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6" }, "Open the full collection workflow surface for rules, history, and collaboration."))), /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: props.quickCreate, hideModuleFilter: true })); } -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: StudioCollections }, Symbol.toStringTag, { value: "Module" })); @@ -93074,7 +93210,7 @@ function StudioComments() { /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-arrow-right" }) ))))); } -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: StudioComments }, Symbol.toStringTag, { value: "Module" })); @@ -93090,7 +93226,7 @@ function StudioContentIndex() { } )); } -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: StudioContentIndex }, Symbol.toStringTag, { value: "Module" })); @@ -93216,7 +93352,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_105 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_106 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -93233,7 +93369,7 @@ function StudioDrafts() { } )); } -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: StudioDrafts }, Symbol.toStringTag, { value: "Module" })); @@ -93316,7 +93452,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_107 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_108 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioFeatured }, Symbol.toStringTag, { value: "Module" })); @@ -93342,7 +93478,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_108 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_109 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioFollowers }, Symbol.toStringTag, { value: "Module" })); @@ -93351,7 +93487,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_109 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_110 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupActivity }, Symbol.toStringTag, { value: "Module" })); @@ -93359,7 +93495,7 @@ function StudioGroupArtworks() { const { props } = X(); 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_110 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_111 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupArtworks }, Symbol.toStringTag, { value: "Module" })); @@ -93400,7 +93536,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_111 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_112 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupAssets }, Symbol.toStringTag, { value: "Module" })); @@ -93472,7 +93608,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_112 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_113 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupChallengeEditor }, Symbol.toStringTag, { value: "Module" })); @@ -93481,7 +93617,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_113 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_114 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupChallenges }, Symbol.toStringTag, { value: "Module" })); @@ -93489,7 +93625,7 @@ function StudioGroupCollections() { const { props } = X(); 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_114 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_115 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupCollections }, Symbol.toStringTag, { value: "Module" })); @@ -93603,7 +93739,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_115 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_116 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupCreate }, Symbol.toStringTag, { value: "Module" })); @@ -93668,7 +93804,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_116 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_117 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupDashboard }, Symbol.toStringTag, { value: "Module" })); @@ -93707,7 +93843,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_117 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_118 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupEventEditor }, Symbol.toStringTag, { value: "Module" })); @@ -93716,7 +93852,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_118 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_119 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupEvents }, Symbol.toStringTag, { value: "Module" })); @@ -93743,7 +93879,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_119 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_120 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupInvitations }, Symbol.toStringTag, { value: "Module" })); @@ -93772,7 +93908,7 @@ function routeUrl(baseUrl, id, action) { if (!baseUrl) return ""; return `${String(baseUrl).replace(/\/$/, "")}/${id}/${action}`; } -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: StudioGroupJoinRequests }, Symbol.toStringTag, { value: "Module" })); @@ -93839,7 +93975,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_121 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_122 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupMembers }, Symbol.toStringTag, { value: "Module" })); @@ -93863,7 +93999,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_122 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_123 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupPostEditor }, Symbol.toStringTag, { value: "Module" })); @@ -93872,7 +94008,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_123 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_124 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupPosts }, Symbol.toStringTag, { value: "Module" })); @@ -93921,7 +94057,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_124 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_125 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupProjectEditor }, Symbol.toStringTag, { value: "Module" })); @@ -93931,7 +94067,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_125 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_126 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupProjects }, Symbol.toStringTag, { value: "Module" })); @@ -93962,7 +94098,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_126 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_127 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupRecruitment }, Symbol.toStringTag, { value: "Module" })); @@ -94015,7 +94151,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_127 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_128 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReleaseEditor }, Symbol.toStringTag, { value: "Module" })); @@ -94027,7 +94163,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_128 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_129 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReleases }, Symbol.toStringTag, { value: "Module" })); @@ -94044,7 +94180,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_129 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_130 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReputation }, Symbol.toStringTag, { value: "Module" })); @@ -94061,7 +94197,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_130 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_131 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupReviewQueue }, Symbol.toStringTag, { value: "Module" })); @@ -94154,7 +94290,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_131 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_132 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupSettings }, Symbol.toStringTag, { value: "Module" })); @@ -94182,7 +94318,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_132 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_133 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGroupsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -94283,7 +94419,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_133 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_134 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioGrowth }, Symbol.toStringTag, { value: "Module" })); @@ -94343,7 +94479,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_134 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_135 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioInbox }, Symbol.toStringTag, { value: "Module" })); @@ -94587,97 +94723,285 @@ function FieldError({ message }) { function normalizeNewTagName(value) { return String(value || "").replace(/\s+/g, " ").trim().slice(0, 80); } +function normalizeNewsTagKey(value) { + return normalizeNewTagName(value).toLowerCase(); +} +function parseNewsTagList(input) { + return String(input || "").split(/[\n,]+/).map((item) => normalizeNewTagName(item)).filter(Boolean); +} +function analyzePastedNewsTags(rawText, selectedKeys) { + const parts = parseNewsTagList(rawText); + const tagsToAdd = []; + const skippedDuplicates = []; + const skippedInvalid = []; + for (const part of parts) { + const normalized = normalizeNewTagName(part); + const key = normalizeNewsTagKey(normalized); + if (!normalized || !key) { + skippedInvalid.push(String(part || "").trim()); + continue; + } + if (selectedKeys.includes(key) || tagsToAdd.some((item) => item.key === key)) { + skippedDuplicates.push(normalized); + continue; + } + tagsToAdd.push({ key, name: normalized }); + } + return { + parsedCount: parts.length, + tagsToAdd, + skippedDuplicates, + skippedInvalid + }; +} function SectionCard({ eyebrow, title, description, actions, children, tone = "default" }) { const toneClass = tone === "feature" ? "bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.16),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", { className: `rounded-[28px] border border-white/10 p-5 ${toneClass}` }, /* @__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 TagPicker({ options, selectedIds, newTagNames, tagQuery, onTagQueryChange, onToggle, onCreateTag, onRemoveNewTag, manageUrl }) { - const selectedTags = reactExports.useMemo(() => options.filter((tag) => selectedIds.includes(tag.id)), [options, selectedIds]); - const normalizedQuery = reactExports.useMemo(() => normalizeNewTagName(tagQuery), [tagQuery]); - const matchingExistingTag = reactExports.useMemo(() => { +function NewsTagInputDialog({ open, preview, onClose, onConfirm }) { + const backdropRef = reactExports.useRef(null); + reactExports.useEffect(() => { + if (!open) return void 0; + const handleKeyDown = (event) => { + if (event.key === "Escape") { + onClose?.(); + } + }; + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [onClose, open]); + if (!open || !preview) return null; + return reactDomExports.createPortal( + /* @__PURE__ */ React.createElement( + "div", + { + ref: backdropRef, + className: "fixed inset-0 z-[9999] flex items-center justify-center bg-[#04070dcc] px-4 backdrop-blur-md", + onClick: (event) => { + if (event.target === backdropRef.current) { + onClose?.(); + } + }, + role: "presentation" + }, + /* @__PURE__ */ React.createElement( + "div", + { + role: "dialog", + "aria-modal": "true", + "aria-labelledby": "news-tag-import-title", + className: "w-full max-w-lg overflow-hidden rounded-3xl border border-white/10 bg-[linear-gradient(180deg,rgba(16,22,34,0.98),rgba(8,12,19,0.98))] shadow-[0_30px_80px_rgba(0,0,0,0.55)]" + }, + /* @__PURE__ */ React.createElement("div", { className: "border-b border-white/[0.06] bg-white/[0.02] px-6 py-5" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.24em] text-white/35" }, "Tag Import"), /* @__PURE__ */ React.createElement("h3", { id: "news-tag-import-title", className: "mt-2 text-lg font-semibold text-white" }, "Add ", preview.tagsToAdd.length, " pasted tag", preview.tagsToAdd.length === 1 ? "" : "s", "?"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm leading-6 text-white/65" }, "Parsed ", preview.parsedCount, " item", preview.parsedCount === 1 ? "" : "s", " from your paste. Confirm before adding them to the article.")), + /* @__PURE__ */ React.createElement("div", { className: "space-y-4 px-6 py-5" }, preview.skippedDuplicates.length > 0 || preview.skippedInvalid.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-white/70" }, preview.skippedDuplicates.length > 0 ? `${preview.skippedDuplicates.length} duplicate tag${preview.skippedDuplicates.length === 1 ? "" : "s"} ignored.` : "", preview.skippedDuplicates.length > 0 && preview.skippedInvalid.length > 0 ? " " : "", preview.skippedInvalid.length > 0 ? `${preview.skippedInvalid.length} invalid tag${preview.skippedInvalid.length === 1 ? "" : "s"} ignored.` : "") : null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "mb-3 text-xs font-semibold uppercase tracking-[0.18em] text-white/40" }, "Tags to add"), /* @__PURE__ */ React.createElement("div", { className: "max-h-56 overflow-auto rounded-2xl border border-white/10 bg-white/[0.03] p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, preview.tagsToAdd.map((tag) => /* @__PURE__ */ React.createElement( + "span", + { + key: tag.key, + className: "inline-flex items-center rounded-full border border-sky-300/25 bg-sky-400/10 px-3 py-1.5 text-xs font-medium text-sky-100" + }, + tag.name + )))))), + /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-end gap-3 border-t border-white/[0.06] px-6 py-4" }, /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => onClose?.(), + className: "inline-flex items-center justify-center rounded-full border border-white/[0.08] bg-white/[0.04] px-4 py-2 text-sm font-medium text-white/70 transition hover:bg-white/[0.08] hover:text-white" + }, + "Cancel" + ), /* @__PURE__ */ React.createElement( + "button", + { + type: "button", + onClick: () => onConfirm?.(), + className: "inline-flex items-center justify-center rounded-full border border-sky-300/25 bg-sky-400/90 px-4 py-2 text-sm font-semibold text-slate-950 transition hover:brightness-110" + }, + "Add tags" + )) + ) + ), + document.body + ); +} +function NewsTagInput({ options, selectedIds, newTagNames, onSelectedIdsChange, onNewTagNamesChange, manageUrl }) { + const [query, setQuery] = reactExports.useState(""); + const [isOpen, setIsOpen] = reactExports.useState(false); + const [highlightedIndex, setHighlightedIndex] = reactExports.useState(-1); + const [error, setError] = reactExports.useState(""); + const [pastePreview, setPastePreview] = reactExports.useState(null); + const selectedIdSet = reactExports.useMemo(() => new Set((selectedIds || []).map((id) => Number(id))), [selectedIds]); + const existingTags = reactExports.useMemo(() => (Array.isArray(options) ? options : []).filter((tag) => selectedIdSet.has(Number(tag.id))), [options, selectedIdSet]); + const pendingTags = reactExports.useMemo(() => (Array.isArray(newTagNames) ? newTagNames : []).map((name2) => ({ key: normalizeNewsTagKey(name2), name: normalizeNewTagName(name2) })).filter((tag) => tag.key), [newTagNames]); + const combinedNames = reactExports.useMemo(() => [...existingTags.map((tag) => String(tag.name || "")), ...pendingTags.map((tag) => tag.name)], [existingTags, pendingTags]); + const combinedKeys = reactExports.useMemo(() => combinedNames.map((name2) => normalizeNewsTagKey(name2)).filter(Boolean), [combinedNames]); + const normalizedQuery = reactExports.useMemo(() => normalizeNewTagName(query), [query]); + const syncNames = reactExports.useCallback((names) => { + const seen = /* @__PURE__ */ new Set(); + const nextIds = []; + const nextNewNames = []; + names.forEach((rawName) => { + const nextName = normalizeNewTagName(rawName); + const key = normalizeNewsTagKey(nextName); + if (!key || seen.has(key)) { + return; + } + seen.add(key); + const existing = (Array.isArray(options) ? options : []).find((tag) => normalizeNewsTagKey(tag.name) === key); + if (existing) { + nextIds.push(Number(existing.id)); + return; + } + nextNewNames.push(nextName); + }); + onSelectedIdsChange(nextIds); + onNewTagNamesChange(nextNewNames); + }, [onNewTagNamesChange, onSelectedIdsChange, options]); + const exactMatch = reactExports.useMemo(() => { if (!normalizedQuery) return null; - const lowerQuery = normalizedQuery.toLowerCase(); - return options.find((tag) => String(tag.name || "").toLowerCase() === lowerQuery) || null; - }, [options, normalizedQuery]); - const queryMatchesPending = reactExports.useMemo(() => { - if (!normalizedQuery) return false; - const lowerQuery = normalizedQuery.toLowerCase(); - return newTagNames.some((tagName) => tagName.toLowerCase() === lowerQuery); - }, [newTagNames, normalizedQuery]); - const availableTags = reactExports.useMemo(() => { - const query = String(tagQuery || "").trim().toLowerCase(); - return options.filter((tag) => !selectedIds.includes(tag.id)).filter((tag) => query === "" ? true : String(tag.name || "").toLowerCase().includes(query)).slice(0, 12); - }, [options, selectedIds, tagQuery]); - return /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "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("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Selected tags"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, "Attach article topics without forcing the editor to scan a wall of checkboxes.")), manageUrl ? /* @__PURE__ */ React.createElement("a", { href: manageUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.14em] text-white" }, "Manage tags") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex min-h-[3.5rem] flex-wrap gap-2" }, selectedTags.length > 0 ? selectedTags.map((tag) => /* @__PURE__ */ React.createElement( - "button", - { - key: tag.id, - type: "button", - onClick: () => onToggle(tag.id), - className: "inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-2 text-sm text-sky-50 transition hover:bg-sky-400/15" - }, - /* @__PURE__ */ React.createElement("span", null, tag.name), - /* @__PURE__ */ React.createElement("span", { className: "text-xs text-sky-100/70" }, "Remove") - )) : null, newTagNames.map((tagName) => /* @__PURE__ */ React.createElement( - "button", - { - key: tagName, - type: "button", - onClick: () => onRemoveNewTag(tagName), - className: "inline-flex items-center gap-2 rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-2 text-sm text-emerald-50 transition hover:bg-emerald-400/15" - }, - /* @__PURE__ */ React.createElement("span", null, tagName), - /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-emerald-200/30 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-emerald-100/80" }, "New") - )), selectedTags.length === 0 && newTagNames.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-slate-500" }, "No tags selected yet.") : null)), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__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" }, "Find tags"), /* @__PURE__ */ React.createElement( + return (Array.isArray(options) ? options : []).find((tag) => normalizeNewsTagKey(tag.name) === normalizeNewsTagKey(normalizedQuery)) || null; + }, [normalizedQuery, options]); + const suggestions = reactExports.useMemo(() => { + const source = Array.isArray(options) ? options : []; + const lowerQuery = normalizeNewsTagKey(query); + return source.filter((tag) => !selectedIdSet.has(Number(tag.id))).filter((tag) => !pendingTags.some((pendingTag) => pendingTag.key === normalizeNewsTagKey(tag.name))).filter((tag) => lowerQuery === "" ? true : normalizeNewsTagKey(tag.name).includes(lowerQuery)).slice(0, 8); + }, [options, pendingTags, query, selectedIdSet]); + reactExports.useEffect(() => { + setHighlightedIndex(suggestions.length > 0 ? 0 : -1); + }, [suggestions]); + const addCandidate = reactExports.useCallback((rawName) => { + const nextName = normalizeNewTagName(rawName); + if (!nextName) { + return; + } + const key = normalizeNewsTagKey(nextName); + if (combinedKeys.includes(key)) { + setError("Duplicate tag"); + return; + } + setError(""); + syncNames([...combinedNames, nextName]); + setQuery(""); + setIsOpen(false); + }, [combinedKeys, combinedNames, syncNames]); + const removeExisting = reactExports.useCallback((tagId) => { + onSelectedIdsChange((selectedIds || []).filter((id) => Number(id) !== Number(tagId))); + }, [onSelectedIdsChange, selectedIds]); + const removePending = reactExports.useCallback((tagName) => { + onNewTagNamesChange((newTagNames || []).filter((name2) => normalizeNewsTagKey(name2) !== normalizeNewsTagKey(tagName))); + }, [newTagNames, onNewTagNamesChange]); + const handlePaste = reactExports.useCallback((event) => { + const raw = event.clipboardData?.getData("text"); + if (!raw) return; + const parts = parseNewsTagList(raw); + if (parts.length <= 1) return; + event.preventDefault(); + const preview = analyzePastedNewsTags(raw, combinedKeys); + if (preview.tagsToAdd.length === 0) { + setError("No new tags found in pasted text"); + return; + } + setError(""); + setPastePreview(preview); + }, [combinedKeys]); + const handleConfirmPaste = reactExports.useCallback(() => { + if (!pastePreview) return; + syncNames([...combinedNames, ...pastePreview.tagsToAdd.map((tag) => tag.name)]); + setPastePreview(null); + setQuery(""); + setIsOpen(false); + }, [combinedNames, pastePreview, syncNames]); + const handleKeyDown = reactExports.useCallback((event) => { + if (event.key === "Escape") { + setIsOpen(false); + return; + } + if (event.key === "Backspace" && query.length === 0 && combinedNames.length > 0) { + const lastPending = pendingTags[pendingTags.length - 1]; + if (lastPending) { + removePending(lastPending.name); + return; + } + const lastExisting = existingTags[existingTags.length - 1]; + if (lastExisting) { + removeExisting(lastExisting.id); + } + return; + } + if (event.key === "ArrowDown") { + event.preventDefault(); + if (suggestions.length === 0) return; + setIsOpen(true); + setHighlightedIndex((current) => Math.min(current + 1, suggestions.length - 1)); + return; + } + if (event.key === "ArrowUp") { + event.preventDefault(); + if (suggestions.length === 0) return; + setIsOpen(true); + setHighlightedIndex((current) => Math.max(current - 1, 0)); + return; + } + if (!["Enter", ",", "Tab"].includes(event.key)) { + return; + } + if (event.key === "Tab" && !isOpen && normalizedQuery === "") { + return; + } + event.preventDefault(); + if ((event.key === "Enter" || event.key === "Tab") && isOpen && highlightedIndex >= 0 && suggestions[highlightedIndex]) { + addCandidate(suggestions[highlightedIndex].name); + return; + } + if (!normalizedQuery) { + return; + } + if (exactMatch) { + addCandidate(exactMatch.name); + return; + } + addCandidate(normalizedQuery); + }, [addCandidate, combinedNames.length, exactMatch, existingTags, highlightedIndex, isOpen, normalizedQuery, pendingTags, query.length, removeExisting, removePending, suggestions]); + return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "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("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Selected tags"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-400" }, "Attach article topics with the same chip-based flow used on artwork tags.")), manageUrl ? /* @__PURE__ */ React.createElement("a", { href: manageUrl, className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.14em] text-white" }, "Manage tags") : null), /* @__PURE__ */ React.createElement("div", { className: "mt-4 min-h-[3rem] rounded-xl border border-white/10 bg-white/5 p-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, existingTags.length === 0 && pendingTags.length === 0 ? /* @__PURE__ */ React.createElement("span", { className: "px-2 py-1 text-xs text-white/50" }, "No tags selected") : null, existingTags.map((tag) => /* @__PURE__ */ React.createElement("span", { key: tag.id, className: "group inline-flex max-w-full items-center gap-2 rounded-full border border-white/20 bg-slate-900/80 px-3 py-1.5 text-xs text-slate-100" }, /* @__PURE__ */ React.createElement("span", { className: "truncate" }, tag.name), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => removeExisting(tag.id), className: "rounded-full p-0.5 text-slate-300 transition hover:bg-white/10 hover:text-white", "aria-label": `Remove tag ${tag.name}` }, "✕"))), pendingTags.map((tag) => /* @__PURE__ */ React.createElement("span", { key: tag.key, className: "group inline-flex max-w-full items-center gap-2 rounded-full border border-emerald-300/25 bg-emerald-400/10 px-3 py-1.5 text-xs text-emerald-50" }, /* @__PURE__ */ React.createElement("span", { className: "truncate" }, tag.name), /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-emerald-200/30 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-emerald-100/80" }, "New"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => removePending(tag.name), className: "rounded-full p-0.5 text-emerald-100/75 transition hover:bg-white/10 hover:text-white", "aria-label": `Remove new tag ${tag.name}` }, "✕")))))), /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__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" }, "Find tags"), /* @__PURE__ */ React.createElement( "input", { - value: tagQuery, - onChange: (event) => onTagQueryChange(event.target.value), - onKeyDown: (event) => { - if (!["Enter", ","].includes(event.key)) { - return; - } - event.preventDefault(); - const nextQuery = normalizeNewTagName(event.currentTarget.value); - if (!nextQuery) { - return; - } - if (matchingExistingTag && !selectedIds.includes(matchingExistingTag.id)) { - onToggle(matchingExistingTag.id); - onTagQueryChange(""); - return; - } - if (!queryMatchesPending) { - onCreateTag(nextQuery); - } - onTagQueryChange(""); + value: query, + onChange: (event) => { + setQuery(event.target.value); + setError(""); + setIsOpen(true); }, + onFocus: () => setIsOpen(true), + onKeyDown: handleKeyDown, + onPaste: handlePaste, placeholder: "Search existing tags or type a new one", - className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" + className: "w-full rounded-xl border border-white/10 bg-white/10 px-3 py-2 text-sm text-white placeholder:text-white/45 focus:border-sky-400 focus:outline-none", + "aria-label": "Search or add news tags" } - )), normalizedQuery && !matchingExistingTag && !queryMatchesPending ? /* @__PURE__ */ React.createElement( - "button", - { - type: "button", - onClick: () => { - onCreateTag(normalizedQuery); - onTagQueryChange(""); + )), isOpen ? /* @__PURE__ */ React.createElement("div", { className: "mt-3 overflow-hidden rounded-xl bg-slate-950/98 shadow-xl shadow-black/50 ring-1 ring-white/10" }, /* @__PURE__ */ React.createElement("ul", { role: "listbox", className: "max-h-56 overflow-auto py-1" }, suggestions.length > 0 ? suggestions.map((tag, index2) => { + const active = index2 === highlightedIndex; + return /* @__PURE__ */ React.createElement( + "li", + { + key: tag.id, + role: "option", + "aria-selected": active, + className: `flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-sm transition ${active ? "bg-sky-500/20 text-white" : "text-white/85 hover:bg-white/10"}`, + onMouseDown: (event) => { + event.preventDefault(); + addCandidate(tag.name); + } }, - className: "mt-3 inline-flex items-center gap-2 rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-2 text-sm font-semibold text-emerald-50" - }, - /* @__PURE__ */ React.createElement("span", null, "Create tag"), - /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-emerald-200/30 px-2 py-0.5 text-xs text-emerald-100" }, normalizedQuery) - ) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap gap-2" }, availableTags.length > 0 ? availableTags.map((tag) => /* @__PURE__ */ React.createElement( - "button", + /* @__PURE__ */ React.createElement("span", { className: "truncate" }, tag.name) + ); + }) : /* @__PURE__ */ React.createElement("li", { className: "px-3 py-2 text-xs text-white/50" }, "No suggestions"))) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex items-center justify-between gap-3 text-xs" }, /* @__PURE__ */ React.createElement("span", { className: error ? "text-amber-200" : "text-white/55", role: "status", "aria-live": "polite" }, error || "Type and press Enter, comma, or Tab to add. Paste a comma-separated list to review multiple tags."), /* @__PURE__ */ React.createElement("span", { className: "text-white/50" }, existingTags.length + pendingTags.length, " selected")))), /* @__PURE__ */ React.createElement( + NewsTagInputDialog, { - key: tag.id, - type: "button", - onClick: () => onToggle(tag.id), - className: "rounded-full border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white transition hover:border-white/20 hover:bg-white/[0.08]" - }, - "+ ", - tag.name - )) : /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-dashed border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-slate-500" }, "No additional tags match the current search.")), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-xs leading-5 text-slate-500" }, "Press Enter or comma to queue a new tag. Pending tags are written into the news tag list when the article is saved."))); + open: Boolean(pastePreview), + preview: pastePreview, + onClose: () => setPastePreview(null), + onConfirm: handleConfirmPaste + } + )); } function RelationCard({ relation, index: index2, onChange, onRemove, onSearch, results, relationTypeOptions }) { return /* @__PURE__ */ React.createElement("div", { className: "rounded-[24px] border border-white/10 bg-black/20 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 lg:grid-cols-[180px_minmax(0,1fr)_auto] lg:items-end" }, /* @__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: relation.entity_type, onChange: (val) => onChange(index2, { ...relation, entity_type: val, entity_id: "", preview: null, query: "" }), options: relationTypeOptions, 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" }, "Search entity"), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("input", { value: relation.query || "", onChange: (event) => onChange(index2, { ...relation, query: event.target.value }), placeholder: "Search by name, slug, or title", className: "min-w-0 flex-1 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => onSearch(index2), className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm font-semibold text-white" }, "Search"))), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => onRemove(index2), className: "rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm font-semibold text-rose-100" }, "Remove")), relation.preview ? /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-2xl border border-emerald-300/20 bg-emerald-400/10 p-4 text-sm text-emerald-50" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, "Linked: ", relation.preview.title), relation.preview.subtitle ? /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.14em] text-emerald-100/70" }, relation.preview.subtitle) : null) : null, /* @__PURE__ */ React.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React.createElement(SearchResultList$3, { items: results, onSelect: (item) => onChange(index2, { ...relation, entity_id: item.id, preview: item, query: item.title }), emptyLabel: "Search to attach a related entity." })), /* @__PURE__ */ React.createElement("label", { className: "mt-4 grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500" }, "Context label"), /* @__PURE__ */ React.createElement("input", { value: relation.context_label || "", onChange: (event) => onChange(index2, { ...relation, context_label: event.target.value }), placeholder: "Featured release, Meet the creator, Join this challenge…", className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }))); @@ -94687,7 +95011,7 @@ function stripHtml$1(value) { } function selectOptionsFromValues(options, emptyLabel = null) { const base = Array.isArray(options) ? options.map((option) => ({ - value: option.value ?? option.id, + value: String(option.value ?? option.id), label: option.label ?? option.name })) : []; return emptyLabel ? [{ value: "", label: emptyLabel }, ...base] : base; @@ -94723,6 +95047,12 @@ function buildSubmitPayload(data) { })) : [] }; } +function hasRequiredCategory(categoryId) { + if (categoryId === "" || categoryId == null) { + return false; + } + return Number(categoryId) > 0; +} function buildInitialFormData(article, defaultAuthor, typeOptions) { return { title: article.title || "", @@ -94731,7 +95061,7 @@ function buildInitialFormData(article, defaultAuthor, typeOptions) { content: article.content || "", cover_image: article.cover_image || "", type: article.type || (typeOptions?.[0]?.value || "announcement"), - category_id: article.category_id || "", + category_id: article.category_id ? String(article.category_id) : "", author_id: article.author_id || defaultAuthor?.id || "", editorial_status: article.editorial_status || "draft", published_at: article.published_at ? String(article.published_at).slice(0, 16) : "", @@ -94766,7 +95096,6 @@ function StudioNewsEditor() { const [authorQuery, setAuthorQuery] = reactExports.useState(article.author?.title || article.author?.subtitle?.replace(/^@/, "") || ""); const [selectedAuthor, setSelectedAuthor] = reactExports.useState(article.author || props.defaultAuthor || null); const [relationResults, setRelationResults] = reactExports.useState({}); - const [tagQuery, setTagQuery] = reactExports.useState(""); const [coverPreviewUrl, setCoverPreviewUrl] = reactExports.useState(article.cover_url || (String(article.cover_image || "").startsWith("http") ? article.cover_image : "")); const [stagedCoverPath, setStagedCoverPath] = reactExports.useState(""); const lastSyncedArticleKeyRef = reactExports.useRef(articleSyncKey); @@ -94781,7 +95110,6 @@ function StudioNewsEditor() { setSelectedAuthor(article.author || props.defaultAuthor || null); setAuthorQuery(article.author?.title || article.author?.subtitle?.replace(/^@/, "") || ""); setRelationResults({}); - setTagQuery(""); setCoverPreviewUrl(article.cover_url || (String(article.cover_image || "").startsWith("http") ? article.cover_image : "")); setStagedCoverPath(""); }, [article, articleSyncKey, form, initialFormData, props.defaultAuthor]); @@ -94792,7 +95120,7 @@ function StudioNewsEditor() { }, [form.data.content]); const typeOptions = reactExports.useMemo(() => selectOptionsFromValues(props.typeOptions || []), [props.typeOptions]); const statusOptions = reactExports.useMemo(() => selectOptionsFromValues(props.statusOptions || []), [props.statusOptions]); - const categoryOptions = reactExports.useMemo(() => selectOptionsFromValues(props.categoryOptions || [], "No category"), [props.categoryOptions]); + const categoryOptions = reactExports.useMemo(() => selectOptionsFromValues(props.categoryOptions || [], "Select category"), [props.categoryOptions]); const searchEntities = async (type2, query) => { const url = new URL(props.entitySearchUrl, window.location.origin); url.searchParams.set("type", type2); @@ -94842,37 +95170,6 @@ function StudioNewsEditor() { const items = await searchEntities(relation.entity_type, relation.query || ""); setRelationResults((current) => ({ ...current, [index2]: items })); }; - const toggleTag = (tagId) => { - const numericId = Number(tagId); - const next = form.data.tag_ids.includes(numericId) ? form.data.tag_ids.filter((currentId) => currentId !== numericId) : [...form.data.tag_ids, numericId]; - form.setData("tag_ids", next); - if (!form.data.tag_ids.includes(numericId)) { - const matchedTag = (Array.isArray(props.tagOptions) ? props.tagOptions : []).find((tag) => tag.id === numericId); - if (matchedTag) { - const lowerName = String(matchedTag.name || "").toLowerCase(); - form.setData("new_tag_names", form.data.new_tag_names.filter((tagName) => tagName.toLowerCase() !== lowerName)); - } - } - }; - const addNewTagName = (rawValue) => { - const nextTagName = normalizeNewTagName(rawValue); - if (!nextTagName) return; - const lowerName = nextTagName.toLowerCase(); - const matchingExistingTag = (Array.isArray(props.tagOptions) ? props.tagOptions : []).find((tag) => String(tag.name || "").toLowerCase() === lowerName); - if (matchingExistingTag) { - if (!form.data.tag_ids.includes(matchingExistingTag.id)) { - form.setData("tag_ids", [...form.data.tag_ids, matchingExistingTag.id]); - } - return; - } - if (form.data.new_tag_names.some((tagName) => tagName.toLowerCase() === lowerName)) { - return; - } - form.setData("new_tag_names", [...form.data.new_tag_names, nextTagName]); - }; - const removeNewTagName = (tagName) => { - form.setData("new_tag_names", form.data.new_tag_names.filter((currentTagName) => currentTagName !== tagName)); - }; const handleManualCoverChange = (nextValue) => { form.setData("cover_image", nextValue); if (stagedCoverPath && nextValue !== stagedCoverPath) { @@ -94890,6 +95187,11 @@ function StudioNewsEditor() { }; const submit = (event) => { event.preventDefault(); + if (!hasRequiredCategory(form.data.category_id)) { + form.setError("category_id", "Choose a category before saving the article."); + pushToast("Choose a category before saving the article.", "error"); + return; + } const options = { preserveScroll: true, preserveState: false, @@ -94967,26 +95269,28 @@ function StudioNewsEditor() { results: relationResults[index2] || [], relationTypeOptions: Array.isArray(props.relationTypeOptions) ? props.relationTypeOptions : [] } - )) : /* @__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 related entities attached yet.")))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement(SectionCard, { eyebrow: "Editorial controls", title: "Publishing", description: "Set ownership, placement, timing, and surface behavior before the article leaves draft." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, props.previewUrl ? /* @__PURE__ */ React.createElement("a", { href: props.previewUrl, target: "_blank", rel: "noreferrer", className: "inline-flex items-center justify-center gap-2 rounded-2xl border border-indigo-300/20 bg-indigo-400/10 px-4 py-3 text-sm font-semibold text-indigo-100 transition hover:bg-indigo-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-regular fa-eye" }), "Preview article") : null, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Type", value: form.data.type || null, onChange: (nextValue) => form.setData("type", String(nextValue || "")), options: typeOptions, searchable: false, className: "bg-black/20", error: form.errors.type })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Category", value: form.data.category_id || "", onChange: (nextValue) => form.setData("category_id", String(nextValue || "")), options: categoryOptions, searchable: false, className: "bg-black/20", error: form.errors.category_id }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Workflow status", value: form.data.editorial_status || null, onChange: (nextValue) => form.setData("editorial_status", String(nextValue || "")), options: statusOptions, searchable: false, className: "bg-black/20", error: form.errors.editorial_status })), /* @__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" }, "Publish at"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: form.data.published_at || "", onChange: (nextValue) => form.setData("published_at", nextValue), placeholder: "Pick a publish slot", clearable: true, className: "bg-black/20" }), /* @__PURE__ */ React.createElement(FieldError, { message: form.errors.published_at }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 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" }, "Author"), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("input", { value: authorQuery, onChange: (event) => setAuthorQuery(event.target.value), placeholder: "Search for an author", className: "min-w-0 flex-1 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: runAuthorSearch, className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm font-semibold text-white" }, "Search")), selectedAuthor ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-emerald-300/20 bg-emerald-400/10 p-4 text-sm text-emerald-50" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, "Selected author: ", selectedAuthor.title), selectedAuthor.subtitle ? /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.14em] text-emerald-100/70" }, selectedAuthor.subtitle) : null) : null, /* @__PURE__ */ React.createElement(SearchResultList$3, { items: authorResults, onSelect: (item) => { + )) : /* @__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 related entities attached yet.")))), /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement(SectionCard, { eyebrow: "Editorial controls", title: "Publishing", description: "Set ownership, placement, timing, and surface behavior before the article leaves draft." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, props.previewUrl ? /* @__PURE__ */ React.createElement("a", { href: props.previewUrl, target: "_blank", rel: "noreferrer", className: "inline-flex items-center justify-center gap-2 rounded-2xl border border-indigo-300/20 bg-indigo-400/10 px-4 py-3 text-sm font-semibold text-indigo-100 transition hover:bg-indigo-400/15" }, /* @__PURE__ */ React.createElement("i", { className: "fa-regular fa-eye" }), "Preview article") : null, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Type", value: form.data.type || null, onChange: (nextValue) => form.setData("type", String(nextValue || "")), options: typeOptions, searchable: false, className: "bg-black/20", error: form.errors.type })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Category", value: form.data.category_id || "", onChange: (nextValue) => { + form.setData("category_id", String(nextValue || "")); + if (nextValue) { + form.clearErrors("category_id"); + } + }, options: categoryOptions, searchable: false, className: "bg-black/20", error: form.errors.category_id }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-2 text-sm text-slate-300" }, /* @__PURE__ */ React.createElement(NovaSelect, { label: "Workflow status", value: form.data.editorial_status || null, onChange: (nextValue) => form.setData("editorial_status", String(nextValue || "")), options: statusOptions, searchable: false, className: "bg-black/20", error: form.errors.editorial_status })), /* @__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" }, "Publish at"), /* @__PURE__ */ React.createElement(DateTimePicker, { value: form.data.published_at || "", onChange: (nextValue) => form.setData("published_at", nextValue), placeholder: "Pick a publish slot", clearable: true, className: "bg-black/20" }), /* @__PURE__ */ React.createElement(FieldError, { message: form.errors.published_at }))), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 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" }, "Author"), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("input", { value: authorQuery, onChange: (event) => setAuthorQuery(event.target.value), placeholder: "Search for an author", className: "min-w-0 flex-1 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" }), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: runAuthorSearch, className: "rounded-2xl border border-white/10 bg-white/[0.04] px-4 py-3 text-sm font-semibold text-white" }, "Search")), selectedAuthor ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-emerald-300/20 bg-emerald-400/10 p-4 text-sm text-emerald-50" }, /* @__PURE__ */ React.createElement("div", { className: "font-semibold" }, "Selected author: ", selectedAuthor.title), selectedAuthor.subtitle ? /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs uppercase tracking-[0.14em] text-emerald-100/70" }, selectedAuthor.subtitle) : null) : null, /* @__PURE__ */ React.createElement(SearchResultList$3, { items: authorResults, onSelect: (item) => { setSelectedAuthor(item); setAuthorQuery(item.title); form.setData("author_id", item.id); }, emptyLabel: "Search to choose an author profile." }), /* @__PURE__ */ React.createElement(FieldError, { message: form.errors.author_id })), /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: form.data.is_featured, onChange: (event) => form.setData("is_featured", event.target.checked), label: "Feature on newsroom surfaces", size: 20, variant: "accent" })), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: form.data.is_pinned, onChange: (event) => form.setData("is_pinned", event.target.checked), label: "Pin to the top of the newsroom", size: 20, variant: "accent" }))), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-white/10 bg-black/20 px-4 py-3" }, /* @__PURE__ */ React.createElement(Checkbox, { checked: form.data.comments_enabled, onChange: (event) => form.setData("comments_enabled", event.target.checked), label: "Allow comments on the article page", size: 20, variant: "accent" }), /* @__PURE__ */ React.createElement(FieldError, { message: form.errors.comments_enabled })))), /* @__PURE__ */ React.createElement(SectionCard, { eyebrow: "Taxonomy", title: "Tags", description: "Search and apply tags quickly instead of scanning a wall of checkboxes." }, /* @__PURE__ */ React.createElement( - TagPicker, + NewsTagInput, { options: Array.isArray(props.tagOptions) ? props.tagOptions : [], selectedIds: form.data.tag_ids, newTagNames: form.data.new_tag_names, - tagQuery, - onTagQueryChange: setTagQuery, - onToggle: toggleTag, - onCreateTag: addNewTagName, - onRemoveNewTag: removeNewTagName, + onSelectedIdsChange: (nextIds) => form.setData("tag_ids", nextIds), + onNewTagNamesChange: (nextNames) => form.setData("new_tag_names", nextNames), manageUrl: props.tagsUrl } ), /* @__PURE__ */ React.createElement("div", { className: "mt-3" }, /* @__PURE__ */ React.createElement(FieldError, { message: form.errors.tag_ids || form.errors.new_tag_names }))), /* @__PURE__ */ React.createElement(SectionCard, { eyebrow: "Metadata", title: "SEO and social", description: "Keep search and sharing fields aligned with the main editorial package." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-4" }, /* @__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" }, "Meta title"), /* @__PURE__ */ React.createElement("input", { value: form.data.meta_title, onChange: (event) => form.setData("meta_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" }, "Meta description"), /* @__PURE__ */ React.createElement("textarea", { value: form.data.meta_description, onChange: (event) => form.setData("meta_description", 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" }, "Meta keywords"), /* @__PURE__ */ React.createElement("input", { value: form.data.meta_keywords, onChange: (event) => form.setData("meta_keywords", event.target.value), placeholder: "creator-story, release, tutorial", 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" }, "Canonical URL"), /* @__PURE__ */ React.createElement("input", { value: form.data.canonical_url, onChange: (event) => form.setData("canonical_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("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__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" }, "OG title"), /* @__PURE__ */ React.createElement("input", { value: form.data.og_title, onChange: (event) => form.setData("og_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" }, "OG image"), /* @__PURE__ */ React.createElement("input", { value: form.data.og_image, onChange: (event) => form.setData("og_image", 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" }, "OG description"), /* @__PURE__ */ React.createElement("textarea", { value: form.data.og_description, onChange: (event) => form.setData("og_description", 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(SectionCard, { eyebrow: "Actions", title: "Save and publish", description: "Use the primary action for create or update, then promote, archive, or trash the article from the same control rail." }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3" }, Object.keys(form.errors || {}).length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-3 text-sm text-rose-100" }, "The article was not saved. Fix the highlighted fields and try again.") : null, /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: form.processing, className: "w-full rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 disabled:opacity-60" }, form.processing ? "Saving article…" : "Save article"), 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 now") : null, props.archiveUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.archiveUrl), className: "w-full rounded-full border border-white/10 bg-white/[0.05] px-4 py-3 text-sm font-semibold text-white" }, "Archive article") : null, props.featureUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => At.post(props.featureUrl), className: "w-full rounded-full border border-white/10 bg-white/[0.05] px-4 py-3 text-sm font-semibold text-white" }, "Toggle featured") : 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.destroyUrl ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: deleteArticle, 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" }, "Move to trash") : 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: StudioNewsEditor }, Symbol.toStringTag, { value: "Module" })); @@ -95082,7 +95386,7 @@ function StudioNewsIndex() { } )), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400 lg:text-right" }, Number(meta.total || 0).toLocaleString(), " articles"))), /* @__PURE__ */ React.createElement("section", { className: "mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3" }, items.length > 0 ? items.map((item) => /* @__PURE__ */ React.createElement("article", { key: item.id, className: "overflow-hidden rounded-[24px] border border-white/10 bg-black/20 shadow-[0_18px_40px_rgba(2,6,23,0.18)]" }, /* @__PURE__ */ React.createElement("div", { className: "aspect-[16/9] bg-slate-950/60" }, item.cover_url ? /* @__PURE__ */ React.createElement("img", { src: item.cover_url, alt: item.title, className: "h-full w-full object-cover" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center text-slate-500" }, /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-newspaper text-3xl" }))), /* @__PURE__ */ React.createElement("div", { className: "p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-white/70" }, item.type_label), /* @__PURE__ */ React.createElement("span", { className: `rounded-full border px-2.5 py-1 ${statusTone$1(item.editorial_status)}` }, item.editorial_status.replaceAll("_", " ")), item.is_pinned ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-amber-300/20 bg-amber-400/10 px-2.5 py-1 text-amber-100" }, "Pinned") : null, item.is_featured ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full border border-emerald-300/20 bg-emerald-400/10 px-2.5 py-1 text-emerald-100" }, "Featured") : null), /* @__PURE__ */ React.createElement("h3", { className: "mt-3 text-xl font-semibold text-white" }, item.title), /* @__PURE__ */ React.createElement("div", { className: "mt-3 flex flex-wrap gap-3 text-sm text-slate-400" }, item.category_name ? /* @__PURE__ */ React.createElement("span", null, item.category_name) : null, /* @__PURE__ */ React.createElement("span", null, item.author_name), /* @__PURE__ */ React.createElement("span", null, formatDate$1(item.published_at))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("a", { href: item.edit_url, className: "rounded-full border border-sky-300/20 bg-sky-400/10 px-4 py-2 text-sm font-semibold text-sky-100" }, "Edit"), /* @__PURE__ */ React.createElement("a", { href: item.editorial_status === "published" ? item.public_url : item.preview_url, className: "rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm font-semibold text-white" }, item.editorial_status === "published" ? "View" : "Preview"), /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => deleteItem(item), className: "rounded-full border border-rose-300/20 bg-rose-400/10 px-4 py-2 text-sm font-semibold text-rose-100" }, "Trash"))))) : /* @__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 News articles match the current filters."))); } -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: StudioNewsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -95115,7 +95419,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_137 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_138 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioNewsTaxonomies }, Symbol.toStringTag, { value: "Module" })); @@ -95265,7 +95569,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_138 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_139 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioPreferences }, Symbol.toStringTag, { value: "Module" })); @@ -95445,7 +95749,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_139 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_140 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioProfile }, Symbol.toStringTag, { value: "Module" })); @@ -95522,7 +95826,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_140 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_141 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioScheduled }, Symbol.toStringTag, { value: "Module" })); @@ -95540,7 +95844,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_141 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_142 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioSearch }, Symbol.toStringTag, { value: "Module" })); @@ -95548,7 +95852,7 @@ function StudioSettings() { const { props } = X(); 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_142 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_143 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioSettings }, Symbol.toStringTag, { value: "Module" })); @@ -95561,7 +95865,7 @@ function StudioStories() { ["Published", summary.published_count, "fa-solid fa-sparkles"] ].map(([label, value, icon]) => /* @__PURE__ */ React.createElement("div", { key: label, className: "rounded-[24px] border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 text-slate-300" }, /* @__PURE__ */ React.createElement("i", { className: icon }), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, label)), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-3xl font-semibold text-white" }, Number(value || 0).toLocaleString()))), /* @__PURE__ */ React.createElement("a", { href: props.dashboardUrl, className: "rounded-[24px] border border-sky-300/20 bg-sky-300/10 p-5 text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-[0.2em]" }, "Story dashboard"), /* @__PURE__ */ React.createElement("p", { className: "mt-3 text-sm leading-6" }, "Jump into the existing story workspace when you need the full editor and publishing controls."))), /* @__PURE__ */ React.createElement(StudioContentBrowser, { listing: props.listing, quickCreate: props.quickCreate, hideModuleFilter: true })); } -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: StudioStories }, Symbol.toStringTag, { value: "Module" })); @@ -96224,7 +96528,7 @@ function StudioUploadQueue() { ))))); }))))); } -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: StudioUploadQueue }, Symbol.toStringTag, { value: "Module" })); @@ -97956,7 +98260,7 @@ function StudioWorldEditor() { )) : null )); } -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: StudioWorldEditor }, Symbol.toStringTag, { value: "Module" })); @@ -98042,7 +98346,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_146 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_147 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: StudioWorldsIndex }, Symbol.toStringTag, { value: "Module" })); @@ -100608,7 +100912,7 @@ function UploadSidebar({ autofocus: false } ))))), /* @__PURE__ */ React.createElement("section", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-5" }, /* @__PURE__ */ React.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-semibold text-white" }, "Tags"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs text-white/60" }, "Use keywords people would search for. Press Enter, comma, or Tab to add a tag.")), /* @__PURE__ */ React.createElement( - TagPicker$1, + TagPicker, { value: metadata.tags, onChange: (nextTags) => onChangeTags?.(nextTags), @@ -102649,7 +102953,7 @@ function UploadPage({ draftId, filesCdnUrl, chunkSize, chunkRequestTimeoutMs }) "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_147 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +const __vite_glob_0_148 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: UploadPage }, Symbol.toStringTag, { value: "Module" })); @@ -102761,7 +103065,7 @@ function WorldIndex() { } ))); } -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: WorldIndex }, Symbol.toStringTag, { value: "Module" })); @@ -103055,7 +103359,7 @@ function WorldShow() { } ))); } -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: WorldShow }, Symbol.toStringTag, { value: "Module" })); @@ -128645,7 +128949,7 @@ function requireServer_node() { } var server_nodeExports = requireServer_node(); const ReactDOMServer = /* @__PURE__ */ getDefaultExportFromCjs(server_nodeExports); -const pages = /* @__PURE__ */ Object.assign({ "./Pages/Admin/AiBiography.jsx": __vite_glob_0_0, "./Pages/Admin/Artworks.jsx": __vite_glob_0_1, "./Pages/Admin/AuthAudit.jsx": __vite_glob_0_2, "./Pages/Admin/Dashboard.jsx": __vite_glob_0_3, "./Pages/Admin/FeaturedArtworks.jsx": __vite_glob_0_4, "./Pages/Admin/HomepageAnnouncements/Form.jsx": __vite_glob_0_5, "./Pages/Admin/HomepageAnnouncements/Index.jsx": __vite_glob_0_6, "./Pages/Admin/Settings.jsx": __vite_glob_0_7, "./Pages/Admin/Stories.jsx": __vite_glob_0_8, "./Pages/Admin/UploadQueue.jsx": __vite_glob_0_9, "./Pages/Admin/UsernameQueue.jsx": __vite_glob_0_10, "./Pages/Admin/Users/Index.jsx": __vite_glob_0_11, "./Pages/Artwork/SimilarArtworksHeader.jsx": __vite_glob_0_12, "./Pages/ArtworkPage.jsx": __vite_glob_0_13, "./Pages/CategoriesPage.jsx": __vite_glob_0_14, "./Pages/Collection/CollectionAnalytics.jsx": __vite_glob_0_15, "./Pages/Collection/CollectionDashboard.jsx": __vite_glob_0_16, "./Pages/Collection/CollectionFeaturedIndex.jsx": __vite_glob_0_17, "./Pages/Collection/CollectionHistory.jsx": __vite_glob_0_18, "./Pages/Collection/CollectionManage.jsx": __vite_glob_0_19, "./Pages/Collection/CollectionSeriesShow.jsx": __vite_glob_0_20, "./Pages/Collection/CollectionShow.jsx": __vite_glob_0_21, "./Pages/Collection/CollectionStaffProgramming.jsx": __vite_glob_0_22, "./Pages/Collection/CollectionStaffSurfaces.jsx": __vite_glob_0_23, "./Pages/Collection/FeaturedArtworksAdmin.jsx": __vite_glob_0_24, "./Pages/Collection/NovaCardsAdminIndex.jsx": __vite_glob_0_25, "./Pages/Collection/NovaCardsAssetPackAdmin.jsx": __vite_glob_0_26, "./Pages/Collection/NovaCardsChallengeAdmin.jsx": __vite_glob_0_27, "./Pages/Collection/NovaCardsCollectionAdmin.jsx": __vite_glob_0_28, "./Pages/Collection/NovaCardsTemplateAdmin.jsx": __vite_glob_0_29, "./Pages/Collection/SavedCollections.jsx": __vite_glob_0_30, "./Pages/Community/CommunityActivityPage.jsx": __vite_glob_0_31, "./Pages/Community/LatestCommentsPage.jsx": __vite_glob_0_32, "./Pages/Feed/FollowingFeed.jsx": __vite_glob_0_33, "./Pages/Feed/HashtagFeed.jsx": __vite_glob_0_34, "./Pages/Feed/SavedFeed.jsx": __vite_glob_0_35, "./Pages/Feed/SearchFeed.jsx": __vite_glob_0_36, "./Pages/Feed/TrendingFeed.jsx": __vite_glob_0_37, "./Pages/Forum/ForumCategory.jsx": __vite_glob_0_38, "./Pages/Forum/ForumEditPost.jsx": __vite_glob_0_39, "./Pages/Forum/ForumIndex.jsx": __vite_glob_0_40, "./Pages/Forum/ForumNewThread.jsx": __vite_glob_0_41, "./Pages/Forum/ForumSection.jsx": __vite_glob_0_42, "./Pages/Forum/ForumThread.jsx": __vite_glob_0_43, "./Pages/Group/GroupChallengeShow.jsx": __vite_glob_0_44, "./Pages/Group/GroupEventShow.jsx": __vite_glob_0_45, "./Pages/Group/GroupFaqPage.jsx": __vite_glob_0_46, "./Pages/Group/GroupHelpPage.jsx": __vite_glob_0_47, "./Pages/Group/GroupIndex.jsx": __vite_glob_0_48, "./Pages/Group/GroupPostShow.jsx": __vite_glob_0_49, "./Pages/Group/GroupProjectShow.jsx": __vite_glob_0_50, "./Pages/Group/GroupQuickstartPage.jsx": __vite_glob_0_51, "./Pages/Group/GroupReleaseShow.jsx": __vite_glob_0_52, "./Pages/Group/GroupShow.jsx": __vite_glob_0_53, "./Pages/Help/AccountHelpPage.jsx": __vite_glob_0_54, "./Pages/Help/AuthHelpPage.jsx": __vite_glob_0_55, "./Pages/Help/CardsHelpPage.jsx": __vite_glob_0_56, "./Pages/Help/HelpCenterPage.jsx": __vite_glob_0_57, "./Pages/Help/ProfileHelpPage.jsx": __vite_glob_0_58, "./Pages/Help/StudioHelpPage.jsx": __vite_glob_0_59, "./Pages/Help/TroubleshootingHelpPage.jsx": __vite_glob_0_60, "./Pages/Help/UploadHelpPage.jsx": __vite_glob_0_61, "./Pages/Help/WorldsHelpPage.jsx": __vite_glob_0_62, "./Pages/Home/HomeBecauseYouLike.jsx": __vite_glob_0_63, "./Pages/Home/HomeCTA.jsx": __vite_glob_0_64, "./Pages/Home/HomeCategories.jsx": __vite_glob_0_65, "./Pages/Home/HomeCollections.jsx": __vite_glob_0_66, "./Pages/Home/HomeCreators.jsx": __vite_glob_0_67, "./Pages/Home/HomeFresh.jsx": __vite_glob_0_68, "./Pages/Home/HomeFromFollowing.jsx": __vite_glob_0_69, "./Pages/Home/HomeGroups.jsx": __vite_glob_0_70, "./Pages/Home/HomeHero.jsx": __vite_glob_0_71, "./Pages/Home/HomeMedalHighlights.jsx": __vite_glob_0_72, "./Pages/Home/HomeNews.jsx": __vite_glob_0_73, "./Pages/Home/HomePage.jsx": __vite_glob_0_74, "./Pages/Home/HomeRising.jsx": __vite_glob_0_75, "./Pages/Home/HomeSuggestedCreators.jsx": __vite_glob_0_76, "./Pages/Home/HomeTags.jsx": __vite_glob_0_77, "./Pages/Home/HomeTrending.jsx": __vite_glob_0_78, "./Pages/Home/HomeTrendingForYou.jsx": __vite_glob_0_79, "./Pages/Home/HomeWelcomeRow.jsx": __vite_glob_0_80, "./Pages/Home/HomeWorldSpotlight.jsx": __vite_glob_0_81, "./Pages/Leaderboard/LeaderboardPage.jsx": __vite_glob_0_82, "./Pages/Messages/Index.jsx": __vite_glob_0_83, "./Pages/Moderation/AiBiographyAdmin.jsx": __vite_glob_0_84, "./Pages/Moderation/ArtworkMaturityQueue.jsx": __vite_glob_0_85, "./Pages/News/NewsComments.jsx": __vite_glob_0_86, "./Pages/Profile/ProfileGallery.jsx": __vite_glob_0_87, "./Pages/Profile/ProfileShow.jsx": __vite_glob_0_88, "./Pages/Settings/ProfileEdit.jsx": __vite_glob_0_89, "./Pages/Studio/StudioActivity.jsx": __vite_glob_0_90, "./Pages/Studio/StudioAnalytics.jsx": __vite_glob_0_91, "./Pages/Studio/StudioArchived.jsx": __vite_glob_0_92, "./Pages/Studio/StudioArtworkAnalytics.jsx": __vite_glob_0_93, "./Pages/Studio/StudioArtworkEdit.jsx": __vite_glob_0_94, "./Pages/Studio/StudioArtworks.jsx": __vite_glob_0_95, "./Pages/Studio/StudioAssets.jsx": __vite_glob_0_96, "./Pages/Studio/StudioCalendar.jsx": __vite_glob_0_97, "./Pages/Studio/StudioCardAnalytics.jsx": __vite_glob_0_98, "./Pages/Studio/StudioCardEditor.jsx": __vite_glob_0_99, "./Pages/Studio/StudioCardsIndex.jsx": __vite_glob_0_100, "./Pages/Studio/StudioChallenges.jsx": __vite_glob_0_101, "./Pages/Studio/StudioCollections.jsx": __vite_glob_0_102, "./Pages/Studio/StudioComments.jsx": __vite_glob_0_103, "./Pages/Studio/StudioContentIndex.jsx": __vite_glob_0_104, "./Pages/Studio/StudioDashboard.jsx": __vite_glob_0_105, "./Pages/Studio/StudioDrafts.jsx": __vite_glob_0_106, "./Pages/Studio/StudioFeatured.jsx": __vite_glob_0_107, "./Pages/Studio/StudioFollowers.jsx": __vite_glob_0_108, "./Pages/Studio/StudioGroupActivity.jsx": __vite_glob_0_109, "./Pages/Studio/StudioGroupArtworks.jsx": __vite_glob_0_110, "./Pages/Studio/StudioGroupAssets.jsx": __vite_glob_0_111, "./Pages/Studio/StudioGroupChallengeEditor.jsx": __vite_glob_0_112, "./Pages/Studio/StudioGroupChallenges.jsx": __vite_glob_0_113, "./Pages/Studio/StudioGroupCollections.jsx": __vite_glob_0_114, "./Pages/Studio/StudioGroupCreate.jsx": __vite_glob_0_115, "./Pages/Studio/StudioGroupDashboard.jsx": __vite_glob_0_116, "./Pages/Studio/StudioGroupEventEditor.jsx": __vite_glob_0_117, "./Pages/Studio/StudioGroupEvents.jsx": __vite_glob_0_118, "./Pages/Studio/StudioGroupInvitations.jsx": __vite_glob_0_119, "./Pages/Studio/StudioGroupJoinRequests.jsx": __vite_glob_0_120, "./Pages/Studio/StudioGroupMembers.jsx": __vite_glob_0_121, "./Pages/Studio/StudioGroupPostEditor.jsx": __vite_glob_0_122, "./Pages/Studio/StudioGroupPosts.jsx": __vite_glob_0_123, "./Pages/Studio/StudioGroupProjectEditor.jsx": __vite_glob_0_124, "./Pages/Studio/StudioGroupProjects.jsx": __vite_glob_0_125, "./Pages/Studio/StudioGroupRecruitment.jsx": __vite_glob_0_126, "./Pages/Studio/StudioGroupReleaseEditor.jsx": __vite_glob_0_127, "./Pages/Studio/StudioGroupReleases.jsx": __vite_glob_0_128, "./Pages/Studio/StudioGroupReputation.jsx": __vite_glob_0_129, "./Pages/Studio/StudioGroupReviewQueue.jsx": __vite_glob_0_130, "./Pages/Studio/StudioGroupSettings.jsx": __vite_glob_0_131, "./Pages/Studio/StudioGroupsIndex.jsx": __vite_glob_0_132, "./Pages/Studio/StudioGrowth.jsx": __vite_glob_0_133, "./Pages/Studio/StudioInbox.jsx": __vite_glob_0_134, "./Pages/Studio/StudioNewsEditor.jsx": __vite_glob_0_135, "./Pages/Studio/StudioNewsIndex.jsx": __vite_glob_0_136, "./Pages/Studio/StudioNewsTaxonomies.jsx": __vite_glob_0_137, "./Pages/Studio/StudioPreferences.jsx": __vite_glob_0_138, "./Pages/Studio/StudioProfile.jsx": __vite_glob_0_139, "./Pages/Studio/StudioScheduled.jsx": __vite_glob_0_140, "./Pages/Studio/StudioSearch.jsx": __vite_glob_0_141, "./Pages/Studio/StudioSettings.jsx": __vite_glob_0_142, "./Pages/Studio/StudioStories.jsx": __vite_glob_0_143, "./Pages/Studio/StudioUploadQueue.jsx": __vite_glob_0_144, "./Pages/Studio/StudioWorldEditor.jsx": __vite_glob_0_145, "./Pages/Studio/StudioWorldsIndex.jsx": __vite_glob_0_146, "./Pages/Upload/Index.jsx": __vite_glob_0_147, "./Pages/World/WorldIndex.jsx": __vite_glob_0_148, "./Pages/World/WorldShow.jsx": __vite_glob_0_149 }); +const pages = /* @__PURE__ */ Object.assign({ "./Pages/Admin/AiBiography.jsx": __vite_glob_0_0, "./Pages/Admin/Artworks.jsx": __vite_glob_0_1, "./Pages/Admin/AuthAudit.jsx": __vite_glob_0_2, "./Pages/Admin/DailyActivity.jsx": __vite_glob_0_3, "./Pages/Admin/Dashboard.jsx": __vite_glob_0_4, "./Pages/Admin/FeaturedArtworks.jsx": __vite_glob_0_5, "./Pages/Admin/HomepageAnnouncements/Form.jsx": __vite_glob_0_6, "./Pages/Admin/HomepageAnnouncements/Index.jsx": __vite_glob_0_7, "./Pages/Admin/Settings.jsx": __vite_glob_0_8, "./Pages/Admin/Stories.jsx": __vite_glob_0_9, "./Pages/Admin/UploadQueue.jsx": __vite_glob_0_10, "./Pages/Admin/UsernameQueue.jsx": __vite_glob_0_11, "./Pages/Admin/Users/Index.jsx": __vite_glob_0_12, "./Pages/Artwork/SimilarArtworksHeader.jsx": __vite_glob_0_13, "./Pages/ArtworkPage.jsx": __vite_glob_0_14, "./Pages/CategoriesPage.jsx": __vite_glob_0_15, "./Pages/Collection/CollectionAnalytics.jsx": __vite_glob_0_16, "./Pages/Collection/CollectionDashboard.jsx": __vite_glob_0_17, "./Pages/Collection/CollectionFeaturedIndex.jsx": __vite_glob_0_18, "./Pages/Collection/CollectionHistory.jsx": __vite_glob_0_19, "./Pages/Collection/CollectionManage.jsx": __vite_glob_0_20, "./Pages/Collection/CollectionSeriesShow.jsx": __vite_glob_0_21, "./Pages/Collection/CollectionShow.jsx": __vite_glob_0_22, "./Pages/Collection/CollectionStaffProgramming.jsx": __vite_glob_0_23, "./Pages/Collection/CollectionStaffSurfaces.jsx": __vite_glob_0_24, "./Pages/Collection/FeaturedArtworksAdmin.jsx": __vite_glob_0_25, "./Pages/Collection/NovaCardsAdminIndex.jsx": __vite_glob_0_26, "./Pages/Collection/NovaCardsAssetPackAdmin.jsx": __vite_glob_0_27, "./Pages/Collection/NovaCardsChallengeAdmin.jsx": __vite_glob_0_28, "./Pages/Collection/NovaCardsCollectionAdmin.jsx": __vite_glob_0_29, "./Pages/Collection/NovaCardsTemplateAdmin.jsx": __vite_glob_0_30, "./Pages/Collection/SavedCollections.jsx": __vite_glob_0_31, "./Pages/Community/CommunityActivityPage.jsx": __vite_glob_0_32, "./Pages/Community/LatestCommentsPage.jsx": __vite_glob_0_33, "./Pages/Feed/FollowingFeed.jsx": __vite_glob_0_34, "./Pages/Feed/HashtagFeed.jsx": __vite_glob_0_35, "./Pages/Feed/SavedFeed.jsx": __vite_glob_0_36, "./Pages/Feed/SearchFeed.jsx": __vite_glob_0_37, "./Pages/Feed/TrendingFeed.jsx": __vite_glob_0_38, "./Pages/Forum/ForumCategory.jsx": __vite_glob_0_39, "./Pages/Forum/ForumEditPost.jsx": __vite_glob_0_40, "./Pages/Forum/ForumIndex.jsx": __vite_glob_0_41, "./Pages/Forum/ForumNewThread.jsx": __vite_glob_0_42, "./Pages/Forum/ForumSection.jsx": __vite_glob_0_43, "./Pages/Forum/ForumThread.jsx": __vite_glob_0_44, "./Pages/Group/GroupChallengeShow.jsx": __vite_glob_0_45, "./Pages/Group/GroupEventShow.jsx": __vite_glob_0_46, "./Pages/Group/GroupFaqPage.jsx": __vite_glob_0_47, "./Pages/Group/GroupHelpPage.jsx": __vite_glob_0_48, "./Pages/Group/GroupIndex.jsx": __vite_glob_0_49, "./Pages/Group/GroupPostShow.jsx": __vite_glob_0_50, "./Pages/Group/GroupProjectShow.jsx": __vite_glob_0_51, "./Pages/Group/GroupQuickstartPage.jsx": __vite_glob_0_52, "./Pages/Group/GroupReleaseShow.jsx": __vite_glob_0_53, "./Pages/Group/GroupShow.jsx": __vite_glob_0_54, "./Pages/Help/AccountHelpPage.jsx": __vite_glob_0_55, "./Pages/Help/AuthHelpPage.jsx": __vite_glob_0_56, "./Pages/Help/CardsHelpPage.jsx": __vite_glob_0_57, "./Pages/Help/HelpCenterPage.jsx": __vite_glob_0_58, "./Pages/Help/ProfileHelpPage.jsx": __vite_glob_0_59, "./Pages/Help/StudioHelpPage.jsx": __vite_glob_0_60, "./Pages/Help/TroubleshootingHelpPage.jsx": __vite_glob_0_61, "./Pages/Help/UploadHelpPage.jsx": __vite_glob_0_62, "./Pages/Help/WorldsHelpPage.jsx": __vite_glob_0_63, "./Pages/Home/HomeBecauseYouLike.jsx": __vite_glob_0_64, "./Pages/Home/HomeCTA.jsx": __vite_glob_0_65, "./Pages/Home/HomeCategories.jsx": __vite_glob_0_66, "./Pages/Home/HomeCollections.jsx": __vite_glob_0_67, "./Pages/Home/HomeCreators.jsx": __vite_glob_0_68, "./Pages/Home/HomeFresh.jsx": __vite_glob_0_69, "./Pages/Home/HomeFromFollowing.jsx": __vite_glob_0_70, "./Pages/Home/HomeGroups.jsx": __vite_glob_0_71, "./Pages/Home/HomeHero.jsx": __vite_glob_0_72, "./Pages/Home/HomeMedalHighlights.jsx": __vite_glob_0_73, "./Pages/Home/HomeNews.jsx": __vite_glob_0_74, "./Pages/Home/HomePage.jsx": __vite_glob_0_75, "./Pages/Home/HomeRising.jsx": __vite_glob_0_76, "./Pages/Home/HomeSuggestedCreators.jsx": __vite_glob_0_77, "./Pages/Home/HomeTags.jsx": __vite_glob_0_78, "./Pages/Home/HomeTrending.jsx": __vite_glob_0_79, "./Pages/Home/HomeTrendingForYou.jsx": __vite_glob_0_80, "./Pages/Home/HomeWelcomeRow.jsx": __vite_glob_0_81, "./Pages/Home/HomeWorldSpotlight.jsx": __vite_glob_0_82, "./Pages/Leaderboard/LeaderboardPage.jsx": __vite_glob_0_83, "./Pages/Messages/Index.jsx": __vite_glob_0_84, "./Pages/Moderation/AiBiographyAdmin.jsx": __vite_glob_0_85, "./Pages/Moderation/ArtworkMaturityQueue.jsx": __vite_glob_0_86, "./Pages/News/NewsComments.jsx": __vite_glob_0_87, "./Pages/Profile/ProfileGallery.jsx": __vite_glob_0_88, "./Pages/Profile/ProfileShow.jsx": __vite_glob_0_89, "./Pages/Settings/ProfileEdit.jsx": __vite_glob_0_90, "./Pages/Studio/StudioActivity.jsx": __vite_glob_0_91, "./Pages/Studio/StudioAnalytics.jsx": __vite_glob_0_92, "./Pages/Studio/StudioArchived.jsx": __vite_glob_0_93, "./Pages/Studio/StudioArtworkAnalytics.jsx": __vite_glob_0_94, "./Pages/Studio/StudioArtworkEdit.jsx": __vite_glob_0_95, "./Pages/Studio/StudioArtworks.jsx": __vite_glob_0_96, "./Pages/Studio/StudioAssets.jsx": __vite_glob_0_97, "./Pages/Studio/StudioCalendar.jsx": __vite_glob_0_98, "./Pages/Studio/StudioCardAnalytics.jsx": __vite_glob_0_99, "./Pages/Studio/StudioCardEditor.jsx": __vite_glob_0_100, "./Pages/Studio/StudioCardsIndex.jsx": __vite_glob_0_101, "./Pages/Studio/StudioChallenges.jsx": __vite_glob_0_102, "./Pages/Studio/StudioCollections.jsx": __vite_glob_0_103, "./Pages/Studio/StudioComments.jsx": __vite_glob_0_104, "./Pages/Studio/StudioContentIndex.jsx": __vite_glob_0_105, "./Pages/Studio/StudioDashboard.jsx": __vite_glob_0_106, "./Pages/Studio/StudioDrafts.jsx": __vite_glob_0_107, "./Pages/Studio/StudioFeatured.jsx": __vite_glob_0_108, "./Pages/Studio/StudioFollowers.jsx": __vite_glob_0_109, "./Pages/Studio/StudioGroupActivity.jsx": __vite_glob_0_110, "./Pages/Studio/StudioGroupArtworks.jsx": __vite_glob_0_111, "./Pages/Studio/StudioGroupAssets.jsx": __vite_glob_0_112, "./Pages/Studio/StudioGroupChallengeEditor.jsx": __vite_glob_0_113, "./Pages/Studio/StudioGroupChallenges.jsx": __vite_glob_0_114, "./Pages/Studio/StudioGroupCollections.jsx": __vite_glob_0_115, "./Pages/Studio/StudioGroupCreate.jsx": __vite_glob_0_116, "./Pages/Studio/StudioGroupDashboard.jsx": __vite_glob_0_117, "./Pages/Studio/StudioGroupEventEditor.jsx": __vite_glob_0_118, "./Pages/Studio/StudioGroupEvents.jsx": __vite_glob_0_119, "./Pages/Studio/StudioGroupInvitations.jsx": __vite_glob_0_120, "./Pages/Studio/StudioGroupJoinRequests.jsx": __vite_glob_0_121, "./Pages/Studio/StudioGroupMembers.jsx": __vite_glob_0_122, "./Pages/Studio/StudioGroupPostEditor.jsx": __vite_glob_0_123, "./Pages/Studio/StudioGroupPosts.jsx": __vite_glob_0_124, "./Pages/Studio/StudioGroupProjectEditor.jsx": __vite_glob_0_125, "./Pages/Studio/StudioGroupProjects.jsx": __vite_glob_0_126, "./Pages/Studio/StudioGroupRecruitment.jsx": __vite_glob_0_127, "./Pages/Studio/StudioGroupReleaseEditor.jsx": __vite_glob_0_128, "./Pages/Studio/StudioGroupReleases.jsx": __vite_glob_0_129, "./Pages/Studio/StudioGroupReputation.jsx": __vite_glob_0_130, "./Pages/Studio/StudioGroupReviewQueue.jsx": __vite_glob_0_131, "./Pages/Studio/StudioGroupSettings.jsx": __vite_glob_0_132, "./Pages/Studio/StudioGroupsIndex.jsx": __vite_glob_0_133, "./Pages/Studio/StudioGrowth.jsx": __vite_glob_0_134, "./Pages/Studio/StudioInbox.jsx": __vite_glob_0_135, "./Pages/Studio/StudioNewsEditor.jsx": __vite_glob_0_136, "./Pages/Studio/StudioNewsIndex.jsx": __vite_glob_0_137, "./Pages/Studio/StudioNewsTaxonomies.jsx": __vite_glob_0_138, "./Pages/Studio/StudioPreferences.jsx": __vite_glob_0_139, "./Pages/Studio/StudioProfile.jsx": __vite_glob_0_140, "./Pages/Studio/StudioScheduled.jsx": __vite_glob_0_141, "./Pages/Studio/StudioSearch.jsx": __vite_glob_0_142, "./Pages/Studio/StudioSettings.jsx": __vite_glob_0_143, "./Pages/Studio/StudioStories.jsx": __vite_glob_0_144, "./Pages/Studio/StudioUploadQueue.jsx": __vite_glob_0_145, "./Pages/Studio/StudioWorldEditor.jsx": __vite_glob_0_146, "./Pages/Studio/StudioWorldsIndex.jsx": __vite_glob_0_147, "./Pages/Upload/Index.jsx": __vite_glob_0_148, "./Pages/World/WorldIndex.jsx": __vite_glob_0_149, "./Pages/World/WorldShow.jsx": __vite_glob_0_150 }); const ClientOnlyPlaceholder = () => null; d( (page) => W({ diff --git a/news_dates.csv b/news_dates.csv new file mode 100644 index 00000000..1d161073 --- /dev/null +++ b/news_dates.csv @@ -0,0 +1,1407 @@ +"news_id","update_date" +"5","2000-09-04 17:52:59" +"6","2000-09-04 17:53:53" +"8","2000-09-12 09:19:03" +"7","2000-09-13 10:56:25" +"9","2000-09-13 11:09:49" +"10","2000-09-14 08:12:55" +"11","2000-09-14 09:33:54" +"12","2000-09-18 08:02:11" +"13","2000-09-18 08:08:08" +"14","2000-09-18 08:13:28" +"16","2000-09-21 09:06:34" +"15","2000-09-21 09:08:23" +"17","2000-09-21 09:09:14" +"18","2000-09-22 03:26:58" +"19","2000-09-22 03:36:00" +"20","2000-09-22 23:58:06" +"21","2000-09-23 09:57:46" +"22","2000-09-27 10:19:27" +"23","2000-09-27 15:43:11" +"24","2000-09-27 15:55:16" +"25","2000-09-28 09:27:06" +"26","2000-09-28 10:19:38" +"27","2000-09-28 17:18:55" +"28","2000-09-29 15:21:43" +"29","2000-10-03 10:53:47" +"30","2000-10-03 12:28:18" +"33","2000-10-04 14:48:41" +"32","2000-10-04 14:49:03" +"34","2000-10-05 13:49:44" +"35","2000-10-06 18:34:26" +"36","2000-10-06 18:40:55" +"31","2000-10-10 11:10:50" +"37","2000-10-11 12:44:15" +"38","2000-10-12 13:32:37" +"39","2000-10-16 15:38:52" +"40","2000-10-16 15:45:24" +"41","2000-10-16 15:46:50" +"42","2000-10-17 10:46:58" +"43","2000-10-19 03:26:12" +"44","2000-10-23 15:37:07" +"45","2000-10-28 13:26:01" +"46","2000-11-01 12:57:03" +"47","2000-11-01 13:00:10" +"48","2000-11-01 13:01:55" +"50","2000-11-03 07:48:49" +"51","2000-11-06 09:23:25" +"52","2000-11-08 08:18:54" +"53","2000-11-08 09:54:40" +"54","2000-11-15 07:33:59" +"55","2000-11-15 07:37:59" +"56","2000-11-16 05:03:29" +"57","2000-11-21 14:15:40" +"58","2000-11-21 14:19:07" +"59","2000-11-21 14:23:55" +"60","2000-11-22 13:42:42" +"61","2000-11-24 11:25:27" +"62","2000-11-27 07:45:19" +"63","2000-11-30 13:13:55" +"64","2000-11-30 13:16:35" +"65","2000-11-30 13:18:18" +"66","2000-11-30 13:20:28" +"67","2000-12-07 05:09:09" +"68","2000-12-11 10:59:21" +"69","2000-12-11 10:59:46" +"70","2000-12-13 07:53:48" +"71","2000-12-20 08:47:36" +"72","2000-12-20 14:14:20" +"73","2000-12-22 08:34:15" +"74","2000-12-28 18:39:00" +"75","2001-01-08 08:12:13" +"76","2001-01-16 08:18:44" +"77","2001-01-16 08:21:52" +"78","2001-01-16 17:22:48" +"79","2001-01-20 10:00:24" +"80","2001-02-13 07:14:23" +"81","2001-02-13 08:49:56" +"82","2001-02-13 14:58:27" +"83","2001-02-14 08:23:25" +"84","2001-02-15 15:16:30" +"85","2001-02-19 08:29:14" +"86","2001-02-21 18:37:18" +"87","2001-02-23 08:52:42" +"88","2001-02-23 13:38:12" +"89","2001-02-25 11:13:43" +"90","2001-02-26 07:24:33" +"91","2001-02-27 14:37:59" +"92","2001-03-02 10:44:30" +"93","2001-03-04 01:57:34" +"94","2001-03-05 18:17:26" +"95","2001-03-05 18:26:39" +"96","2001-03-05 18:29:41" +"97","2001-03-05 18:34:37" +"98","2001-03-07 22:40:02" +"99","2001-03-08 06:49:36" +"100","2001-03-08 14:01:09" +"101","2001-03-09 17:51:17" +"102","2001-03-10 17:51:17" +"103","2001-03-11 11:31:17" +"104","2001-03-12 17:31:17" +"105","2001-03-13 17:51:17" +"106","2001-03-14 17:51:17" +"107","2001-03-14 17:55:17" +"108","2001-03-14 18:31:17" +"109","2001-03-15 19:51:17" +"110","2001-03-16 02:54:25" +"111","2001-03-17 09:58:04" +"112","2001-03-17 18:12:02" +"113","2001-03-17 18:16:14" +"114","2001-03-17 18:20:48" +"115","2001-03-18 16:46:50" +"116","2001-03-19 03:27:05" +"117","2001-03-20 08:41:04" +"118","2001-03-21 05:00:53" +"119","2001-03-22 18:50:34" +"120","2001-03-22 18:55:46" +"121","2001-03-24 08:13:17" +"122","2001-03-27 00:19:47" +"123","2001-03-28 14:06:34" +"124","2001-03-29 08:44:21" +"125","2001-03-30 23:32:46" +"126","2001-04-04 10:58:41" +"127","2001-04-05 13:25:19" +"128","2001-04-07 05:34:15" +"129","2001-04-08 17:51:17" +"130","2001-04-09 17:51:17" +"131","2001-04-09 17:51:17" +"132","2001-04-10 13:31:17" +"133","2001-04-18 12:51:17" +"134","2001-04-30 17:51:17" +"135","2001-05-02 17:51:17" +"136","2001-05-03 17:51:17" +"137","2001-05-04 17:51:17" +"138","2001-05-05 17:51:17" +"139","2001-05-06 17:51:17" +"140","2001-05-07 12:51:17" +"141","2001-05-08 11:51:17" +"142","2001-05-08 18:51:17" +"143","2001-05-09 19:57:42" +"144","2001-05-10 15:31:43" +"145","2001-05-14 16:16:40" +"146","2001-05-16 22:25:06" +"147","2001-05-16 22:46:22" +"148","2001-05-17 05:14:15" +"149","2001-05-18 02:42:11" +"150","2001-05-18 08:24:29" +"151","2001-05-19 07:24:45" +"152","2001-05-19 17:49:46" +"153","2001-05-19 17:52:43" +"154","2001-05-19 17:55:35" +"155","2001-05-24 13:21:27" +"156","2001-05-24 15:50:22" +"157","2001-05-26 00:41:12" +"158","2001-05-28 01:12:50" +"159","2001-05-29 03:09:24" +"160","2001-05-30 03:27:31" +"161","2001-06-01 08:15:01" +"162","2001-06-02 10:07:27" +"163","2001-06-03 18:40:40" +"164","2001-06-04 09:02:04" +"165","2001-06-10 23:08:45" +"166","2001-06-12 04:22:30" +"167","2001-06-15 20:22:11" +"168","2001-06-15 20:24:36" +"169","2001-06-15 20:27:21" +"170","2001-06-16 23:52:23" +"171","2001-06-18 15:25:04" +"172","2001-06-18 15:28:08" +"173","2001-06-19 06:47:55" +"174","2001-06-20 07:36:09" +"175","2001-06-21 01:25:35" +"176","2001-06-22 09:15:09" +"177","2001-06-24 23:45:12" +"178","2001-06-25 01:30:26" +"179","2001-06-25 20:14:41" +"180","2001-06-26 03:59:08" +"181","2001-06-26 19:20:24" +"182","2001-06-29 00:44:15" +"183","2001-06-29 11:35:59" +"184","2001-06-30 03:17:19" +"185","2001-07-01 20:37:10" +"186","2001-07-04 01:10:56" +"187","2001-07-04 09:09:15" +"188","2001-07-04 18:23:04" +"189","2001-07-05 13:08:13" +"190","2001-07-06 07:43:07" +"191","2001-07-13 00:08:13" +"192","2001-07-17 23:27:44" +"193","2001-07-22 23:45:32" +"194","2001-07-23 02:10:11" +"195","2001-07-24 07:00:00" +"196","2001-07-26 01:36:58" +"197","2001-07-27 01:28:07" +"198","2001-07-30 01:27:29" +"199","2001-07-30 23:47:39" +"200","2001-07-31 06:52:54" +"201","2001-07-31 13:15:51" +"202","2001-08-02 23:20:11" +"203","2001-08-03 23:58:09" +"204","2001-08-07 00:35:09" +"205","2001-08-11 13:42:14" +"206","2001-08-13 06:40:39" +"207","2001-08-14 19:11:33" +"208","2001-08-15 00:10:50" +"209","2001-08-15 00:17:43" +"210","2001-08-16 02:08:08" +"211","2001-08-17 00:07:24" +"212","2001-08-17 05:56:19" +"213","2001-08-18 01:04:20" +"214","2001-08-20 13:32:49" +"215","2001-08-22 09:37:13" +"216","2001-08-23 16:34:27" +"217","2001-08-28 00:31:53" +"218","2001-08-30 00:41:31" +"219","2001-08-31 00:10:44" +"220","2001-09-01 00:57:05" +"221","2001-09-01 12:53:39" +"222","2001-09-03 09:26:44" +"223","2001-09-06 01:30:09" +"224","2001-09-07 23:45:07" +"225","2001-09-10 00:57:16" +"226","2001-09-11 09:45:20" +"227","2001-09-11 19:11:21" +"228","2001-09-12 03:30:13" +"229","2001-09-15 00:22:05" +"230","2001-09-18 07:59:05" +"231","2001-09-19 05:52:26" +"232","2001-09-22 00:25:19" +"233","2001-09-26 18:55:54" +"234","2001-09-27 21:36:38" +"235","2001-09-29 00:42:04" +"236","2001-09-30 23:20:14" +"237","2001-10-01 10:34:12" +"238","2001-10-02 00:39:49" +"239","2001-10-02 23:10:06" +"240","2001-10-03 00:10:57" +"241","2001-10-04 07:18:28" +"242","2001-10-04 07:22:32" +"243","2001-10-04 07:27:46" +"244","2001-10-04 22:53:14" +"245","2001-10-05 08:53:37" +"246","2001-10-08 08:21:57" +"247","2001-10-09 00:50:47" +"248","2001-10-09 01:08:15" +"249","2001-10-10 03:25:32" +"250","2001-10-10 09:48:49" +"251","2001-10-11 02:03:38" +"252","2001-10-12 22:46:52" +"253","2001-10-15 04:44:18" +"254","2001-10-15 04:48:17" +"255","2001-10-15 08:50:51" +"256","2001-10-16 04:39:30" +"257","2001-10-16 04:41:53" +"258","2001-10-17 00:32:07" +"259","2001-10-17 01:04:09" +"260","2001-10-17 03:36:00" +"261","2001-10-17 22:41:58" +"262","2001-10-22 09:25:31" +"263","2001-10-24 23:34:52" +"264","2001-10-25 03:20:55" +"265","2001-10-25 03:50:19" +"266","2001-10-26 22:55:54" +"267","2001-10-29 00:49:03" +"268","2001-10-29 05:18:57" +"269","2001-10-30 00:22:00" +"270","2001-10-30 17:22:47" +"271","2001-10-30 18:49:11" +"272","2001-10-31 22:17:18" +"273","2001-10-31 22:24:06" +"274","2001-10-31 22:31:22" +"275","2001-11-01 00:53:54" +"276","2001-11-01 11:45:54" +"277","2001-11-01 21:35:27" +"278","2001-11-01 21:53:18" +"279","2001-11-02 22:18:25" +"280","2001-11-05 10:28:17" +"281","2001-11-06 23:48:59" +"282","2001-11-07 05:10:20" +"283","2001-11-09 04:44:41" +"284","2001-11-10 07:45:34" +"285","2001-11-11 11:59:31" +"286","2001-11-11 21:45:00" +"287","2001-11-11 23:51:40" +"288","2001-11-12 17:00:59" +"289","2001-11-12 23:55:40" +"290","2001-11-13 01:10:40" +"291","2001-11-13 22:30:41" +"292","2001-11-14 07:20:22" +"293","2001-11-14 11:59:35" +"294","2001-11-14 22:38:27" +"295","2001-11-15 20:37:16" +"296","2001-11-16 06:43:14" +"297","2001-11-16 22:37:17" +"298","2001-11-16 23:23:09" +"299","2001-11-18 12:27:09" +"300","2001-11-18 17:42:20" +"301","2001-11-19 01:05:21" +"302","2001-11-19 02:34:24" +"303","2001-11-19 02:55:07" +"304","2001-11-19 23:18:00" +"305","2001-11-23 03:43:13" +"306","2001-11-23 09:31:07" +"307","2001-11-24 02:22:36" +"308","2001-11-26 00:12:29" +"309","2001-11-26 17:58:19" +"310","2001-11-27 23:51:19" +"311","2001-11-28 09:30:44" +"312","2001-11-29 00:31:30" +"313","2001-11-29 10:06:00" +"314","2001-11-29 19:37:38" +"315","2001-11-29 21:59:04" +"316","2001-12-01 17:04:24" +"317","2001-12-01 20:54:49" +"318","2001-12-03 22:16:27" +"319","2001-12-04 13:36:32" +"320","2001-12-04 19:55:39" +"321","2001-12-06 08:51:55" +"322","2001-12-09 23:11:49" +"323","2001-12-10 09:21:53" +"324","2001-12-10 10:19:27" +"325","2001-12-10 19:29:26" +"326","2001-12-10 22:03:24" +"327","2001-12-10 22:03:48" +"328","2001-12-11 10:33:02" +"329","2001-12-11 16:29:08" +"330","2001-12-11 19:43:33" +"331","2001-12-12 18:09:58" +"332","2001-12-13 00:51:31" +"333","2001-12-13 08:56:25" +"334","2001-12-14 01:31:19" +"335","2001-12-14 09:26:15" +"336","2001-12-15 05:48:16" +"337","2001-12-15 13:10:46" +"338","2001-12-17 22:17:16" +"339","2001-12-18 11:02:39" +"340","2001-12-18 22:37:20" +"341","2001-12-21 00:43:23" +"342","2001-12-23 01:12:50" +"343","2001-12-23 15:33:02" +"344","2001-12-24 08:55:40" +"345","2001-12-24 09:04:45" +"346","2001-12-24 09:08:27" +"347","2001-12-24 11:34:33" +"348","2001-12-26 00:10:45" +"349","2001-12-27 22:11:12" +"350","2001-12-28 23:08:59" +"351","2001-12-30 23:54:46" +"352","2001-12-31 00:23:46" +"353","2002-01-03 02:49:18" +"354","2002-01-03 08:57:47" +"355","2002-01-03 22:37:38" +"356","2002-01-05 02:40:18" +"357","2002-01-07 02:50:49" +"358","2002-01-07 13:33:56" +"359","2002-01-07 23:50:43" +"360","2002-01-08 01:13:19" +"361","2002-01-08 12:16:54" +"362","2002-01-08 22:29:12" +"363","2002-01-10 00:55:25" +"364","2002-01-10 01:22:50" +"365","2002-01-10 19:38:45" +"366","2002-01-11 22:06:46" +"367","2002-01-12 00:16:16" +"368","2002-01-12 07:24:45" +"369","2002-01-13 02:42:46" +"370","2002-01-13 15:40:05" +"371","2002-01-13 22:55:02" +"372","2002-01-14 23:13:15" +"373","2002-01-15 08:53:18" +"374","2002-01-16 02:27:40" +"375","2002-01-16 02:39:05" +"376","2002-01-16 04:55:12" +"377","2002-01-16 05:49:38" +"378","2002-01-16 23:51:11" +"379","2002-01-21 01:03:00" +"380","2002-01-21 02:13:23" +"381","2002-01-22 23:43:37" +"382","2002-01-22 23:49:40" +"383","2002-01-23 00:10:20" +"384","2002-01-23 09:01:21" +"385","2002-01-23 23:50:21" +"386","2002-01-24 04:50:01" +"387","2002-01-24 05:51:23" +"388","2002-01-24 23:57:29" +"389","2002-01-25 01:31:11" +"390","2002-01-25 02:01:02" +"391","2002-01-25 08:18:32" +"392","2002-01-25 21:36:27" +"393","2002-01-25 22:25:46" +"394","2002-01-26 00:15:06" +"395","2002-01-27 01:44:23" +"396","2002-01-27 12:36:21" +"397","2002-01-27 16:07:18" +"398","2002-01-27 21:13:11" +"399","2002-01-28 21:22:57" +"400","2002-01-29 08:23:00" +"401","2002-01-29 23:41:26" +"402","2002-01-30 08:14:21" +"403","2002-01-30 08:26:09" +"49","2002-01-30 11:23:10" +"404","2002-01-31 15:44:16" +"405","2002-02-01 06:19:15" +"406","2002-02-01 06:30:49" +"407","2002-02-01 22:12:36" +"408","2002-02-02 00:22:49" +"409","2002-02-02 06:31:10" +"410","2002-02-02 20:47:22" +"411","2002-02-03 21:35:45" +"412","2002-02-04 08:05:34" +"413","2002-02-04 15:44:40" +"414","2002-02-05 22:18:19" +"415","2002-02-06 03:11:35" +"416","2002-02-07 16:46:49" +"417","2002-02-07 20:55:34" +"418","2002-02-08 00:00:22" +"419","2002-02-10 23:31:36" +"420","2002-02-11 03:16:18" +"421","2002-02-11 13:11:17" +"422","2002-02-11 21:26:06" +"424","2002-02-11 23:17:25" +"425","2002-02-11 23:23:13" +"426","2002-02-12 11:00:38" +"427","2002-02-13 23:21:38" +"428","2002-02-13 23:57:21" +"429","2002-02-15 17:40:06" +"430","2002-02-16 10:24:06" +"431","2002-02-18 22:30:37" +"432","2002-02-21 04:55:43" +"433","2002-02-22 13:49:11" +"434","2002-02-22 15:02:35" +"435","2002-02-23 01:40:38" +"436","2002-02-25 08:21:22" +"437","2002-02-25 08:25:59" +"438","2002-02-25 18:32:58" +"439","2002-02-25 23:46:08" +"440","2002-02-28 23:12:08" +"441","2002-03-01 19:52:55" +"442","2002-03-03 15:56:34" +"443","2002-03-04 14:09:27" +"444","2002-03-04 14:59:31" +"445","2002-03-05 09:19:38" +"446","2002-03-05 09:23:00" +"447","2002-03-05 19:11:45" +"448","2002-03-05 21:56:45" +"449","2002-03-06 08:30:07" +"450","2002-03-07 16:22:53" +"451","2002-03-07 22:30:34" +"452","2002-03-11 14:44:38" +"453","2002-03-12 11:53:53" +"454","2002-03-12 16:26:02" +"455","2002-03-13 06:08:32" +"456","2002-03-15 23:14:41" +"457","2002-03-16 03:14:26" +"458","2002-03-16 12:29:24" +"459","2002-03-16 23:31:32" +"460","2002-03-18 08:36:53" +"461","2002-03-19 15:33:02" +"462","2002-03-20 10:47:11" +"463","2002-03-20 14:00:06" +"464","2002-03-21 01:51:41" +"465","2002-03-21 03:22:03" +"466","2002-03-21 08:17:02" +"467","2002-03-21 23:12:56" +"468","2002-03-22 08:14:59" +"469","2002-03-22 12:52:56" +"470","2002-03-24 11:42:02" +"471","2002-03-24 23:28:44" +"472","2002-03-25 15:33:09" +"473","2002-03-25 23:20:45" +"474","2002-03-27 22:30:31" +"475","2002-03-28 00:38:16" +"476","2002-03-28 23:14:48" +"477","2002-03-30 12:29:13" +"478","2002-03-30 12:42:30" +"479","2002-03-30 16:54:42" +"480","2002-04-01 00:20:55" +"481","2002-04-02 05:27:58" +"482","2002-04-02 13:21:45" +"483","2002-04-03 13:15:50" +"484","2002-04-03 13:16:02" +"485","2002-04-03 22:46:39" +"486","2002-04-05 00:30:41" +"488","2002-04-08 00:25:36" +"489","2002-04-08 09:33:59" +"490","2002-04-09 00:11:32" +"491","2002-04-10 01:25:18" +"492","2002-04-10 09:32:04" +"493","2002-04-10 10:13:24" +"494","2002-04-11 09:03:43" +"495","2002-04-11 09:30:23" +"496","2002-04-11 20:08:26" +"497","2002-04-14 10:31:27" +"498","2002-04-16 08:05:38" +"499","2002-04-16 17:29:03" +"500","2002-04-16 22:10:03" +"501","2002-04-16 23:35:32" +"502","2002-04-17 23:50:29" +"503","2002-04-18 06:36:10" +"504","2002-04-18 13:50:18" +"505","2002-04-18 13:50:38" +"506","2002-04-18 23:53:58" +"507","2002-04-22 16:23:41" +"508","2002-04-23 00:37:03" +"509","2002-04-23 19:16:46" +"510","2002-04-23 22:54:30" +"511","2002-04-24 23:09:16" +"512","2002-04-25 02:20:52" +"513","2002-04-25 08:31:26" +"514","2002-04-26 20:18:41" +"515","2002-04-28 16:52:19" +"516","2002-04-29 23:50:27" +"517","2002-04-29 23:57:06" +"518","2002-04-30 23:56:53" +"519","2002-05-01 01:16:30" +"520","2002-05-01 15:48:41" +"521","2002-05-01 23:13:17" +"522","2002-05-02 00:28:48" +"523","2002-05-03 16:56:27" +"524","2002-05-04 17:17:51" +"525","2002-05-05 06:47:17" +"526","2002-05-07 23:02:53" +"527","2002-05-08 23:45:09" +"528","2002-05-09 10:10:42" +"529","2002-05-11 11:52:45" +"530","2002-05-13 23:39:46" +"531","2002-05-14 03:15:12" +"532","2002-05-15 14:23:18" +"533","2002-05-16 08:12:26" +"534","2002-05-16 15:46:31" +"535","2002-05-16 15:46:46" +"536","2002-05-20 01:58:13" +"537","2002-05-20 06:02:22" +"538","2002-05-20 23:40:30" +"539","2002-05-21 20:05:44" +"540","2002-05-22 01:47:34" +"541","2002-05-23 02:37:38" +"542","2002-05-23 02:47:21" +"543","2002-05-23 18:32:58" +"544","2002-05-24 16:01:29" +"545","2002-05-24 16:01:49" +"546","2002-05-26 18:27:18" +"547","2002-05-29 00:35:14" +"548","2002-05-29 00:51:05" +"549","2002-05-29 18:45:27" +"550","2002-05-29 18:45:39" +"551","2002-05-29 18:46:15" +"552","2002-05-29 18:50:06" +"553","2002-05-30 18:44:20" +"554","2002-05-30 18:44:43" +"555","2002-05-31 05:00:13" +"556","2002-06-03 18:11:55" +"557","2002-06-03 18:25:43" +"558","2002-06-04 17:50:33" +"559","2002-06-07 15:05:39" +"560","2002-06-09 02:17:30" +"561","2002-06-12 16:33:59" +"562","2002-06-13 23:08:29" +"563","2002-06-14 13:52:18" +"564","2002-06-19 14:40:38" +"565","2002-06-21 23:53:22" +"566","2002-06-23 18:25:47" +"567","2002-06-27 01:39:28" +"568","2002-06-27 22:09:23" +"569","2002-06-27 22:09:24" +"570","2002-06-29 09:37:34" +"571","2002-07-02 16:29:06" +"572","2002-07-04 02:07:20" +"573","2002-07-06 11:19:22" +"574","2002-07-08 02:58:52" +"575","2002-07-08 09:27:22" +"576","2002-07-08 19:07:32" +"577","2002-07-09 19:34:09" +"578","2002-07-09 19:34:12" +"579","2002-07-10 15:58:43" +"580","2002-07-14 14:11:25" +"581","2002-07-14 22:25:55" +"582","2002-07-14 23:18:44" +"583","2002-07-15 08:06:57" +"584","2002-07-16 13:35:53" +"585","2002-07-18 23:00:44" +"586","2002-07-18 23:00:53" +"587","2002-07-22 05:48:31" +"588","2002-07-23 17:55:47" +"589","2002-07-24 19:51:34" +"590","2002-07-24 20:04:31" +"591","2002-07-25 21:09:56" +"592","2002-07-26 21:13:14" +"593","2002-07-27 09:45:06" +"594","2002-07-29 04:02:17" +"595","2002-07-29 20:05:05" +"596","2002-07-31 21:58:14" +"597","2002-08-02 20:02:07" +"598","2002-08-02 20:12:15" +"599","2002-08-04 19:34:54" +"600","2002-08-07 08:46:43" +"601","2002-08-07 11:30:05" +"602","2002-08-08 02:22:58" +"603","2002-08-08 18:27:30" +"604","2002-08-10 20:11:53" +"605","2002-08-10 21:51:43" +"606","2002-08-11 14:39:45" +"607","2002-08-17 02:51:38" +"608","2002-08-19 03:52:55" +"609","2002-08-22 16:13:04" +"610","2002-08-23 21:34:21" +"611","2002-08-23 21:51:23" +"612","2002-08-24 22:20:29" +"613","2002-08-25 23:30:33" +"614","2002-08-28 01:10:18" +"615","2002-08-28 11:08:29" +"616","2002-08-29 21:25:09" +"617","2002-08-30 01:13:27" +"618","2002-09-03 08:28:18" +"619","2002-09-04 02:31:24" +"620","2002-09-05 07:52:52" +"621","2002-09-06 03:17:36" +"622","2002-09-06 10:35:16" +"623","2002-09-07 00:46:40" +"624","2002-09-08 09:28:27" +"625","2002-09-10 03:11:26" +"626","2002-09-10 08:20:51" +"627","2002-09-10 16:09:42" +"628","2002-09-10 19:04:24" +"629","2002-09-12 23:54:03" +"630","2002-09-16 09:15:41" +"631","2002-09-17 02:19:14" +"632","2002-09-19 11:16:25" +"633","2002-09-20 04:25:20" +"634","2002-09-20 18:25:24" +"635","2002-09-23 08:05:03" +"636","2002-09-23 18:20:36" +"637","2002-09-24 10:03:34" +"638","2002-09-24 13:19:26" +"639","2002-09-25 08:24:55" +"640","2002-09-26 04:58:27" +"641","2002-09-26 20:44:58" +"643","2002-09-27 22:33:04" +"644","2002-09-30 03:49:09" +"645","2002-09-30 22:57:24" +"646","2002-10-01 09:11:04" +"647","2002-10-01 09:20:02" +"648","2002-10-01 17:04:16" +"649","2002-10-01 23:39:47" +"650","2002-10-02 00:30:45" +"651","2002-10-03 02:12:26" +"652","2002-10-03 02:18:54" +"653","2002-10-03 07:35:49" +"654","2002-10-04 00:10:48" +"655","2002-10-04 23:17:49" +"656","2002-10-06 20:25:43" +"657","2002-10-07 09:38:40" +"658","2002-10-08 23:10:13" +"659","2002-10-12 01:28:04" +"660","2002-10-12 01:39:51" +"661","2002-10-13 01:01:16" +"663","2002-10-15 23:23:40" +"664","2002-10-16 12:22:54" +"665","2002-10-19 23:09:22" +"666","2002-10-20 21:59:01" +"667","2002-10-21 08:29:51" +"668","2002-10-21 08:35:21" +"669","2002-10-22 17:49:06" +"670","2002-10-23 16:32:46" +"671","2002-10-23 23:21:03" +"672","2002-10-24 08:55:15" +"673","2002-10-25 00:15:44" +"674","2002-10-25 22:54:12" +"675","2002-10-26 01:03:19" +"676","2002-10-28 08:27:53" +"677","2002-10-29 17:47:54" +"678","2002-10-30 00:30:39" +"679","2002-10-30 04:28:52" +"680","2002-10-31 22:10:46" +"681","2002-11-01 08:26:15" +"682","2002-11-01 08:55:57" +"683","2002-11-01 11:10:54" +"684","2002-11-02 13:41:53" +"685","2002-11-04 11:07:17" +"686","2002-11-05 13:06:45" +"687","2002-11-05 22:12:15" +"688","2002-11-06 20:11:30" +"689","2002-11-12 05:20:46" +"690","2002-11-12 11:18:16" +"691","2002-11-13 07:51:03" +"692","2002-11-16 16:17:35" +"693","2002-11-19 12:30:30" +"694","2002-11-19 12:33:01" +"695","2002-11-21 13:43:47" +"696","2002-11-22 21:51:37" +"697","2002-11-24 08:26:25" +"698","2002-11-26 19:00:21" +"699","2002-11-26 21:14:51" +"700","2002-11-27 06:04:25" +"701","2002-11-28 04:26:45" +"702","2002-12-01 01:16:53" +"703","2002-12-01 22:42:43" +"704","2002-12-02 08:09:31" +"705","2002-12-02 20:46:45" +"706","2002-12-03 04:09:55" +"707","2002-12-03 09:00:17" +"708","2002-12-03 09:16:10" +"709","2002-12-03 22:05:22" +"710","2002-12-04 00:55:29" +"711","2002-12-04 01:09:16" +"712","2002-12-05 18:23:41" +"713","2002-12-06 23:17:53" +"714","2002-12-07 00:02:34" +"715","2002-12-07 14:40:01" +"716","2002-12-08 14:48:27" +"717","2002-12-10 18:09:45" +"718","2002-12-11 05:13:58" +"719","2002-12-11 07:27:48" +"720","2002-12-13 13:16:55" +"721","2002-12-14 16:25:07" +"722","2002-12-17 22:16:39" +"723","2002-12-18 02:15:21" +"724","2002-12-19 06:54:40" +"725","2002-12-23 14:34:25" +"726","2002-12-26 22:33:18" +"727","2002-12-30 00:35:21" +"728","2002-12-31 11:54:12" +"729","2003-01-04 00:52:30" +"730","2003-01-04 12:48:15" +"732","2003-01-05 20:09:16" +"733","2003-01-05 23:18:07" +"734","2003-01-06 22:10:54" +"736","2003-01-08 06:05:28" +"737","2003-01-10 01:16:56" +"738","2003-01-11 21:27:02" +"739","2003-01-12 03:37:42" +"740","2003-01-14 01:11:23" +"741","2003-01-15 08:53:06" +"742","2003-01-19 21:21:56" +"743","2003-01-19 21:38:36" +"744","2003-01-21 10:04:05" +"745","2003-01-21 21:50:38" +"746","2003-01-25 00:34:48" +"747","2003-01-27 08:33:22" +"748","2003-01-28 08:33:22" +"749","2003-01-31 11:12:12" +"750","2003-02-02 00:52:28" +"751","2003-02-02 22:05:58" +"752","2003-02-04 21:25:44" +"753","2003-02-05 11:36:27" +"754","2003-02-05 21:52:16" +"755","2003-02-12 00:51:06" +"756","2003-02-13 18:51:29" +"757","2003-02-16 04:02:56" +"758","2003-02-16 22:09:27" +"759","2003-02-17 09:02:52" +"760","2003-02-18 00:08:58" +"761","2003-02-18 03:42:58" +"762","2003-02-18 17:53:11" +"763","2003-02-20 02:41:51" +"764","2003-02-20 02:41:52" +"765","2003-02-21 08:12:43" +"766","2003-02-21 22:41:41" +"767","2003-02-22 18:24:03" +"768","2003-02-24 02:49:07" +"769","2003-02-25 04:11:05" +"770","2003-02-25 08:53:26" +"771","2003-02-26 13:13:04" +"772","2003-02-27 18:17:37" +"773","2003-02-28 12:34:18" +"774","2003-02-28 18:31:53" +"775","2003-03-06 00:54:36" +"776","2003-03-06 01:09:07" +"777","2003-03-06 01:17:35" +"778","2003-03-07 13:36:24" +"779","2003-03-08 13:28:08" +"780","2003-03-09 20:00:27" +"781","2003-03-10 07:02:21" +"782","2003-03-12 07:57:05" +"783","2003-03-12 19:09:28" +"784","2003-03-12 22:21:58" +"785","2003-03-18 02:05:20" +"786","2003-03-18 02:08:42" +"787","2003-03-20 05:38:11" +"788","2003-03-23 13:17:16" +"789","2003-03-26 11:37:11" +"790","2003-03-26 11:37:12" +"791","2003-03-26 15:06:30" +"792","2003-03-26 19:18:58" +"796","2003-04-03 08:06:53" +"797","2003-04-03 09:14:25" +"798","2003-04-03 21:49:19" +"799","2003-04-04 23:50:55" +"801","2003-04-09 21:22:17" +"802","2003-04-10 07:19:15" +"803","2003-04-12 11:50:25" +"804","2003-04-12 11:50:26" +"805","2003-04-12 23:43:47" +"806","2003-04-16 02:22:21" +"807","2003-04-18 12:06:10" +"808","2003-04-18 22:23:15" +"809","2003-04-21 15:55:00" +"810","2003-04-22 02:44:25" +"811","2003-04-22 02:44:33" +"812","2003-04-22 02:44:43" +"813","2003-04-22 08:46:17" +"814","2003-04-22 21:02:47" +"815","2003-04-23 12:51:14" +"816","2003-04-24 11:39:54" +"818","2003-04-26 10:31:15" +"819","2003-05-01 19:00:18" +"820","2003-05-02 22:20:20" +"821","2003-05-02 22:20:21" +"822","2003-05-03 12:18:35" +"823","2003-05-06 01:03:07" +"824","2003-05-07 20:42:53" +"825","2003-05-09 22:44:13" +"826","2003-05-10 11:56:35" +"827","2003-05-10 11:56:36" +"828","2003-05-10 11:56:37" +"829","2003-05-10 16:54:40" +"830","2003-05-13 11:04:23" +"831","2003-05-16 12:21:39" +"832","2003-05-16 21:41:58" +"833","2003-05-18 00:43:02" +"835","2003-05-22 19:30:18" +"836","2003-05-23 18:40:52" +"837","2003-05-25 15:52:34" +"838","2003-05-26 11:24:26" +"839","2003-05-27 10:27:45" +"842","2003-05-30 19:55:23" +"843","2003-06-02 03:34:38" +"844","2003-06-02 23:45:45" +"845","2003-06-04 18:56:09" +"846","2003-06-05 15:11:58" +"847","2003-06-06 12:47:32" +"848","2003-06-06 22:18:43" +"849","2003-06-07 20:48:21" +"850","2003-06-10 10:46:09" +"851","2003-06-11 03:09:13" +"852","2003-06-11 16:31:25" +"853","2003-06-13 14:35:46" +"854","2003-06-13 21:08:25" +"855","2003-06-15 18:35:55" +"856","2003-06-16 04:39:37" +"857","2003-06-19 23:19:41" +"858","2003-06-21 03:59:18" +"859","2003-06-21 10:41:47" +"860","2003-06-21 10:41:47" +"861","2003-06-21 20:06:32" +"862","2003-06-21 20:06:33" +"863","2003-06-22 11:23:42" +"864","2003-06-23 11:12:11" +"865","2003-06-25 09:14:59" +"866","2003-06-25 09:15:00" +"867","2003-06-26 11:20:01" +"868","2003-06-27 13:07:07" +"869","2003-06-29 19:34:16" +"870","2003-06-29 22:30:33" +"871","2003-06-30 18:59:37" +"872","2003-07-01 00:33:25" +"873","2003-07-02 15:12:31" +"874","2003-07-04 09:40:13" +"875","2003-07-08 08:18:04" +"876","2003-07-08 12:49:14" +"877","2003-07-10 02:22:56" +"878","2003-07-12 19:40:40" +"879","2003-07-13 20:23:44" +"880","2003-07-14 12:43:58" +"881","2003-07-14 23:10:50" +"882","2003-07-15 00:19:43" +"883","2003-07-15 17:58:47" +"885","2003-07-19 18:53:14" +"886","2003-07-21 16:45:36" +"887","2003-07-25 13:00:51" +"888","2003-07-25 23:14:47" +"889","2003-07-25 23:14:48" +"890","2003-07-28 09:35:32" +"891","2003-07-29 00:31:58" +"892","2003-07-30 21:30:42" +"893","2003-08-01 00:15:40" +"894","2003-08-01 00:22:08" +"895","2003-08-01 21:42:37" +"896","2003-08-01 23:44:54" +"897","2003-08-02 09:17:24" +"898","2003-08-03 16:35:04" +"899","2003-08-03 16:41:24" +"900","2003-08-03 23:17:36" +"901","2003-08-04 00:23:48" +"902","2003-08-04 22:53:06" +"903","2003-08-05 23:59:35" +"904","2003-08-06 19:06:01" +"905","2003-08-07 11:27:20" +"906","2003-08-07 11:27:22" +"907","2003-08-09 11:48:15" +"908","2003-08-09 19:14:20" +"909","2003-08-10 10:22:08" +"910","2003-08-10 10:22:09" +"911","2003-08-10 23:58:35" +"912","2003-08-12 00:42:14" +"913","2003-08-12 06:48:39" +"914","2003-08-12 23:27:18" +"915","2003-08-12 23:54:17" +"916","2003-08-13 14:02:34" +"917","2003-08-15 00:45:10" +"918","2003-08-16 00:44:51" +"919","2003-08-16 00:44:52" +"920","2003-08-16 20:33:46" +"921","2003-08-18 03:34:32" +"922","2003-08-19 12:02:08" +"923","2003-08-19 23:00:25" +"924","2003-08-20 12:07:59" +"925","2003-08-27 21:23:01" +"926","2003-08-29 18:08:16" +"928","2003-08-31 19:24:16" +"929","2003-09-01 13:50:06" +"930","2003-09-03 13:53:56" +"931","2003-09-03 16:29:27" +"932","2003-09-03 16:29:53" +"933","2003-09-04 09:52:55" +"934","2003-09-07 22:59:26" +"935","2003-09-09 11:18:45" +"936","2003-09-12 01:13:27" +"937","2003-09-13 18:53:38" +"938","2003-09-14 10:37:42" +"939","2003-09-16 18:11:24" +"940","2003-09-16 18:11:27" +"941","2003-09-16 18:11:35" +"942","2003-09-18 21:24:15" +"943","2003-09-20 21:55:16" +"944","2003-09-26 11:21:06" +"945","2003-09-27 10:51:01" +"946","2003-09-29 11:20:13" +"947","2003-09-30 19:58:44" +"948","2003-09-30 23:09:15" +"949","2003-10-02 21:28:54" +"950","2003-10-03 18:36:52" +"951","2003-10-04 00:12:07" +"952","2003-10-05 10:56:39" +"953","2003-10-05 11:42:17" +"954","2003-10-06 22:30:33" +"955","2003-10-15 17:21:44" +"956","2003-10-15 21:02:10" +"957","2003-10-18 22:52:47" +"958","2003-10-24 20:59:30" +"959","2003-10-25 22:29:46" +"960","2003-10-26 00:47:16" +"961","2003-10-26 09:54:53" +"962","2003-10-28 21:30:29" +"963","2003-10-28 23:31:04" +"964","2003-10-28 23:32:54" +"965","2003-10-30 05:50:53" +"966","2003-11-01 19:38:09" +"967","2003-11-01 19:38:10" +"968","2003-11-04 23:22:01" +"969","2003-11-09 11:40:30" +"970","2003-11-11 18:19:57" +"971","2003-11-14 21:15:47" +"972","2003-11-15 10:38:48" +"973","2003-11-17 22:56:31" +"974","2003-11-18 03:19:02" +"975","2003-11-20 16:13:43" +"976","2003-11-22 08:36:26" +"977","2003-11-25 18:52:48" +"978","2003-11-25 22:34:19" +"979","2003-12-02 21:35:39" +"980","2003-12-09 21:13:32" +"981","2003-12-12 22:26:06" +"982","2003-12-18 21:31:59" +"983","2003-12-18 21:32:01" +"984","2003-12-21 10:31:42" +"985","2003-12-30 22:51:30" +"986","2003-12-31 12:23:27" +"987","2004-01-08 00:35:22" +"988","2004-01-09 18:17:46" +"989","2004-01-12 23:16:09" +"990","2004-01-13 18:43:23" +"991","2004-01-15 21:50:36" +"992","2004-01-15 21:51:51" +"993","2004-01-18 15:01:25" +"994","2004-01-19 19:27:06" +"995","2004-01-22 13:31:30" +"996","2004-01-27 16:38:51" +"997","2004-01-27 19:42:51" +"998","2004-02-10 22:44:04" +"1000","2004-02-23 18:50:11" +"1001","2004-02-25 17:02:01" +"1002","2004-02-29 22:49:19" +"1003","2004-03-02 01:24:39" +"1004","2004-03-03 21:38:18" +"1005","2004-03-10 23:24:09" +"1006","2004-03-12 11:11:57" +"1007","2004-03-16 22:29:38" +"1008","2004-03-20 10:19:18" +"1009","2004-03-20 21:03:54" +"1010","2004-03-26 21:45:57" +"1011","2004-03-30 07:50:18" +"1012","2004-04-07 02:14:35" +"1013","2004-04-08 19:26:44" +"1014","2004-04-09 19:54:58" +"1015","2004-04-16 18:23:43" +"1016","2004-04-16 18:23:44" +"1018","2004-04-21 00:09:21" +"1019","2004-04-21 00:09:22" +"1020","2004-04-22 08:38:40" +"1021","2004-04-24 11:36:28" +"1022","2004-05-02 02:48:07" +"1023","2004-05-06 19:42:18" +"1024","2004-05-07 23:49:36" +"1025","2004-05-08 21:04:21" +"1026","2004-05-10 07:21:55" +"1027","2004-05-12 09:08:21" +"1028","2004-05-12 19:17:00" +"1029","2004-05-13 17:20:22" +"1030","2004-05-19 06:41:34" +"1031","2004-05-23 19:00:19" +"1032","2004-05-23 22:48:41" +"1033","2004-05-28 09:32:09" +"1034","2004-06-09 12:39:13" +"1035","2004-06-20 21:17:25" +"1036","2004-06-25 08:10:13" +"1037","2004-06-25 22:34:24" +"1038","2004-06-28 22:51:29" +"1039","2004-06-30 13:30:07" +"1041","2004-07-02 15:19:22" +"1042","2004-07-05 12:27:43" +"1043","2004-07-11 13:10:33" +"1044","2004-07-16 01:22:13" +"1045","2004-07-18 01:49:43" +"1046","2004-07-24 22:43:38" +"1047","2004-07-26 23:35:15" +"1048","2004-07-31 01:35:20" +"1049","2004-08-18 08:20:54" +"1050","2004-08-18 11:04:05" +"1051","2004-08-27 22:50:14" +"1052","2004-08-28 12:28:02" +"1053","2004-08-31 01:06:17" +"1054","2004-08-31 08:28:29" +"1055","2004-09-06 17:21:58" +"1056","2004-09-10 15:01:12" +"1057","2004-09-18 09:49:56" +"1058","2004-09-18 16:57:09" +"1059","2004-09-24 07:46:55" +"1061","2004-10-04 19:46:24" +"1062","2004-10-11 14:13:30" +"1063","2004-10-12 10:30:03" +"1064","2004-10-12 10:30:32" +"1065","2004-10-21 13:18:10" +"1066","2004-10-26 13:41:11" +"1067","2004-11-09 13:35:08" +"1068","2004-11-12 10:40:31" +"1069","2004-12-02 08:52:34" +"1070","2004-12-09 20:43:47" +"1072","2004-12-15 00:08:05" +"1073","2004-12-16 20:18:27" +"1074","2005-01-02 21:21:42" +"1075","2005-01-09 08:36:35" +"1076","2005-01-12 20:12:15" +"1077","2005-01-26 11:02:01" +"1078","2005-01-27 11:34:22" +"1079","2005-02-01 11:53:51" +"1080","2005-02-02 19:15:29" +"1081","2005-02-17 18:42:10" +"1082","2005-03-06 17:04:36" +"1083","2005-03-10 09:01:51" +"1084","2005-03-17 05:54:12" +"1085","2005-03-18 03:33:42" +"1086","2005-03-26 20:48:45" +"1087","2005-03-30 01:41:21" +"1088","2005-03-31 13:54:44" +"1089","2005-04-04 17:46:25" +"1090","2005-04-07 20:30:15" +"1091","2005-04-12 22:24:16" +"1092","2005-04-27 14:44:47" +"1093","2005-05-19 04:28:24" +"1097","2005-05-21 07:17:03" +"1098","2005-05-25 02:47:15" +"1099","2005-05-26 15:54:05" +"1100","2005-05-31 12:09:32" +"1101","2005-06-02 23:52:43" +"1102","2005-06-02 23:52:44" +"1106","2005-06-08 15:17:28" +"1107","2005-06-15 00:11:29" +"1108","2005-06-16 09:03:22" +"1109","2005-06-20 09:10:02" +"1113","2005-06-27 14:43:45" +"1114","2005-06-28 06:53:24" +"1115","2005-07-06 07:35:02" +"1116","2005-07-12 23:28:19" +"1117","2005-07-14 15:11:07" +"1118","2005-07-15 11:13:33" +"1119","2005-07-15 21:20:24" +"1120","2005-07-20 08:05:53" +"1121","2005-07-25 17:40:33" +"1122","2005-07-26 05:24:16" +"1124","2005-07-26 17:46:50" +"1125","2005-07-26 21:40:34" +"1126","2005-07-29 08:03:34" +"1127","2005-08-04 21:31:26" +"1128","2005-08-15 23:48:40" +"1129","2005-08-23 20:00:49" +"1130","2005-09-06 14:54:10" +"1131","2005-09-08 22:59:36" +"1132","2005-09-09 13:00:43" +"1133","2005-09-12 00:04:56" +"1134","2005-09-12 00:24:15" +"1135","2005-09-20 22:07:40" +"1136","2005-09-28 18:52:25" +"1137","2005-09-28 21:39:48" +"1138","2005-10-06 04:42:53" +"1139","2005-10-10 10:16:01" +"1140","2005-10-11 20:11:08" +"1141","2005-10-12 11:17:33" +"1142","2005-10-13 09:13:17" +"1143","2005-10-13 10:24:35" +"1144","2005-10-14 10:29:59" +"1145","2005-10-15 06:40:24" +"1146","2005-10-18 18:37:33" +"1147","2005-10-20 09:59:21" +"1148","2005-10-20 18:41:37" +"1149","2005-10-20 18:59:55" +"1150","2005-10-21 08:03:36" +"1151","2005-10-25 10:15:37" +"1152","2005-10-26 08:12:18" +"1153","2005-11-04 07:35:56" +"1154","2005-11-08 22:34:45" +"1155","2005-11-14 07:52:56" +"1156","2005-11-17 23:53:02" +"1157","2005-11-23 09:27:19" +"1158","2005-12-03 10:26:22" +"1159","2005-12-14 00:09:16" +"1160","2006-01-02 01:14:51" +"1161","2006-01-03 15:46:31" +"1162","2006-01-06 13:05:41" +"1163","2006-01-06 14:20:30" +"1165","2006-01-17 19:35:32" +"1166","2006-01-22 12:50:12" +"1167","2006-02-06 09:35:29" +"1168","2006-02-06 21:25:14" +"1169","2006-02-14 00:47:39" +"1170","2006-02-14 17:19:51" +"1171","2006-02-15 13:26:42" +"1174","2006-03-03 08:55:46" +"1175","2006-03-08 20:34:16" +"1176","2006-03-09 17:09:36" +"1181","2006-03-15 17:12:55" +"1182","2006-03-20 10:14:12" +"1184","2006-03-27 16:03:52" +"1186","2006-03-30 21:49:05" +"1187","2006-03-30 21:49:12" +"1190","2006-04-04 20:55:16" +"1191","2006-04-06 08:02:10" +"1193","2006-04-17 10:05:37" +"1194","2006-04-23 08:52:39" +"1195","2006-04-23 08:53:45" +"1197","2006-04-25 18:02:15" +"1198","2006-04-27 15:22:40" +"1199","2006-05-04 15:41:58" +"1200","2006-05-12 15:56:27" +"1201","2006-05-16 06:20:06" +"1202","2006-05-25 12:35:26" +"1204","2006-05-30 02:41:48" +"1205","2006-06-07 21:32:01" +"1206","2006-06-11 20:47:28" +"1208","2006-06-24 11:36:41" +"1210","2006-06-29 19:57:54" +"1211","2006-07-12 06:15:37" +"1212","2006-07-19 08:23:43" +"1213","2006-07-21 08:12:10" +"1214","2006-08-03 00:32:01" +"1215","2006-08-05 02:07:08" +"1216","2006-08-31 09:50:42" +"1217","2006-09-01 18:09:34" +"1218","2006-09-06 11:55:18" +"1219","2006-09-07 16:52:55" +"1220","2006-09-08 08:42:37" +"1221","2006-09-08 14:59:36" +"1223","2006-09-10 00:24:57" +"1224","2006-09-10 00:47:08" +"1225","2006-09-10 22:39:44" +"1226","2006-09-11 10:10:33" +"1228","2006-09-11 16:53:54" +"1229","2006-09-11 16:54:03" +"1230","2006-09-12 09:15:13" +"1231","2006-09-16 23:22:42" +"1232","2006-09-18 20:56:16" +"1233","2006-09-19 22:40:39" +"1234","2006-09-21 21:31:00" +"1235","2006-09-21 21:32:32" +"1236","2006-09-21 21:33:32" +"1237","2006-09-21 21:34:22" +"1238","2006-09-21 22:59:31" +"1239","2006-09-22 00:26:31" +"1240","2006-09-27 19:02:49" +"1241","2006-10-06 08:14:06" +"1242","2006-10-07 11:54:41" +"1243","2006-10-08 07:13:00" +"1244","2006-10-08 07:13:23" +"1245","2006-10-08 07:13:50" +"1246","2006-10-15 03:49:04" +"1248","2006-10-19 09:37:52" +"1249","2006-11-05 12:01:27" +"1250","2006-11-08 08:36:02" +"1251","2006-11-11 11:32:28" +"1252","2006-11-15 20:25:03" +"1253","2006-11-19 12:17:55" +"1254","2006-11-21 18:46:14" +"1255","2006-11-26 11:17:56" +"1256","2006-11-26 13:11:54" +"1257","2006-11-26 22:58:49" +"1258","2006-11-27 22:44:51" +"1259","2006-12-08 13:30:45" +"1260","2006-12-24 22:55:15" +"1261","2006-12-25 08:50:12" +"1263","2007-01-09 17:05:32" +"1264","2007-02-14 00:59:09" +"1265","2007-02-15 13:11:16" +"1266","2007-03-03 10:58:11" +"1267","2007-03-14 12:19:07" +"1268","2007-03-21 18:40:37" +"1269","2007-04-01 08:58:29" +"1270","2007-04-21 11:22:18" +"1271","2007-05-21 13:41:47" +"1272","2007-06-07 23:07:55" +"1274","2007-06-12 18:30:23" +"1275","2007-06-15 09:59:01" +"1276","2007-06-28 13:37:59" +"1277","2007-06-28 13:38:05" +"1278","2007-06-29 22:44:36" +"1279","2007-07-09 14:30:08" +"1280","2007-07-10 22:47:09" +"1282","2007-07-11 12:55:52" +"1283","2007-07-31 03:10:42" +"1284","2007-08-08 04:01:39" +"1285","2007-08-23 07:44:04" +"1286","2007-08-24 10:29:37" +"1287","2007-08-24 11:04:08" +"1288","2007-08-24 11:19:29" +"1289","2007-08-30 13:52:14" +"1290","2007-09-07 09:41:47" +"1291","2007-09-11 02:48:26" +"1292","2007-09-23 14:02:12" +"1293","2007-10-04 22:20:57" +"1294","2007-11-02 00:15:55" +"1295","2007-11-04 02:43:41" +"1296","2007-11-05 09:49:49" +"1297","2007-11-08 10:28:31" +"1298","2007-12-16 17:13:39" +"1299","2007-12-17 09:19:27" +"1300","2008-01-02 16:00:21" +"1301","2008-01-02 16:00:26" +"1302","2008-01-02 16:00:43" +"1303","2008-01-26 18:49:45" +"1304","2008-03-06 09:38:06" +"1305","2008-03-07 07:59:32" +"1306","2008-03-11 09:19:28" +"1307","2008-03-14 09:38:32" +"1308","2008-03-26 00:39:38" +"1309","2008-04-04 19:14:15" +"1310","2008-04-10 02:11:49" +"1311","2008-04-18 14:28:00" +"1312","2008-05-21 15:55:50" +"1313","2008-06-09 23:36:55" +"1314","2008-06-18 01:34:37" +"1315","2008-06-20 15:02:29" +"1316","2008-07-24 18:58:19" +"1317","2008-07-28 18:58:48" +"1318","2008-08-27 09:33:11" +"1319","2008-08-29 01:00:05" +"1320","2008-08-30 23:33:04" +"1321","2008-09-02 21:09:35" +"1322","2008-09-09 15:58:27" +"1323","2008-09-11 16:13:46" +"1324","2008-09-19 19:28:23" +"1325","2008-10-05 05:14:23" +"1326","2008-10-07 15:21:08" +"1327","2008-10-12 17:37:14" +"1328","2008-10-12 19:20:54" +"1329","2008-10-18 23:46:31" +"1330","2008-10-24 14:53:36" +"1331","2008-10-25 19:39:18" +"1332","2008-11-01 14:09:56" +"1333","2008-11-04 00:51:38" +"1334","2008-11-08 19:46:06" +"1335","2008-11-11 20:17:52" +"1336","2008-11-15 02:01:22" +"1337","2008-11-20 01:39:55" +"1338","2008-11-20 01:39:58" +"1339","2008-11-20 01:40:33" +"1340","2008-11-20 01:40:47" +"1341","2008-11-20 01:40:55" +"1342","2008-11-20 01:41:06" +"1343","2008-11-24 20:08:51" +"1344","2008-11-25 03:25:08" +"1345","2008-11-30 02:17:27" +"1346","2008-12-07 17:25:04" +"1347","2008-12-14 20:51:05" +"1348","2008-12-25 17:57:29" +"1349","2009-01-09 19:42:16" +"1350","2009-01-22 15:09:11" +"1351","2009-01-23 23:24:19" +"1352","2009-02-01 18:23:48" +"1353","2009-02-07 14:51:54" +"1354","2009-02-15 21:11:43" +"1355","2009-02-23 20:38:16" +"1356","2009-02-26 01:55:49" +"1357","2009-03-01 01:25:28" +"1358","2009-03-08 17:46:55" +"1359","2009-03-15 21:11:47" +"1360","2009-04-11 21:42:41" +"1361","2009-04-18 01:50:59" +"1362","2009-05-01 18:45:20" +"1363","2009-06-03 16:41:04" +"1364","2009-07-05 22:45:33" +"1365","2009-07-15 00:42:21" +"1366","2009-08-01 16:16:12" +"1367","2009-08-01 20:36:53" +"1368","2009-08-17 21:01:24" +"1369","2009-09-01 00:20:04" +"1370","2009-09-01 22:18:41" +"1371","2009-10-01 14:58:35" +"1372","2009-11-02 19:02:49" +"1373","2009-12-01 18:30:56" +"1374","2010-01-04 17:38:13" +"1375","2010-01-15 05:00:11" +"1376","2010-01-25 22:20:30" +"1377","2010-01-27 21:43:57" +"1378","2010-02-04 15:49:28" +"1379","2010-03-09 15:50:59" +"1380","2010-04-16 00:03:38" +"1381","2010-04-21 18:22:49" +"1382","2010-05-08 00:58:14" +"1383","2010-06-09 00:48:42" +"1384","2010-07-01 15:31:41" +"1385","2010-07-19 12:52:17" +"1386","2010-07-19 12:53:14" +"1387","2010-08-02 01:16:03" +"1388","2010-09-01 23:23:55" +"1389","2010-10-01 15:22:40" +"1390","2010-11-02 00:45:55" +"1391","2010-12-04 00:41:01" +"1392","2011-01-03 23:41:36" +"1393","2011-02-03 20:56:28" +"1394","2011-03-01 18:17:20" +"1395","2011-03-03 17:25:31" +"1402","2011-09-15 15:33:33" +"1410","2012-05-27 10:09:07" +"1411","2012-05-27 10:52:26" +"1412","2012-05-27 11:56:04" +"1413","2012-05-27 12:03:20" +"1415","2012-05-27 13:41:01" +"1416","2012-05-28 09:37:27" +"1418","2012-06-01 14:57:20" +"1419","2012-06-01 21:35:30" +"1420","2012-06-03 02:35:52" +"1422","2012-06-06 10:21:32" +"1423","2012-06-07 16:23:55" +"1425","2012-06-10 20:38:18" +"1427","2012-06-13 20:28:43" +"1428","2012-06-17 00:49:04" +"1429","2012-06-18 07:30:55" +"1430","2012-06-23 15:13:41" +"1431","2012-06-26 14:55:03" +"1432","2012-06-29 01:30:49" +"1433","2012-07-02 20:22:35" +"1434","2012-07-12 22:52:29" +"1435","2012-07-18 22:59:03" +"1436","2012-07-25 19:34:11" +"1437","2012-07-26 15:57:49" +"1438","2012-08-13 00:08:52" +"1439","2012-08-25 23:30:11" +"1440","2012-08-28 16:03:50" +"1441","2012-09-12 01:35:57" +"1442","2012-09-12 22:13:19" +"1443","2012-09-20 01:06:20" +"1444","2012-10-13 02:08:25" +"1445","2012-10-23 21:12:52" +"1446","2012-10-26 17:35:43" +"1447","2012-11-02 15:35:07" +"1448","2012-11-14 02:26:21" +"1449","2012-12-06 08:05:42" +"1450","2012-12-25 18:01:17" +"1451","2013-01-17 14:55:14" +"1452","2013-01-22 14:58:33" +"1453","2013-01-28 16:24:31" +"1454","2013-01-30 06:46:24" +"1455","2013-02-20 15:28:38" +"1456","2013-03-02 14:55:50" +"1460","2013-03-08 01:31:26" +"1461","2013-03-10 23:30:14" +"1462","2013-04-02 16:31:26" +"1463","2013-05-06 01:19:32" +"1464","2013-06-03 14:56:54" +"1465","2013-06-11 01:48:23" +"1467","2013-07-25 18:06:38" +"1468","2013-09-07 01:18:49" +"1469","2013-09-18 15:10:07" +"1470","2013-10-03 15:13:52" +"1471","2013-11-01 14:00:16" +"1472","2013-11-10 20:49:57" +"1474","2013-12-15 09:02:55" +"1475","2014-01-02 10:05:42" +"1476","2014-01-10 06:49:19" +"1477","2014-02-09 01:29:34" +"1478","2014-03-20 14:22:45" +"1480","2014-08-13 00:17:27" +"1483","2014-08-23 19:48:11" +"1490","2014-09-13 08:59:53" +"1491","2014-09-15 07:59:55" +"1492","2015-01-20 14:58:33" +"1493","2015-01-20 15:00:01" +"1494","2015-01-22 17:31:10" +"1495","2015-07-27 23:00:15" diff --git a/resources/js/Layouts/AdminLayout.jsx b/resources/js/Layouts/AdminLayout.jsx index 47e633d0..09da038b 100644 --- a/resources/js/Layouts/AdminLayout.jsx +++ b/resources/js/Layouts/AdminLayout.jsx @@ -6,6 +6,7 @@ const buildAdminNavGroups = (isAdmin) => [ label: 'Overview', items: [ { label: 'Dashboard', href: '/moderation', icon: 'fa-solid fa-gauge-high', exact: true }, + { label: 'Daily Activity', href: '/moderation/activity', icon: 'fa-solid fa-calendar-day' }, ], }, { diff --git a/resources/js/Pages/Admin/DailyActivity.jsx b/resources/js/Pages/Admin/DailyActivity.jsx new file mode 100644 index 00000000..3667b5ed --- /dev/null +++ b/resources/js/Pages/Admin/DailyActivity.jsx @@ -0,0 +1,271 @@ +import React from 'react' +import { Head, router } from '@inertiajs/react' +import AdminLayout from '../../Layouts/AdminLayout' + +function formatDateTime(value) { + if (!value) return '—' + + try { + return new Intl.DateTimeFormat(undefined, { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }).format(new Date(value)) + } catch { + return String(value) + } +} + +function StatCard({ icon, label, value, tone = 'sky' }) { + const tones = { + sky: 'border-sky-400/20 bg-sky-400/10 text-sky-200', + rose: 'border-rose-400/20 bg-rose-400/10 text-rose-200', + amber: 'border-amber-400/20 bg-amber-400/10 text-amber-200', + emerald: 'border-emerald-400/20 bg-emerald-400/10 text-emerald-200', + } + + return ( +
+
+
+
{label}
+
{Number(value || 0).toLocaleString()}
+
+
+ +
+
+
+ ) +} + +function SectionCard({ title, subtitle, actionHref, actionLabel, children }) { + return ( +
+
+
+

{title}

+ {subtitle ?

{subtitle}

: null} +
+ {actionHref ? ( + + {actionLabel || 'Open queue'} + + + ) : null} +
+
{children}
+
+ ) +} + +function EmptyState({ label }) { + return
{label}
+} + +function DataTable({ columns, rows, emptyLabel }) { + if (!rows?.length) { + return + } + + return ( +
+ + + + {columns.map((column) => ( + + ))} + + + + {rows.map((row, index) => ( + + {columns.map((column) => ( + + ))} + + ))} + +
{column.label}
+ {column.render ? column.render(row) : row[column.key]} +
+
+ ) +} + +export default function DailyActivity({ selectedDate, summary, queues, sections }) { + const onDateChange = (event) => { + router.get('/moderation/activity', { date: event.target.value }, { preserveState: true, replace: true }) + } + + return ( + + + +
+
+
+
Moderation review
+

Selected day: {selectedDate}

+

+ This view pulls together the moderation-adjacent activity for the selected day so admins can triage queues and jump into the right review surface quickly. +

+
+ +
+
+ +
+ + + + + + +
+ +
+
+
Queues right now
+
+
+ Pending uploads + {queues.pending_uploads} +
+
+ Open reports + {queues.open_reports} +
+
+ Pending username requests + {queues.pending_username_requests} +
+
+
+ +
+
Moderation throughput on this day
+
+
+
Moderated uploads
+
{summary.moderated_uploads}
+
+
+
Moderated reports
+
{summary.moderated_reports}
+
+
+
Username events
+
{summary.username_events}
+
+
+
+
+ +
+ +
{row.title}
{row.type} · {row.status} · {row.processing_state}
}, + { key: 'moderation_status', label: 'Moderation', render: (row) =>
{row.moderation_status}
{row.moderation_note || 'No note'}
}, + { key: 'created_at', label: 'Created', render: (row) => formatDateTime(row.created_at) }, + { key: 'moderated_at', label: 'Moderated', render: (row) => formatDateTime(row.moderated_at) }, + ]} + /> +
+ + +
{row.reason}
{row.status} · {row.target_type} #{row.target_id}
}, + { key: 'reporter', label: 'Reporter', render: (row) => row.reporter ? `@${row.reporter.username}` : '—' }, + { key: 'target', label: 'Target', render: (row) => row.target?.title || row.target?.context || 'Resolved via moderation target' }, + { key: 'last_moderated_at', label: 'Reviewed', render: (row) =>
{formatDateTime(row.last_moderated_at)}
{row.last_moderated_by ? `@${row.last_moderated_by.username}` : 'Unassigned'}
}, + ]} + /> +
+ +
+ +
{row.requested_username}
Current: {row.current_username || row.current_name || 'Unknown user'}
}, + { key: 'status', label: 'Status' }, + { key: 'created_at', label: 'Created', render: (row) => formatDateTime(row.created_at) }, + { key: 'reviewed_at', label: 'Reviewed', render: (row) => formatDateTime(row.reviewed_at) }, + ]} + /> +
+ + +
{row.event_type}
{row.status} · {row.ip || 'No IP'}
}, + { key: 'user', label: 'User', render: (row) => row.user ? `@${row.user.username || row.user.name}` : (row.identifier || 'Guest') }, + { key: 'reason', label: 'Reason', render: (row) => row.reason || '—' }, + { key: 'created_at', label: 'When', render: (row) => formatDateTime(row.created_at) }, + ]} + /> +
+
+ +
+ +
{row.username ? `@${row.username}` : row.name}
{row.email}
}, + { key: 'role', label: 'Role' }, + { key: 'created_at', label: 'Joined', render: (row) => formatDateTime(row.created_at) }, + ]} + /> +
+ + +
{row.title}
{row.user?.username ? `@${row.user.username}` : 'Unknown artist'}
}, + { key: 'status', label: 'Status' }, + { key: 'created_at', label: 'Created', render: (row) => formatDateTime(row.created_at) }, + ]} + /> +
+ + +
{row.title}
{row.creator?.username ? `@${row.creator.username}` : 'Unknown creator'}
}, + { key: 'status', label: 'Status' }, + { key: 'created_at', label: 'Created', render: (row) => formatDateTime(row.created_at) }, + ]} + /> +
+
+
+
+ ) +} \ No newline at end of file diff --git a/resources/js/Pages/Admin/Dashboard.jsx b/resources/js/Pages/Admin/Dashboard.jsx index d184b06d..aa924378 100644 --- a/resources/js/Pages/Admin/Dashboard.jsx +++ b/resources/js/Pages/Admin/Dashboard.jsx @@ -43,6 +43,7 @@ export default function Dashboard({ stats }) {

Quick Actions

{[ + { label: 'Daily Activity', href: '/moderation/activity', icon: 'fa-solid fa-calendar-day', desc: 'Review everything created or moderated on a selected day' }, { label: 'Manage Users', href: '/moderation/users', icon: 'fa-solid fa-users', desc: 'Search, promote or demote users' }, { label: 'Staff Roles', href: '/moderation/users?role=admin', icon: 'fa-solid fa-shield-halved', desc: 'View all admins, managers and editorial staff' }, { label: 'Username Queue', href: '/moderation/usernames/moderation', icon: 'fa-solid fa-id-badge', desc: 'Review pending username requests' }, diff --git a/resources/views/web/stories/editor.blade.php b/resources/views/web/stories/editor.blade.php index ab835e2c..046bb4b2 100644 --- a/resources/views/web/stories/editor.blade.php +++ b/resources/views/web/stories/editor.blade.php @@ -25,13 +25,13 @@ 'id' => $story->id, 'title' => old('title', (string) $story->title), 'excerpt' => old('excerpt', (string) ($story->excerpt ?? '')), - 'cover_image' => old('cover_image', (string) ($story->cover_image ?? '')), + 'cover_image' => old('cover_image', (string) ($story->cover_url ?? $story->cover_image ?? '')), 'story_type' => old('story_type', (string) ($story->story_type ?? 'creator_story')), 'tags_csv' => old('tags_csv', (string) ($story->tags?->pluck('name')->implode(', ') ?? '')), 'meta_title' => old('meta_title', (string) ($story->meta_title ?? $story->title ?? '')), 'meta_description' => old('meta_description', (string) ($story->meta_description ?? $story->excerpt ?? '')), 'canonical_url' => old('canonical_url', (string) ($story->canonical_url ?? '')), - 'og_image' => old('og_image', (string) ($story->og_image ?? $story->cover_image ?? '')), + 'og_image' => old('og_image', (string) ($story->og_image_url ?? $story->cover_url ?? $story->cover_image ?? '')), 'status' => old('status', (string) ($story->status ?? 'draft')), 'scheduled_for' => old('scheduled_for', optional($story->scheduled_for)->format('Y-m-d\\TH:i')), 'content' => $initialContent, diff --git a/resources/views/web/stories/preview.blade.php b/resources/views/web/stories/preview.blade.php index 902af604..05757dd4 100644 --- a/resources/views/web/stories/preview.blade.php +++ b/resources/views/web/stories/preview.blade.php @@ -62,8 +62,8 @@
- @if($story->cover_image) - {{ $story->title }} + @if($story->cover_url) + {{ $story->title }} @endif
diff --git a/routes/web.php b/routes/web.php index 328ad122..721d2f49 100644 --- a/routes/web.php +++ b/routes/web.php @@ -975,6 +975,7 @@ Route::middleware(['auth', 'admin.access']) ->name('admin.') ->group(function () { Route::get('/', [AdminController::class, 'dashboard'])->name('dashboard'); + Route::get('/activity', [AdminController::class, 'dailyActivity'])->name('activity'); Route::get('/users', [AdminController::class, 'users'])->name('users'); Route::patch('/users/{user}/role', [AdminController::class, 'updateRole'])->name('users.role'); Route::get('/stories', [AdminController::class, 'stories'])->name('stories'); diff --git a/tests/Feature/Admin/ModerationDailyActivityPageTest.php b/tests/Feature/Admin/ModerationDailyActivityPageTest.php new file mode 100644 index 00000000..3dafa00b --- /dev/null +++ b/tests/Feature/Admin/ModerationDailyActivityPageTest.php @@ -0,0 +1,39 @@ +create([ + 'role' => 'admin', + ]); + + $this->actingAs($admin) + ->get('/moderation/activity?date=2026-04-29') + ->assertOk() + ->assertInertia(fn (AssertableInertia $page) => $page + ->component('Admin/DailyActivity') + ->where('selectedDate', '2026-04-29') + ->where('summary.new_users', 0) + ->where('queues.pending_uploads', 0) + ->has('sections.users') + ->has('sections.artworks') + ->has('sections.stories') + ->has('sections.uploads') + ->has('sections.reports') + ->has('sections.username_requests') + ->has('sections.auth_events')); + } +} \ No newline at end of file diff --git a/tests/Feature/Stories/CreatorStoryWorkflowTest.php b/tests/Feature/Stories/CreatorStoryWorkflowTest.php index ac161b8b..b81b4879 100644 --- a/tests/Feature/Stories/CreatorStoryWorkflowTest.php +++ b/tests/Feature/Stories/CreatorStoryWorkflowTest.php @@ -32,7 +32,7 @@ it('creator can create a draft story from editor form', function () { expect($story->status)->toBe('draft'); expect($story->slug)->not->toBe(''); - $response->assertRedirect(route('creator.stories.edit', ['story' => $story->id])); + $response->assertRedirect(route('studio.stories.edit', ['story' => $story->id])); }); it('creator autosave updates draft fields and creates tags from csv', function () { diff --git a/tests/Feature/Stories/StoryCoverCdnTest.php b/tests/Feature/Stories/StoryCoverCdnTest.php new file mode 100644 index 00000000..a80c9053 --- /dev/null +++ b/tests/Feature/Stories/StoryCoverCdnTest.php @@ -0,0 +1,36 @@ +set('cdn.files_url', 'https://cdn.skinbase.test'); + + $creator = User::factory()->create(); + $story = Story::query()->create([ + 'creator_id' => $creator->id, + 'title' => 'Cover Story', + 'slug' => 'cover-story-' . Str::lower(Str::random(6)), + 'content' => '

Cover story content

', + 'story_type' => 'creator_story', + 'status' => 'draft', + 'cover_image' => 'stories/md/a1/b2/a1b2c3d4e5f60123456789abcdef0123456789abcdef0123456789abcdef0123.webp', + 'og_image' => 'stories/md/a1/b2/a1b2c3d4e5f60123456789abcdef0123456789abcdef0123456789abcdef0123.webp', + ]); + + $response = $this->actingAs($creator)->get(route('creator.stories.edit', ['story' => $story->id])); + + $response->assertOk(); + + $html = $response->getContent(); + $this->assertNotFalse($html); + + expect($html)->toContain('https:\/\/cdn.skinbase.test\/stories\/md\/a1\/b2\/a1b2c3d4e5f60123456789abcdef0123456789abcdef0123456789abcdef0123.webp'); + expect($html)->not->toContain('https:\/\/skinbase.org\/stories\/md\/a1\/b2\/a1b2c3d4e5f60123456789abcdef0123456789abcdef0123456789abcdef0123.webp'); +}); \ No newline at end of file diff --git a/tests/Feature/Stories/StoryImageUploadTest.php b/tests/Feature/Stories/StoryImageUploadTest.php new file mode 100644 index 00000000..5ff4017c --- /dev/null +++ b/tests/Feature/Stories/StoryImageUploadTest.php @@ -0,0 +1,37 @@ +set('uploads.object_storage.disk', 's3'); + config()->set('cdn.files_url', 'https://cdn.skinbase.test'); + + $creator = User::factory()->create(); + + $response = $this->actingAs($creator)->postJson(route('api.story.upload-image'), [ + 'image' => UploadedFile::fake()->image('cover.png', 1600, 900), + ]); + + $response->assertOk(); + + $mediumUrl = (string) $response->json('medium_url'); + $thumbnailUrl = (string) $response->json('thumbnail_url'); + $originalUrl = (string) $response->json('original_url'); + + expect($mediumUrl)->toMatch('#^https://cdn\.skinbase\.test/stories/md/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{64}\.webp$#'); + expect($thumbnailUrl)->toMatch('#^https://cdn\.skinbase\.test/stories/sm/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{64}\.webp$#'); + expect($originalUrl)->toMatch('#^https://cdn\.skinbase\.test/stories/original/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{64}\.(jpg|jpeg|png|webp)$#'); + + Storage::disk('s3')->assertExists(ltrim(parse_url($mediumUrl, PHP_URL_PATH) ?: '', '/')); + Storage::disk('s3')->assertExists(ltrim(parse_url($thumbnailUrl, PHP_URL_PATH) ?: '', '/')); + Storage::disk('s3')->assertExists(ltrim(parse_url($originalUrl, PHP_URL_PATH) ?: '', '/')); +}); \ No newline at end of file