186 lines
8.0 KiB
HTML
186 lines
8.0 KiB
HTML
|
|
{% extends "admin/base.html" %}
|
||
|
|
|
||
|
|
{% block title %}User: {{ user.username }}{% endblock %}
|
||
|
|
|
||
|
|
{% block content %}
|
||
|
|
<div class="page-header">
|
||
|
|
<h1 class="page-title">{{ user.username }}</h1>
|
||
|
|
<p class="page-subtitle">User ID: {{ user.id }} | Created: {{ user.created_at.strftime('%Y-%m-%d %H:%M') }}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="detail-grid">
|
||
|
|
<div class="detail-section">
|
||
|
|
<h3 class="detail-section-title">Storage Usage</h3>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">Used</span>
|
||
|
|
<span class="detail-value">{{ user.used_storage_bytes | format_bytes }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">Quota</span>
|
||
|
|
<span class="detail-value">{{ user.storage_quota_bytes | format_bytes }}</span>
|
||
|
|
</div>
|
||
|
|
<div style="margin-top: 12px;">
|
||
|
|
<div class="progress-bar">
|
||
|
|
<div class="progress-fill {% if usage_percent > 90 %}danger{% elif usage_percent > 75 %}warning{% endif %}" style="width: {{ usage_percent }}%"></div>
|
||
|
|
</div>
|
||
|
|
<div style="text-align: center; margin-top: 8px; font-size: 0.85rem; color: var(--text-color-light);">
|
||
|
|
{{ "%.1f" | format(usage_percent) }}% used
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="detail-section">
|
||
|
|
<h3 class="detail-section-title">Account Status</h3>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">Status</span>
|
||
|
|
<span class="detail-value">
|
||
|
|
{% if user.is_active %}
|
||
|
|
<span class="badge badge-success">Active</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-danger">Inactive</span>
|
||
|
|
{% endif %}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">Role</span>
|
||
|
|
<span class="detail-value">
|
||
|
|
{% if user.is_superuser %}
|
||
|
|
<span class="badge badge-info">Administrator</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-secondary">User</span>
|
||
|
|
{% endif %}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">2FA</span>
|
||
|
|
<span class="detail-value">
|
||
|
|
{% if user.is_2fa_enabled %}
|
||
|
|
<span class="badge badge-success">Enabled</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-secondary">Disabled</span>
|
||
|
|
{% endif %}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div class="detail-row">
|
||
|
|
<span class="detail-label">Plan</span>
|
||
|
|
<span class="detail-value">{{ user.plan_type }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card" style="margin-top: 24px;">
|
||
|
|
<div class="card-header">
|
||
|
|
<h2 class="card-title">Edit User</h2>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<form method="POST" action="/manage/users/{{ user.id }}">
|
||
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
|
|
|
||
|
|
<div class="form-row">
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label" for="username">Username</label>
|
||
|
|
<input type="text" id="username" name="username" class="form-input" value="{{ user.username }}" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label" for="email">Email</label>
|
||
|
|
<input type="email" id="email" name="email" class="form-input" value="{{ user.email }}" required>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-row">
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label" for="password">New Password (leave empty to keep current)</label>
|
||
|
|
<input type="password" id="password" name="password" class="form-input" placeholder="Enter new password...">
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label" for="storage_quota_gb">Storage Quota (GB)</label>
|
||
|
|
<input type="number" id="storage_quota_gb" name="storage_quota_gb" class="form-input"
|
||
|
|
value="{{ (user.storage_quota_bytes / 1073741824) | round(2) }}" step="0.1" min="0" required>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-row">
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label" for="plan_type">Plan Type</label>
|
||
|
|
<select id="plan_type" name="plan_type" class="form-select">
|
||
|
|
<option value="free" {% if user.plan_type == 'free' %}selected{% endif %}>Free</option>
|
||
|
|
<option value="basic" {% if user.plan_type == 'basic' %}selected{% endif %}>Basic</option>
|
||
|
|
<option value="premium" {% if user.plan_type == 'premium' %}selected{% endif %}>Premium</option>
|
||
|
|
<option value="enterprise" {% if user.plan_type == 'enterprise' %}selected{% endif %}>Enterprise</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label class="form-label"> </label>
|
||
|
|
<div style="display: flex; gap: 24px; padding-top: 8px;">
|
||
|
|
<label class="form-checkbox">
|
||
|
|
<input type="checkbox" name="is_active" value="true" {% if user.is_active %}checked{% endif %}>
|
||
|
|
<span>Active</span>
|
||
|
|
</label>
|
||
|
|
<label class="form-checkbox">
|
||
|
|
<input type="checkbox" name="is_superuser" value="true" {% if user.is_superuser %}checked{% endif %}>
|
||
|
|
<span>Administrator</span>
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-actions">
|
||
|
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||
|
|
<a href="/manage/users" class="btn btn-outline">Cancel</a>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{% if invoices %}
|
||
|
|
<div class="card" style="margin-top: 24px;">
|
||
|
|
<div class="card-header">
|
||
|
|
<h2 class="card-title">Recent Invoices</h2>
|
||
|
|
<a href="/manage/payments?user_id={{ user.id }}" class="btn btn-sm btn-outline">View All</a>
|
||
|
|
</div>
|
||
|
|
<div class="table-container">
|
||
|
|
<table class="data-table">
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>Invoice #</th>
|
||
|
|
<th>Period</th>
|
||
|
|
<th>Total</th>
|
||
|
|
<th>Status</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
{% for invoice in invoices %}
|
||
|
|
<tr>
|
||
|
|
<td><a href="/manage/payments/{{ invoice.id }}">{{ invoice.invoice_number }}</a></td>
|
||
|
|
<td>{{ invoice.period_start.strftime('%Y-%m-%d') }} - {{ invoice.period_end.strftime('%Y-%m-%d') }}</td>
|
||
|
|
<td>{{ invoice.total | format_currency }}</td>
|
||
|
|
<td>
|
||
|
|
{% if invoice.status == 'paid' %}
|
||
|
|
<span class="badge badge-success">Paid</span>
|
||
|
|
{% elif invoice.status == 'open' %}
|
||
|
|
<span class="badge badge-warning">Open</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-secondary">{{ invoice.status }}</span>
|
||
|
|
{% endif %}
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
{% endfor %}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
<div class="card" style="margin-top: 24px; border-color: var(--danger-color);">
|
||
|
|
<div class="card-header">
|
||
|
|
<h2 class="card-title" style="color: var(--danger-color);">Danger Zone</h2>
|
||
|
|
</div>
|
||
|
|
<p style="margin-bottom: 16px; color: var(--text-color-light);">
|
||
|
|
Deleting a user is permanent and cannot be undone. All files and data associated with this user will be lost.
|
||
|
|
</p>
|
||
|
|
<form method="POST" action="/manage/users/{{ user.id }}/delete" onsubmit="return confirm('Are you sure you want to delete this user? This action cannot be undone.');">
|
||
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
|
|
<button type="submit" class="btn btn-danger">Delete User</button>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
{% endblock %}
|