Nyan-Proxy / pages /admin /edit_user.html
WasabiDrop's picture
Refactor: Organize codebase with modular structure
62be87c
Raw
History Blame Contribute Delete
6.52 kB
{% extends "admin/base.html" %}
{% block title %}Edit User{% endblock %}
{% block content %}
<div class="edit-user">
<h1>Edit User</h1>
<div class="user-summary">
<p><strong>Token:</strong> <code>{{ user.token }}</code></p>
<p><strong>Created:</strong> {{ user.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</p>
<p><strong>Status:</strong>
{% if user.disabled_at %}
<span class="status-disabled">Disabled</span>
{% else %}
<span class="status-active">Active</span>
{% endif %}
</p>
</div>
<form method="POST" action="{{ url_for('admin.edit_user', token=user.token) }}" onsubmit="return validateUserForm()">
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
<div class="form-group">
<label for="nickname">Nickname:</label>
<input type="text" id="nickname" name="nickname" value="{{ user.nickname or '' }}" required>
<small>A human-readable identifier for this user</small>
</div>
<div class="form-group">
<label for="type">User Type:</label>
<select id="type" name="type">
<option value="normal" {{ 'selected' if user.type == 'normal' }}>Normal</option>
<option value="special" {{ 'selected' if user.type == 'special' }}>Special</option>
<option value="temporary" {{ 'selected' if user.type == 'temporary' }}>Temporary</option>
</select>
<small>
<strong>Normal:</strong> Standard user with default quotas<br>
<strong>Special:</strong> Premium user with higher limits and no rate limiting<br>
<strong>Temporary:</strong> Time-limited user (expires after 24 hours)
</small>
</div>
<div class="form-group">
<label for="openai_limit">OpenAI Token Limit:</label>
<input type="number" id="openai_limit" name="openai_limit" min="0"
value="{{ user.token_limits.get('openai', '') }}" placeholder="Leave empty for unlimited">
<small>Maximum tokens this user can consume for OpenAI models</small>
</div>
<div class="form-group">
<label for="anthropic_limit">Anthropic Token Limit:</label>
<input type="number" id="anthropic_limit" name="anthropic_limit" min="0"
value="{{ user.token_limits.get('anthropic', '') }}" placeholder="Leave empty for unlimited">
<small>Maximum tokens this user can consume for Anthropic models</small>
</div>
<div class="current-usage">
<h3>Current Usage</h3>
<table class="usage-table">
<thead>
<tr>
<th>Model Family</th>
<th>Input Tokens</th>
<th>Output Tokens</th>
<th>Total Tokens</th>
<th>Current Limit</th>
</tr>
</thead>
<tbody>
{% for family, count in user.token_counts.items() %}
<tr>
<td>{{ family }}</td>
<td>{{ count.input }}</td>
<td>{{ count.output }}</td>
<td>{{ count.total }}</td>
<td>{{ user.token_limits.get(family, 'Unlimited') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save Changes</button>
<a href="{{ url_for('admin.view_user', token=user.token) }}" class="btn btn-secondary">Cancel</a>
<button type="button" class="btn btn-warning" onclick="resetUserUsage()">Reset Usage</button>
</div>
</form>
</div>
<style>
.edit-user {
max-width: 800px;
margin: 0 auto;
}
.user-summary {
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-bottom: 30px;
}
.user-summary p {
margin: 5px 0;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input,
.form-group select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 3px;
font-size: 14px;
}
.form-group small {
display: block;
margin-top: 5px;
color: #666;
font-size: 12px;
}
.current-usage {
margin: 30px 0;
padding: 20px;
background: #f8f9fa;
border-radius: 5px;
}
.current-usage h3 {
margin-top: 0;
margin-bottom: 15px;
}
.usage-table {
width: 100%;
border-collapse: collapse;
}
.usage-table th,
.usage-table td {
padding: 8px;
border: 1px solid #dee2e6;
text-align: left;
}
.usage-table th {
background-color: #e9ecef;
}
.form-actions {
display: flex;
gap: 10px;
margin-top: 30px;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
text-decoration: none;
display: inline-block;
text-align: center;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
.btn-warning {
background-color: #ffc107;
color: black;
}
.btn:hover {
opacity: 0.9;
}
.status-active { color: #28a745; }
.status-disabled { color: #dc3545; }
</style>
<script>
function resetUserUsage() {
if (confirm('Are you sure you want to reset this user\'s token usage? This action cannot be undone.')) {
$.post(`/admin/users/{{ user.token }}/reset-usage`, {})
.done(function(data) {
if (data.success) {
alert('User usage reset successfully');
location.reload();
} else {
alert('Error: ' + data.error);
}
})
.fail(function() {
alert('Error: Failed to reset user usage');
});
}
}
</script>
{% endblock %}