| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- {% extends 'layout.twig' %}
- {% block title %}Allowlist — IRDB{% endblock %}
- {% block content %}
- {% import 'partials/sort.twig' as sort %}
- <div class="mx-auto max-w-5xl">
- <div class="flex items-center justify-between">
- <h1 class="text-2xl font-semibold tracking-tight">Allowlist</h1>
- <span class="text-sm text-slate-500 dark:text-slate-400">{{ list.total|default(0) }} total</span>
- </div>
- {% set kind_links = [
- { label: 'All', value: '' },
- { label: 'IPs', value: 'ip' },
- { label: 'Subnets', value: 'subnet' },
- ] %}
- <div class="mt-4 flex gap-2 text-sm">
- {% for k in kind_links %}
- {% set is_active = (kind|default('') == k.value) or (kind == null and k.value == '') %}
- <a href="/app/allowlist{% if k.value %}?kind={{ k.value }}{% endif %}"
- class="rounded-full px-3 py-1 {% if is_active %}bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-100{% else %}border border-slate-300 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800{% endif %}">{{ k.label }}</a>
- {% endfor %}
- </div>
- {% if can_write %}
- <section class="mt-6 rounded-2xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900">
- <h2 class="text-sm font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Add allowlist entry</h2>
- <form method="post" action="/app/allowlist" class="mt-3 grid grid-cols-1 gap-3 md:grid-cols-3 text-sm" x-data="kindSwitcher" data-initial-kind="ip">
- <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
- <div>
- <label for="al-kind" class="block text-xs font-medium text-slate-600 dark:text-slate-400">Kind</label>
- <select id="al-kind" name="kind" x-model="kind"
- class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 dark:border-slate-700 dark:bg-slate-950">
- <option value="ip">Single IP</option>
- <option value="subnet">Subnet (CIDR)</option>
- </select>
- </div>
- <div x-show="isKind('ip')">
- <label for="al-ip" class="block text-xs font-medium text-slate-600 dark:text-slate-400">IP</label>
- <input type="text" id="al-ip" name="ip" placeholder="203.0.113.5"
- class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 font-mono dark:border-slate-700 dark:bg-slate-950">
- </div>
- <div x-show="isKind('subnet')">
- <label for="al-cidr" class="block text-xs font-medium text-slate-600 dark:text-slate-400">CIDR</label>
- <input type="text" id="al-cidr" name="cidr" placeholder="10.0.0.0/8"
- class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 font-mono dark:border-slate-700 dark:bg-slate-950">
- </div>
- <div>
- <label for="al-reason" class="block text-xs font-medium text-slate-600 dark:text-slate-400">Reason</label>
- <input type="text" id="al-reason" name="reason"
- class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 dark:border-slate-700 dark:bg-slate-950">
- </div>
- <div class="md:col-span-3 flex justify-end">
- <button type="submit" class="rounded-md bg-emerald-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-emerald-500">Add entry</button>
- </div>
- </form>
- </section>
- {% endif %}
- <section class="mt-6 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900">
- <table class="w-full text-sm" data-sortable-table="allowlist-index">
- <thead class="border-b border-slate-200 bg-slate-50 text-left text-xs uppercase tracking-wider text-slate-500 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-400">
- <tr>
- {{ sort.th('Kind', 'kind') }}
- {{ sort.th('Target', 'target') }}
- {{ sort.th('Reason', 'reason') }}
- {{ sort.th('Created', 'created', 'date') }}
- {% if can_write %}<th class="px-4 py-2 text-right font-medium">Actions</th>{% endif %}
- </tr>
- </thead>
- <tbody class="divide-y divide-slate-100 dark:divide-slate-800">
- {% for item in list.items|default([]) %}
- <tr>
- <td class="px-4 py-2 font-mono text-xs uppercase" data-sort-value="{{ item.kind }}">{{ item.kind }}</td>
- <td class="px-4 py-2 font-mono" data-sort-value="{{ item.kind == 'ip' ? item.ip : item.cidr }}">{{ item.kind == 'ip' ? item.ip : item.cidr }}</td>
- <td class="px-4 py-2 text-slate-600 dark:text-slate-300" data-sort-value="{{ item.reason|default('') }}">{{ item.reason|default('—') }}</td>
- <td class="px-4 py-2 text-slate-500 dark:text-slate-400" data-sort-value="{{ item.created_at|default('') }}">{% if item.created_at %}<time class="irdb-dt" datetime="{{ item.created_at }}">{{ item.created_at }}</time>{% endif %}</td>
- {% if can_write %}
- <td class="px-4 py-2 text-right">
- {% include 'partials/confirm_form.twig' with {
- action: '/app/allowlist/' ~ item.id ~ '/delete',
- label: 'Remove',
- description: 'This removes the allowlist entry immediately.',
- } only %}
- </td>
- {% endif %}
- </tr>
- {% else %}
- <tr><td colspan="5" class="px-4 py-6 text-center text-slate-400">No allowlist entries.</td></tr>
- {% endfor %}
- </tbody>
- </table>
- </section>
- </div>
- {% endblock %}
|