fix: add missing each-block keys (svelte/require-each-key)
Fixed all 27 remaining instances across 19 files. Keys used: - Object ID fields where available (e.g. account_id_random, event_file_id) - index for logger lists with no reliable unique key - Property name for Object.entries() loops
This commit is contained in:
@@ -12,9 +12,9 @@
|
||||
let qry_str = $state('');
|
||||
|
||||
let filtered_li = $derived(
|
||||
qry_str
|
||||
? account_li.filter(a =>
|
||||
a.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
qry_str
|
||||
? account_li.filter(a =>
|
||||
a.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
a.code?.toLowerCase().includes(qry_str.toLowerCase())
|
||||
)
|
||||
: account_li
|
||||
@@ -40,7 +40,7 @@
|
||||
if (!name) return;
|
||||
|
||||
const code = prompt('Enter account code (optional):');
|
||||
|
||||
|
||||
const new_acct = await create_ae_obj__account({
|
||||
api_cfg: $ae_api,
|
||||
data_kv: {
|
||||
@@ -81,11 +81,11 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name or code..."
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name or code..."
|
||||
/>
|
||||
<button class="variant-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]" onclick={load_accounts} disabled={loading}>
|
||||
{#if loading}
|
||||
@@ -138,7 +138,7 @@
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{#each filtered_li as acct}
|
||||
{#each filtered_li as acct (acct.account_id_random)}
|
||||
<div class="card p-5 space-y-4 variant-soft-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
|
||||
<div class="absolute top-4 right-4 flex gap-1">
|
||||
{#if acct.hide}
|
||||
@@ -158,7 +158,7 @@
|
||||
<p class="text-[10px] uppercase font-bold opacity-50 font-mono tracking-tighter">Code: {acct.code || '--'}</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="space-y-2 text-xs opacity-70">
|
||||
<div class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
|
||||
<Calendar size={14} class="text-primary-500 shrink-0" />
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
async function load_logs() {
|
||||
if (!$ae_loc.account_id) return;
|
||||
loading = true;
|
||||
|
||||
|
||||
const results = await qry__activity_log({
|
||||
api_cfg: $ae_api,
|
||||
account_id: $ae_loc.account_id,
|
||||
@@ -77,11 +77,11 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Action, name, description..."
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Action, name, description..."
|
||||
/>
|
||||
<button type="submit" class="variant-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]" disabled={loading}>
|
||||
<span class="whitespace-nowrap tracking-wide">Search</span>
|
||||
@@ -131,7 +131,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each log_li as log}
|
||||
{#each log_li as log, index (index)}
|
||||
<tr class="transition-colors text-sm">
|
||||
<!-- Date/Time -->
|
||||
<td class="whitespace-nowrap">
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
let show_add_form = $state(false);
|
||||
let qry_str = $state('');
|
||||
let filtered_li: any[] = $derived(
|
||||
qry_str
|
||||
? address_li.filter(a =>
|
||||
a.city?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
qry_str
|
||||
? address_li.filter(a =>
|
||||
a.city?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
a.state_province?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
a.organization_name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
a.line_1?.toLowerCase().includes(qry_str.toLowerCase())
|
||||
@@ -51,8 +51,8 @@
|
||||
</div>
|
||||
<h1 class="h2 font-black tracking-tight">Address Management</h1>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-sm variant-filled-primary font-bold shadow-lg"
|
||||
<button
|
||||
class="btn btn-sm variant-filled-primary font-bold shadow-lg"
|
||||
onclick={() => show_add_form = !show_add_form}
|
||||
>
|
||||
{#if show_add_form}
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
{#if show_add_form}
|
||||
<div class="animate-fade-in">
|
||||
<Address_form
|
||||
<Address_form
|
||||
onSave={(new_addr) => {
|
||||
show_add_form = false;
|
||||
load_addresses();
|
||||
@@ -85,11 +85,11 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by city, state, organization, or street..."
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by city, state, organization, or street..."
|
||||
/>
|
||||
<button class="variant-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]" onclick={load_addresses} disabled={loading}>
|
||||
{#if loading}
|
||||
@@ -119,9 +119,9 @@
|
||||
Linked Addresses
|
||||
<span class="badge variant-soft-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">
|
||||
{#each filtered_li as addr}
|
||||
{#each filtered_li as addr (addr.address_id_random)}
|
||||
<div class="card p-5 space-y-4 variant-soft-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
|
||||
<div class="absolute top-4 right-4">
|
||||
<span class="badge {addr.enable ? 'variant-filled-success' : 'variant-filled-error'} text-[8px] uppercase font-bold shadow-sm">
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $lq_kv__person_obj_li as person_obj}
|
||||
{#each $lq_kv__person_obj_li as person_obj (person_obj.person_id_random)}
|
||||
<tr class:dim={person_obj?.hide}>
|
||||
<td class="px-4 py-2">
|
||||
<span class="fas fa-user"></span>
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
let contact_li: any[] = $state([]);
|
||||
let qry_str = $state('');
|
||||
let filtered_li: any[] = $derived(
|
||||
qry_str
|
||||
? contact_li.filter(c =>
|
||||
c.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
qry_str
|
||||
? contact_li.filter(c =>
|
||||
c.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
c.title?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
c.email?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
c.phone_office?.toLowerCase().includes(qry_str.toLowerCase())
|
||||
@@ -51,8 +51,8 @@
|
||||
</div>
|
||||
<h1 class="h2 font-black tracking-tight">Contact Management</h1>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-sm variant-filled-primary font-bold shadow-lg"
|
||||
<button
|
||||
class="btn btn-sm variant-filled-primary font-bold shadow-lg"
|
||||
onclick={() => show_add_form = !show_add_form}
|
||||
>
|
||||
{#if show_add_form}
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
{#if show_add_form}
|
||||
<div class="animate-fade-in">
|
||||
<Contact_form
|
||||
<Contact_form
|
||||
onSave={(new_con) => {
|
||||
show_add_form = false;
|
||||
load_contacts();
|
||||
@@ -85,11 +85,11 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name, title, email, or phone..."
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name, title, email, or phone..."
|
||||
/>
|
||||
<button class="variant-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]" onclick={load_contacts} disabled={loading}>
|
||||
{#if loading}
|
||||
@@ -121,7 +121,7 @@
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{#each filtered_li as con}
|
||||
{#each filtered_li as con (con.contact_id_random)}
|
||||
<div class="card p-5 space-y-4 variant-soft-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
|
||||
<div class="absolute top-4 right-4">
|
||||
<span class="badge {con.enable ? 'variant-filled-success' : 'variant-filled-error'} text-[8px] uppercase font-bold shadow-sm">
|
||||
@@ -138,7 +138,7 @@
|
||||
<p class="text-[10px] uppercase font-bold opacity-50 truncate">{con.title || 'Support Contact'}</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="space-y-2 text-xs opacity-70">
|
||||
<div class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
|
||||
<Mail size={14} class="text-primary-500 shrink-0" />
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
const [countries, subdivisions, time_zones] = await Promise.all([
|
||||
api.get_ae_obj_li_for_lu({ api_cfg: $ae_api, for_lu_type: 'country', log_lvl: 1 }),
|
||||
api.get_ae_obj_li_for_lu({ api_cfg: $ae_api, for_lu_type: 'country_subdivision', log_lvl: 1 }),
|
||||
api.get_ae_obj_li_for_lu({
|
||||
api_cfg: $ae_api,
|
||||
for_lu_type: 'time_zone',
|
||||
api.get_ae_obj_li_for_lu({
|
||||
api_cfg: $ae_api,
|
||||
for_lu_type: 'time_zone',
|
||||
only_priority: tz_only_priority,
|
||||
log_lvl: 1
|
||||
log_lvl: 1
|
||||
})
|
||||
]);
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
Country Reference
|
||||
<span class="badge variant-soft-secondary ml-auto text-[10px] uppercase font-bold">{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">
|
||||
<thead>
|
||||
@@ -101,7 +101,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each lookups.countries as c}
|
||||
{#each lookups.countries as c (c.alpha_2_code)}
|
||||
<tr class="transition-colors">
|
||||
<td class="font-bold">{c.name || c.english_short_name}</td>
|
||||
<td class="text-center"><span class="badge variant-soft-surface font-mono text-primary-500">{c.alpha_2_code}</span></td>
|
||||
@@ -119,7 +119,7 @@
|
||||
Country Subdivisions (States/Provinces)
|
||||
<span class="badge variant-soft-secondary ml-auto text-[10px] uppercase font-bold">{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">
|
||||
<thead>
|
||||
@@ -130,7 +130,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each lookups.subdivisions as s}
|
||||
{#each lookups.subdivisions as s, i (i)}
|
||||
<tr class="transition-colors">
|
||||
<td class="opacity-60">{s.country_alpha_2_code}</td>
|
||||
<td class="font-bold">{s.name}</td>
|
||||
@@ -150,7 +150,7 @@
|
||||
Time Zone Reference
|
||||
<span class="badge variant-soft-secondary text-[10px] uppercase font-bold">{lookups.time_zones.length} Zones</span>
|
||||
</h3>
|
||||
<button
|
||||
<button
|
||||
class="btn btn-sm transition-all {tz_only_priority ? 'variant-filled-warning' : 'variant-soft-surface'}"
|
||||
onclick={toggle_tz_priority}
|
||||
disabled={loading}
|
||||
@@ -159,7 +159,7 @@
|
||||
{tz_only_priority ? 'Showing Priority' : 'Show Only Priority'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="table-container max-h-[500px] overflow-auto border border-surface-500/10 rounded-lg">
|
||||
<table class="table table-hover table-compact">
|
||||
<thead>
|
||||
@@ -169,7 +169,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each lookups.time_zones as tz}
|
||||
{#each lookups.time_zones as tz (tz.name)}
|
||||
<tr class="transition-colors">
|
||||
<td class="font-bold">{tz.name}</td>
|
||||
<td class="text-right"><span class="badge variant-soft-surface font-mono">{tz.offset_seconds / 3600}h</span></td>
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
<p class="text-center py-4 italic opacity-60 border border-dashed border-surface-500/30">No unlinked user accounts found.</p>
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
|
||||
{#each available_users as user}
|
||||
{#each available_users as user (user.user_id)}
|
||||
<button
|
||||
class="card p-3 variant-soft-primary hover:variant-filled-primary text-left transition-all flex flex-col gap-1"
|
||||
onclick={() => handle_link_user(user.user_id)}
|
||||
@@ -335,7 +335,7 @@
|
||||
<p class="text-sm italic opacity-50">No related events found.</p>
|
||||
{:else}
|
||||
<div class="space-y-2">
|
||||
{#each related_events as ev}
|
||||
{#each related_events as ev (ev.event_id)}
|
||||
<a href="/events/{ev.event_id}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
||||
<span class="font-bold text-sm">{ev.name}</span>
|
||||
<span class="text-[10px] opacity-60">{new Date(ev.start_datetime).toLocaleDateString()}</span>
|
||||
@@ -356,7 +356,7 @@
|
||||
<p class="text-sm italic opacity-50">No related posts found.</p>
|
||||
{:else}
|
||||
<div class="space-y-2">
|
||||
{#each related_posts as post}
|
||||
{#each related_posts as post (post.post_id)}
|
||||
<a href="/idaa/bb/{post.post_id}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
||||
<span class="font-bold text-sm">{post.title}</span>
|
||||
<div class="flex justify-between items-center text-[10px] opacity-60">
|
||||
@@ -380,7 +380,7 @@
|
||||
<p class="text-sm italic opacity-50">No recent activity logs.</p>
|
||||
{:else}
|
||||
<div class="space-y-2">
|
||||
{#each related_activity_logs as log}
|
||||
{#each related_activity_logs as log, index (index)}
|
||||
<div class="card p-3 variant-soft flex flex-col gap-1">
|
||||
<div class="flex justify-between items-start gap-2">
|
||||
<span class="badge variant-filled-surface text-[9px] uppercase tracking-tighter">{log.action}</span>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
let qry_str = $state('');
|
||||
|
||||
let filtered_li = $derived(
|
||||
qry_str
|
||||
? site_li.filter(s =>
|
||||
s.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
qry_str
|
||||
? site_li.filter(s =>
|
||||
s.name?.toLowerCase().includes(qry_str.toLowerCase()) ||
|
||||
s.code?.toLowerCase().includes(qry_str.toLowerCase())
|
||||
)
|
||||
: site_li
|
||||
@@ -42,7 +42,7 @@
|
||||
if (!name) return;
|
||||
|
||||
const code = prompt('Enter site code (optional):');
|
||||
|
||||
|
||||
const new_site = await create_ae_obj__site({
|
||||
api_cfg: $ae_api,
|
||||
account_id: $ae_loc.account_id,
|
||||
@@ -84,11 +84,11 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name or code..."
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search by name or code..."
|
||||
/>
|
||||
<button class="variant-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]" onclick={load_sites} disabled={loading}>
|
||||
{#if loading}
|
||||
@@ -141,7 +141,7 @@
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{#each filtered_li as site}
|
||||
{#each filtered_li as site (site.site_id_random)}
|
||||
<div class="card p-5 space-y-4 variant-soft-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group relative">
|
||||
<div class="absolute top-4 right-4 flex gap-1">
|
||||
{#if site.hide}
|
||||
@@ -161,7 +161,7 @@
|
||||
<p class="text-[10px] uppercase font-bold opacity-50 font-mono tracking-tighter">Code: {site.code || '--'}</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="space-y-2 text-xs opacity-70">
|
||||
<div class="flex items-center gap-2 bg-black/5 p-2 rounded-lg">
|
||||
<Calendar size={14} class="text-primary-500 shrink-0" />
|
||||
|
||||
@@ -166,9 +166,9 @@
|
||||
<h3 class="h4 font-bold border-b border-surface-500/30 pb-2 flex items-center gap-2">
|
||||
<Database size={18} class="text-warning-500" /> Site Settings (cfg_json)
|
||||
</h3>
|
||||
<AE_Comp_Site_Config_Editor
|
||||
bind:cfg_json={site.cfg_json}
|
||||
on_save={handle_save_site}
|
||||
<AE_Comp_Site_Config_Editor
|
||||
bind:cfg_json={site.cfg_json}
|
||||
on_save={handle_save_site}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
<p class="text-sm opacity-60 text-center py-8 bg-surface-500/5 rounded-lg border-2 border-dashed border-surface-500/20">No domains configured.</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each domain_li as dom}
|
||||
{#each domain_li as dom (dom.site_domain_id_random)}
|
||||
<div class="card p-3 variant-soft shadow-sm border border-surface-500/10 flex justify-between items-center group">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-bold text-sm flex items-center gap-1">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
async function load_users() {
|
||||
loading = true;
|
||||
|
||||
|
||||
let for_obj_id: string | null = $ae_loc.account_id;
|
||||
let include_global = true;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
const username = prompt('Enter new username:');
|
||||
if (!username) return;
|
||||
const email = prompt('Enter email address:');
|
||||
|
||||
|
||||
// Link to account if scope is 'account' or 'all', otherwise create global user
|
||||
const account_id = qry_account_scope === 'global' ? undefined : $ae_loc.account_id;
|
||||
|
||||
@@ -87,12 +87,12 @@
|
||||
<div class="flex items-center justify-center px-4 bg-surface-300-600-token border-r border-surface-500/20">
|
||||
<Search size={18} class="opacity-50" />
|
||||
</div>
|
||||
<input
|
||||
<input
|
||||
class="bg-transparent border-0 ring-0 focus:ring-0 p-3 grow placeholder:opacity-50"
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search username or email..."
|
||||
onkeydown={(e) => e.key === 'Enter' && load_users()}
|
||||
type="search"
|
||||
bind:value={qry_str}
|
||||
placeholder="Search username or email..."
|
||||
onkeydown={(e) => e.key === 'Enter' && load_users()}
|
||||
/>
|
||||
<button class="variant-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]" onclick={load_users} disabled={loading}>
|
||||
{#if loading}
|
||||
@@ -145,7 +145,7 @@
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{#each user_li as user}
|
||||
{#each user_li as user (user.user_id_random)}
|
||||
<div class="card p-5 space-y-4 variant-soft-surface shadow-md border border-surface-500/10 hover:border-primary-500/30 transition-all group">
|
||||
<header class="flex justify-between items-start">
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -174,7 +174,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-2 text-xs opacity-70 bg-black/5 p-2 rounded-lg">
|
||||
<Mail size={14} class="text-primary-500" />
|
||||
|
||||
Reference in New Issue
Block a user