role_form.html
139 lignes · 5974 octets
{% extends "base.html" %} {% block title %}{{ page_title }}{% endblock %} {% block navbar %} {% include "components/navbar.html" %} {% endblock %} {% block content %} <div class="container mx-auto px-4 py-8"> <!-- Breadcrumb --> <div class="text-sm breadcrumbs mb-6"> <ul> <li><a href="/">{{ breadcrumb_home }}</a></li> <li><a href="/admin">{{ breadcrumb_admin }}</a></li> <li><a href="/admin/roles">{{ breadcrumb_roles }}</a></li> <li>{{ breadcrumb_mode }}</li> </ul> </div> <div class="flex items-center gap-4 mb-6"> <a href="/admin/roles" class="btn btn-ghost btn-sm"> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" /> </svg> {{ back_to_list }} </a> <h1 class="text-3xl font-bold">{{ form_title }}</h1> </div> <div class="card bg-base-100 shadow-xl max-w-3xl"> <div class="card-body"> <form id="roleForm" {% if mode == "create" %} hx-post="/admin/roles" {% else %} action="/admin/roles/{{ role_id }}" method="POST" {% endif %} hx-target="#form-message" hx-swap="innerHTML"> {% if mode == "edit" %} <input type="hidden" name="_method" value="PUT"> {% endif %} <input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <!-- Name --> <div class="form-control mb-4"> <label class="label"> <span class="label-text font-semibold">{{ name_label }}</span> </label> {% if is_protected %} <input type="text" name="name" value="{{ form_name }}" class="input input-bordered" readonly> <label class="label"> <span class="label-text-alt text-warning">{{ protected_name_hint }}</span> </label> {% else %} <input type="text" name="name" value="{{ form_name }}" class="input input-bordered" placeholder="{{ name_placeholder }}" required> {% endif %} </div> <!-- Description --> <div class="form-control mb-4"> <label class="label"> <span class="label-text font-semibold">{{ description_label }}</span> </label> <textarea name="description" class="textarea textarea-bordered" placeholder="{{ description_placeholder }}" rows="3">{{ form_description }}</textarea> </div> <!-- Permissions grouped by category --> <div class="form-control mb-6"> <label class="label"> <span class="label-text font-semibold">{{ permissions_label }}</span> </label> {% for group in permission_groups %} <div class="collapse collapse-arrow bg-base-200 mb-2"> <input type="checkbox" checked> <div class="collapse-title font-medium capitalize"> {{ group.category }} <span class="badge badge-sm badge-ghost ml-2">{{ group.permissions.len() }}</span> </div> <div class="collapse-content"> <div class="grid grid-cols-1 md:grid-cols-2 gap-2 pt-2"> {% for perm in group.permissions %} <label class="flex items-start gap-3 cursor-pointer p-2 rounded hover:bg-base-300 transition-colors"> <input type="checkbox" name="permissions" value="{{ perm.id }}" class="checkbox checkbox-sm checkbox-primary mt-0.5" {% if perm.is_selected %}checked{% endif %}> <div> <div class="text-sm font-mono">{{ perm.name }}</div> {% if !perm.description.is_empty() %} <div class="text-xs text-base-content/60">{{ perm.description }}</div> {% endif %} </div> </label> {% endfor %} </div> </div> </div> {% endfor %} </div> <!-- Message area --> <div id="form-message" class="mb-4"></div> <!-- Actions --> <div class="flex justify-end gap-4"> <a href="/admin/roles" class="btn btn-ghost">{{ cancel }}</a> <button type="submit" class="btn btn-primary">{{ submit_label }}</button> </div> </form> </div> </div> </div> {% if mode == "edit" %} <script> document.getElementById('roleForm').addEventListener('submit', function(e) { e.preventDefault(); const form = e.target; const formData = new FormData(form); fetch(form.action, { method: 'PUT', headers: { 'X-CSRF-Token': '{{ csrf_token }}', }, body: new URLSearchParams(formData), }).then(function(resp) { if (resp.redirected) { window.location.href = resp.url; } }); }); </script> {% endif %} {% endblock %}
GitRust