Now even prettier with the new Tailwind CSS plugin. Probably should have done this long ago...

This commit is contained in:
Scott Idem
2026-03-24 12:11:25 -04:00
parent 9a75243d9c
commit e9379be5a1
22 changed files with 615 additions and 615 deletions

View File

@@ -38,10 +38,10 @@ onMount(() => {
</svelte:head>
<div
class="ae_core h-full max-h-full max-w-6xl overflow-auto flex flex-col gap-1 m-auto p-4">
class="ae_core m-auto flex h-full max-h-full max-w-6xl flex-col gap-1 overflow-auto p-4">
{#if $ae_loc.manager_access}
<nav
class="flex flex-wrap gap-2 mb-6 border-b border-surface-500/30 pb-4">
class="border-surface-500/30 mb-6 flex flex-wrap gap-2 border-b pb-4">
<a href="/core" class="btn btn-sm preset-tonal-surface">
<LayoutDashboard size={14} class="mr-1" /> Dashboard
</a>
@@ -73,13 +73,13 @@ onMount(() => {
</a>
</nav>
<section class="main_content grow px-1 md:px-2 pb-28">
<section class="main_content grow px-1 pb-28 md:px-2">
{@render children?.()}
</section>
{:else}
<section
class="flex flex-col items-center justify-center grow text-center space-y-4 py-20">
<div class="p-6 bg-error-500/10 rounded-full">
class="flex grow flex-col items-center justify-center space-y-4 py-20 text-center">
<div class="bg-error-500/10 rounded-full p-6">
<Lock size={64} class="text-error-500" />
</div>
<h1 class="h1 font-black">Access Restricted</h1>

View File

@@ -25,11 +25,11 @@ $effect(() => {
});
</script>
<div class="container mx-auto p-4 space-y-8">
<div class="container mx-auto space-y-8 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-6 rounded-2xl shadow-xl border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-2xl border p-6 shadow-xl">
<div class="flex items-center gap-4">
<div class="p-3 bg-primary-500/10 rounded-xl">
<div class="bg-primary-500/10 rounded-xl p-3">
<LayoutDashboard size={32} class="text-primary-500" />
</div>
<div>
@@ -37,42 +37,42 @@ $effect(() => {
Æ Core Management
</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
System Infrastructure & Identity
</p>
</div>
</div>
<div
class="bg-black/5 p-3 rounded-xl border border-surface-500/10 min-w-50">
class="border-surface-500/10 min-w-50 rounded-xl border bg-black/5 p-3">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1 mb-1">
class="mb-1 flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Landmark size={10} /> Active Account
</p>
<p class="font-bold text-sm">
<p class="text-sm font-bold">
{$ae_loc.account_name ?? 'Loading...'}
</p>
</div>
</header>
<div
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
<!-- Account Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-primary shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between">
class="card preset-tonal-primary group flex flex-col justify-between space-y-4 p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-primary-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-primary-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<Building size={24} />
</div>
<h3 class="h4 font-black">Accounts</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Manage client accounts and high-level system settings.
</p>
</div>
<a
class="btn preset-filled-primary font-bold shadow-md w-full mt-4"
class="btn preset-filled-primary mt-4 w-full font-bold shadow-md"
href="/core/accounts">
Manage
</a>
@@ -80,22 +80,22 @@ $effect(() => {
<!-- Site Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-secondary shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between">
class="card preset-tonal-secondary group flex flex-col justify-between space-y-4 p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-secondary-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-secondary-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<Globe size={24} />
</div>
<h3 class="h4 font-black">Sites</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Configure sites and domains associated with the active
account.
</p>
</div>
<a
class="btn preset-filled-secondary font-bold shadow-md w-full mt-4"
class="btn preset-filled-secondary mt-4 w-full font-bold shadow-md"
href="/core/sites">
Manage
</a>
@@ -103,21 +103,21 @@ $effect(() => {
<!-- User Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-error shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between">
class="card preset-tonal-error group flex flex-col justify-between space-y-4 p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-error-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-error-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<ShieldCheck size={24} />
</div>
<h3 class="h4 font-black">Users</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Manage system access, permissions, and user credentials.
</p>
</div>
<a
class="btn preset-filled-error font-bold shadow-md w-full mt-4"
class="btn preset-filled-error mt-4 w-full font-bold shadow-md"
href="/core/users">
Manage
</a>
@@ -125,21 +125,21 @@ $effect(() => {
<!-- Person Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-warning shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between">
class="card preset-tonal-warning group flex flex-col justify-between space-y-4 p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-warning-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-warning-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<Users size={24} />
</div>
<h3 class="h4 font-black">People</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Search and manage person records and their user linking.
</p>
</div>
<a
class="btn preset-filled-warning font-bold shadow-md w-full mt-4"
class="btn preset-filled-warning mt-4 w-full font-bold shadow-md"
href="/core/people">
Manage
</a>
@@ -147,21 +147,21 @@ $effect(() => {
<!-- Address Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-surface shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between border border-surface-500/10">
class="card preset-tonal-surface group border-surface-500/10 flex flex-col justify-between space-y-4 border p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-surface-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-surface-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<MapPin size={24} />
</div>
<h3 class="h4 font-black">Addresses</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Manage physical locations, shipping, and billing addresses.
</p>
</div>
<a
class="btn preset-filled-surface font-bold shadow-md w-full mt-4"
class="btn preset-filled-surface mt-4 w-full font-bold shadow-md"
href="/core/addresses">
Manage
</a>
@@ -169,22 +169,22 @@ $effect(() => {
<!-- Contact Management Card -->
<div
class="card p-6 space-y-4 preset-tonal-surface shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between border border-surface-500/10">
class="card preset-tonal-surface group border-surface-500/10 flex flex-col justify-between space-y-4 border p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-surface-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-surface-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<Phone size={24} />
</div>
<h3 class="h4 font-black">Contacts</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Maintain support contacts, office numbers, and digital
links.
</p>
</div>
<a
class="btn preset-filled-surface font-bold shadow-md w-full mt-4"
class="btn preset-filled-surface mt-4 w-full font-bold shadow-md"
href="/core/contacts">
Manage
</a>
@@ -192,22 +192,22 @@ $effect(() => {
<!-- Activity Log Card -->
<div
class="card p-6 space-y-4 preset-tonal-success shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between">
class="card preset-tonal-success group flex flex-col justify-between space-y-4 p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-success-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-success-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<History size={24} />
</div>
<h3 class="h4 font-black">Activity Logs</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
Monitor system actions and historical changes for the
account.
</p>
</div>
<a
class="btn preset-filled-success font-bold shadow-md w-full mt-4"
class="btn preset-filled-success mt-4 w-full font-bold shadow-md"
href="/core/activity_logs">
View Logs
</a>
@@ -215,21 +215,21 @@ $effect(() => {
<!-- Lookups Card -->
<div
class="card p-6 space-y-4 preset-tonal-surface shadow-lg hover:brightness-110 transition-all group flex flex-col justify-between border border-surface-500/10">
class="card preset-tonal-surface group border-surface-500/10 flex flex-col justify-between space-y-4 border p-6 shadow-lg transition-all hover:brightness-110">
<div class="space-y-4">
<div class="flex items-center gap-3">
<div
class="p-2 bg-surface-500/20 rounded-lg group-hover:scale-110 transition-transform">
class="bg-surface-500/20 rounded-lg p-2 transition-transform group-hover:scale-110">
<List size={24} />
</div>
<h3 class="h4 font-black">Lookups</h3>
</div>
<p class="text-sm opacity-80 leading-relaxed">
<p class="text-sm leading-relaxed opacity-80">
View system lookup tables (countries, time zones, etc).
</p>
</div>
<a
class="btn preset-filled-surface font-bold shadow-md w-full mt-4"
class="btn preset-filled-surface mt-4 w-full font-bold shadow-md"
href="/core/lookups">
View
</a>

View File

@@ -71,17 +71,17 @@ async function handle_add_account() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Building size={24} class="text-primary-500" />
</div>
<div>
<h1 class="h2 font-black tracking-tight">Account Management</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Client Entities & Billing
</p>
</div>
@@ -94,44 +94,44 @@ async function handle_add_account() {
</header>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-4">
<div class="flex flex-wrap gap-6 items-end">
<div class="flex-1 min-w-[280px] space-y-1">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<div class="flex flex-wrap items-end gap-6">
<div class="min-w-[280px] flex-1 space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Accounts</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search by name or code..." />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={load_accounts}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Refresh</span>
{/if}
</button>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Status</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_enabled}
onchange={load_accounts}>
<option value="all">All Statuses</option>
@@ -142,10 +142,10 @@ async function handle_add_account() {
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Visibility</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_hidden}
onchange={load_accounts}>
<option value="all">All Visibility</option>
@@ -158,59 +158,59 @@ async function handle_add_account() {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if filtered_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<Building size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Accounts Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Try adjusting your filters or add a new client account.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Directory Results
<span class="badge preset-tonal-secondary ml-auto"
>{filtered_li.length} found</span>
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each filtered_li as acct (acct.account_id_random)}
<div
class="card p-5 space-y-4 preset-tonal-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
class="card preset-tonal-surface border-surface-500/10 hover:border-primary-500/30 group relative space-y-4 border p-5 shadow-md transition-all">
<div class="absolute top-4 right-4 flex gap-1">
{#if acct.hide}
<span
class="badge preset-filled-warning text-[8px] uppercase font-bold shadow-sm"
class="badge preset-filled-warning text-[8px] font-bold uppercase shadow-sm"
>Hidden</span>
{/if}
<span
class="badge {acct.enable
? 'preset-filled-success'
: 'preset-filled-error'} text-[8px] uppercase font-bold shadow-sm">
: 'preset-filled-error'} text-[8px] font-bold uppercase shadow-sm">
{acct.enable ? 'Active' : 'Disabled'}
</span>
</div>
<header class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-lg shadow-inner group-hover:scale-110 transition-transform">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-lg shadow-inner transition-transform group-hover:scale-110">
<Building size={24} />
</div>
<div class="pr-12">
<p class="font-black tracking-tight truncate">
<p class="truncate font-black tracking-tight">
{acct.name}
</p>
<p
class="text-[10px] uppercase font-bold opacity-50 font-mono tracking-tighter">
class="font-mono text-[10px] font-bold tracking-tighter uppercase opacity-50">
Code: {acct.code || '--'}
</p>
</div>
@@ -218,7 +218,7 @@ async function handle_add_account() {
<div class="space-y-2 text-xs opacity-70">
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Calendar
size={14}
class="text-primary-500 shrink-0" />
@@ -228,17 +228,17 @@ async function handle_add_account() {
).toLocaleDateString()}</span>
</div>
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<ShieldCheck
size={14}
class="text-secondary-500 shrink-0" />
<span class="font-mono truncate"
<span class="truncate font-mono"
>{acct.account_id_random}</span>
</div>
</div>
<a
class="btn btn-sm preset-filled-primary font-bold w-full shadow-lg group-hover:brightness-110 transition-all"
class="btn btn-sm preset-filled-primary w-full font-bold shadow-lg transition-all group-hover:brightness-110"
href="/core/accounts/{acct.account_id_random}">
Manage Account
</a>

View File

@@ -80,9 +80,9 @@ async function handle_delete() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-4">
<a
class="btn btn-sm preset-tonal-surface shadow-sm"
@@ -90,7 +90,7 @@ async function handle_delete() {
<ArrowLeft size={16} />
</a>
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Building size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">
@@ -110,7 +110,7 @@ async function handle_delete() {
onclick={handle_save}
disabled={loading || saving}>
{#if saving}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-2" />
{/if}
@@ -120,22 +120,22 @@ async function handle_delete() {
</header>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if account}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Info size={18} class="text-primary-500" /> Basic Information
</h3>
<div class="space-y-4">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Account Name</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -144,7 +144,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Short Name</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -153,16 +153,16 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Account Code</span>
<input
class="input preset-filled-surface rounded-lg font-mono p-3"
class="input preset-filled-surface rounded-lg p-3 font-mono"
type="text"
bind:value={account.code} />
</div>
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Description</span>
<textarea
class="textarea preset-filled-surface rounded-lg p-3"
@@ -173,47 +173,47 @@ async function handle_delete() {
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Settings size={18} class="text-secondary-500" /> Settings & Status
</h3>
<div class="flex flex-col gap-4 py-2">
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={account.enable} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Enabled</span>
</label>
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={account.hide} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Hidden</span>
</label>
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={account.priority} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Priority Account</span>
</label>
</div>
<div class="space-y-4 border-t border-surface-500/30 pt-4">
<div class="border-surface-500/30 space-y-4 border-t pt-4">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Group</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -222,7 +222,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Sort Order</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -233,9 +233,9 @@ async function handle_delete() {
</div>
<div
class="card p-6 space-y-4 md:col-span-2 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl md:col-span-2">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Activity size={18} class="text-tertiary-500" /> Internal Notes
</h3>
<div class="space-y-1">

View File

@@ -57,17 +57,17 @@ function handle_search(e: Event) {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<History size={24} class="text-primary-500" />
</div>
<div>
<h1 class="h2 font-black tracking-tight">Activity Logs</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Audit Trail & History
</p>
</div>
@@ -88,29 +88,29 @@ function handle_search(e: Event) {
<!-- Filter Bar -->
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-4">
<div class="flex flex-wrap gap-6 items-end">
<div class="flex-1 min-w-[280px] space-y-1">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<div class="flex flex-wrap items-end gap-6">
<div class="min-w-[280px] flex-1 space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Keywords</span>
<form
onsubmit={handle_search}
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Action, name, description..." />
<button
type="submit"
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
disabled={loading}>
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Search</span>
</button>
</form>
@@ -118,10 +118,10 @@ function handle_search(e: Event) {
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Display Limit</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={limit}
onchange={load_logs}>
<option value={25}>Latest 25</option>
@@ -134,24 +134,24 @@ function handle_search(e: Event) {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if log_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<Activity size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Logs Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Try broadening your search or check another account.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
System Events
<span class="badge preset-tonal-secondary ml-auto"
@@ -159,10 +159,10 @@ function handle_search(e: Event) {
</h3>
<div class="table-container">
<table class="table table-hover">
<table class="table-hover table">
<thead>
<tr
class="uppercase text-[10px] tracking-widest opacity-60">
class="text-[10px] tracking-widest uppercase opacity-60">
<th>Timestamp</th>
<th>Identity</th>
<th>Action</th>
@@ -172,7 +172,7 @@ function handle_search(e: Event) {
</thead>
<tbody>
{#each log_li as log, index (index)}
<tr class="transition-colors text-sm">
<tr class="text-sm transition-colors">
<!-- Date/Time -->
<td class="whitespace-nowrap">
<div class="flex items-center gap-2">
@@ -186,7 +186,7 @@ function handle_search(e: Event) {
'date_short'
)}</span>
<span
class="text-[10px] opacity-50 flex items-center gap-1">
class="flex items-center gap-1 text-[10px] opacity-50">
<Clock size={10} />
{ae_util.iso_datetime_formatter(
log.created_on,
@@ -201,26 +201,26 @@ function handle_search(e: Event) {
<td>
<div class="flex items-center gap-2">
<div
class="avatar preset-tonal-surface w-8 h-8 flex items-center justify-center rounded-full shadow-inner">
class="avatar preset-tonal-surface flex h-8 w-8 items-center justify-center rounded-full shadow-inner">
<User
size={14}
class="opacity-60" />
</div>
<div
class="flex flex-col max-w-[180px]">
class="flex max-w-[180px] flex-col">
{#if log.person_full_name || log.person_id_random}
<span class="font-bold truncate"
<span class="truncate font-bold"
>{log.person_full_name ||
'Person'}</span>
<span
class="text-[9px] opacity-40 font-mono uppercase"
class="font-mono text-[9px] uppercase opacity-40"
>ID: {log.person_id_random ||
'--'}</span>
{:else if log.name}
<span class="italic opacity-70"
>{log.name}</span>
{:else}
<span class="opacity-30 italic"
<span class="italic opacity-30"
>Unknown</span>
{/if}
</div>
@@ -231,12 +231,12 @@ function handle_search(e: Event) {
<td>
<div class="flex flex-col gap-1">
<span
class="badge preset-filled-surface text-[9px] font-black tracking-tighter uppercase px-2">
class="badge preset-filled-surface px-2 text-[9px] font-black tracking-tighter uppercase">
{log.action}
</span>
{#if log.action_with}
<span
class="text-[9px] opacity-40 font-bold uppercase ml-1 flex items-center gap-1">
class="ml-1 flex items-center gap-1 text-[9px] font-bold uppercase opacity-40">
<ShieldCheck size={8} /> via {log.action_with}
</span>
{/if}
@@ -247,46 +247,46 @@ function handle_search(e: Event) {
<td>
{#if log.object_type}
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg border border-surface-500/10">
class="border-surface-500/10 flex items-center gap-2 rounded-lg border bg-black/5 p-2">
<Tag
size={12}
class="text-secondary-500 shrink-0" />
<div
class="flex flex-col text-[10px] truncate">
class="flex flex-col truncate text-[10px]">
<span
class="font-bold uppercase tracking-tighter"
class="font-bold tracking-tighter uppercase"
>{log.object_type}</span>
{#if log.external_client_id}
<span
class="opacity-40 font-mono truncate"
class="truncate font-mono opacity-40"
>{log.external_client_id}</span>
{/if}
</div>
</div>
{:else}
<span class="opacity-20 italic text-xs"
<span class="text-xs italic opacity-20"
>--</span>
{/if}
</td>
<!-- Summary/Description -->
<td>
<div class="flex flex-col gap-1 max-w-sm">
<div class="flex max-w-sm flex-col gap-1">
{#if log.summary}
<span
class="font-bold text-primary-500 leading-tight"
class="text-primary-500 leading-tight font-bold"
>{log.summary}</span>
{/if}
{#if log.description}
<p
class="text-xs opacity-60 line-clamp-2 italic"
class="line-clamp-2 text-xs italic opacity-60"
title={log.description}>
{log.description}
</p>
{/if}
{#if !log.summary && !log.description}
<span
class="italic opacity-20 text-[10px]"
class="text-[10px] italic opacity-20"
>No detail record</span>
{/if}
</div>

View File

@@ -61,11 +61,11 @@ onMount(() => {
});
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<MapPin size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">Address Management</h1>
@@ -96,30 +96,30 @@ onMount(() => {
{/if}
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<div class="max-w-2xl space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Directory</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search by city, state, organization, or street..." />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={load_addresses}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Refresh</span>
{/if}
</button>
@@ -128,54 +128,54 @@ onMount(() => {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if filtered_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<MapPinned size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Addresses Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Addresses associated with this account will appear here.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Linked Addresses
<span class="badge preset-tonal-secondary ml-auto"
>{filtered_li.length} entries</span>
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each filtered_li as addr (addr.address_id_random)}
<div
class="card p-5 space-y-4 preset-tonal-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
class="card preset-tonal-surface border-surface-500/10 hover:border-primary-500/30 group relative space-y-4 border p-5 shadow-md transition-all">
<div class="absolute top-4 right-4">
<span
class="badge {addr.enable
? 'preset-filled-success'
: 'preset-filled-error'} text-[8px] uppercase font-bold shadow-sm">
: 'preset-filled-error'} text-[8px] font-bold uppercase shadow-sm">
{addr.enable ? 'Active' : 'Disabled'}
</span>
</div>
<div class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-10 h-10 flex items-center justify-center rounded-lg shadow-inner group-hover:scale-110 transition-transform">
class="avatar preset-filled-primary flex h-10 w-10 items-center justify-center rounded-lg shadow-inner transition-transform group-hover:scale-110">
<MapPin size={20} />
</div>
<div class="pr-12">
<p class="font-black tracking-tight truncate">
<p class="truncate font-black tracking-tight">
{addr.city || '--'}
</p>
<p
class="text-[10px] uppercase font-bold opacity-50 truncate">
class="truncate text-[10px] font-bold uppercase opacity-50">
{addr.state_province || '--'}
</p>
</div>
@@ -184,7 +184,7 @@ onMount(() => {
<div class="space-y-2 text-xs opacity-70">
{#if addr.organization_name}
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Building2
size={14}
class="text-primary-500 shrink-0" />
@@ -193,7 +193,7 @@ onMount(() => {
</div>
{/if}
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Globe
size={14}
class="text-secondary-500 shrink-0" />
@@ -205,7 +205,7 @@ onMount(() => {
</div>
<a
class="btn btn-sm preset-filled-primary font-bold w-full shadow-lg group-hover:brightness-110 transition-all"
class="btn btn-sm preset-filled-primary w-full font-bold shadow-lg transition-all group-hover:brightness-110"
href="/core/addresses/{addr.address_id_random}">
View Details
</a>

View File

@@ -62,9 +62,9 @@ async function handle_delete() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-4">
<a
class="btn btn-sm preset-tonal-surface shadow-sm"
@@ -72,7 +72,7 @@ async function handle_delete() {
<ArrowLeft size={16} />
</a>
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<MapPin size={24} class="text-primary-500" />
</div>
<div>
@@ -82,7 +82,7 @@ async function handle_delete() {
: 'Loading...'}
</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Address Detail
</p>
</div>
@@ -109,8 +109,8 @@ async function handle_delete() {
</header>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if address}
@@ -125,19 +125,19 @@ async function handle_delete() {
onCancel={() => (is_editing = false)} />
</div>
{:else}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 animate-fade-in">
<div class="lg:col-span-2 space-y-6">
<div class="animate-fade-in grid grid-cols-1 gap-6 lg:grid-cols-3">
<div class="space-y-6 lg:col-span-2">
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<MapPinned size={20} class="text-primary-500" />
Location Information
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<User size={10} /> Attention To
</p>
<p class="font-bold">
@@ -146,7 +146,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Building2 size={10} /> Organization
</p>
<p class="font-bold">
@@ -154,29 +154,29 @@ async function handle_delete() {
</p>
</div>
<div
class="md:col-span-2 space-y-1 bg-black/5 p-4 rounded-xl border border-surface-500/10">
class="border-surface-500/10 space-y-1 rounded-xl border bg-black/5 p-4 md:col-span-2">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest">
class="text-[10px] font-black tracking-widest uppercase opacity-60">
Street Address
</p>
<div class="space-y-1 mt-1">
<div class="mt-1 space-y-1">
<p
class="text-lg font-black tracking-tight leading-tight">
class="text-lg leading-tight font-black tracking-tight">
{address.line_1}
</p>
{#if address.line_2}<p
class="text-lg font-black tracking-tight leading-tight opacity-75">
class="text-lg leading-tight font-black tracking-tight opacity-75">
{address.line_2}
</p>{/if}
{#if address.line_3}<p
class="text-lg font-black tracking-tight leading-tight opacity-50">
class="text-lg leading-tight font-black tracking-tight opacity-50">
{address.line_3}
</p>{/if}
</div>
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<MapPin size={10} /> City, State/Province
</p>
<p class="font-bold">
@@ -186,7 +186,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Globe size={10} /> Postal Code / Country
</p>
<p class="font-bold">
@@ -201,16 +201,16 @@ async function handle_delete() {
</div>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Activity size={20} class="text-secondary-500" />
Technical Details
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Clock size={10} /> Timezone
</p>
<p class="font-mono">
@@ -219,7 +219,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<MapPin size={10} /> Coordinates
</p>
<p class="font-mono">
@@ -227,13 +227,13 @@ async function handle_delete() {
'--'}
</p>
</div>
<div class="md:col-span-2 space-y-2">
<div class="space-y-2 md:col-span-2">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Info size={10} /> Internal Notes
</p>
<div
class="p-4 bg-black/5 rounded-xl border border-dashed border-surface-500/20 italic opacity-80 min-h-[80px]">
class="border-surface-500/20 min-h-[80px] rounded-xl border border-dashed bg-black/5 p-4 italic opacity-80">
{address.notes ||
'No internal notes provided for this address.'}
</div>
@@ -244,15 +244,15 @@ async function handle_delete() {
<div class="space-y-6">
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<ShieldCheck size={20} class="text-warning-500" />
Visibility & Status
</h3>
<div class="space-y-4">
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Enabled</span>
<span
@@ -263,7 +263,7 @@ async function handle_delete() {
</span>
</div>
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Hidden</span>
<span
@@ -274,7 +274,7 @@ async function handle_delete() {
</span>
</div>
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Priority</span>
<span
@@ -288,12 +288,12 @@ async function handle_delete() {
</div>
<div
class="card p-5 preset-tonal-surface shadow-inner border border-surface-500/10 space-y-3">
class="card preset-tonal-surface border-surface-500/10 space-y-3 border p-5 shadow-inner">
<p
class="text-[10px] uppercase font-black opacity-40 tracking-widest border-b border-surface-500/20 pb-1">
class="border-surface-500/20 border-b pb-1 text-[10px] font-black tracking-widest uppercase opacity-40">
System Audit
</p>
<div class="space-y-2 text-[10px] font-mono opacity-60">
<div class="space-y-2 font-mono text-[10px] opacity-60">
<p class="flex justify-between">
<span>ID:</span>
<span class="text-primary-500 font-bold"

View File

@@ -115,9 +115,9 @@ async function handleSubmit(event: Event) {
<form
onsubmit={handleSubmit}
class="card p-6 space-y-6 shadow-xl preset-tonal-surface">
class="card preset-tonal-surface space-y-6 p-6 shadow-xl">
<header
class="flex justify-between items-center border-b border-surface-500/30 pb-4">
class="border-surface-500/30 flex items-center justify-between border-b pb-4">
<h3 class="h3 flex items-center gap-2">
<MapPin size={24} />
{address ? 'Edit Address' : 'Create New Address'}
@@ -136,7 +136,7 @@ async function handleSubmit(event: Event) {
class="btn btn-sm preset-filled-primary font-bold shadow-lg"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-1" />
{/if}
@@ -153,11 +153,11 @@ async function handleSubmit(event: Event) {
</aside>
{/if}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<!-- Location Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Location Details</legend>
<div class="space-y-1">
@@ -165,7 +165,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-attention-to">Attention To / Name</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-attention-to"
type="text"
bind:value={formData.attention_to}
@@ -177,7 +177,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-org-name">Organization Name</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-org-name"
type="text"
bind:value={formData.organization_name}
@@ -189,7 +189,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-line-1">Address Line 1</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-line-1"
type="text"
bind:value={formData.line_1}
@@ -203,7 +203,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-line-2">Line 2</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-line-2"
type="text"
bind:value={formData.line_2}
@@ -214,7 +214,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-line-3">Line 3</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-line-3"
type="text"
bind:value={formData.line_3}
@@ -226,7 +226,7 @@ async function handleSubmit(event: Event) {
<!-- Region Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Region & Code</legend>
<div class="grid grid-cols-2 gap-2">
@@ -235,7 +235,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-city">City</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-city"
type="text"
bind:value={formData.city}
@@ -247,7 +247,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-state">State / Province</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-state"
type="text"
bind:value={formData.state_province}
@@ -261,7 +261,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-postal">Postal Code</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-postal"
type="text"
bind:value={formData.postal_code}
@@ -272,10 +272,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-country">Country (Code)</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Globe size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="addr-country"
type="text"
bind:value={formData.country}
@@ -288,7 +288,7 @@ async function handleSubmit(event: Event) {
<!-- Technical Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Technical & GIS</legend>
<div class="space-y-1">
@@ -296,10 +296,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-timezone">Timezone</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Clock size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="addr-timezone"
type="text"
bind:value={formData.timezone}
@@ -313,12 +313,12 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-latitude">Latitude</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim">
<Navigation size={16} />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="addr-latitude"
type="text"
bind:value={formData.latitude}
@@ -330,12 +330,12 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-longitude">Longitude</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim">
<Navigation size={16} />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="addr-longitude"
type="text"
bind:value={formData.longitude}
@@ -348,25 +348,25 @@ async function handleSubmit(event: Event) {
<!-- Status Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Status</legend>
<div class="flex flex-wrap gap-4 pt-2">
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.enable} />
<span class="text-sm font-medium">Enabled</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.hide} />
<span class="text-sm font-medium">Hidden</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
@@ -380,7 +380,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="addr-notes">Internal Notes</label>
<textarea
class="textarea preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="textarea preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="addr-notes"
rows="2"
bind:value={formData.notes}
@@ -389,13 +389,13 @@ async function handleSubmit(event: Event) {
</fieldset>
</div>
<footer class="flex justify-end gap-2 border-t border-surface-500/30 pt-4">
<footer class="border-surface-500/30 flex justify-end gap-2 border-t pt-4">
<button
type="submit"
class="btn preset-filled-primary font-bold shadow-lg w-full md:w-auto"
class="btn preset-filled-primary w-full font-bold shadow-lg md:w-auto"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{/if}
{address ? 'Update Address Record' : 'Create Address Record'}
</button>

View File

@@ -61,7 +61,7 @@ let lq_kv__person_obj_li = $derived(
{#if $lq_kv__person_obj_li.length}
<span
class="text-3xl font-bold bg-success-100 px-4 border rounded-lg border-success-200"
class="bg-success-100 border-success-200 rounded-lg border px-4 text-3xl font-bold"
title="Count {$lq_kv__person_obj_li.length ?? 'None'}">
<ListOrdered size="1em" class="mx-4" />
{$lq_kv__person_obj_li.length ?? 'None'}
@@ -70,7 +70,7 @@ let lq_kv__person_obj_li = $derived(
</h2>
<table
class="table table-auto table-striped w-full text-xs lg:text-sm">
class="table-striped table w-full table-auto text-xs lg:text-sm">
<thead>
<tr>
<th class="px-4 py-2"
@@ -124,7 +124,7 @@ let lq_kv__person_obj_li = $derived(
{#if person_obj?.user_id_random}
<div class="flex flex-col gap-1">
<span
class="font-bold flex items-center gap-1">
class="flex items-center gap-1 font-bold">
<UserCheck
size="1em"
class="text-success-500" />
@@ -136,7 +136,7 @@ let lq_kv__person_obj_li = $derived(
</a>
</span>
<span
class="text-[10px] opacity-50 font-mono"
class="font-mono text-[10px] opacity-50"
>{person_obj.user_id_random}</span>
</div>
{:else}

View File

@@ -59,11 +59,11 @@ onMount(() => {
});
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Phone size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">Contact Management</h1>
@@ -94,30 +94,30 @@ onMount(() => {
{/if}
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<div class="max-w-2xl space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Directory</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search by name, title, email, or phone..." />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={load_contacts}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Refresh</span>
{/if}
</button>
@@ -126,54 +126,54 @@ onMount(() => {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if filtered_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<Contact size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Contacts Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Business and support contacts will appear here.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Directory Results
<span class="badge preset-tonal-secondary ml-auto"
>{filtered_li.length} entries</span>
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each filtered_li as con (con.contact_id_random)}
<div
class="card p-5 space-y-4 preset-tonal-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
class="card preset-tonal-surface border-surface-500/10 hover:border-primary-500/30 group relative space-y-4 border p-5 shadow-md transition-all">
<div class="absolute top-4 right-4">
<span
class="badge {con.enable
? 'preset-filled-success'
: 'preset-filled-error'} text-[8px] uppercase font-bold shadow-sm">
: 'preset-filled-error'} text-[8px] font-bold uppercase shadow-sm">
{con.enable ? 'Active' : 'Disabled'}
</span>
</div>
<header class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-full shadow-inner group-hover:scale-110 transition-transform">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-full shadow-inner transition-transform group-hover:scale-110">
<User size={24} />
</div>
<div class="pr-12">
<p class="font-black tracking-tight truncate">
<p class="truncate font-black tracking-tight">
{con.name || con.title || '--'}
</p>
<p
class="text-[10px] uppercase font-bold opacity-50 truncate">
class="truncate text-[10px] font-bold uppercase opacity-50">
{con.title || 'Support Contact'}
</p>
</div>
@@ -181,7 +181,7 @@ onMount(() => {
<div class="space-y-2 text-xs opacity-70">
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Mail
size={14}
class="text-primary-500 shrink-0" />
@@ -189,7 +189,7 @@ onMount(() => {
>{con.email || 'No Email'}</span>
</div>
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Phone
size={14}
class="text-secondary-500 shrink-0" />
@@ -201,7 +201,7 @@ onMount(() => {
</div>
<a
class="btn btn-sm preset-filled-primary font-bold w-full shadow-lg group-hover:brightness-110 transition-all"
class="btn btn-sm preset-filled-primary w-full font-bold shadow-lg transition-all group-hover:brightness-110"
href="/core/contacts/{con.contact_id_random}">
Manage Contact
</a>

View File

@@ -63,9 +63,9 @@ async function handle_delete() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-4">
<a
class="btn btn-sm preset-tonal-surface shadow-sm"
@@ -73,7 +73,7 @@ async function handle_delete() {
<ArrowLeft size={16} />
</a>
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<UserRound size={24} class="text-primary-500" />
</div>
<div>
@@ -81,7 +81,7 @@ async function handle_delete() {
{contact?.name || contact?.title || 'Loading...'}
</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Contact Detail
</p>
</div>
@@ -108,8 +108,8 @@ async function handle_delete() {
</header>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if contact}
@@ -124,29 +124,29 @@ async function handle_delete() {
onCancel={() => (is_editing = false)} />
</div>
{:else}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 animate-fade-in">
<div class="lg:col-span-2 space-y-6">
<div class="animate-fade-in grid grid-cols-1 gap-6 lg:grid-cols-3">
<div class="space-y-6 lg:col-span-2">
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Contact size={20} class="text-primary-500" />
Core Information
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<UserRound size={10} /> Full Name / Title
</p>
<p
class="text-lg font-black tracking-tight leading-tight">
class="text-lg leading-tight font-black tracking-tight">
{contact.name || contact.title || '--'}
</p>
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Activity size={10} /> Tagline / Role
</p>
<p class="font-bold">
@@ -154,19 +154,19 @@ async function handle_delete() {
</p>
</div>
<div
class="space-y-1 bg-black/5 p-4 rounded-xl border border-surface-500/10">
class="border-surface-500/10 space-y-1 rounded-xl border bg-black/5 p-4">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Mail size={10} /> Email Address
</p>
<p class="font-bold text-primary-500 break-all">
<p class="text-primary-500 font-bold break-all">
{contact.email || '--'}
</p>
</div>
<div
class="space-y-1 bg-black/5 p-4 rounded-xl border border-surface-500/10">
class="border-surface-500/10 space-y-1 rounded-xl border bg-black/5 p-4">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Globe size={10} /> Website
</p>
{#if contact.website_url}
@@ -174,7 +174,7 @@ async function handle_delete() {
href={contact.website_url}
target="_blank"
rel="noopener noreferrer"
class="font-bold text-secondary-500 hover:underline flex items-center gap-2 truncate">
class="text-secondary-500 flex items-center gap-2 truncate font-bold hover:underline">
{contact.website_url}
<Link2 size={12} />
</a>
@@ -186,16 +186,16 @@ async function handle_delete() {
</div>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Phone size={20} class="text-secondary-500" />
Communication & Social
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Phone size={10} /> Mobile Phone
</p>
<p class="font-mono font-bold">
@@ -206,7 +206,7 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Phone size={10} /> Office Phone
</p>
<p class="font-mono font-bold">
@@ -215,20 +215,20 @@ async function handle_delete() {
</div>
<div class="space-y-1">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Linkedin size={10} /> LinkedIn
</p>
<p class="font-bold truncate">
<p class="truncate font-bold">
{contact.linkedin_url || '--'}
</p>
</div>
<div class="md:col-span-2 space-y-2">
<div class="space-y-2 md:col-span-2">
<p
class="text-[10px] opacity-60 uppercase font-black tracking-widest flex items-center gap-1">
class="flex items-center gap-1 text-[10px] font-black tracking-widest uppercase opacity-60">
<Info size={10} /> Internal Notes
</p>
<div
class="p-4 bg-black/5 rounded-xl border border-dashed border-surface-500/20 italic opacity-80 min-h-[80px]">
class="border-surface-500/20 min-h-[80px] rounded-xl border border-dashed bg-black/5 p-4 italic opacity-80">
{contact.notes ||
'No internal notes provided for this contact.'}
</div>
@@ -239,15 +239,15 @@ async function handle_delete() {
<div class="space-y-6">
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<ShieldCheck size={20} class="text-warning-500" />
Status & Flags
</h3>
<div class="space-y-4">
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Enabled</span>
<span
@@ -258,7 +258,7 @@ async function handle_delete() {
</span>
</div>
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Hidden</span>
<span
@@ -269,7 +269,7 @@ async function handle_delete() {
</span>
</div>
<div
class="flex justify-between items-center p-3 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-3">
<span class="text-sm font-bold opacity-75"
>Priority</span>
<span
@@ -283,12 +283,12 @@ async function handle_delete() {
</div>
<div
class="card p-5 preset-tonal-surface shadow-inner border border-surface-500/10 space-y-3">
class="card preset-tonal-surface border-surface-500/10 space-y-3 border p-5 shadow-inner">
<p
class="text-[10px] uppercase font-black opacity-40 tracking-widest border-b border-surface-500/20 pb-1">
class="border-surface-500/20 border-b pb-1 text-[10px] font-black tracking-widest uppercase opacity-40">
System Audit
</p>
<div class="space-y-2 text-[10px] font-mono opacity-60">
<div class="space-y-2 font-mono text-[10px] opacity-60">
<p class="flex justify-between">
<span>ID:</span>
<span class="text-primary-500 font-bold"

View File

@@ -119,9 +119,9 @@ async function handleSubmit(event: Event) {
<form
onsubmit={handleSubmit}
class="card p-6 space-y-6 shadow-xl preset-tonal-surface">
class="card preset-tonal-surface space-y-6 p-6 shadow-xl">
<header
class="flex justify-between items-center border-b border-surface-500/30 pb-4">
class="border-surface-500/30 flex items-center justify-between border-b pb-4">
<h3 class="h3 flex items-center gap-2">
<UserPlus size={24} />
{contact ? 'Edit Contact' : 'Create New Contact'}
@@ -140,7 +140,7 @@ async function handleSubmit(event: Event) {
class="btn btn-sm preset-filled-primary font-bold shadow-lg"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-1" />
{/if}
@@ -157,11 +157,11 @@ async function handleSubmit(event: Event) {
</aside>
{/if}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<!-- Identity Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Identity & Branding</legend>
<div class="space-y-1">
@@ -169,7 +169,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-title">Title / Name</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="contact-title"
type="text"
bind:value={formData.title}
@@ -182,7 +182,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-tagline">Tagline</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="contact-tagline"
type="text"
bind:value={formData.tagline}
@@ -194,10 +194,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-email">Email Address</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Mail size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-email"
type="email"
bind:value={formData.email}
@@ -209,7 +209,7 @@ async function handleSubmit(event: Event) {
<!-- Communication Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Phone & Web</legend>
<div class="grid grid-cols-2 gap-2">
@@ -218,10 +218,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-phone-mobile">Mobile Phone</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Phone size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-phone-mobile"
type="tel"
bind:value={formData.phone_mobile}
@@ -233,10 +233,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-phone-office">Office Phone</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Phone size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-phone-office"
type="tel"
bind:value={formData.phone_office}
@@ -250,10 +250,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-website">Website URL</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Globe size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-website"
type="url"
bind:value={formData.website_url}
@@ -265,7 +265,7 @@ async function handleSubmit(event: Event) {
<!-- Social Media Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Social Media</legend>
<div class="space-y-1">
@@ -273,10 +273,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-linkedin">LinkedIn URL</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Linkedin size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-linkedin"
type="url"
bind:value={formData.linkedin_url}
@@ -290,12 +290,12 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-facebook">Facebook URL</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim">
<Facebook size={16} />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-facebook"
type="url"
bind:value={formData.facebook_url}
@@ -307,12 +307,12 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-instagram">Instagram URL</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim">
<Instagram size={16} />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="contact-instagram"
type="url"
bind:value={formData.instagram_url}
@@ -325,25 +325,25 @@ async function handleSubmit(event: Event) {
<!-- Status Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Status</legend>
<div class="flex flex-wrap gap-4 pt-2">
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.enable} />
<span class="text-sm font-medium">Enabled</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.hide} />
<span class="text-sm font-medium">Hidden</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
@@ -357,7 +357,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="contact-notes">Internal Notes</label>
<textarea
class="textarea preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="textarea preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="contact-notes"
rows="2"
bind:value={formData.notes}
@@ -366,13 +366,13 @@ async function handleSubmit(event: Event) {
</fieldset>
</div>
<footer class="flex justify-end gap-2 border-t border-surface-500/30 pt-4">
<footer class="border-surface-500/30 flex justify-end gap-2 border-t pt-4">
<button
type="submit"
class="btn preset-filled-primary font-bold shadow-lg w-full md:w-auto"
class="btn preset-filled-primary w-full font-bold shadow-lg md:w-auto"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{/if}
{contact ? 'Update Contact Record' : 'Create Contact Record'}
</button>

View File

@@ -74,17 +74,17 @@ function toggle_tz_priority() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<List size={24} class="text-primary-500" />
</div>
<div>
<h1 class="h2 font-black tracking-tight">System Lookups</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Global Reference Data
</p>
</div>
@@ -104,30 +104,30 @@ function toggle_tz_priority() {
</header>
{#if loading && !lookups.countries.length}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else}
<div class="space-y-6 animate-fade-in">
<div class="animate-fade-in space-y-6">
<!-- 1. Countries -->
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Globe size={20} class="text-secondary-500" />
Country Reference
<span
class="badge preset-tonal-secondary ml-auto text-[10px] uppercase font-bold"
class="badge preset-tonal-secondary ml-auto text-[10px] font-bold uppercase"
>{lookups.countries.length} Records</span>
</h3>
<div
class="table-container max-h-[400px] overflow-auto border border-surface-500/10 rounded-lg">
<table class="table table-hover table-compact">
class="table-container border-surface-500/10 max-h-[400px] overflow-auto rounded-lg border">
<table class="table-hover table-compact table">
<thead>
<tr
class="uppercase text-[10px] tracking-widest opacity-60">
class="text-[10px] tracking-widest uppercase opacity-60">
<th>Name</th>
<th class="text-center">ISO Alpha-2</th>
</tr>
@@ -139,7 +139,7 @@ function toggle_tz_priority() {
>{c.name || c.english_short_name}</td>
<td class="text-center"
><span
class="badge preset-tonal-surface font-mono text-primary-500"
class="badge preset-tonal-surface text-primary-500 font-mono"
>{c.alpha_2_code}</span
></td>
</tr>
@@ -151,22 +151,22 @@ function toggle_tz_priority() {
<!-- 2. Subdivisions -->
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<MapPin size={20} class="text-primary-500" />
Country Subdivisions (States/Provinces)
<span
class="badge preset-tonal-secondary ml-auto text-[10px] uppercase font-bold"
class="badge preset-tonal-secondary ml-auto text-[10px] font-bold uppercase"
>{lookups.subdivisions.length} Records</span>
</h3>
<div
class="table-container max-h-[500px] overflow-auto border border-surface-500/10 rounded-lg">
<table class="table table-hover table-compact">
class="table-container border-surface-500/10 max-h-[500px] overflow-auto rounded-lg border">
<table class="table-hover table-compact table">
<thead>
<tr
class="uppercase text-[10px] tracking-widest opacity-60">
class="text-[10px] tracking-widest uppercase opacity-60">
<th>Country</th>
<th>Name</th>
<th class="text-center">Code</th>
@@ -192,14 +192,14 @@ function toggle_tz_priority() {
<!-- 3. Time Zones -->
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-6">
class="card preset-tonal-surface border-surface-500/10 space-y-6 border p-6 shadow-xl">
<div
class="flex flex-wrap justify-between items-center border-b border-surface-500/30 pb-2 gap-4">
<h3 class="h4 font-bold flex items-center gap-2">
class="border-surface-500/30 flex flex-wrap items-center justify-between gap-4 border-b pb-2">
<h3 class="h4 flex items-center gap-2 font-bold">
<Clock size={20} class="text-tertiary-500" />
Time Zone Reference
<span
class="badge preset-tonal-secondary text-[10px] uppercase font-bold"
class="badge preset-tonal-secondary text-[10px] font-bold uppercase"
>{lookups.time_zones.length} Zones</span>
</h3>
<button
@@ -220,11 +220,11 @@ function toggle_tz_priority() {
</div>
<div
class="table-container max-h-[500px] overflow-auto border border-surface-500/10 rounded-lg">
<table class="table table-hover table-compact">
class="table-container border-surface-500/10 max-h-[500px] overflow-auto rounded-lg border">
<table class="table-hover table-compact table">
<thead>
<tr
class="uppercase text-[10px] tracking-widest opacity-60">
class="text-[10px] tracking-widest uppercase opacity-60">
<th>Zone Name</th>
<th class="text-right">Offset (Hours)</th>
</tr>
@@ -247,7 +247,7 @@ function toggle_tz_priority() {
</div>
<div
class="card p-4 preset-tonal-surface border border-surface-500/10 flex items-center gap-3">
class="card preset-tonal-surface border-surface-500/10 flex items-center gap-3 border p-4">
<Info size={16} class="text-primary-500" />
<p class="text-xs opacity-70">
Lookup data is synchronized with the global system database and

View File

@@ -19,11 +19,11 @@ onMount(() => {
});
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Users size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">People Management</h1>
@@ -60,9 +60,9 @@ onMount(() => {
{#if $ae_sess.person.show_report__person_li}
<div
class="card p-6 preset-tonal-surface shadow-xl space-y-4 border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Search Results
<span class="badge preset-tonal-secondary ml-auto"

View File

@@ -186,7 +186,7 @@ $ae_loc.person.show_content__person_page_help = false;
</svelte:head>
<section
class="ae_core__person md:container h-full mx-auto flex flex-col space-y-4 pt-0 pb-8">
class="ae_core__person mx-auto flex h-full flex-col space-y-4 pt-0 pb-8 md:container">
<div
class="core__person_view_menu {ae_snip.classes__core_menu}"
class:border-gray-100={!$ae_loc.person.show_content__person_page_help}>
@@ -245,7 +245,7 @@ $ae_loc.person.show_content__person_page_help = false;
$ae_loc.person.show_content__person_page_help =
!$ae_loc.person.show_content__person_page_help;
}}
class="btn btn-sm mx-1 preset-tonal-error border border-error-500 hover:preset-filled-error-500"
class="btn btn-sm preset-tonal-error border-error-500 hover:preset-filled-error-500 mx-1 border"
class:hidden={!$ae_loc.person.show_content__person_page_help}
title="Help and information about the session search">
<HelpCircle size="1em" class="mx-1" />
@@ -260,9 +260,9 @@ $ae_loc.person.show_content__person_page_help = false;
</div>
{#if $ae_loc.manager_access}
<div class="card p-4 preset-tonal-surface space-y-4 mx-4">
<div class="card preset-tonal-surface mx-4 space-y-4 p-4">
<header
class="flex justify-between items-center border-b border-surface-500/30 pb-2">
class="border-surface-500/30 flex items-center justify-between border-b pb-2">
<div class="flex items-center gap-2 font-bold">
<ShieldCheck size={18} />
<span>User Account Linking</span>
@@ -289,12 +289,12 @@ $ae_loc.person.show_content__person_page_help = false;
{#if $lq__person_obj?.user_id}
<div class="flex items-center gap-4 py-2">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-full">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-full">
<Users size={24} />
</div>
<div>
<p
class="text-sm opacity-60 uppercase tracking-widest font-bold">
class="text-sm font-bold tracking-widest uppercase opacity-60">
Linked User ID
</p>
<p class="font-mono text-lg">
@@ -312,29 +312,29 @@ $ae_loc.person.show_content__person_page_help = false;
accounts without a linked person are shown.
</p>
{#if loading_users}
<div class="placeholder animate-pulse h-20 w-full">
<div class="placeholder h-20 w-full animate-pulse">
</div>
{:else if available_users.length === 0}
<p
class="text-center py-4 italic opacity-60 border border-dashed border-surface-500/30">
class="border-surface-500/30 border border-dashed py-4 text-center italic opacity-60">
No unlinked user accounts found.
</p>
{:else}
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
{#each available_users as user (user.user_id)}
<button
class="card p-3 preset-tonal-primary hover:preset-filled-primary text-left transition-all flex flex-col gap-1"
class="card preset-tonal-primary hover:preset-filled-primary flex flex-col gap-1 p-3 text-left transition-all"
onclick={() =>
handle_link_user(user.user_id)}>
<span
class="font-bold flex items-center gap-2">
class="flex items-center gap-2 font-bold">
<User size={14} />
{user.username}
</span>
<span class="text-xs opacity-70 truncate"
<span class="truncate text-xs opacity-70"
>{user.email}</span>
<div class="flex gap-1 mt-1">
<div class="mt-1 flex gap-1">
{#if user.super}<span
class="badge preset-filled-error text-[10px]"
>Super</span
@@ -352,7 +352,7 @@ $ae_loc.person.show_content__person_page_help = false;
{:else}
<div class="flex items-center gap-2 py-2 opacity-60">
<Users size={20} />
<p class="italic text-sm">
<p class="text-sm italic">
This person is not currently linked to a user account.
</p>
</div>
@@ -360,22 +360,22 @@ $ae_loc.person.show_content__person_page_help = false;
</div>
<!-- Activity & Content Section -->
<div class="card p-4 preset-tonal-surface space-y-4 mx-4">
<div class="card preset-tonal-surface mx-4 space-y-4 p-4">
<header
class="flex items-center gap-2 font-bold border-b border-surface-500/30 pb-2">
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<History size={18} />
<span>Linked Activity & Content</span>
</header>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
<!-- Related Events -->
<div class="space-y-3">
<h4
class="h4 flex items-center gap-2 text-sm opacity-70 uppercase tracking-wider font-bold">
class="h4 flex items-center gap-2 text-sm font-bold tracking-wider uppercase opacity-70">
<Calendar size={16} /> Related Events
</h4>
{#if loading_activity}
<div class="placeholder animate-pulse h-20 w-full">
<div class="placeholder h-20 w-full animate-pulse">
</div>
{:else if related_events.length === 0}
<p class="text-sm italic opacity-50">
@@ -386,8 +386,8 @@ $ae_loc.person.show_content__person_page_help = false;
{#each related_events as ev (ev.event_id)}
<a
href="/events/{ev.event_id}"
class="card p-3 preset-tonal-surface flex flex-col gap-1 hover:preset-tonal-primary transition-all">
<span class="font-bold text-sm"
class="card preset-tonal-surface hover:preset-tonal-primary flex flex-col gap-1 p-3 transition-all">
<span class="text-sm font-bold"
>{ev.name}</span>
<span class="text-[10px] opacity-60"
>{new Date(
@@ -402,11 +402,11 @@ $ae_loc.person.show_content__person_page_help = false;
<!-- Related Posts -->
<div class="space-y-3">
<h4
class="h4 flex items-center gap-2 text-sm opacity-70 uppercase tracking-wider font-bold">
class="h4 flex items-center gap-2 text-sm font-bold tracking-wider uppercase opacity-70">
<MessageSquare size={16} /> Related Posts
</h4>
{#if loading_activity}
<div class="placeholder animate-pulse h-20 w-full">
<div class="placeholder h-20 w-full animate-pulse">
</div>
{:else if related_posts.length === 0}
<p class="text-sm italic opacity-50">
@@ -417,11 +417,11 @@ $ae_loc.person.show_content__person_page_help = false;
{#each related_posts as post (post.post_id)}
<a
href="/idaa/bb/{post.post_id}"
class="card p-3 preset-tonal-surface flex flex-col gap-1 hover:preset-tonal-primary transition-all">
<span class="font-bold text-sm"
class="card preset-tonal-surface hover:preset-tonal-primary flex flex-col gap-1 p-3 transition-all">
<span class="text-sm font-bold"
>{post.title}</span>
<div
class="flex justify-between items-center text-[10px] opacity-60">
class="flex items-center justify-between text-[10px] opacity-60">
<span
>{new Date(
post.created_on
@@ -439,11 +439,11 @@ $ae_loc.person.show_content__person_page_help = false;
<!-- Recent Activity -->
<div class="space-y-3">
<h4
class="h4 flex items-center gap-2 text-sm opacity-70 uppercase tracking-wider font-bold">
class="h4 flex items-center gap-2 text-sm font-bold tracking-wider uppercase opacity-70">
<Activity size={16} /> Recent Activity
</h4>
{#if loading_activity}
<div class="placeholder animate-pulse h-20 w-full">
<div class="placeholder h-20 w-full animate-pulse">
</div>
{:else if related_activity_logs.length === 0}
<p class="text-sm italic opacity-50">
@@ -453,11 +453,11 @@ $ae_loc.person.show_content__person_page_help = false;
<div class="space-y-2">
{#each related_activity_logs as log, index (index)}
<div
class="card p-3 preset-tonal-surface flex flex-col gap-1">
class="card preset-tonal-surface flex flex-col gap-1 p-3">
<div
class="flex justify-between items-start gap-2">
class="flex items-start justify-between gap-2">
<span
class="badge preset-filled-surface text-[9px] uppercase tracking-tighter"
class="badge preset-filled-surface text-[9px] tracking-tighter uppercase"
>{log.action}</span>
<span class="text-[9px] opacity-50"
>{new Date(
@@ -466,7 +466,7 @@ $ae_loc.person.show_content__person_page_help = false;
</div>
{#if log.summary}
<span
class="text-xs opacity-80 line-clamp-1"
class="line-clamp-1 text-xs opacity-80"
>{log.summary}</span>
{/if}
</div>

View File

@@ -142,9 +142,9 @@ async function handleSubmit(event: Event) {
<form
onsubmit={handleSubmit}
class="card p-6 space-y-6 shadow-xl preset-tonal-surface">
class="card preset-tonal-surface space-y-6 p-6 shadow-xl">
<header
class="flex justify-between items-center border-b border-surface-500/30 pb-4">
class="border-surface-500/30 flex items-center justify-between border-b pb-4">
<h3 class="h3 flex items-center gap-2">
<User size={24} />
{person ? 'Edit Person' : 'Create New Person'}
@@ -163,7 +163,7 @@ async function handleSubmit(event: Event) {
class="btn btn-sm preset-filled-primary font-bold shadow-lg"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-1" />
{/if}
@@ -180,31 +180,31 @@ async function handleSubmit(event: Event) {
</aside>
{/if}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<!-- Name Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Identity</legend>
<div class="grid grid-cols-4 gap-2">
<div class="space-y-1 col-span-1">
<div class="col-span-1 space-y-1">
<label
class="label text-xs font-bold opacity-75"
for="person-prefix">Prefix</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-prefix"
type="text"
bind:value={formData.prefix}
placeholder="Mr." />
</div>
<div class="space-y-1 col-span-3">
<div class="col-span-3 space-y-1">
<label
class="label text-xs font-bold opacity-75"
for="person-given-name">Given Name</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-given-name"
type="text"
bind:value={formData.given_name}
@@ -214,24 +214,24 @@ async function handleSubmit(event: Event) {
</div>
<div class="grid grid-cols-4 gap-2">
<div class="space-y-1 col-span-3">
<div class="col-span-3 space-y-1">
<label
class="label text-xs font-bold opacity-75"
for="person-family-name">Family Name</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-family-name"
type="text"
bind:value={formData.family_name}
required
placeholder="Doe" />
</div>
<div class="space-y-1 col-span-1">
<div class="col-span-1 space-y-1">
<label
class="label text-xs font-bold opacity-75"
for="person-suffix">Suffix</label>
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-suffix"
type="text"
bind:value={formData.suffix}
@@ -246,13 +246,13 @@ async function handleSubmit(event: Event) {
>Middle Name / Informal Name (Nickname)</label>
<div class="grid grid-cols-2 gap-2">
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-middle-name"
type="text"
bind:value={formData.middle_name}
placeholder="Middle" />
<input
class="input preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="input preset-filled-surface placeholder-surface-400 rounded-lg p-2"
type="text"
bind:value={formData.nickname}
placeholder="Nickname" />
@@ -263,7 +263,7 @@ async function handleSubmit(event: Event) {
<!-- Contact Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Contact Information</legend>
<div class="space-y-1">
@@ -271,10 +271,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-primary-email">Primary Email</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Mail size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="person-primary-email"
type="email"
bind:value={formData.primary_email}
@@ -287,16 +287,16 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-phone">Phone Number</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Phone size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="person-phone"
type="tel"
bind:value={formData.phone}
placeholder="+1 (555) 000-0000" />
</div>
<small class="opacity-60 text-xs px-1"
<small class="px-1 text-xs opacity-60"
>(Saved only locally until Contact created)</small>
</div>
@@ -305,10 +305,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-tagline">Tagline</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Tag size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="person-tagline"
type="text"
bind:value={formData.tagline}
@@ -320,7 +320,7 @@ async function handleSubmit(event: Event) {
<!-- Professional Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Professional</legend>
<div class="space-y-1">
@@ -328,10 +328,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-professional-title">Professional Title</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Briefcase size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="person-professional-title"
type="text"
bind:value={formData.professional_title}
@@ -344,10 +344,10 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-affiliations">Affiliations</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Building size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 ring-0 focus:ring-0"
id="person-affiliations"
type="text"
bind:value={formData.affiliations}
@@ -359,25 +359,25 @@ async function handleSubmit(event: Event) {
<!-- Metadata Section -->
<fieldset class="space-y-4">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>Status & Flags</legend>
<div class="flex flex-wrap gap-4 pt-2">
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.enable} />
<span class="text-sm font-medium">Enabled</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={formData.hide} />
<span class="text-sm font-medium">Hidden</span>
</label>
<label class="flex items-center space-x-2 cursor-pointer">
<label class="flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
@@ -391,7 +391,7 @@ async function handleSubmit(event: Event) {
class="label text-xs font-bold opacity-75"
for="person-notes">Notes (Internal)</label>
<textarea
class="textarea preset-filled-surface rounded-lg placeholder-surface-400 p-2"
class="textarea preset-filled-surface placeholder-surface-400 rounded-lg p-2"
id="person-notes"
rows="3"
bind:value={formData.notes}
@@ -402,28 +402,28 @@ async function handleSubmit(event: Event) {
{#if $ae_loc.manager_access}
<!-- Admin/Linking Section -->
<fieldset
class="space-y-4 md:col-span-2 border-t border-surface-500/30 pt-4">
class="border-surface-500/30 space-y-4 border-t pt-4 md:col-span-2">
<legend
class="text-sm font-bold uppercase tracking-widest opacity-60"
class="text-sm font-bold tracking-widest uppercase opacity-60"
>System Linking (Managers Only)</legend>
<div class="space-y-1 max-w-md">
<div class="max-w-md space-y-1">
<label
class="label text-xs font-bold opacity-75"
for="person-user-id-random"
>Linked User ID (Random)</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-filled-surface rounded-lg overflow-hidden">
class="input-group input-group-divider preset-filled-surface grid-cols-[auto_1fr] overflow-hidden rounded-lg">
<div class="input-group-shim"><Link size={16} /></div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 font-mono placeholder-surface-400 p-2"
class="placeholder-surface-400 border-0 bg-transparent p-2 font-mono ring-0 focus:ring-0"
id="person-user-id-random"
type="text"
bind:value={formData.user_id_random}
placeholder="e.g. AB12CD34" />
</div>
<small
class="opacity-60 text-[10px] uppercase px-1 tracking-tighter"
class="px-1 text-[10px] tracking-tighter uppercase opacity-60"
>Enter the unique random ID of the user account to link
to this person.</small>
</div>
@@ -431,13 +431,13 @@ async function handleSubmit(event: Event) {
{/if}
</div>
<footer class="flex justify-end gap-2 border-t border-surface-500/30 pt-4">
<footer class="border-surface-500/30 flex justify-end gap-2 border-t pt-4">
<button
type="submit"
class="btn preset-filled-primary font-bold shadow-lg w-full md:w-auto"
class="btn preset-filled-primary w-full font-bold shadow-lg md:w-auto"
disabled={is_loading}>
{#if is_loading}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{/if}
{person ? 'Update Person Record' : 'Create Person Record'}
</button>

View File

@@ -48,32 +48,32 @@ async function handle_search() {
</script>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-4">
<div class="flex flex-wrap gap-6 items-end">
<div class="flex-1 min-w-[280px] space-y-1">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<div class="flex flex-wrap items-end gap-6">
<div class="min-w-[280px] flex-1 space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search People</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search by name, email, or ID..."
onkeydown={(e) => e.key === 'Enter' && handle_search()} />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={handle_search}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide">Go</span>
<span class="tracking-wide whitespace-nowrap">Go</span>
{/if}
</button>
</div>
@@ -82,10 +82,10 @@ async function handle_search() {
<div class="grid grid-cols-2 gap-4">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Account Status</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_enabled}
onchange={handle_search}>
<option value="all">All Records</option>
@@ -96,10 +96,10 @@ async function handle_search() {
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Visibility</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_hidden}
onchange={handle_search}>
<option value="all">All Visible</option>

View File

@@ -501,7 +501,7 @@ $effect(() => {
});
}}>
{#await ae_promises.update__person_obj}
<LoaderCircle size="1em" class="animate-spin mx-1" />
<LoaderCircle size="1em" class="mx-1 animate-spin" />
{:then}
{#if ae_tmp.value__data_json == $lq__person_obj.data_json}
<Check size="1em" class="mx-1" />

View File

@@ -73,17 +73,17 @@ async function handle_add_site() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex flex-wrap justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10 gap-4">
class="bg-surface-50-900-token border-surface-500/10 flex flex-wrap items-center justify-between gap-4 rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Globe size={24} class="text-primary-500" />
</div>
<div>
<h1 class="h2 font-black tracking-tight">Site Management</h1>
<p
class="text-xs font-bold opacity-50 uppercase tracking-widest">
class="text-xs font-bold tracking-widest uppercase opacity-50">
Digital Properties & Domains
</p>
</div>
@@ -96,44 +96,44 @@ async function handle_add_site() {
</header>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-4">
<div class="flex flex-wrap gap-6 items-end">
<div class="flex-1 min-w-[280px] space-y-1">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<div class="flex flex-wrap items-end gap-6">
<div class="min-w-[280px] flex-1 space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Sites</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search by name or code..." />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={load_sites}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Refresh</span>
{/if}
</button>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Status</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_enabled}
onchange={load_sites}>
<option value="all">All Statuses</option>
@@ -144,10 +144,10 @@ async function handle_add_site() {
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Visibility</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_hidden}
onchange={load_sites}>
<option value="all">All Visibility</option>
@@ -160,60 +160,60 @@ async function handle_add_site() {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if filtered_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<Globe size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Sites Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Sites for this account will appear here. Add your first site to
get started.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Linked Properties
<span class="badge preset-tonal-secondary ml-auto"
>{filtered_li.length} found</span>
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each filtered_li as site (site.site_id_random)}
<div
class="card p-5 space-y-4 preset-tonal-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
class="card preset-tonal-surface border-surface-500/10 hover:border-primary-500/30 group relative space-y-4 border p-5 shadow-md transition-all">
<div class="absolute top-4 right-4 flex gap-1">
{#if site.hide}
<span
class="badge preset-filled-warning text-[8px] uppercase font-bold shadow-sm"
class="badge preset-filled-warning text-[8px] font-bold uppercase shadow-sm"
>Hidden</span>
{/if}
<span
class="badge {site.enable
? 'preset-filled-success'
: 'preset-filled-error'} text-[8px] uppercase font-bold shadow-sm">
: 'preset-filled-error'} text-[8px] font-bold uppercase shadow-sm">
{site.enable ? 'Active' : 'Disabled'}
</span>
</div>
<header class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-lg shadow-inner group-hover:scale-110 transition-transform">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-lg shadow-inner transition-transform group-hover:scale-110">
<Globe size={24} />
</div>
<div class="pr-12">
<p class="font-black tracking-tight truncate">
<p class="truncate font-black tracking-tight">
{site.name}
</p>
<p
class="text-[10px] uppercase font-bold opacity-50 font-mono tracking-tighter">
class="font-mono text-[10px] font-bold tracking-tighter uppercase opacity-50">
Code: {site.code || '--'}
</p>
</div>
@@ -221,7 +221,7 @@ async function handle_add_site() {
<div class="space-y-2 text-xs opacity-70">
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<Calendar
size={14}
class="text-primary-500 shrink-0" />
@@ -231,17 +231,17 @@ async function handle_add_site() {
).toLocaleDateString()}</span>
</div>
<div
class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2">
<ShieldCheck
size={14}
class="text-secondary-500 shrink-0" />
<span class="font-mono truncate"
<span class="truncate font-mono"
>{site.site_id_random}</span>
</div>
</div>
<a
class="btn btn-sm preset-filled-primary font-bold w-full shadow-lg group-hover:brightness-110 transition-all"
class="btn btn-sm preset-filled-primary w-full font-bold shadow-lg transition-all group-hover:brightness-110"
href="/core/sites/{site.site_id_random}">
Manage Site
</a>

View File

@@ -118,9 +118,9 @@ async function handle_delete_domain(dom: any) {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-4">
<a
class="btn btn-sm preset-tonal-surface shadow-sm"
@@ -128,7 +128,7 @@ async function handle_delete_domain(dom: any) {
<ArrowLeft size={16} />
</a>
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<Globe size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">
@@ -141,7 +141,7 @@ async function handle_delete_domain(dom: any) {
onclick={handle_save_site}
disabled={loading || saving}>
{#if saving}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-2" />
{/if}
@@ -150,24 +150,24 @@ async function handle_delete_domain(dom: any) {
</header>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if site}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<!-- Site Config -->
<div class="lg:col-span-2 space-y-6">
<div class="space-y-6 lg:col-span-2">
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Settings size={18} class="text-primary-500" /> Site Configuration
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Site Name</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -176,16 +176,16 @@ async function handle_delete_domain(dom: any) {
</div>
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Site Code</span>
<input
class="input preset-filled-surface rounded-lg font-mono p-3"
class="input preset-filled-surface rounded-lg p-3 font-mono"
type="text"
bind:value={site.code} />
</div>
<div class="space-y-1 md:col-span-2">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Tagline</span>
<input
class="input preset-filled-surface rounded-lg p-3"
@@ -194,7 +194,7 @@ async function handle_delete_domain(dom: any) {
</div>
<div class="space-y-1 md:col-span-2">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Description</span>
<textarea
class="textarea preset-filled-surface rounded-lg p-3"
@@ -206,9 +206,9 @@ async function handle_delete_domain(dom: any) {
<!-- Advanced Site JSON Config -->
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Database size={18} class="text-warning-500" /> Site Settings
(cfg_json)
</h3>
@@ -218,29 +218,29 @@ async function handle_delete_domain(dom: any) {
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Key size={18} class="text-secondary-500" /> Access Control
</h3>
<div class="flex flex-col gap-4">
<label
class="flex items-center space-x-2 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-2">
<input
class="checkbox"
type="checkbox"
bind:checked={site.restrict_access} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Restrict Access</span>
</label>
{#if site.restrict_access}
<div class="space-y-1 max-w-md animate-fade-in">
<div class="animate-fade-in max-w-md space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Access Key</span>
<input
class="input preset-filled-surface rounded-lg font-mono p-3"
class="input preset-filled-surface rounded-lg p-3 font-mono"
type="text"
bind:value={site.access_key} />
</div>
@@ -252,10 +252,10 @@ async function handle_delete_domain(dom: any) {
<!-- Domains Management -->
<div class="space-y-6">
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<header
class="flex justify-between items-center border-b border-surface-500/30 pb-2">
<h3 class="h4 font-bold flex items-center gap-2">
class="border-surface-500/30 flex items-center justify-between border-b pb-2">
<h3 class="h4 flex items-center gap-2 font-bold">
<Globe size={18} class="text-tertiary-500" /> Site Domains
</h3>
<button
@@ -268,28 +268,28 @@ async function handle_delete_domain(dom: any) {
{#if domain_li.length === 0}
<p
class="text-sm opacity-60 text-center py-8 bg-surface-500/5 rounded-lg border-2 border-dashed border-surface-500/20">
class="bg-surface-500/5 border-surface-500/20 rounded-lg border-2 border-dashed py-8 text-center text-sm opacity-60">
No domains configured.
</p>
{:else}
<div class="space-y-3">
{#each domain_li as dom (dom.site_domain_id_random)}
<div
class="card p-3 preset-tonal-surface shadow-sm border border-surface-500/10 flex justify-between items-center group">
class="card preset-tonal-surface border-surface-500/10 group flex items-center justify-between border p-3 shadow-sm">
<div class="flex flex-col">
<span
class="font-bold text-sm flex items-center gap-1">
class="flex items-center gap-1 text-sm font-bold">
{dom.fqdn}
<a
href="https://{dom.fqdn}"
target="_blank"
rel="noopener noreferrer"
class="opacity-30 group-hover:opacity-100 transition-opacity">
class="opacity-30 transition-opacity group-hover:opacity-100">
<ExternalLink size={12} />
</a>
</span>
<span
class="text-[10px] uppercase font-bold tracking-tighter opacity-50">
class="text-[10px] font-bold tracking-tighter uppercase opacity-50">
Key: <code class="text-primary-500"
>{dom.access_key || '--'}</code>
&bull; {dom.enable
@@ -322,30 +322,30 @@ async function handle_delete_domain(dom: any) {
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Activity size={18} class="text-error-500" /> System Status
</h3>
<div class="space-y-4 py-2">
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={site.enable} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Site Enabled</span>
</label>
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={site.hide} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Hidden from Public</span>
</label>
</div>

View File

@@ -77,11 +77,11 @@ async function handle_add_user() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-2">
<div class="p-2 bg-primary-500/10 rounded-lg">
<div class="bg-primary-500/10 rounded-lg p-2">
<ShieldCheck size={24} class="text-primary-500" />
</div>
<h1 class="h2 font-black tracking-tight">User Management</h1>
@@ -98,45 +98,45 @@ async function handle_add_user() {
</header>
<div
class="card p-6 shadow-xl preset-tonal-surface border border-surface-500/10 space-y-4">
<div class="flex flex-wrap gap-6 items-end">
<div class="flex-1 min-w-[280px] space-y-1">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<div class="flex flex-wrap items-end gap-6">
<div class="min-w-[280px] flex-1 space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Search Users</span>
<div
class="flex bg-surface-200-700-token rounded-lg overflow-hidden border border-surface-500/20 shadow-inner group focus-within:ring-2 focus-within:ring-primary-500/50 transition-all">
class="bg-surface-200-700-token border-surface-500/20 group focus-within:ring-primary-500/50 flex overflow-hidden rounded-lg border shadow-inner transition-all focus-within:ring-2">
<div
class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
class="bg-surface-300-600-token border-surface-500/20 flex items-center justify-center border-r px-4">
<Search size={18} class="opacity-50" />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
class="grow border-0 bg-transparent p-3 ring-0 placeholder:opacity-50 focus:ring-0"
type="search"
bind:value={qry_str}
placeholder="Search username or email..."
onkeydown={(e) => e.key === 'Enter' && load_users()} />
<button
class="preset-filled-primary font-bold px-10 py-3 hover:brightness-110 transition-all border-l border-surface-500/20 flex items-center justify-center min-w-[100px]"
class="preset-filled-primary border-surface-500/20 flex min-w-[100px] items-center justify-center border-l px-10 py-3 font-bold transition-all hover:brightness-110"
onclick={load_users}
disabled={loading}>
{#if loading}
<span class="animate-spin text-xl"></span>
{:else}
<span class="whitespace-nowrap tracking-wide"
<span class="tracking-wide whitespace-nowrap"
>Go</span>
{/if}
</button>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Scope</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_account_scope}
onchange={load_users}>
<option value="all">All (Current + Global)</option>
@@ -147,10 +147,10 @@ async function handle_add_user() {
<div class="space-y-1">
<span
class="label block text-xs font-bold opacity-75 uppercase tracking-wider ml-1"
class="label ml-1 block text-xs font-bold tracking-wider uppercase opacity-75"
>Status</span>
<select
class="select preset-filled-surface rounded-lg text-sm border border-surface-500/20 p-2"
class="select preset-filled-surface border-surface-500/20 rounded-lg border p-2 text-sm"
bind:value={qry_enabled}
onchange={load_users}>
<option value="all">All</option>
@@ -163,38 +163,38 @@ async function handle_add_user() {
</div>
{#if loading}
<div class="card p-8 flex justify-center items-center h-64">
<div class="placeholder animate-pulse w-full h-full rounded-2xl">
<div class="card flex h-64 items-center justify-center p-8">
<div class="placeholder h-full w-full animate-pulse rounded-2xl">
</div>
</div>
{:else if user_li.length === 0}
<div
class="card p-12 text-center preset-tonal-surface border-2 border-dashed border-surface-500/20 rounded-2xl">
class="card preset-tonal-surface border-surface-500/20 rounded-2xl border-2 border-dashed p-12 text-center">
<Fingerprint size={48} class="mx-auto mb-4 opacity-20" />
<h3 class="h3 font-bold opacity-50">No Users Found</h3>
<p class="opacity-60 max-w-xs mx-auto mt-2">
<p class="mx-auto mt-2 max-w-xs opacity-60">
Try adjusting your search or scope filters.
</p>
</div>
{:else}
<div
class="card p-6 preset-tonal-surface shadow-xl border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 mb-6 flex items-center gap-2">
class="h4 border-surface-500/30 mb-6 flex items-center gap-2 border-b pb-2 font-bold">
<ListFilter size={18} class="text-secondary-500" />
Directory Results
<span class="badge preset-tonal-secondary ml-auto"
>{user_li.length} found</span>
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each user_li as user (user.user_id_random)}
<div
class="card p-5 space-y-4 preset-tonal-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group">
<header class="flex justify-between items-start">
class="card preset-tonal-surface border-surface-500/10 hover:border-primary-500/30 group space-y-4 border p-5 shadow-md transition-all">
<header class="flex items-start justify-between">
<div class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-full shadow-inner group-hover:scale-110 transition-transform">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-full shadow-inner transition-transform group-hover:scale-110">
<User size={24} />
</div>
<div>
@@ -202,7 +202,7 @@ async function handle_add_user() {
{user.username}
</p>
<p
class="text-[10px] uppercase font-bold opacity-50">
class="text-[10px] font-bold uppercase opacity-50">
{user.name || 'No Display Name'}
</p>
</div>
@@ -210,21 +210,21 @@ async function handle_add_user() {
<div class="flex flex-col items-end gap-1">
{#if user.super}
<span
class="badge preset-filled-error text-[8px] uppercase font-bold"
class="badge preset-filled-error text-[8px] font-bold uppercase"
>Super</span>
{:else if user.manager}
<span
class="badge preset-filled-warning text-[8px] uppercase font-bold"
class="badge preset-filled-warning text-[8px] font-bold uppercase"
>Manager</span>
{/if}
{#if !user.account_id && !user.account_id_random}
<span
class="badge preset-tonal-secondary text-[8px] uppercase font-bold flex items-center gap-1">
class="badge preset-tonal-secondary flex items-center gap-1 text-[8px] font-bold uppercase">
<Globe size={8} /> Global
</span>
{:else}
<span
class="badge preset-tonal-primary text-[8px] uppercase font-bold flex items-center gap-1">
class="badge preset-tonal-primary flex items-center gap-1 text-[8px] font-bold uppercase">
<Landmark size={8} /> Account
</span>
{/if}
@@ -233,13 +233,13 @@ async function handle_add_user() {
<div class="space-y-2">
<div
class="flex items-center gap-2 text-xs opacity-70 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2 text-xs opacity-70">
<Mail size={14} class="text-primary-500" />
<span class="truncate"
>{user.email || '--'}</span>
</div>
<div
class="flex items-center gap-2 text-xs opacity-70 bg-black/5 p-2 rounded-lg">
class="flex items-center gap-2 rounded-lg bg-black/5 p-2 text-xs opacity-70">
<Activity
size={14}
class="text-secondary-500" />
@@ -249,7 +249,7 @@ async function handle_add_user() {
</div>
<a
class="btn btn-sm preset-filled-primary font-bold w-full shadow-lg group-hover:brightness-110 transition-all"
class="btn btn-sm preset-filled-primary w-full font-bold shadow-lg transition-all group-hover:brightness-110"
href="/core/users/{user.user_id_random}">
Manage User
</a>

View File

@@ -79,9 +79,9 @@ async function handle_delete() {
}
</script>
<div class="container mx-auto p-4 space-y-6">
<div class="container mx-auto space-y-6 p-4">
<header
class="flex justify-between items-center bg-surface-50-900-token p-4 rounded-xl shadow-lg border border-surface-500/10">
class="bg-surface-50-900-token border-surface-500/10 flex items-center justify-between rounded-xl border p-4 shadow-lg">
<div class="flex items-center gap-4">
<a
class="btn btn-sm preset-tonal-surface shadow-sm"
@@ -90,7 +90,7 @@ async function handle_delete() {
</a>
<div class="flex items-center gap-3">
<div
class="avatar preset-filled-primary w-12 h-12 flex items-center justify-center rounded-full shadow-inner">
class="avatar preset-filled-primary flex h-12 w-12 items-center justify-center rounded-full shadow-inner">
<UserIcon size={24} />
</div>
<div>
@@ -98,7 +98,7 @@ async function handle_delete() {
{user.username}
</h1>
<p
class="text-[10px] uppercase font-bold tracking-widest opacity-50">
class="text-[10px] font-bold tracking-widest uppercase opacity-50">
UID: {user.user_id_random}
</p>
</div>
@@ -116,7 +116,7 @@ async function handle_delete() {
onclick={handle_save}
disabled={saving}>
{#if saving}
<span class="animate-spin mr-2"></span>
<span class="mr-2 animate-spin"></span>
{:else}
<Save size={16} class="mr-2" />
{/if}
@@ -125,16 +125,16 @@ async function handle_delete() {
</div>
</header>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<!-- Main Info -->
<div class="lg:col-span-2 space-y-6">
<div class="space-y-6 lg:col-span-2">
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<UserIcon size={18} class="text-primary-500" /> Basic Profile
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
<div class="space-y-1">
<label
class="label text-xs font-bold opacity-75"
@@ -161,19 +161,19 @@ async function handle_delete() {
class="label text-xs font-bold opacity-75"
for="user-username">Username</label>
<div
class="input-group input-group-divider grid-cols-[auto_1fr] preset-tonal-surface rounded-lg overflow-hidden border border-surface-500/20">
<div class="input-group-shim !pl-4 !pr-0">
class="input-group input-group-divider preset-tonal-surface border-surface-500/20 grid-cols-[auto_1fr] overflow-hidden rounded-lg border">
<div class="input-group-shim !pr-0 !pl-4">
<Fingerprint size={16} />
</div>
<input
class="bg-transparent border-0 ring-0 focus:ring-0 font-mono opacity-60 p-2"
class="border-0 bg-transparent p-2 font-mono opacity-60 ring-0 focus:ring-0"
id="user-username"
type="text"
bind:value={user.username}
disabled />
</div>
<p
class="text-[10px] opacity-50 mt-1 italic uppercase tracking-tighter">
class="mt-1 text-[10px] tracking-tighter uppercase italic opacity-50">
Username changes are currently restricted.
</p>
</div>
@@ -181,21 +181,21 @@ async function handle_delete() {
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<ShieldCheck size={18} class="text-secondary-500" /> System Permissions
</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<label
class="flex items-center space-x-3 card p-4 preset-tonal-error cursor-pointer border border-error-500/20 hover:preset-filled-error transition-all group">
class="card preset-tonal-error border-error-500/20 hover:preset-filled-error group flex cursor-pointer items-center space-x-3 border p-4 transition-all">
<input
class="checkbox"
type="checkbox"
bind:checked={user.super} />
<div class="flex flex-col">
<span
class="font-black uppercase text-xs tracking-widest"
class="text-xs font-black tracking-widest uppercase"
>Super User</span>
<span
class="text-[10px] opacity-70 group-hover:opacity-100"
@@ -203,14 +203,14 @@ async function handle_delete() {
</div>
</label>
<label
class="flex items-center space-x-3 card p-4 preset-tonal-warning cursor-pointer border border-warning-500/20 hover:preset-filled-warning transition-all group">
class="card preset-tonal-warning border-warning-500/20 hover:preset-filled-warning group flex cursor-pointer items-center space-x-3 border p-4 transition-all">
<input
class="checkbox"
type="checkbox"
bind:checked={user.manager} />
<div class="flex flex-col">
<span
class="font-black uppercase text-xs tracking-widest"
class="text-xs font-black tracking-widest uppercase"
>Manager</span>
<span
class="text-[10px] opacity-70 group-hover:opacity-100"
@@ -218,14 +218,14 @@ async function handle_delete() {
</div>
</label>
<label
class="flex items-center space-x-3 card p-4 preset-tonal-primary cursor-pointer border border-primary-500/20 hover:preset-filled-primary transition-all group">
class="card preset-tonal-primary border-primary-500/20 hover:preset-filled-primary group flex cursor-pointer items-center space-x-3 border p-4 transition-all">
<input
class="checkbox"
type="checkbox"
bind:checked={user.administrator} />
<div class="flex flex-col">
<span
class="font-black uppercase text-xs tracking-widest"
class="text-xs font-black tracking-widest uppercase"
>Administrator</span>
<span
class="text-[10px] opacity-70 group-hover:opacity-100"
@@ -233,14 +233,14 @@ async function handle_delete() {
</div>
</label>
<label
class="flex items-center space-x-3 card p-4 preset-tonal-secondary cursor-pointer border border-secondary-500/20 hover:preset-filled-secondary transition-all group">
class="card preset-tonal-secondary border-secondary-500/20 hover:preset-filled-secondary group flex cursor-pointer items-center space-x-3 border p-4 transition-all">
<input
class="checkbox"
type="checkbox"
bind:checked={user.verified} />
<div class="flex flex-col">
<span
class="font-black uppercase text-xs tracking-widest"
class="text-xs font-black tracking-widest uppercase"
>Verified User</span>
<span
class="text-[10px] opacity-70 group-hover:opacity-100"
@@ -254,56 +254,56 @@ async function handle_delete() {
<!-- Sidebar / Meta -->
<div class="space-y-6">
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Activity size={18} class="text-tertiary-500" /> Account Status
</h3>
<div class="space-y-4 py-2">
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={user.enable} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Login Enabled</span>
</label>
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={user.hide} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Hidden from Lists</span>
</label>
<label
class="flex items-center space-x-3 cursor-pointer group">
class="group flex cursor-pointer items-center space-x-3">
<input
class="checkbox"
type="checkbox"
bind:checked={user.allow_auth_key} />
<span
class="text-sm font-bold opacity-70 group-hover:opacity-100 transition-opacity"
class="text-sm font-bold opacity-70 transition-opacity group-hover:opacity-100"
>Allow Email Auth Key</span>
</label>
</div>
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Lock size={18} class="text-surface-500" /> Linking Info
</h3>
<div class="space-y-3 text-xs">
<div
class="flex justify-between items-center p-2 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-2">
<span
class="font-bold opacity-50 uppercase tracking-tighter"
class="font-bold tracking-tighter uppercase opacity-50"
>Linked Person</span>
<span class="font-mono font-bold">
{#if user.person_id_random}
@@ -313,15 +313,15 @@ async function handle_delete() {
{user.person_id_random}
</a>
{:else}
<span class="italic text-error-500"
<span class="text-error-500 italic"
>Unlinked</span>
{/if}
</span>
</div>
<div
class="flex justify-between items-center p-2 bg-black/5 rounded-lg">
class="flex items-center justify-between rounded-lg bg-black/5 p-2">
<span
class="font-bold opacity-50 uppercase tracking-tighter"
class="font-bold tracking-tighter uppercase opacity-50"
>Account Context</span>
<span class="font-mono font-bold"
>{user.account_id_random || '--'}</span>
@@ -330,25 +330,25 @@ async function handle_delete() {
</div>
<div
class="card p-6 space-y-4 shadow-xl preset-tonal-surface border border-surface-500/10">
class="card preset-tonal-surface border-surface-500/10 space-y-4 border p-6 shadow-xl">
<h3
class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
class="h4 border-surface-500/30 flex items-center gap-2 border-b pb-2 font-bold">
<Clock size={18} class="text-surface-500" /> Timestamps
</h3>
<div
class="space-y-3 text-[10px] uppercase font-bold tracking-wider">
class="space-y-3 text-[10px] font-bold tracking-wider uppercase">
<div class="flex flex-col gap-1 opacity-60">
<span>Created On</span>
<span
class="text-xs text-surface-900 dark:text-surface-100"
class="text-surface-900 dark:text-surface-100 text-xs"
>{new Date(user.created_on).toLocaleString()}</span>
</div>
{#if user.updated_on}
<div
class="flex flex-col gap-1 opacity-60 border-t border-surface-500/10 pt-2">
class="border-surface-500/10 flex flex-col gap-1 border-t pt-2 opacity-60">
<span>Last Updated</span>
<span
class="text-xs text-surface-900 dark:text-surface-100"
class="text-surface-900 dark:text-surface-100 text-xs"
>{new Date(
user.updated_on
).toLocaleString()}</span>