Refactor user table display logic in users page
Publish telemt-api gateway Docker image / test (push) Successful in 26s
Publish telemt-api gateway Docker image / build-and-push (push) Successful in 2m11s

- Updated the user table to conditionally render rows based on the presence of IP-server pairs, improving clarity in data presentation.
- Simplified the rendering of user data when no pairs are available, ensuring a cleaner UI.
- Enhanced the display of user links and metrics, maintaining consistent formatting across different scenarios.
This commit is contained in:
Denozordec
2026-03-30 13:48:40 +07:00
parent 40bcfbf993
commit 43ef4a799e
+80 -50
View File
@@ -127,58 +127,88 @@
{@const username = row.username ?? ''}
{@const pairs = ipServerPairsByUser[username] ?? []}
<Table.Row>
<Table.Cell class="font-medium">
<a href="/users/{encodeURIComponent(row.username ?? '')}" class="text-primary hover:underline">
{row.username}
</a>
</Table.Cell>
<Table.Cell>
<div class="flex flex-wrap gap-1">
{#each row.links?.tls ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
TLS
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
{#each row.links?.secure ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
t.me
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
</div>
</Table.Cell>
<Table.Cell class="text-right tabular-nums">{formatMiB(row.total_megabytes ?? 0)}</Table.Cell>
<Table.Cell class="text-right text-sm tabular-nums">
{#if (row.active_unique_ips ?? 0) > 0}
{row.active_unique_ips}
{#if row.max_unique_ips != null}
<span class="text-muted-foreground"> / {row.max_unique_ips}</span>
{/if}
{:else}
{/if}
</Table.Cell>
<Table.Cell class="text-right text-sm">
{row.data_quota_bytes != null ? formatBytes(row.data_quota_bytes) : '—'}
</Table.Cell>
<Table.Cell class="text-sm text-muted-foreground">
{row.expiration_rfc3339
? new Date(row.expiration_rfc3339).toLocaleString()
: '—'}
</Table.Cell>
</Table.Row>
{#if pairs.length > 0}
{#each pairs as pair (pair.ip + '|' + pair.server)}
{#if pairs.length === 0}
<Table.Row>
<Table.Cell class="font-medium">
<a href="/users/{encodeURIComponent(row.username ?? '')}" class="text-primary hover:underline">
{row.username}
</a>
</Table.Cell>
<Table.Cell>
<div class="flex flex-wrap gap-1">
{#each row.links?.tls ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
TLS
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
{#each row.links?.secure ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
t.me
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
</div>
</Table.Cell>
<Table.Cell class="text-right tabular-nums">{formatMiB(row.total_megabytes ?? 0)}</Table.Cell>
<Table.Cell class="text-right text-sm font-mono"></Table.Cell>
<Table.Cell class="text-right text-sm">
{row.data_quota_bytes != null ? formatBytes(row.data_quota_bytes) : '—'}
</Table.Cell>
<Table.Cell class="text-sm text-muted-foreground">
{row.expiration_rfc3339 ? new Date(row.expiration_rfc3339).toLocaleString() : '—'}
</Table.Cell>
</Table.Row>
{:else}
{#each pairs as pair, idx (pair.ip + '|' + pair.server)}
<Table.Row>
<Table.Cell>&nbsp;</Table.Cell>
<Table.Cell>&nbsp;</Table.Cell>
<Table.Cell>&nbsp;</Table.Cell>
<Table.Cell class="font-medium">
<a href="/users/{encodeURIComponent(row.username ?? '')}" class="text-primary hover:underline">
{row.username}
</a>
</Table.Cell>
<Table.Cell>
{#if idx === 0}
<div class="flex flex-wrap gap-1">
{#each row.links?.tls ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
TLS
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
{#each row.links?.secure ?? [] as link (link)}
<Button variant="outline" size="xs" class="h-7 gap-1 px-2 text-xs" onclick={() => copy(link)}>
t.me
<CopyIcon class="size-3 opacity-60" />
</Button>
{/each}
</div>
{:else}
&nbsp;
{/if}
</Table.Cell>
<Table.Cell class="text-right tabular-nums">
{#if idx === 0}
{formatMiB(row.total_megabytes ?? 0)}
{:else}
&nbsp;
{/if}
</Table.Cell>
<Table.Cell class="text-right text-sm font-mono">{pair.ip} - {pair.server}</Table.Cell>
<Table.Cell>&nbsp;</Table.Cell>
<Table.Cell>&nbsp;</Table.Cell>
<Table.Cell class="text-right text-sm tabular-nums">
{#if idx === 0}
{row.data_quota_bytes != null ? formatBytes(row.data_quota_bytes) : '—'}
{:else}
&nbsp;
{/if}
</Table.Cell>
<Table.Cell class="text-sm text-muted-foreground">
{#if idx === 0}
{row.expiration_rfc3339 ? new Date(row.expiration_rfc3339).toLocaleString() : '—'}
{:else}
&nbsp;
{/if}
</Table.Cell>
</Table.Row>
{/each}
{/if}