Add Go rewrite with Postgres 17 and Dokploy Docker Compose
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
{{define "page_cabinet"}}
|
||||
{{template "guest_shell_open" dict "Title" "Личный кабинет" "Lang" (lang)}}
|
||||
<div class="cyber-shell">
|
||||
<span class="cyber-corner cyber-corner--tl"></span><span class="cyber-corner cyber-corner--tr"></span>
|
||||
<span class="cyber-corner cyber-corner--bl"></span><span class="cyber-corner cyber-corner--br"></span>
|
||||
<div class="cyber-hero">
|
||||
<div class="hero-icon"><i class="fa-solid fa-user-shield"></i></div>
|
||||
<div class="hero-brand">{{t "hero_brand"}}</div>
|
||||
<h1>{{.Member.Username}}</h1>
|
||||
<p class="lead">Личный кабинет VPN</p>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end mb-2">
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{{appURL "cabinet/logout"}}"><i class="fa-solid fa-right-from-bracket"></i> Выйти</a>
|
||||
</div>
|
||||
|
||||
{{template "guest_flash" .}}
|
||||
|
||||
{{if .Maintenance}}<div class="alert alert-warning">{{htmlSafe (t "maintenance_banner")}}</div>{{end}}
|
||||
|
||||
<div class="share-stats">
|
||||
<div class="card share-panel"><div class="share-panel__body text-center">
|
||||
<div class="stat__value--sm fw-bold">{{if .Sub}}{{.SubLabel}}{{else}}—{{end}}</div>
|
||||
<div class="hint mb-0">{{t "stat_valid_until"}}</div>
|
||||
</div></div>
|
||||
<div class="card share-panel"><div class="share-panel__body text-center">
|
||||
<div class="stat__value--sm fw-bold">{{if .Sub}}{{.ConfigsRemaining}} {{t "stat_of"}} {{.Sub.MaxConfigs}}{{else}}—{{end}}</div>
|
||||
<div class="hint mb-0">{{t "stat_remaining"}}</div>
|
||||
</div></div>
|
||||
</div>
|
||||
|
||||
{{if .Expired}}
|
||||
<div class="card share-panel">
|
||||
<div class="share-panel__head share-panel__head--pink"><i class="fa-solid fa-hourglass-end"></i> {{t "expired_card"}}</div>
|
||||
<div class="share-panel__body">
|
||||
<form method="post" action="{{appURL "cabinet"}}">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<input type="hidden" name="action" value="renew">
|
||||
<div class="mb-2"><input class="form-control" name="code" placeholder="{{t "renewal_code_ph"}}" required></div>
|
||||
<button class="btn btn-primary w-100" type="submit"><i class="fa-solid fa-key"></i> {{t "renewal_btn"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
|
||||
{{if .LimitReached}}
|
||||
<div class="alert alert-warning">{{t "limit_reached" "max" (printf "%d" .Sub.MaxConfigs)}}</div>
|
||||
{{else}}
|
||||
<div class="card share-panel">
|
||||
<div class="share-panel__head"><i class="fa-solid fa-plus"></i> {{t "field_location"}}</div>
|
||||
<div class="share-panel__body">
|
||||
<form method="post" action="{{appURL "cabinet"}}">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<input type="hidden" name="action" value="create">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{{t "field_location"}}</label>
|
||||
<select class="form-select" name="server_id" required {{if not .Servers}}disabled{{end}}>
|
||||
{{range .Servers}}<option value="{{.ID}}" {{if .Disabled}}disabled{{end}}>{{.Label}}</option>{{end}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label d-block">{{t "field_protocol"}}</label>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="protocol" id="proto_wg" value="wireguard" checked>
|
||||
<label class="form-check-label" for="proto_wg">WireGuard</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="protocol" id="proto_awg" value="awg2">
|
||||
<label class="form-check-label" for="proto_awg">AmneziaWG 2</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="protocol" id="proto_vless" value="vless">
|
||||
<label class="form-check-label" for="proto_vless">VLESS</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="hint">{{htmlSafe (t "hint_wait")}}</p>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fa-solid fa-bolt"></i> {{t "btn_get_config"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if .Bundles}}
|
||||
<div class="card share-panel card--download">
|
||||
<div class="share-panel__head"><i class="fa-solid fa-list"></i> {{t "configs_title"}}</div>
|
||||
<div class="share-panel__body">
|
||||
{{range .Bundles}}
|
||||
<div class="dl-bundle">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<strong class="mono">{{.ConnectionName}}</strong>
|
||||
<span class="badge text-bg-secondary">{{.Protocol}}</span>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
{{if .Conf}}<a class="btn btn-sm btn-outline-info" href="{{appURL "cabinet/download"}}?cre={{.CreationID}}&part=conf"><i class="fa-solid fa-download"></i> {{.Conf.Filename}}</a>{{end}}
|
||||
{{if .Vpn}}<a class="btn btn-sm btn-outline-info" href="{{appURL "cabinet/download"}}?cre={{.CreationID}}&part=vpn"><i class="fa-solid fa-download"></i> {{.Vpn.Filename}}</a>{{end}}
|
||||
{{if .Zip}}<a class="btn btn-sm btn-outline-secondary" href="{{appURL "cabinet/download"}}?cre={{.CreationID}}&part=zip"><i class="fa-solid fa-file-zipper"></i> .zip</a>{{end}}
|
||||
</div>
|
||||
<form method="post" action="{{appURL "cabinet"}}" class="mt-2" onsubmit="return confirm('Удалить эту конфигурацию?');">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="config_id" value="{{.CreationID}}">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger"><i class="fa-solid fa-trash"></i> Удалить</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if not .Expired}}
|
||||
<div class="card share-panel">
|
||||
<div class="share-panel__head"><i class="fa-solid fa-key"></i> {{t "renewal_title"}}</div>
|
||||
<div class="share-panel__body">
|
||||
<p class="hint">{{t "renewal_hint"}}</p>
|
||||
<form method="post" action="{{appURL "cabinet"}}">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<input type="hidden" name="action" value="renew">
|
||||
<div class="mb-2"><input class="form-control" name="code" placeholder="{{t "renewal_code_ph"}}" required></div>
|
||||
<button class="btn btn-outline-info w-100" type="submit"><i class="fa-solid fa-arrow-rotate-right"></i> {{t "renewal_btn"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{template "guest_footer" .}}
|
||||
{{template "guest_shell_close" .}}
|
||||
{{end}}
|
||||
@@ -0,0 +1,57 @@
|
||||
{{define "page_cabinet_auth"}}
|
||||
{{template "guest_shell_open" dict "Title" "Личный кабинет — вход" "Lang" (lang)}}
|
||||
<div class="cyber-shell">
|
||||
<span class="cyber-corner cyber-corner--tl"></span><span class="cyber-corner cyber-corner--tr"></span>
|
||||
<span class="cyber-corner cyber-corner--bl"></span><span class="cyber-corner cyber-corner--br"></span>
|
||||
<div class="cyber-hero">
|
||||
<div class="hero-icon"><i class="fa-solid fa-user-lock"></i></div>
|
||||
<div class="hero-brand">{{t "hero_brand"}}</div>
|
||||
<h1>Личный кабинет</h1>
|
||||
<p class="lead">Войдите или зарегистрируйтесь, чтобы получить свою подписку VPN.</p>
|
||||
</div>
|
||||
|
||||
{{if .Error}}<div class="alert alert-danger"><i class="fa-solid fa-triangle-exclamation"></i> {{.Error}}</div>{{end}}
|
||||
|
||||
<div class="card share-panel">
|
||||
<div class="share-panel__head"><i class="fa-solid fa-right-to-bracket"></i> Вход</div>
|
||||
<div class="share-panel__body">
|
||||
<form method="post" action="{{appURL "cabinet/login"}}">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Логин</label>
|
||||
<input class="form-control" name="username" required autocomplete="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Пароль</label>
|
||||
<input class="form-control" name="password" type="password" required autocomplete="current-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fa-solid fa-right-to-bracket"></i> Войти</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card share-panel">
|
||||
<div class="share-panel__head share-panel__head--pink"><i class="fa-solid fa-user-plus"></i> Регистрация</div>
|
||||
<div class="share-panel__body">
|
||||
<form method="post" action="{{appURL "cabinet/register"}}">
|
||||
<input type="hidden" name="_csrf" value="{{csrf}}">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Логин</label>
|
||||
<input class="form-control" name="username" required minlength="3" maxlength="64" pattern="[a-zA-Z0-9._-]+" autocomplete="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">E-mail (необязательно)</label>
|
||||
<input class="form-control" name="email" type="email" autocomplete="email">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Пароль</label>
|
||||
<input class="form-control" name="password" type="password" required minlength="8" autocomplete="new-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-info w-100"><i class="fa-solid fa-user-plus"></i> Создать аккаунт</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "guest_footer" .}}
|
||||
{{template "guest_shell_close" .}}
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user