feat: remove easy admin bundle, adopt admin theme

This commit is contained in:
Björn Fromme
2026-06-22 08:59:47 +02:00
parent 52ee6b26b1
commit 2fc7ffe458
52 changed files with 1947 additions and 690 deletions
+13
View File
@@ -0,0 +1,13 @@
<div class="relative inline-block text-left group">
<button type="button" class="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-0" aria-expanded="true" aria-haspopup="true">
<span class="sr-only">Funktionen</span>
{{ icon('dots', 'w-6 h-6') }}
</button>
<div class="hidden group-hover:block absolute right-0 top-0 z-10 w-56 origin-top-right pt-4" role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
<div class="rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div class="py-1 menu menu--pulldown" role="none">
{% block content %}{% endblock %}
</div>
</div>
</div>
</div>
@@ -1,5 +1,6 @@
{% import _self as self %}
{% macro render_value(value) %}
{% import _self as self %}
{% if value is iterable %}
<ul class="list-disc list-inside ml-4">
{% for key, item in value %}
@@ -17,6 +18,5 @@
{{ value }}
{% endif %}
{% endmacro %}
{% import _self as self %}
{{ self.render_value(field.value) }}
{{ self.render_value(value) }}
+82
View File
@@ -0,0 +1,82 @@
{% extends 'knp_menu.html.twig' %}
{% block list %}
{% if item.hasChildren and options.depth is not same as(0) and item.displayChildren %}
{% if item.level == 0 %}
<div class="min-h-full flex grow flex-col gap-y-5 lg:border-r border-gray-200 bg-white md:pr-6">
<nav class="flex flex-1 flex-col">
<ul role="list" class="space-y-1">
{{ block('children') }}
</ul>
</nav>
</div>
{% else %}
<ul class="{{ html_classes('mt-1 px-2', { 'hidden': not matcher.isCurrent(item) }) }}" {{ stimulus_target('sidebar-menu', 'submenu') }}>
{{ block('children') }}
</ul>
{% endif %}
{% endif %}
{% endblock %}
{% block item %}
{% if item.displayed %}
<li>
{%- if item.hasChildren and item.displayChildren %}
<div {{ stimulus_controller('sidebar-menu', {'expanded': matcher.isAncestor(item)}, {'closed': 'hidden', 'iconClosed': 'text-gray-400', 'iconExpanded': 'text-gray-500'}) }}>
{%- endif %}
{%- if item.uri is not empty %}
{{ block('linkElement') }}
{%- else %}
{{ block('spanElement') }}
{%- endif %}
{{ block('list') }}
{%- if item.hasChildren and item.displayChildren %}
</div>
{%- endif %}
</li>
{% endif %}
{% endblock %}
{% block linkElement %}
{% import _self as knp_menu %}
<a href="{{ item.uri }}"
class="{{ html_classes('', {
'group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold text-gray-700 hover:bg-gray-50': item.level == 1,
'block rounded-md py-2 pr-2 pl-9 text-sm leading-6 text-gray-700 hover:bg-gray-50': item.level > 1,
'bg-gray-50': matcher.isCurrent(item) or matcher.isAncestor(item)
}) }}"
{{ knp_menu.attributes(item.linkAttributes) }}>
{{ block('label') }}
</a>
{% endblock %}
{% block spanElement %}
{% import _self as knp_menu %}
{% if item.hasChildren %}
<button type="button"
{{ stimulus_action('sidebar-menu', 'toggleSubmenu') }}
{{ stimulus_target('sidebar-menu', 'button') }}
{{ knp_menu.attributes(item.linkAttributes) }}
class="{{ html_classes('hover:bg-gray-50 flex items-center w-full text-left rounded-md p-2 gap-x-3 text-sm leading-6 font-semibold text-gray-700', { 'bg-gray-50': matcher.isAncestor(item) }) }}"
aria-expanded="false">
{{ block('label') }}
</button>
{% elseif item.extras.divider is defined %}
<hr class="my-4 h-px bg-gray-200">
{% else %}
<div class="hover:bg-gray-50 group flex gap-x-3 rounded-md p-2 text-sm leading-5 font-semibold text-gray-700"
role="button">
{{ block('label') }}
</div>
{% endif %}
{% endblock %}
{% block label %}
{% if item.extras.icon is defined %}
{{ icon(item.extras.icon, 'h-5 w-5 shrink-0 text-gray-400') }}
<span class="flex-1">{{ item.label|raw }}</span>
{% else %}
{{ item.label|raw }}
{% endif %}
{% endblock %}
@@ -0,0 +1,69 @@
{% if pageCount > 0 %}
<div class="bg-gray-100 border border-gray-300 border-t-0 px-4 py-3 flex items-center justify-between sm:px-4">
<div class="flex-1 flex items-center justify-between">
<div class="flex items-center space-x-4">
<div class="text-sm leading-5 text-gray-700">
{{ 'paginator.info'|trans({ '{from}': firstItemNumber, '{to}': lastItemNumber, '{total}': totalCount })|raw }}
</div>
<select name="limit"
class="text-sm py-1 border-gray-300"
hx-get="{{ path(route, query|merge({(pageParameterName): 1})) }}"
hx-replace-url="{{ path(route, query|merge({(pageParameterName): 1})) }}"
hx-target="body">
<option value="10"{% if numItemsPerPage == 10 %} selected{% endif %}>10 pro Seite</option>
<option value="20"{% if numItemsPerPage == 20 %} selected{% endif %}>20 pro Seite</option>
<option value="50"{% if numItemsPerPage == 50 %} selected{% endif %}>50 pro Seite</option>
</select>
</div>
<div>
<nav class="relative z-0 inline-flex">
{% if pageCount > 1 %}
{% if first is defined and current != first %}
<a href="{{ path(route, query|merge({(pageParameterName): first})) }}" class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5" />
</svg>
</a>
{% endif %}
{% if previous is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): previous})) }}" class="-ml-px relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white" aria-label="Previous">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
</svg>
</a>
{% endif %}
{% if current > 3 %}
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
...
</span>
{% endif %}
{% for page in pagesInRange %}
<a href="{{ path(route, query|merge({(pageParameterName): page})) }}" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium focus:z-10 hover:bg-secondary {% if page == current %}bg-primary text-white hover:text-white{% else %}bg-white text-gray-700 hover:text-white{% endif %}">
{{ page }}
</a>
{% endfor %}
{% if current < pageCount - 3 %}
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
...
</span>
{% endif %}
{% if next is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): next})) }}" class="-ml-px relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white" aria-label="Next">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
</svg>
</a>
{% endif %}
{% if last is defined and current != last %}
<a href="{{ path(route, query|merge({(pageParameterName): last})) }}" class="-ml-px relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
</svg>
</a>
{% endif %}
{% endif %}
</nav>
</div>
</div>
</div>
{% endif %}
@@ -0,0 +1,44 @@
{% if pageCount > 0 %}
<div class="bg-gray-100 border border-gray-200 rounded-md px-4 py-3 flex items-center justify-between sm:px-4">
<div class="flex-1 flex items-center justify-between">
<div>
<p class="text-sm leading-5 text-gray-700">{{ 'paginator.info'|trans({ '{from}': firstItemNumber, '{to}': lastItemNumber, '{total}': totalCount })|raw }}</p>
</div>
<div>
<nav class="relative z-0 inline-flex">
{% if pageCount > 1 %}
{% if previous is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): previous})) }}" class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white" aria-label="Previous">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</a>
{% endif %}
{% if current > 3 %}
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
...
</span>
{% endif %}
{% for page in pagesInRange %}
<a href="{{ path(route, query|merge({(pageParameterName): page})) }}" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium focus:z-10 hover:bg-secondary {% if page == current %}bg-primary text-white hover:text-white{% else %}bg-white text-gray-700 hover:text-white{% endif %}">
{{ page }}
</a>
{% endfor %}
{% if current < pageCount - 3 %}
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
...
</span>
{% endif %}
{% if next is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): next})) }}" class="-ml-px relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium hover:bg-secondary hover:text-white" aria-label="Next">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
</svg>
</a>
{% endif %}
{% endif %}
</nav>
</div>
</div>
</div>
{% endif %}
@@ -0,0 +1,15 @@
<a href="{{ options.href }}" class="flex items-center space-x-2">
<span>{{ title|raw }}</span>
{%- if sorted -%}
{%- if direction == 'desc' -%}
<svg class="w-4 h-4 shrink-0" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"></path>
</svg>
{%- else -%}
<svg class="w-4 h-4 shrink-0" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"></path>
</svg>
{%- endif -%}
{%- endif -%}
</a>
+1 -1
View File
@@ -23,7 +23,7 @@
</li>
{% if is_granted('ROLE_ADMIN') %}
<li class="py-4">
<a href="{{ path('admin') }}" class="flex items-center space-x-2 group" hx-boost="false">
<a href="{{ path('app_admin_dashboard') }}" class="flex items-center space-x-2 group" hx-boost="false">
<svg class="w-8 h-8 text-white group-hover:text-primary-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><circle cx="128" cy="128" r="40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M41.43,178.09A99.14,99.14,0,0,1,31.36,153.8l16.78-21a81.59,81.59,0,0,1,0-9.64l-16.77-21a99.43,99.43,0,0,1,10.05-24.3l26.71-3a81,81,0,0,1,6.81-6.81l3-26.7A99.14,99.14,0,0,1,102.2,31.36l21,16.78a81.59,81.59,0,0,1,9.64,0l21-16.77a99.43,99.43,0,0,1,24.3,10.05l3,26.71a81,81,0,0,1,6.81,6.81l26.7,3a99.14,99.14,0,0,1,10.07,24.29l-16.78,21a81.59,81.59,0,0,1,0,9.64l16.77,21a99.43,99.43,0,0,1-10,24.3l-26.71,3a81,81,0,0,1-6.81,6.81l-3,26.7a99.14,99.14,0,0,1-24.29,10.07l-21-16.78a81.59,81.59,0,0,1-9.64,0l-21,16.77a99.43,99.43,0,0,1-24.3-10l-3-26.71a81,81,0,0,1-6.81-6.81Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
<span class="text-xl uppercase text-white group-hover:text-primary-light">Admin</span>
</a>
@@ -0,0 +1,87 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
Buchungsentwürfe
</h1>
<div class="data-table-wrapper">
<div class="data-table-wrapper__inner text-sm">
<table class="data-table">
<thead>
<tr>
<th>
{{ knp_pagination_sortable(pagination, 'erstellt am', 'booking_edit_draft.createdAt') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Vorgang', 'booking_edit_draft.bookingNumber') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Kundenaccount', 'user.email') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'aktualisiert am', 'booking_edit_draft.updatedAt') }}
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for draft in pagination %}
<tr>
<td>
{{ draft.createdAt | date('d.m.Y, H:i') }}
</td>
<td>
{{ draft.bookingNumber | default('-') }}
</td>
<td>
{{ draft.user.email | default('-') }}
</td>
<td>
{% if draft.updatedAt is not null and draft.updatedAt != draft.createdAt %}
{{ draft.updatedAt | date('d.m.Y, H:i') }}
{% else %}
-
{% endif %}
</td>
<td>
{% embed '_partials/_dropdown.html.twig' %}
{% block content %}
<a href="{{ path('app_admin_bookingeditdraft_show', { 'id': draft.id, 'r': return_url() }) }}"
class="text-gray-700 hover:text-primary block px-4 py-2 text-sm"
role="menuitem"
tabindex="-1">
Details
</a>
<a href="{{ path('app_admin_bookingeditdraft_export', { 'id': draft.id }) }}"
class="text-gray-700 hover:text-primary block px-4 py-2 text-sm"
role="menuitem"
tabindex="-1">
XLS-Export
</a>
<button type="button"
class="text-red-500 hover:text-primary block px-4 py-2 text-sm w-full text-left"
role="menuitem"
tabindex="-1"
hx-get="{{ path('app_admin_bookingeditdraft_delete', { 'id': draft.id, 'r': return_url() }) }}"
hx-target="body"
hx-swap="beforeend">
löschen
</button>
{% endblock %}
{% endembed %}
</td>
</tr>
{% else %}
<tr>
<td colspan="5">
Keine Daten...
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ knp_pagination_render(pagination) }}
</div>
</div>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du den Buchungsentwurf zum Vorgang <em>{{ draft.bookingNumber }}</em> wirklich löschen?
</div>
{% endblock %}
@@ -0,0 +1,16 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
Buchungsentwurf
</h1>
<h2 class="text-xl font-bold pb-4">
Vorgang {{ draft.bookingNumber }}
</h2>
{% include('_partials/_json.html.twig') with { 'value': draft.formData } %}
<div class="flex justify-end pt-8">
<a href="{{ returnUrl }}" class="button button--secondary button--small">
zurück
</a>
</div>
{% endblock %}
+10
View File
@@ -0,0 +1,10 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1>
MyE&amp;P Admin
</h1>
<p>
Noch nicht wirklich was zu sehen hier...
</p>
{% endblock %}
@@ -1,5 +0,0 @@
{% extends '@EasyAdmin/layout.html.twig' %}
{% block main %}
{% endblock main %}
+81
View File
@@ -0,0 +1,81 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
Logs
</h1>
<div class="data-table-wrapper">
<div class="data-table-wrapper__inner text-sm">
<table class="data-table">
<thead>
<tr>
<th>
{{ knp_pagination_sortable(pagination, 'Datum', 'log.timestamp') }}
</th>
<th>
Fehlercode
</th>
<th>
Benutzer
</th>
<th>
Aktion
</th>
<th>
<span class="whitespace-nowrap">Request ID</span>
</th>
<th>
URI
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for entry in pagination %}
<tr>
<td>
{{ entry.createdAt | date('d.m.Y H:i') }}
</td>
<td>
{{ entry.errorCode | default('-') }}
</td>
<td>
{{ entry.userName }}
</td>
<td>
{{ entry.message }}
</td>
<td>
{{ entry.requestId | default('-') }}
</td>
<td>
<span class="text-xs">{{ entry.uri | default('-') | u.truncate(48, '...') }}</span>
</td>
<td>
{% if entry.channel == 'bpn' %}
{% embed '_partials/_dropdown.html.twig' %}
{% block content %}
<a href="{{ path('app_admin_log_xmldumps', { 'id': entry.id }) }}"
class="text-gray-700 hover:text-primary block px-4 py-2 text-sm"
role="menuitem"
tabindex="-1">
XML-Dumps
</a>
{% endblock %}
{% endembed %}
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="7">
Keine Daten...
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ knp_pagination_render(pagination) }}
</div>
</div>
{% endblock %}
+61
View File
@@ -0,0 +1,61 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
XML-Dumps für Request ID {{ logEntry.requestId }}
</h1>
{% if dumps is empty %}
<div class="alert alert-warning">
<i class="fa fa-exclamation-triangle"></i>
Keine XML-Dumps gefunden. Die Dateien wurden vermutlich bereits bereinigt.
</div>
{% else %}
<div class="data-table-wrapper">
<div class="data-table-wrapper__inner text-sm">
<table class="data-table">
<thead>
<tr>
<th>
Dateiname
</th>
<th>
Typ
</th>
<th>
Dateigröße
</th>
<th>
Aktion
</th>
</tr>
</thead>
<tbody>
{% for dump in dumps %}
<tr>
<td>
<code>{{ dump.filename }}</code>
</td>
<td>
{% if dump.type == 'request' %}
<span class="badge bg-primary">Request</span>
{% else %}
<span class="badge bg-success">Response</span>
{% endif %}
</td>
<td>
{{ (dump.size / 1024)|number_format(1) }} KB
</td>
<td>
<a href="{{ path('app_admin_log_xmldump_download', { filename: dump.filename }) }}"
class="">
{{ icon('download', 'w-4 h-4')}} Download
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
{% endblock %}
+54
View File
@@ -0,0 +1,54 @@
{% extends 'layout_admin.html.twig' %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
Benutzeraccounts
</h1>
<div class="data-table-wrapper">
<div class="data-table-wrapper__inner text-sm">
<table class="data-table">
<thead>
<tr>
<th>
{{ knp_pagination_sortable(pagination, 'E-Mail', 'user.email') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'BusPro Adress Id', 'user.addressId') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'BusPro Personen Id', 'user.personId') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Letzter Login', 'user.lastLoginAt') }}
</th>
</tr>
</thead>
<tbody>
{% for user in pagination %}
<tr>
<td>
{{ user.email }}
</td>
<td>
{{ user.addressId | default('-') }}
</td>
<td>
{{ user.personId | default('-') }}
</td>
<td>
{{ user.lastLoginAt | date('d.m.Y, H:i') }}
</td>
</tr>
{% else %}
<tr>
<td colspan="2">
Keine Daten...
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ knp_pagination_render(pagination) }}
</div>
</div>
{% endblock %}
-62
View File
@@ -1,62 +0,0 @@
{% extends '@EasyAdmin/layout.html.twig' %}
{% block content_title %}
XML Dumps
{% endblock %}
{% block main %}
<div class="content-panel">
<div class="content-panel-header">
<h2>XML Dumps for Request ID</h2>
<code>{{ requestId }}</code>
</div>
<div class="content-panel-body">
{% if dumps is empty %}
<div class="alert alert-warning">
<i class="fa fa-exclamation-triangle"></i>
Keine XML-Dumps gefunden. Die Dateien wurden vermutlich bereits bereinigt.
</div>
{% else %}
<table class="table table-striped">
<thead>
<tr>
<th>Dateiname</th>
<th>Typ</th>
<th class="text-end">Dateigröße</th>
<th class="text-end">Aktion</th>
</tr>
</thead>
<tbody>
{% for dump in dumps %}
<tr>
<td><code>{{ dump.filename }}</code></td>
<td>
{% if dump.type == 'request' %}
<span class="badge bg-primary">Request</span>
{% else %}
<span class="badge bg-success">Response</span>
{% endif %}
</td>
<td class="text-end">{{ (dump.size / 1024)|number_format(1) }} KB</td>
<td class="text-end">
<a href="{{ path('admin_xml_dump_download', {filename: dump.filename}) }}"
class="btn btn-sm btn-outline-primary">
<i class="fa fa-download"></i> Download
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
<div class="content-panel-footer">
<a href="{{ ea_url().setController('App\\Controller\\Admin\\LogEntryCrudController').setAction('index') }}"
class="btn btn-secondary">
<i class="fa fa-arrow-left"></i> Zurück zur Liste
</a>
</div>
</div>
{% endblock %}
+22
View File
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex,nofollow">
<title>{% block title %}MyE&amp;P{% endblock %}</title>
<link rel="icon" href="{{ asset('build/favicon/favicon.ico') }}" sizes="32x32">
<link rel="icon" href="{{ asset('build/favicon/icon.svg') }}" type="image/svg+xml">
<link rel="apple-touch-icon" href="{{ asset('build/favicon/apple-touch-icon.png') }}">
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</head>
<body class="bg-white text-gray-700 font-sans antialiased {{ booking_theme() }}">
{% block body %}{% endblock %}
{% block data_layer %}{% endblock %}
</body>
</html>
@@ -0,0 +1,25 @@
<div id="htmx-confirmation-modal" class="fixed top-0 left-0 z-50 inset-0" {{ stimulus_controller('modal') }}>
<div class="absolute top-0 left-0 inset-0 bg-black/80" {{ stimulus_action('modal', 'close', 'click') }}></div>
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-8 w-full max-w-3xl rounded-md">
<div class="flex justify-between border-b border-gray-200 pb-2 mb-4">
<div class="flex items-center space-x-2">
{{ icon('alert', 'w-8 h-8') }}
<div class="text-xl font-bold">
{% block title %}Bist du sicher?{% endblock %}
</div>
</div>
<button type="button" class="inline-block" {{ stimulus_action('modal', 'close') }}>
{{ icon('close', 'w-8 h-8') }}
</button>
</div>
{% block content %}{% endblock %}
<div class="mt-6 flex items-center justify-between">
<button type="button" class="button button--warning" {% block button_attribute %}hx-post="{{ app.request.uri }}"{% endblock %}>
{% block button_confirm %}Ja{% endblock %}
</button>
<button type="button" class="button button--neutral" {{ stimulus_action('modal', 'close') }}>
{% block button_cancel %}Abbrechen{% endblock %}
</button>
</div>
</div>
</div>
+44
View File
@@ -0,0 +1,44 @@
{% extends 'base_admin.html.twig' %}
{% block body %}
<div class="max-w-screen-2xl mx-auto px-4 lg:px-8 lg:grid lg:grid-cols-4 gap-8 py-8">
<div class="lg:col-span-4 flex items-center justify-between pb-4 lg:pb-0">
<a href="{{ path(app.user ? 'app_admin_dashboard' : 'app_security_login') }}">
<img class="h-8 w-auto" src="{{ asset('build/images/logo_ep.svg') }}" alt="My E&amp;P Admin">
</a>
{% if app.user %}
<div class="flex items-center space-x-4">
<button type="button"
class="lg:hidden"
{{ stimulus_controller('mobilenav', [], [], { 'mobilenav': '#mobilenav' }) }}
{{ stimulus_action('mobilenav', 'trigger', null, { 'mode': 'open' }) }}>
{{ icon('menu', 'w-8 h-8 text-gray-700') }}
</button>
</div>
{% endif %}
</div>
<div class="hidden lg:block">
{{ knp_menu_render(knp_menu_get('admin_main')) }}
</div>
<div class="lg:col-span-3">
{% block content %}{% endblock %}
</div>
</div>
<div id="mobilenav"
class="fixed z-50 top-0 left-0 inset-0 pr-16 bg-black/70 -translate-x-full"
{{ stimulus_controller('mobilenav', [], { 'closed': '-translate-x-full' }, { 'mobilenav': '#mobilenav' }) }}
>
<div class="h-screen w-full bg-white">
<div class="flex justify-between p-8">
<img src="{{ asset('build/images/logo_ep.svg') }}" alt="" class="block w-auto h-8">
<button type="button"
{{ stimulus_action('mobilenav', 'trigger', null, { 'mode': 'close' }) }}>
{{ icon('close', 'w-8 h-8') }}
</button>
</div>
<div class="w-full h-full p-8 pt-0 overflow-y-scroll">
{{ knp_menu_render(knp_menu_get('admin_main')) }}
</div>
</div>
</div>
{% endblock %}