feat: add the admin layout shell
This commit is contained in:
1 parent
da8af9ff08
commit
ad5c93049c
21 files changed
+441
-15
No files matched your search
@@ -0,0 +1,13 @@
|
||||
{# Flat inline alerts for now. myep renders these as Toastify toasts, but that means adopting
|
||||
toastify-js as a dependency -- deferred until the toast/OOB work (plan step 7). #}
|
||||
{% set levels = { error: 'bg-red-600', warning: 'bg-red-600', success: 'bg-emerald-600', info: 'bg-primary' } %}
|
||||
|
||||
{% for level, messages in app.flashes(levels|keys) %}
|
||||
<div class="fixed bottom-4 right-4 z-50 space-y-2">
|
||||
{% for message in messages %}
|
||||
<div class="{{ levels[level] }} text-gray-100 rounded shadow-lg px-4 py-3 text-sm">
|
||||
{{ message|trans }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,25 @@
|
||||
{# Plain nav instead of myep's knp-menu builder: a handful of links does not justify the
|
||||
indirection. Active state is a prefix match on the current route name, which mirrors what
|
||||
myep's menu matcher does with its 'routes' extras. #}
|
||||
{% set current_route = app.request.attributes.get('_route') %}
|
||||
{% set items = [
|
||||
{ route: 'app_dashboard', label: 'Übersicht', icon: 'lucide:layout-grid' },
|
||||
{ route: 'app_booking', label: 'Meine Buchungen', icon: 'lucide:calendar-days' },
|
||||
] %}
|
||||
|
||||
<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">
|
||||
{% for item in items %}
|
||||
{% set is_active = current_route starts with item.route %}
|
||||
<li>
|
||||
<a href="{{ path(item.route) }}"
|
||||
class="group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold {{ is_active ? 'bg-gray-100 text-gray-900' : 'text-gray-700 hover:bg-gray-50' }}">
|
||||
{{ ux_icon(item.icon, { class: 'h-5 w-5 shrink-0 ' ~ (is_active ? 'text-gray-600' : 'text-gray-400') }) }}
|
||||
<span class="flex-1">{{ item.label }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
+12
-13
@@ -1,24 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
|
||||
{% block stylesheets %}
|
||||
{% endblock %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{# Internal tool -- keep it out of search engines. #}
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title>{% block title %}ephub{% endblock %}</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.15em%22 font-size=%2296%22>🪑</text></svg>">
|
||||
|
||||
{# The Tailwind build is pulled in by assets/app.js's `import './styles/app.css'`,
|
||||
so importmap() emits the <link> for it. This block is for anything outside that graph. #}
|
||||
{% block stylesheets %}{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{% block importmap %}{{ importmap('app') }}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% set frankenphp_hot_reload = app.request.server.get('FRANKENPHP_HOT_RELOAD') %}
|
||||
{% if frankenphp_hot_reload %}
|
||||
<meta name="frankenphp-hot-reload:url" content="{{ frankenphp_hot_reload }}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
|
||||
{% endif %}
|
||||
</head>
|
||||
<body>
|
||||
{# No hx-boost: htmx handles fragments only, the browser owns navigation. #}
|
||||
<body class="bg-white text-gray-700 font-sans antialiased">
|
||||
{% block body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block title %}Meine Buchungen · ephub{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Meine Buchungen</h1>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block title %}Übersicht · ephub{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Übersicht</h1>
|
||||
<p class="subline">Schreibtische und Parkplätze buchen.</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,43 @@
|
||||
{% extends 'base.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_dashboard') }}" class="text-2xl font-black tracking-tight text-primary-dark">
|
||||
ep<span class="text-pink">hub</span>
|
||||
</a>
|
||||
<button type="button"
|
||||
class="lg:hidden"
|
||||
{{ stimulus_controller('mobilenav', [], [], { 'mobilenav': '#mobilenav' }) }}
|
||||
{{ stimulus_action('mobilenav', 'trigger', null, { 'mode': 'open' }) }}>
|
||||
{{ ux_icon('lucide:menu', { class: 'w-8 h-8 text-gray-700' }) }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="hidden lg:block sticky top-0 h-screen">
|
||||
{% include '_partials/_nav.html.twig' %}
|
||||
</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">
|
||||
<span class="text-2xl font-black tracking-tight text-primary-dark">ep<span class="text-pink">hub</span></span>
|
||||
<button type="button" {{ stimulus_action('mobilenav', 'trigger', null, { 'mode': 'close' }) }}>
|
||||
{{ ux_icon('lucide:x', { class: 'w-8 h-8' }) }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-full h-full p-8 pt-0 overflow-y-scroll">
|
||||
{% include '_partials/_nav.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include '_partials/_flashes.html.twig' %}
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user