Enhance VpnConfigDto to include ClientEmail and update related components
- Added ClientEmail property to VpnConfigDto for better client identification. - Updated ConfigCard to display the ClientEmail in the UI for improved user information. - Modified API schema and types to accommodate the new ClientEmail field. - Enhanced localization for displaying the ClientEmail in both Russian and English.
This commit is contained in:
@@ -5,13 +5,15 @@ namespace PnvPanel.Application.Configs;
|
||||
|
||||
/// <summary>
|
||||
/// Пользователю показываем только DisplayName + протокол инбаунда — адрес/хост ноды и прочие
|
||||
/// детали 3x-ui в этот DTO не попадают (см. domain-model.md).
|
||||
/// детали 3x-ui в этот DTO не попадают (см. domain-model.md). Исключение — ClientEmail: это не
|
||||
/// секрет и не адрес ноды, а просто ключ клиента в 3x-ui, полезный владельцу для диагностики
|
||||
/// (сверка конфига с записью в панели у админа).
|
||||
/// </summary>
|
||||
public sealed record VpnConfigDto(
|
||||
Guid Id, string? Label, VpnProtocol Protocol, string Location,
|
||||
Guid Id, string? Label, string ClientEmail, VpnProtocol Protocol, string Location,
|
||||
long UsedUpBytes, long UsedDownBytes, DateTimeOffset? ExpiresAt, ConfigStatus Status, DateTimeOffset CreatedAt)
|
||||
{
|
||||
public static VpnConfigDto FromDomain(VpnConfig config, Inbound inbound) => new(
|
||||
config.Id, config.Label, config.Protocol, inbound.DisplayName ?? inbound.Remark,
|
||||
config.Id, config.Label, config.ClientEmail, config.Protocol, inbound.DisplayName ?? inbound.Remark,
|
||||
config.UsedUpBytes, config.UsedDownBytes, config.ExpiresAt, config.Status, config.CreatedAt);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,9 @@ export function ConfigCard({ config }: { config: VpnConfigDto }) {
|
||||
<div className="text-sm text-muted-foreground">
|
||||
↑ {formatBytes(config.usedUpBytes)} ↓ {formatBytes(config.usedDownBytes)}
|
||||
</div>
|
||||
<p className="truncate font-mono text-xs text-muted-foreground/60">
|
||||
{t('configs.panelEmail', { email: config.clientEmail })}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button size="sm" variant="outline" onClick={() => setDetailsOpen(true)}>
|
||||
<QrCode className="h-4 w-4" />
|
||||
|
||||
@@ -2071,6 +2071,7 @@ export interface components {
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
label: null | string;
|
||||
clientEmail: string;
|
||||
protocol: components["schemas"]["VpnProtocol"];
|
||||
location: string;
|
||||
/** Format: int64 */
|
||||
|
||||
@@ -49,6 +49,7 @@ export type ActivationStatusDto = {
|
||||
export type VpnConfigDto = {
|
||||
id: string
|
||||
label: string | null
|
||||
clientEmail: string
|
||||
protocol: VpnProtocol
|
||||
location: string
|
||||
usedUpBytes: number
|
||||
|
||||
@@ -87,6 +87,7 @@ const resources = {
|
||||
copyLink: 'Скопировать ссылку',
|
||||
loadingLink: 'Загрузка ссылки…',
|
||||
subscriptionLink: 'Ссылка-подписка (для клиента):',
|
||||
panelEmail: 'Email в панели: {{email}}',
|
||||
aggregatedSubscription: 'Общая подписка',
|
||||
aggregatedSubscriptionHint: 'Одна ссылка/QR со всеми активными конфигами — удобно добавить один раз в клиент.',
|
||||
status: {
|
||||
@@ -379,6 +380,7 @@ const resources = {
|
||||
copyLink: 'Copy link',
|
||||
loadingLink: 'Loading link…',
|
||||
subscriptionLink: 'Subscription link (for the client app):',
|
||||
panelEmail: 'Panel email: {{email}}',
|
||||
aggregatedSubscription: 'Aggregated subscription',
|
||||
aggregatedSubscriptionHint: 'One link/QR with all active configs — add it once to your client.',
|
||||
status: {
|
||||
|
||||
Reference in New Issue
Block a user