mirror of
https://github.com/wizarrrr/wizarr.git
synced 2026-07-31 23:37:07 -04:00
fix: lint:
This commit is contained in:
@@ -3,109 +3,109 @@
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-title">
|
||||
<!-- Modal header -->
|
||||
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ _("Remove User") }}: {{ display_name }}</h3>
|
||||
<button type="button"
|
||||
onclick="closeModal()"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Modal header -->
|
||||
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ _("Remove User") }}: {{ display_name }}</h3>
|
||||
<button type="button"
|
||||
onclick="closeModal()"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Modal body -->
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<form hx-post="{{ url_for('admin.process_user_deletion') }}"
|
||||
hx-include="this">
|
||||
<!-- User info -->
|
||||
<div class="mb-4 p-3 bg-gray-50 rounded-lg dark:bg-gray-600">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="flex-shrink-0 w-10 h-10 bg-gray-200 dark:bg-gray-700 rounded-full flex items-center justify-center">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-300">{{ display_name[0]|upper }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-gray-900 dark:text-white">{{ display_name }}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">{{ user_email or _("Home User") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal body -->
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<form hx-post="{{ url_for('admin.process_user_deletion') }}"
|
||||
hx-include="this">
|
||||
<!-- User info -->
|
||||
<div class="mb-4 p-3 bg-gray-50 rounded-lg dark:bg-gray-600">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="flex-shrink-0 w-10 h-10 bg-gray-200 dark:bg-gray-700 rounded-full flex items-center justify-center">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-300">{{ display_name[0]|upper }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-gray-900 dark:text-white">{{ display_name }}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">{{ user_email or _("Home User") }}</div>
|
||||
</div>
|
||||
<p class="mb-4 text-sm text-gray-500 dark:text-gray-400">{{ _("Select which servers to remove the user from:") }}</p>
|
||||
<!-- Server list -->
|
||||
<div class="space-y-2 mb-6">
|
||||
{% for account in accounts %}
|
||||
<label class="flex items-center p-3 border border-gray-200 rounded-lg hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-700 cursor-pointer">
|
||||
<input type="checkbox"
|
||||
name="server_accounts"
|
||||
value="{{ account.id }}"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:bg-gray-700 dark:border-gray-600">
|
||||
<div class="ml-3 flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{% if account.server %}
|
||||
{{ account.server.server_type|title }}
|
||||
{% else %}
|
||||
{{ _("Local") }}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if account.server %}
|
||||
<span class="text-xs px-2 py-1 bg-gray-100 text-gray-600 rounded dark:bg-gray-600 dark:text-gray-300">
|
||||
{{ account.server.name }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">{{ _("User ID") }}: {{ account.id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mb-4 text-sm text-gray-500 dark:text-gray-400">{{ _("Select which servers to remove the user from:") }}</p>
|
||||
<!-- Server list -->
|
||||
<div class="space-y-2 mb-6">
|
||||
{% for account in accounts %}
|
||||
<label class="flex items-center p-3 border border-gray-200 rounded-lg hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-700 cursor-pointer">
|
||||
<input type="checkbox"
|
||||
name="server_accounts"
|
||||
value="{{ account.id }}"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:bg-gray-700 dark:border-gray-600">
|
||||
<div class="ml-3 flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{% if account.server %}
|
||||
{{ account.server.server_type|title }}
|
||||
{% else %}
|
||||
{{ _("Local") }}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if account.server %}
|
||||
<span class="text-xs px-2 py-1 bg-gray-100 text-gray-600 rounded dark:bg-gray-600 dark:text-gray-300">
|
||||
{{ account.server.name }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">{{ _("User ID") }}: {{ account.id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Select all checkbox -->
|
||||
<div class="mb-6 p-3 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900 dark:border-red-700">
|
||||
<label class="flex items-center cursor-pointer">
|
||||
<input type="checkbox"
|
||||
id="select_all_servers"
|
||||
class="w-4 h-4 text-red-600 bg-gray-100 border-gray-300 rounded focus:ring-red-500 dark:focus:ring-red-600 dark:ring-offset-gray-800 dark:bg-gray-700 dark:border-gray-600">
|
||||
<div class="ml-3">
|
||||
<div class="text-sm font-medium text-red-800 dark:text-red-300">{{ _("Delete from ALL servers") }}</div>
|
||||
<div class="text-xs text-red-700 dark:text-red-400">
|
||||
{{ _("This will remove the user completely and cannot be undone") }}
|
||||
</div>
|
||||
<!-- Select all checkbox -->
|
||||
<div class="mb-6 p-3 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900 dark:border-red-700">
|
||||
<label class="flex items-center cursor-pointer">
|
||||
<input type="checkbox"
|
||||
id="select_all_servers"
|
||||
class="w-4 h-4 text-red-600 bg-gray-100 border-gray-300 rounded focus:ring-red-500 dark:focus:ring-red-600 dark:ring-offset-gray-800 dark:bg-gray-700 dark:border-gray-600">
|
||||
<div class="ml-3">
|
||||
<div class="text-sm font-medium text-red-800 dark:text-red-300">{{ _("Delete from ALL servers") }}</div>
|
||||
<div class="text-xs text-red-700 dark:text-red-400">
|
||||
{{ _("This will remove the user completely and cannot be undone") }}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Action buttons -->
|
||||
<div class="flex items-center justify-end space-x-3">
|
||||
<button type="button"
|
||||
onclick="closeModal()"
|
||||
class="px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 hover:bg-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||
{{ _("Cancel") }}
|
||||
</button>
|
||||
<button type="submit"
|
||||
id="delete_submit_btn"
|
||||
disabled
|
||||
class="px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:bg-gray-400 disabled:cursor-not-allowed rounded-lg">
|
||||
<span id="delete-btn-text">{{ _("Remove Selected") }}</span>
|
||||
<span id="delete-btn-loading" class="hidden">
|
||||
<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white inline"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
|
||||
</path>
|
||||
</svg>
|
||||
{{ _("Deleting user...") }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Action buttons -->
|
||||
<div class="flex items-center justify-end space-x-3">
|
||||
<button type="button"
|
||||
onclick="closeModal()"
|
||||
class="px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 hover:bg-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||
{{ _("Cancel") }}
|
||||
</button>
|
||||
<button type="submit"
|
||||
id="delete_submit_btn"
|
||||
disabled
|
||||
class="px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:bg-gray-400 disabled:cursor-not-allowed rounded-lg">
|
||||
<span id="delete-btn-text">{{ _("Remove Selected") }}</span>
|
||||
<span id="delete-btn-loading" class="hidden">
|
||||
<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white inline"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
|
||||
</path>
|
||||
</svg>
|
||||
{{ _("Deleting user...") }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Initialize modal functionality immediately when content loads
|
||||
|
||||
@@ -2,146 +2,146 @@
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-title">
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<div class="flex justify-between items-center pb-3">
|
||||
<h2 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ _("User Details") }}
|
||||
</h2>
|
||||
<button type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
<span class="sr-only">Close modal</span>
|
||||
</button>
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<div class="flex justify-between items-center pb-3">
|
||||
<h2 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ _("User Details") }}
|
||||
</h2>
|
||||
<button type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
<span class="sr-only">Close modal</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Header -->
|
||||
<div class="flex items-center mb-4">
|
||||
{% if user.photo %}
|
||||
<img class="w-12 h-12 rounded-full mr-3"
|
||||
src="{{ user.photo }}"
|
||||
alt="{{ user.username }}">
|
||||
{% else %}
|
||||
<div class="w-12 h-12 rounded-full bg-gray-200 dark:bg-gray-600 flex items-center justify-center mr-3">
|
||||
<svg class="w-6 h-6 text-gray-500 dark:text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ user.username }}</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ user.email or 'Home User' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Details body -->
|
||||
<div class="space-y-6 text-sm text-gray-600 dark:text-gray-300">
|
||||
<!-- Join date -->
|
||||
<div class="flex items-center">
|
||||
<svg class="w-4 h-4 mr-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1z">
|
||||
</path>
|
||||
</svg>
|
||||
<span class="font-medium mr-1">{{ _("Joined") }}:</span>
|
||||
{{ join_date|default(_('Unknown') ) if join_date else _('Unknown') }}
|
||||
</div>
|
||||
<!-- Account sections -->
|
||||
{% for info in accounts_info %}
|
||||
<div class="border border-gray-200 dark:border-gray-600 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-medium text-gray-900 dark:text-white">{{ _("Account Details") }}</span>
|
||||
{{ info.server_type|server_name_tag(info.server_name) }}
|
||||
</div>
|
||||
<!-- Header -->
|
||||
<div class="flex items-center mb-4">
|
||||
{% if user.photo %}
|
||||
<img class="w-12 h-12 rounded-full mr-3"
|
||||
src="{{ user.photo }}"
|
||||
alt="{{ user.username }}">
|
||||
<p class="mb-3 text-gray-500 dark:text-gray-400">
|
||||
<span class="font-medium">{{ _("Username") }}:</span> {{ info.username }}
|
||||
</p>
|
||||
<!-- Libraries -->
|
||||
<div class="mb-4">
|
||||
<p class="font-medium mb-2">{{ _("Libraries") }}:</p>
|
||||
{% if info.libraries %}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{% for lib in info.libraries %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M7 3a1 1 0 000 2h6a1 1 0 100-2H7zM4 7a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1zM2 11a2 2 0 012-2h12a2 2 0 012 2v4a2 2 0 01-2 2H4a2 2 0 01-2-2v-4z" />
|
||||
</svg>
|
||||
{{ lib }}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="w-12 h-12 rounded-full bg-gray-200 dark:bg-gray-600 flex items-center justify-center mr-3">
|
||||
<svg class="w-6 h-6 text-gray-500 dark:text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path>
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
{{ _("All libraries") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ user.username }}</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ user.email or 'Home User' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Details body -->
|
||||
<div class="space-y-6 text-sm text-gray-600 dark:text-gray-300">
|
||||
<!-- Join date -->
|
||||
<div class="flex items-center">
|
||||
<svg class="w-4 h-4 mr-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1z">
|
||||
</path>
|
||||
</svg>
|
||||
<span class="font-medium mr-1">{{ _("Joined") }}:</span>
|
||||
{{ join_date|default(_('Unknown') ) if join_date else _('Unknown') }}
|
||||
<!-- Permissions -->
|
||||
<div>
|
||||
<p class="font-medium mb-2">{{ _("Permissions") }}:</p>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{% if info.is_admin %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-0.257-0.257A6 6 0 1118 8zM2 8a6 6 0 1010.743 5.743L12 14l0.257-0.257A6 6 0 012 8zm8-2a2 2 0 100 4 2 2 0 000-4z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Admin") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_downloads %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Downloads") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_live_tv %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M2 3a1 1 0 011-1h14a1 1 0 011 1v14a1 1 0 01-1 1H3a1 1 0 01-1-1V3zm2 2v10h12V5H4zm2 2h2v2H6V7zm6 0h2v2h-2V7zM6 11h2v2H6v-2zm6 0h2v2h-2v-2z" />
|
||||
</svg>
|
||||
{{ _("Live TV") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_camera_upload %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4 5a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-1.586a1 1 0 01-.707-.293l-1.121-1.121A2 2 0 0011.172 3H8.828a2 2 0 00-1.414.586L6.293 4.707A1 1 0 015.586 5H4zm6 9a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Camera Upload") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if not info.is_admin and not info.allow_downloads and not info.allow_live_tv and not info.allow_camera_upload %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Basic Access") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- Account sections -->
|
||||
{% for info in accounts_info %}
|
||||
<div class="border border-gray-200 dark:border-gray-600 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-medium text-gray-900 dark:text-white">{{ _("Account Details") }}</span>
|
||||
{{ info.server_type|server_name_tag(info.server_name) }}
|
||||
</div>
|
||||
<p class="mb-3 text-gray-500 dark:text-gray-400">
|
||||
<span class="font-medium">{{ _("Username") }}:</span> {{ info.username }}
|
||||
</p>
|
||||
<!-- Libraries -->
|
||||
<div class="mb-4">
|
||||
<p class="font-medium mb-2">{{ _("Libraries") }}:</p>
|
||||
{% if info.libraries %}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{% for lib in info.libraries %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M7 3a1 1 0 000 2h6a1 1 0 100-2H7zM4 7a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1zM2 11a2 2 0 012-2h12a2 2 0 012 2v4a2 2 0 01-2 2H4a2 2 0 01-2-2v-4z" />
|
||||
</svg>
|
||||
{{ lib }}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("All libraries") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- Permissions -->
|
||||
<div>
|
||||
<p class="font-medium mb-2">{{ _("Permissions") }}:</p>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{% if info.is_admin %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-0.257-0.257A6 6 0 1118 8zM2 8a6 6 0 1010.743 5.743L12 14l0.257-0.257A6 6 0 012 8zm8-2a2 2 0 100 4 2 2 0 000-4z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Admin") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_downloads %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Downloads") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_live_tv %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M2 3a1 1 0 011-1h14a1 1 0 011 1v14a1 1 0 01-1 1H3a1 1 0 01-1-1V3zm2 2v10h12V5H4zm2 2h2v2H6V7zm6 0h2v2h-2V7zM6 11h2v2H6v-2zm6 0h2v2h-2v-2z" />
|
||||
</svg>
|
||||
{{ _("Live TV") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if info.allow_camera_upload %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4 5a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-1.586a1 1 0 01-.707-.293l-1.121-1.121A2 2 0 0011.172 3H8.828a2 2 0 00-1.414.586L6.293 4.707A1 1 0 015.586 5H4zm6 9a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Camera Upload") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if not info.is_admin and not info.allow_downloads and not info.allow_live_tv and not info.allow_camera_upload %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300">
|
||||
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{{ _("Basic Access") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Actions -->
|
||||
<div class="px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-gray-800 mt-6">
|
||||
<button type="button"
|
||||
class="inline-flex w-full justify-center rounded-md bg-primary px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-primary_hover sm:ml-3 sm:w-auto"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">{{ _("Close") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Actions -->
|
||||
<div class="px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-gray-800 mt-6">
|
||||
<button type="button"
|
||||
class="inline-flex w-full justify-center rounded-md bg-primary px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-primary_hover sm:ml-3 sm:w-auto"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">{{ _("Close") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,140 +2,140 @@
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-title">
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<div class="flex justify-between items-center pb-3">
|
||||
<h2 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ _("Edit expiry") }} – {{ user.username or user.email }}
|
||||
</h2>
|
||||
<button type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
<span class="sr-only">Close modal</span>
|
||||
</button>
|
||||
</div>
|
||||
{% if user.identity_id and related_users and related_users|length > 1 %}
|
||||
<!-- Multi-server user management -->
|
||||
<div class="mb-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">{{ _("Server-specific Expiry Management") }}</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
{{ _("This user exists on multiple servers. You can set different expiry dates for each server.") }}
|
||||
</p>
|
||||
<div class="space-y-4">
|
||||
{% for related_user in related_users %}
|
||||
<div class="border border-gray-200 dark:border-gray-600 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="flex items-center">
|
||||
{% if related_user.server %}
|
||||
{{ related_user.server.server_type|server_name_tag(related_user.server.name) }}
|
||||
{% else %}
|
||||
{{ 'local'|server_type_tag }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">ID: {{ related_user.id }}</span>
|
||||
</div>
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=related_user.id) }}"
|
||||
class="flex items-end gap-3">
|
||||
<div class="flex-1">
|
||||
<label for="expires_{{ related_user.id }}"
|
||||
class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{{ _("Expiry date") }}
|
||||
</label>
|
||||
<input id="expires_{{ related_user.id }}"
|
||||
name="expires"
|
||||
type="datetime-local"
|
||||
value="{{ related_user.expires|default('', true) and related_user.expires.strftime('%Y-%m-%dT%H:%M') or '' }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-3 py-2.5 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary_hover focus:ring-4 focus:outline-none focus:ring-primary_focus dark:bg-primary dark:hover:bg-primary_hover dark:focus:ring-primary_focus">
|
||||
{{ _("Update") }}
|
||||
</button>
|
||||
</form>
|
||||
<div class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{% if related_user.expires %}
|
||||
{{ _("Current expiry") }}: {{ related_user.expires|human_date }}
|
||||
{% else %}
|
||||
{{ _("No expiry set") }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Global Notes section for multi-server users -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-600">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">{{ _("Notes") }}</h4>
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=user.id) }}"
|
||||
class="space-y-3">
|
||||
<div>
|
||||
<textarea id="notes"
|
||||
name="notes"
|
||||
rows="3"
|
||||
placeholder="{{ _('Add notes about this user...') }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">{{ user.notes|default('', true) }}</textarea>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary_hover focus:ring-4 focus:outline-none focus:ring-primary_focus dark:bg-primary dark:hover:bg-primary_hover dark:focus:ring-primary_focus">
|
||||
{{ _("Update Notes") }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Single server user management -->
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=user.id) }}"
|
||||
class="space-y-4 md:space-y-6">
|
||||
<div>
|
||||
<label for="expires"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ _("Expiry date (leave blank for never)") }}
|
||||
</label>
|
||||
<input id="expires"
|
||||
name="expires"
|
||||
type="datetime-local"
|
||||
value="{{ user.expires|default('', true) and user.expires.strftime('%Y-%m-%dT%H:%M') or '' }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
|
||||
</div>
|
||||
<div>
|
||||
<label for="notes"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{{ _("Notes") }}</label>
|
||||
<textarea id="notes"
|
||||
name="notes"
|
||||
rows="3"
|
||||
placeholder="{{ _('Add notes about this user...') }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">{{ user.notes|default('', true) }}</textarea>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-gray-800">
|
||||
<button type="submit"
|
||||
class="inline-flex w-full justify-center rounded-md bg-primary px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-primary_hover sm:ml-3 sm:w-auto">
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
<button type="button"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">{{ _("Cancel") }}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if invitation %}
|
||||
<!-- Additional invitation context -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-600">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">{{ _("Invitation Details") }}</h4>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<div>
|
||||
{{ _("Code") }}: <span class="font-mono">{{ invitation.code }}</span>
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-gray-800">
|
||||
<div class="flex justify-between items-center pb-3">
|
||||
<h2 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ _("Edit expiry") }} – {{ user.username or user.email }}
|
||||
</h2>
|
||||
<button type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">
|
||||
<svg class="w-3 h-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
<span class="sr-only">Close modal</span>
|
||||
</button>
|
||||
</div>
|
||||
{% if user.identity_id and related_users and related_users|length > 1 %}
|
||||
<!-- Multi-server user management -->
|
||||
<div class="mb-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">{{ _("Server-specific Expiry Management") }}</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
{{ _("This user exists on multiple servers. You can set different expiry dates for each server.") }}
|
||||
</p>
|
||||
<div class="space-y-4">
|
||||
{% for related_user in related_users %}
|
||||
<div class="border border-gray-200 dark:border-gray-600 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="flex items-center">
|
||||
{% if related_user.server %}
|
||||
{{ related_user.server.server_type|server_name_tag(related_user.server.name) }}
|
||||
{% else %}
|
||||
{{ 'local'|server_type_tag }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if invitation.duration %}<div>{{ _("Duration") }}: {{ invitation.duration }} {{ _("days") }}</div>{% endif %}
|
||||
{% if invitation.expires %}<div>{{ _("Invitation expires") }}: {{ invitation.expires|human_date }}</div>{% endif %}
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">ID: {{ related_user.id }}</span>
|
||||
</div>
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=related_user.id) }}"
|
||||
class="flex items-end gap-3">
|
||||
<div class="flex-1">
|
||||
<label for="expires_{{ related_user.id }}"
|
||||
class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{{ _("Expiry date") }}
|
||||
</label>
|
||||
<input id="expires_{{ related_user.id }}"
|
||||
name="expires"
|
||||
type="datetime-local"
|
||||
value="{{ related_user.expires|default('', true) and related_user.expires.strftime('%Y-%m-%dT%H:%M') or '' }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-3 py-2.5 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary_hover focus:ring-4 focus:outline-none focus:ring-primary_focus dark:bg-primary dark:hover:bg-primary_hover dark:focus:ring-primary_focus">
|
||||
{{ _("Update") }}
|
||||
</button>
|
||||
</form>
|
||||
<div class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{% if related_user.expires %}
|
||||
{{ _("Current expiry") }}: {{ related_user.expires|human_date }}
|
||||
{% else %}
|
||||
{{ _("No expiry set") }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Global Notes section for multi-server users -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-600">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">{{ _("Notes") }}</h4>
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=user.id) }}"
|
||||
class="space-y-3">
|
||||
<div>
|
||||
<textarea id="notes"
|
||||
name="notes"
|
||||
rows="3"
|
||||
placeholder="{{ _('Add notes about this user...') }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">{{ user.notes|default('', true) }}</textarea>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary_hover focus:ring-4 focus:outline-none focus:ring-primary_focus dark:bg-primary dark:hover:bg-primary_hover dark:focus:ring-primary_focus">
|
||||
{{ _("Update Notes") }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Single server user management -->
|
||||
<form hx-post="{{ url_for('admin.user_detail', db_id=user.id) }}"
|
||||
class="space-y-4 md:space-y-6">
|
||||
<div>
|
||||
<label for="expires"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ _("Expiry date (leave blank for never)") }}
|
||||
</label>
|
||||
<input id="expires"
|
||||
name="expires"
|
||||
type="datetime-local"
|
||||
value="{{ user.expires|default('', true) and user.expires.strftime('%Y-%m-%dT%H:%M') or '' }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
|
||||
</div>
|
||||
<div>
|
||||
<label for="notes"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{{ _("Notes") }}</label>
|
||||
<textarea id="notes"
|
||||
name="notes"
|
||||
rows="3"
|
||||
placeholder="{{ _('Add notes about this user...') }}"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary focus:border-primary block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">{{ user.notes|default('', true) }}</textarea>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-gray-800">
|
||||
<button type="submit"
|
||||
class="inline-flex w-full justify-center rounded-md bg-primary px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-primary_hover sm:ml-3 sm:w-auto">
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
<button type="button"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
|
||||
onclick="document.getElementById('modal').classList.add('hidden')">{{ _("Cancel") }}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if invitation %}
|
||||
<!-- Additional invitation context -->
|
||||
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-600">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">{{ _("Invitation Details") }}</h4>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 space-y-1">
|
||||
<div>
|
||||
{{ _("Code") }}: <span class="font-mono">{{ invitation.code }}</span>
|
||||
</div>
|
||||
{% if invitation.duration %}<div>{{ _("Duration") }}: {{ invitation.duration }} {{ _("days") }}</div>{% endif %}
|
||||
{% if invitation.expires %}<div>{{ _("Invitation expires") }}: {{ invitation.expires|human_date }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -304,8 +304,7 @@
|
||||
aria-modal="true">
|
||||
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-900 dark:bg-opacity-80"></div>
|
||||
<div class="flex min-h-full items-center justify-center p-4">
|
||||
<div id="modal-user"
|
||||
class="relative z-10"></div>
|
||||
<div id="modal-user" class="relative z-10"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user