more hardcodes are done
This commit is contained in:
@@ -120,54 +120,7 @@
|
||||
|
||||
<!-- settings (language + theme) dropdown -->
|
||||
<div x-data="{ open: false }" @keydown.escape="open = false" class="relative ml-auto">
|
||||
<button type="button" @click="open = !open" :aria-expanded="open"
|
||||
aria-label="{{ t(key='settings', lang=lang | default(value='sk')) }}"
|
||||
class="inline-flex size-9 items-center justify-center rounded-radius text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open" x-cloak @click.outside="open = false" x-transition.origin.top.right
|
||||
class="absolute right-0 mt-2 w-56 rounded-radius border border-outline bg-surface p-2 shadow-lg dark:border-outline-dark dark:bg-surface-dark-alt">
|
||||
<form method="post" action="/lang" hx-boost="false">
|
||||
<p class="px-2 py-1 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-language", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<button type="submit" name="lang" value="en"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>English</span>
|
||||
{% if lang | default(value='sk') == "en" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
<button type="submit" name="lang" value="sk"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>Slovenčina</span>
|
||||
{% if lang | default(value='sk') == "sk" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<p class="mt-1 px-2 py-1 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-theme", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<div x-data="{ theme: currentTheme() }" @theme:changed.document="theme = $event.detail">
|
||||
<button type="button" @click="setTheme('system')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-system", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'system'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('light')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-light", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'light'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('dark')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-dark", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'dark'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% include "partials/settings_dropdown.html" %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="admin-categories", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-categories", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -9,10 +10,7 @@
|
||||
<h1 class="text-2xl font-bold text-on-surface-strong dark:text-on-surface-dark-strong">{{ t(key="admin-categories", lang=lang | default(value='sk')) }}</h1>
|
||||
<p class="text-sm text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="admin-categories-desc", lang=lang | default(value='sk')) }}</p>
|
||||
</div>
|
||||
<a href="/admin/catalog/categories/new"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="new-category", lang=lang | default(value='sk')) }}
|
||||
</a>
|
||||
{{ ui::button_primary(label=t(key="new-category", lang=lang | default(value='sk')), href="/admin/catalog/categories/new") }}
|
||||
</div>
|
||||
|
||||
<div class="mt-6 overflow-hidden rounded-radius border border-outline dark:border-outline-dark">
|
||||
@@ -38,9 +36,9 @@
|
||||
<td class="px-4 py-3 tabular-nums">{{ row.product_count }}</td>
|
||||
<td class="px-4 py-3">
|
||||
{% if row.category.published %}
|
||||
<span class="inline-flex rounded-full bg-success/15 px-2 py-0.5 text-xs font-medium text-success">{{ t(key="published", lang=lang | default(value='sk')) }}</span>
|
||||
{{ ui::badge(label=t(key="published", lang=lang | default(value='sk')), variant="success") }}
|
||||
{% else %}
|
||||
<span class="inline-flex rounded-full bg-surface-alt px-2 py-0.5 text-xs font-medium text-on-surface/70 dark:bg-surface-dark-alt dark:text-on-surface-dark/70">{{ t(key="draft", lang=lang | default(value='sk')) }}</span>
|
||||
{{ ui::badge(label=t(key="draft", lang=lang | default(value='sk')), variant="neutral") }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
@@ -60,10 +58,7 @@
|
||||
{% else %}
|
||||
<div class="flex flex-col items-center gap-3 px-4 py-16 text-center">
|
||||
<p class="text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="admin-no-categories", lang=lang | default(value='sk')) }}</p>
|
||||
<a href="/admin/catalog/categories/new"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="new-category", lang=lang | default(value='sk')) }}
|
||||
</a>
|
||||
{{ ui::button_primary(label=t(key="new-category", lang=lang | default(value='sk')), href="/admin/catalog/categories/new") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{% if category %}{{ t(key="edit-category", lang=lang | default(value='sk')) }}{% else %}{{ t(key="new-category", lang=lang | default(value='sk')) }}{% endif %}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-categories", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -8,8 +9,7 @@
|
||||
<h1 class="text-2xl font-bold text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||
{% if category %}{{ t(key="edit-category", lang=lang | default(value='sk')) }}{% else %}{{ t(key="new-category", lang=lang | default(value='sk')) }}{% endif %}
|
||||
</h1>
|
||||
<a href="/admin/catalog/categories"
|
||||
class="inline-flex items-center rounded-radius border border-outline px-3 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cancel", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_outline(label=t(key="cancel", lang=lang | default(value='sk')), href="/admin/catalog/categories") }}
|
||||
</div>
|
||||
|
||||
<form method="post" enctype="multipart/form-data"
|
||||
@@ -71,12 +71,8 @@
|
||||
</label>
|
||||
|
||||
<div class="flex gap-3 pt-2">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="save", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
<a href="/admin/catalog/categories"
|
||||
class="inline-flex items-center rounded-radius border border-outline px-4 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cancel", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_primary(label=t(key="save", lang=lang | default(value='sk')), type="submit") }}
|
||||
{{ ui::button_outline(label=t(key="cancel", lang=lang | default(value='sk')), href="/admin/catalog/categories") }}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{% if product %}{{ t(key="edit-product", lang=lang | default(value='sk')) }}{% else %}{{ t(key="new-product", lang=lang | default(value='sk')) }}{% endif %}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-products", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -8,8 +9,7 @@
|
||||
<h1 class="text-2xl font-bold text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||
{% if product %}{{ t(key="edit-product", lang=lang | default(value='sk')) }}{% else %}{{ t(key="new-product", lang=lang | default(value='sk')) }}{% endif %}
|
||||
</h1>
|
||||
<a href="/admin/catalog/products"
|
||||
class="inline-flex items-center rounded-radius border border-outline px-3 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cancel", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_outline(label=t(key="cancel", lang=lang | default(value='sk')), href="/admin/catalog/products") }}
|
||||
</div>
|
||||
|
||||
<form method="post" enctype="multipart/form-data"
|
||||
@@ -89,12 +89,8 @@
|
||||
</label>
|
||||
|
||||
<div class="flex gap-3 pt-2">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="save", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
<a href="/admin/catalog/products"
|
||||
class="inline-flex items-center rounded-radius border border-outline px-4 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cancel", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_primary(label=t(key="save", lang=lang | default(value='sk')), type="submit") }}
|
||||
{{ ui::button_outline(label=t(key="cancel", lang=lang | default(value='sk')), href="/admin/catalog/products") }}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="admin-products", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-products", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -9,10 +10,7 @@
|
||||
<h1 class="text-2xl font-bold text-on-surface-strong dark:text-on-surface-dark-strong">{{ t(key="admin-products", lang=lang | default(value='sk')) }}</h1>
|
||||
<p class="text-sm text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="admin-products-desc", lang=lang | default(value='sk')) }}</p>
|
||||
</div>
|
||||
<a href="/admin/catalog/products/new"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="new-product", lang=lang | default(value='sk')) }}
|
||||
</a>
|
||||
{{ ui::button_primary(label=t(key="new-product", lang=lang | default(value='sk')), href="/admin/catalog/products/new") }}
|
||||
</div>
|
||||
|
||||
<div class="mt-6 overflow-hidden rounded-radius border border-outline dark:border-outline-dark">
|
||||
@@ -47,9 +45,9 @@
|
||||
<td class="px-4 py-3 tabular-nums">{{ product.stock }}</td>
|
||||
<td class="px-4 py-3">
|
||||
{% if product.published %}
|
||||
<span class="inline-flex rounded-full bg-success/15 px-2 py-0.5 text-xs font-medium text-success">{{ t(key="published", lang=lang | default(value='sk')) }}</span>
|
||||
{{ ui::badge(label=t(key="published", lang=lang | default(value='sk')), variant="success") }}
|
||||
{% else %}
|
||||
<span class="inline-flex rounded-full bg-surface-alt px-2 py-0.5 text-xs font-medium text-on-surface/70 dark:bg-surface-dark-alt dark:text-on-surface-dark/70">{{ t(key="draft", lang=lang | default(value='sk')) }}</span>
|
||||
{{ ui::badge(label=t(key="draft", lang=lang | default(value='sk')), variant="neutral") }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
@@ -71,10 +69,7 @@
|
||||
{% else %}
|
||||
<div class="flex flex-col items-center gap-3 px-4 py-16 text-center">
|
||||
<p class="text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="admin-no-products", lang=lang | default(value='sk')) }}</p>
|
||||
<a href="/admin/catalog/products/new"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="new-product", lang=lang | default(value='sk')) }}
|
||||
</a>
|
||||
{{ ui::button_primary(label=t(key="new-product", lang=lang | default(value='sk')), href="/admin/catalog/products/new") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="login-title", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
|
||||
@@ -11,10 +12,7 @@
|
||||
<span class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||
{{ t(key="nav-admin", lang=lang | default(value='sk')) }}
|
||||
</span>
|
||||
<span
|
||||
class="rounded-radius border border-danger/40 px-2 py-0.5 text-xs font-medium text-danger">
|
||||
{{ t(key="auth", lang=lang | default(value='sk')) }}
|
||||
</span>
|
||||
{{ ui::badge(label=t(key="auth", lang=lang | default(value='sk')), variant="danger") }}
|
||||
</div>
|
||||
|
||||
<div class="p-5">
|
||||
@@ -23,11 +21,7 @@
|
||||
</h1>
|
||||
|
||||
{% if error %}
|
||||
<div
|
||||
class="mt-3 rounded-radius border border-danger/40 bg-danger/10 px-3 py-2 text-sm text-danger"
|
||||
role="alert">
|
||||
✗ {{ t(key="login-error", lang=lang | default(value='sk')) }}
|
||||
</div>
|
||||
{{ ui::alert_danger(message=t(key="login-error", lang=lang | default(value='sk')), extra="mt-3") }}
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="/admin/login" hx-boost="false" class="mt-4 flex flex-col gap-4">
|
||||
@@ -51,10 +45,7 @@
|
||||
class="w-full rounded-radius border border-outline bg-surface px-3 py-2 text-sm text-on-surface focus:outline-none focus:ring-2 focus:ring-primary dark:border-outline-dark dark:bg-surface-dark dark:text-on-surface-dark dark:focus:ring-primary-dark">
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="mt-1 w-full rounded-radius bg-primary px-4 py-2 text-sm font-semibold text-on-primary transition hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-surface-alt dark:bg-primary-dark dark:text-on-primary-dark dark:focus:ring-primary-dark dark:focus:ring-offset-surface-dark-alt">
|
||||
{{ t(key="login-auth", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
{{ ui::button_primary(label=t(key="login-auth", lang=lang | default(value='sk')), type="submit", extra="mt-1 w-full") }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="admin-orders", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-orders", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -24,7 +25,7 @@
|
||||
<td class="px-4 py-3 font-mono font-medium text-on-surface-strong dark:text-on-surface-dark-strong">{{ order.order_number }}</td>
|
||||
<td class="px-4 py-3">{{ order.email }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="inline-flex rounded-full bg-surface-alt px-2 py-0.5 text-xs font-medium text-on-surface/80 dark:bg-surface-dark-alt dark:text-on-surface-dark/80">{{ t(key="order-status-" ~ order.status, lang=lang | default(value='sk')) }}</span>
|
||||
{{ ui::badge(label=t(key="order-status-" ~ order.status, lang=lang | default(value='sk')), variant="neutral") }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right tabular-nums">{{ order.total }} {{ order.currency }}</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ order.order_number }}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-orders", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -6,13 +7,11 @@
|
||||
{% block content %}
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<h1 class="font-mono text-2xl font-bold text-on-surface-strong dark:text-on-surface-dark-strong">{{ order.order_number }}</h1>
|
||||
<a href="/admin/orders" class="inline-flex items-center rounded-radius border border-outline px-3 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="admin-orders", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_outline(label=t(key="admin-orders", lang=lang | default(value='sk')), href="/admin/orders") }}
|
||||
</div>
|
||||
|
||||
{% if ship_error %}
|
||||
<div class="mt-4 rounded-radius border border-danger/40 bg-danger/10 px-4 py-3 text-sm font-medium text-danger">
|
||||
{{ ship_error }}
|
||||
</div>
|
||||
{{ ui::alert_danger(message=ship_error, extra="mt-4") }}
|
||||
{% endif %}
|
||||
|
||||
<div class="mt-6 grid gap-6 lg:grid-cols-3">
|
||||
@@ -95,10 +94,9 @@
|
||||
<p class="text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="order-send-hint", lang=lang | default(value='sk')) }}</p>
|
||||
<form method="post" action="/admin/orders/{{ order.id }}/ship"
|
||||
onsubmit="return confirm('{{ t(key="order-send-confirm", lang=lang | default(value='sk')) }}')">
|
||||
<button type="submit"
|
||||
class="inline-flex w-full items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="order-send-to-carrier", lang=lang | default(value='sk')) }} {{ carrier | upper }}
|
||||
</button>
|
||||
{% set carrier_up = carrier | upper %}
|
||||
{% set ship_label = t(key="order-send-to-carrier", lang=lang | default(value='sk')) ~ " " ~ carrier_up %}
|
||||
{{ ui::button_primary(label=ship_label, type="submit", extra="w-full") }}
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -111,7 +109,7 @@
|
||||
<option value="{{ status }}" {% if order.status == status %}selected{% endif %}>{{ t(key="order-status-" ~ status, lang=lang | default(value='sk')) }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit" class="inline-flex w-full items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">{{ t(key="order-update-status", lang=lang | default(value='sk')) }}</button>
|
||||
{{ ui::button_primary(label=t(key="order-update-status", lang=lang | default(value='sk')), type="submit", extra="w-full") }}
|
||||
</form>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="admin-shipping", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
{% block crumb %}{{ t(key="admin-shipping", lang=lang | default(value='sk')) }}{% endblock crumb %}
|
||||
@@ -27,10 +28,7 @@
|
||||
class="size-4 rounded border-outline text-primary focus:ring-primary dark:border-outline-dark">
|
||||
<span class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">{{ t(key="shipping-enabled", lang=lang | default(value='sk')) }}</span>
|
||||
</label>
|
||||
<button type="submit"
|
||||
class="ml-auto inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="save", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
{{ ui::button_primary(label=t(key="save", lang=lang | default(value='sk')), type="submit", extra="ml-auto") }}
|
||||
</form>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -111,56 +111,7 @@
|
||||
</a>
|
||||
<!-- settings (language + theme) dropdown -->
|
||||
<div x-data="{ open: false }" @keydown.escape="open = false" class="relative">
|
||||
<button type="button" @click="open = !open" :aria-expanded="open"
|
||||
aria-label="{{ t(key='settings', lang=lang | default(value='sk')) }}"
|
||||
title="{{ t(key='settings', lang=lang | default(value='sk')) }}"
|
||||
class="inline-flex size-9 items-center justify-center rounded-radius text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open" x-cloak @click.outside="open = false"
|
||||
x-transition.origin.top.right
|
||||
class="absolute right-0 mt-2 w-56 rounded-radius border border-outline bg-surface p-2 shadow-lg dark:border-outline-dark dark:bg-surface-dark-alt">
|
||||
<form method="post" action="/lang" hx-boost="false">
|
||||
<p class="px-2 py-1 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-language", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<button type="submit" name="lang" value="en"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>English</span>
|
||||
{% if lang | default(value='sk') == "en" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
<button type="submit" name="lang" value="sk"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>Slovenčina</span>
|
||||
{% if lang | default(value='sk') == "sk" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<p class="mt-1 px-2 py-1 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-theme", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<div x-data="{ theme: currentTheme() }" @theme:changed.document="theme = $event.detail">
|
||||
<button type="button" @click="setTheme('system')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-system", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'system'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('light')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-light", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'light'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('dark')"
|
||||
class="flex w-full items-center justify-between rounded-radius px-2 py-1.5 text-sm text-on-surface transition hover:bg-surface-alt dark:text-on-surface-dark dark:hover:bg-surface-dark">
|
||||
<span>{{ t(key="theme-dark", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'dark'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% include "partials/settings_dropdown.html" %}
|
||||
</div>
|
||||
|
||||
<!-- mobile hamburger -->
|
||||
|
||||
67
assets/views/macros/ui.html
Normal file
67
assets/views/macros/ui.html
Normal file
@@ -0,0 +1,67 @@
|
||||
{# Reusable UI macros adapted from vendored Penguin UI components.
|
||||
These are OUR adaptation layer; the byte-for-byte upstream sources live under
|
||||
assets/views/penguinui/. Tailwind sees the full literal class strings here
|
||||
(assets/css/app.css has @source "../views"), so every branch must spell its
|
||||
classes out in full — never build class names by concatenation.
|
||||
|
||||
Usage:
|
||||
{% import "macros/ui.html" as ui %}
|
||||
{{ ui::button_primary(label=t(key="save", lang=lang)) }}
|
||||
{{ ui::button_primary(label="Add", attrs='hx-post="/x"' | safe) }}
|
||||
{{ ui::button_outline(label="Cancel", href="/back") }}
|
||||
{{ ui::badge(label="Published", variant="success") }}
|
||||
|
||||
Notes:
|
||||
- Macros can't see template context vars (e.g. `lang`); pass already-translated
|
||||
strings as `label`.
|
||||
- `attrs` is injected raw (caller must pass it through `| safe`); use it for
|
||||
htmx / name / value / @click etc. For buttons whose attrs carry nested
|
||||
quotes (e.g. hx-on with toast(...)), keep them inline instead.
|
||||
- Source: penguinui/buttons/{default,outline,ghost}-button.html and
|
||||
penguinui/badge/soft-color-badge.html. Upstream's color-button typos
|
||||
(text-onDanger etc.) are fixed to our real tokens (text-on-danger). #}
|
||||
|
||||
{% macro button_primary(label, type="button", href="", attrs="", extra="") -%}
|
||||
{% if href %}<a href="{{ href }}"{% else %}<button type="{{ type }}"{% endif %} class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-radius border border-primary bg-primary px-4 py-2 text-center text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75 dark:border-primary-dark dark:bg-primary-dark dark:text-on-primary-dark dark:focus-visible:outline-primary-dark {{ extra }}" {{ attrs | safe }}>{{ label }}</{% if href %}a{% else %}button{% endif %}>
|
||||
{%- endmacro button_primary %}
|
||||
|
||||
{% macro button_outline(label, type="button", href="", attrs="", extra="") -%}
|
||||
{% if href %}<a href="{{ href }}"{% else %}<button type="{{ type }}"{% endif %} class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-radius border border-outline bg-surface-alt px-4 py-2 text-center text-sm font-medium tracking-wide text-on-surface transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-outline-strong active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75 dark:border-outline-dark dark:bg-surface-dark-alt dark:text-on-surface-dark dark:focus-visible:outline-outline-dark-strong {{ extra }}" {{ attrs | safe }}>{{ label }}</{% if href %}a{% else %}button{% endif %}>
|
||||
{%- endmacro button_outline %}
|
||||
|
||||
{% macro button_danger(label, type="button", href="", attrs="", extra="") -%}
|
||||
{% if href %}<a href="{{ href }}"{% else %}<button type="{{ type }}"{% endif %} class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-radius border border-danger bg-danger px-4 py-2 text-center text-sm font-medium tracking-wide text-on-danger transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75 dark:focus-visible:outline-danger {{ extra }}" {{ attrs | safe }}>{{ label }}</{% if href %}a{% else %}button{% endif %}>
|
||||
{%- endmacro button_danger %}
|
||||
|
||||
{% macro button_ghost(label, type="button", href="", attrs="", extra="") -%}
|
||||
{% if href %}<a href="{{ href }}"{% else %}<button type="{{ type }}"{% endif %} class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-radius bg-transparent px-4 py-2 text-center text-sm font-medium tracking-wide text-primary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75 dark:text-primary-dark dark:focus-visible:outline-primary-dark {{ extra }}" {{ attrs | safe }}>{{ label }}</{% if href %}a{% else %}button{% endif %}>
|
||||
{%- endmacro button_ghost %}
|
||||
|
||||
{# Compact danger alert (form/inline errors). Adapted from
|
||||
penguinui/alert/default-alert.html (danger variant), trimmed to a single line
|
||||
with the danger icon. #}
|
||||
{% macro alert_danger(message, extra="") -%}
|
||||
<div class="flex w-full items-center gap-2 overflow-hidden rounded-radius border border-danger bg-danger/10 px-3 py-2 text-sm text-danger {{ extra }}" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 shrink-0" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM8.28 7.22a.75.75 0 0 0-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 1 0 1.06 1.06L10 11.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L11.06 10l1.72-1.72a.75.75 0 0 0-1.06-1.06L10 8.94 8.28 7.22Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<span>{{ message }}</span>
|
||||
</div>
|
||||
{%- endmacro alert_danger %}
|
||||
|
||||
{# Soft-color badge. variant ∈ success | danger | warning | info | primary | neutral #}
|
||||
{% macro badge(label, variant="neutral") -%}
|
||||
{% if variant == "success" -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-success bg-surface text-xs font-medium text-success dark:bg-surface-dark"><span class="bg-success/10 px-2 py-1">{{ label }}</span></span>
|
||||
{%- elif variant == "danger" -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-danger bg-surface text-xs font-medium text-danger dark:bg-surface-dark"><span class="bg-danger/10 px-2 py-1">{{ label }}</span></span>
|
||||
{%- elif variant == "warning" -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-warning bg-surface text-xs font-medium text-warning dark:bg-surface-dark"><span class="bg-warning/10 px-2 py-1">{{ label }}</span></span>
|
||||
{%- elif variant == "info" -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-info bg-surface text-xs font-medium text-info dark:bg-surface-dark"><span class="bg-info/10 px-2 py-1">{{ label }}</span></span>
|
||||
{%- elif variant == "primary" -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-primary bg-surface text-xs font-medium text-primary dark:border-primary-dark dark:bg-surface-dark dark:text-primary-dark"><span class="bg-primary/10 px-2 py-1 dark:bg-primary-dark/10">{{ label }}</span></span>
|
||||
{%- else -%}
|
||||
<span class="inline-flex w-fit overflow-hidden rounded-radius border border-outline bg-surface text-xs font-medium text-on-surface dark:border-outline-dark dark:bg-surface-dark dark:text-on-surface-dark"><span class="bg-surface-alt/40 px-2 py-1 dark:bg-surface-dark-alt/40">{{ label }}</span></span>
|
||||
{%- endif %}
|
||||
{%- endmacro badge %}
|
||||
63
assets/views/partials/settings_dropdown.html
Normal file
63
assets/views/partials/settings_dropdown.html
Normal file
@@ -0,0 +1,63 @@
|
||||
{# Settings dropdown (language + theme). Shared by base.html and admin/base.html
|
||||
to kill the former ~100-line copy-paste duplication.
|
||||
|
||||
Adapted from the vendored Penguin UI component
|
||||
assets/views/penguinui/dropdowns/dropdown-with-click.html: Penguin's dropdown
|
||||
menu container + item treatment. Deviations: kept our gear icon-only trigger
|
||||
and our core-Alpine open / @click.outside toggle (upstream's x-trap / $focus
|
||||
need the Alpine Focus plugin, which we don't bundle); item hover uses
|
||||
bg-primary/5 to stay consistent with the rest of our Penguin-ified UI.
|
||||
|
||||
The host template provides the wrapper
|
||||
<div x-data="{ open: false }" @keydown.escape="open = false" class="relative ...">
|
||||
so it controls its own positioning (e.g. ml-auto in admin). #}
|
||||
<button type="button" @click="open = !open" :aria-expanded="open"
|
||||
aria-label="{{ t(key='settings', lang=lang | default(value='sk')) }}"
|
||||
title="{{ t(key='settings', lang=lang | default(value='sk')) }}"
|
||||
class="inline-flex size-9 items-center justify-center rounded-radius text-on-surface transition hover:bg-surface-alt focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-outline-strong dark:text-on-surface-dark dark:hover:bg-surface-dark-alt dark:focus-visible:outline-outline-dark-strong">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open" x-cloak @click.outside="open = false" x-transition.origin.top.right
|
||||
class="absolute right-0 mt-2 flex w-56 flex-col overflow-hidden rounded-radius border border-outline bg-surface-alt py-1 shadow-lg dark:border-outline-dark dark:bg-surface-dark-alt"
|
||||
role="menu">
|
||||
<form method="post" action="/lang" hx-boost="false">
|
||||
<p class="px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-language", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<button type="submit" name="lang" value="en" role="menuitem"
|
||||
class="flex w-full items-center justify-between px-4 py-2 text-sm text-on-surface transition hover:bg-primary/5 hover:text-on-surface-strong focus-visible:bg-primary/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:text-on-surface-dark dark:hover:bg-primary-dark/5 dark:hover:text-on-surface-dark-strong">
|
||||
<span>English</span>
|
||||
{% if lang | default(value='sk') == "en" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
<button type="submit" name="lang" value="sk" role="menuitem"
|
||||
class="flex w-full items-center justify-between px-4 py-2 text-sm text-on-surface transition hover:bg-primary/5 hover:text-on-surface-strong focus-visible:bg-primary/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:text-on-surface-dark dark:hover:bg-primary-dark/5 dark:hover:text-on-surface-dark-strong">
|
||||
<span>Slovenčina</span>
|
||||
{% if lang | default(value='sk') == "sk" %}<span class="text-primary dark:text-primary-dark">✓</span>{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<p class="mt-1 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-on-surface/60 dark:text-on-surface-dark/60">
|
||||
{{ t(key="settings-theme", lang=lang | default(value='sk')) }}
|
||||
</p>
|
||||
<div x-data="{ theme: currentTheme() }" @theme:changed.document="theme = $event.detail">
|
||||
<button type="button" @click="setTheme('system')" role="menuitem"
|
||||
class="flex w-full items-center justify-between px-4 py-2 text-sm text-on-surface transition hover:bg-primary/5 hover:text-on-surface-strong focus-visible:bg-primary/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:text-on-surface-dark dark:hover:bg-primary-dark/5 dark:hover:text-on-surface-dark-strong">
|
||||
<span>{{ t(key="theme-system", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'system'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('light')" role="menuitem"
|
||||
class="flex w-full items-center justify-between px-4 py-2 text-sm text-on-surface transition hover:bg-primary/5 hover:text-on-surface-strong focus-visible:bg-primary/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:text-on-surface-dark dark:hover:bg-primary-dark/5 dark:hover:text-on-surface-dark-strong">
|
||||
<span>{{ t(key="theme-light", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'light'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
<button type="button" @click="setTheme('dark')" role="menuitem"
|
||||
class="flex w-full items-center justify-between px-4 py-2 text-sm text-on-surface transition hover:bg-primary/5 hover:text-on-surface-strong focus-visible:bg-primary/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:text-on-surface-dark dark:hover:bg-primary-dark/5 dark:hover:text-on-surface-dark-strong">
|
||||
<span>{{ t(key="theme-dark", lang=lang | default(value='sk')) }}</span>
|
||||
<span x-show="theme === 'dark'" class="text-primary dark:text-primary-dark">✓</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
101
assets/views/penguinui/alert/default-alert.html
Normal file
101
assets/views/penguinui/alert/default-alert.html
Normal file
@@ -0,0 +1,101 @@
|
||||
<!-- info Alert -->
|
||||
<div class="relative w-full overflow-hidden rounded-sm border border-sky-500 bg-surface text-on-surface dark:bg-surface-dark dark:text-on-surface-dark"
|
||||
role="alert">
|
||||
<div class="flex w-full items-center gap-2 bg-info/10 p-4">
|
||||
<div class="bg-sky-500/15 text-sky-500 rounded-full p-1" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<h3 class="text-sm font-semibold text-info">Update Available</h3>
|
||||
<p class="text-xs font-medium sm:text-sm">A new version is available. Please update to the latest version.
|
||||
</p>
|
||||
</div>
|
||||
<button class="ml-auto" aria-label="dismiss alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
|
||||
fill="none" stroke-width="2.5" class="size-4 shrink-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- success Alert -->
|
||||
<div class="relative w-full overflow-hidden rounded-sm border border-green-500 bg-surface text-on-surface dark:bg-surface-dark dark:text-on-surface-dark"
|
||||
role="alert">
|
||||
<div class="flex w-full items-center gap-2 bg-success/10 p-4">
|
||||
<div class="bg-green-500/15 text-green-500 rounded-full p-1" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm3.857-9.809a.75.75 0 0 0-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 1 0-1.06 1.061l2.5 2.5a.75.75 0 0 0 1.137-.089l4-5.5Z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<h3 class="text-sm font-semibold text-success">Successfully Subscribed</h3>
|
||||
<p class="text-xs font-medium sm:text-sm">Success! You've subscribed to our newsletter. Welcome aboard!</p>
|
||||
</div>
|
||||
<button class="ml-auto" aria-label="dismiss alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
|
||||
fill="none" stroke-width="2.5" class="size-4 shrink-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- warning Alert -->
|
||||
<div class="relative w-full overflow-hidden rounded-sm border border-amber-500 bg-surface text-on-surface dark:bg-surface-dark dark:text-on-surface-dark"
|
||||
role="alert">
|
||||
<div class="flex w-full items-center gap-2 bg-warning/10 p-4">
|
||||
<div class="bg-amber-500/15 text-amber-500 rounded-full p-1" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-8-5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 10 5Zm0 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<h3 class="text-sm font-semibold text-warning">Credit Card Expires Soon</h3>
|
||||
<p class="text-xs font-medium sm:text-sm">Your credit card expires soon. Please update your payment
|
||||
information.</p>
|
||||
</div>
|
||||
<button class="ml-auto" aria-label="dismiss alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
|
||||
fill="none" stroke-width="2.5" class="size-4 shrink-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- danger Alert -->
|
||||
<div class="relative w-full overflow-hidden rounded-sm border border-red-500 bg-surface text-on-surface dark:bg-surface-dark dark:text-on-surface-dark"
|
||||
role="alert">
|
||||
<div class="flex w-full items-center gap-2 bg-danger/10 p-4">
|
||||
<div class="bg-red-500/15 text-red-500 rounded-full p-1" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM8.28 7.22a.75.75 0 0 0-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 1 0 1.06 1.06L10 11.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L11.06 10l1.72-1.72a.75.75 0 0 0-1.06-1.06L10 8.94 8.28 7.22Z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<h3 class="text-sm font-semibold text-danger">Invalid Email Address</h3>
|
||||
<p class="text-xs font-medium sm:text-sm">The email address you entered is invalid. Please try again.</p>
|
||||
</div>
|
||||
<button class="ml-auto" aria-label="dismiss alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
|
||||
fill="none" stroke-width="2.5" class="size-4 shrink-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
40
assets/views/penguinui/badge/soft-color-badge.html
Normal file
40
assets/views/penguinui/badge/soft-color-badge.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<!-- default Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-outline bg-surface text-xs font-medium text-on-surface dark:border-outline-dark dark:bg-surface-dark dark:text-on-surface-dark">
|
||||
<span class="px-2 py-1 bg-surface-alt/10 dark:bg-surface-dark-alt/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- inverse Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-outline-dark bg-surface text-xs font-medium text-on-surface dark:border-outline dark:bg-surface-dark dark:text-on-surface-dark">
|
||||
<span class="px-2 py-1 bg-surface-dark-alt/10 dark:bg-surface-alt/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- primary Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-primary bg-surface text-xs font-medium text-primary dark:border-primary-dark dark:bg-surface-dark dark:text-primary-dark">
|
||||
<span class="px-2 py-1 bg-primary/10 dark:bg-primary-dark/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- secondary Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-secondary bg-surface text-xs font-medium text-secondary dark:border-secondary-dark dark:bg-surface-dark dark:text-secondary-dark">
|
||||
<span class="px-2 py-1 bg-secondary/10 dark:bg-secondary-dark/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- info Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-info bg-surface text-xs font-medium text-info dark:border-info dark:bg-surface-dark dark:text-info">
|
||||
<span class="px-2 py-1 bg-info/10 dark:bg-info/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- success Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-success bg-surface text-xs font-medium text-success dark:border-success dark:bg-surface-dark dark:text-success">
|
||||
<span class="px-2 py-1 bg-success/10 dark:bg-success/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- warning Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-warning bg-surface text-xs font-medium text-warning dark:border-warning dark:bg-surface-dark dark:text-warning">
|
||||
<span class="px-2 py-1 bg-warning/10 dark:bg-warning/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
<!-- danger Badge -->
|
||||
<span class="w-fit inline-flex overflow-hidden rounded-radius border border-danger bg-surface text-xs font-medium text-danger dark:border-danger dark:bg-surface-dark dark:text-danger">
|
||||
<span class="px-2 py-1 bg-danger/10 dark:bg-danger/10">Bagde</span>
|
||||
</span>
|
||||
|
||||
64
assets/views/penguinui/buttons/button-with-icon.html
Normal file
64
assets/views/penguinui/buttons/button-with-icon.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- primary Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-primary border border-primary dark:border-primary-dark px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-primary-dark dark:text-on-primary-dark dark:focus-visible:outline-primary-dark">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-primary dark:fill-on-primary-dark" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- secondary Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-secondary border border-secondary dark:border-secondary-dark px-4 py-2 text-sm font-medium tracking-wide text-on-secondary transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-secondary-dark dark:text-on-secondary-dark dark:focus-visible:outline-secondary-dark">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-secondary dark:fill-on-secondary-dark" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- alternate Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-surface-alt border border-surface-alt dark:border-surface-dark-alt px-4 py-2 text-sm font-medium tracking-wide text-on-surface-strong transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-alt active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-surface-dark-alt dark:text-on-surface-dark-strong dark:focus-visible:outline-surface-dark-alt">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-surface-strong dark:fill-on-surface-dark-strong" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- inverse Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-surface-dark border border-surface-dark dark:border-surface px-4 py-2 text-sm font-medium tracking-wide text-on-surface-dark transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-dark active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-surface dark:text-on-surface dark:focus-visible:outline-surface">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-surface-dark dark:fill-on-surface" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- info Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-info border border-info dark:border-info px-4 py-2 text-sm font-medium tracking-wide text-on-info transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-info active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-info dark:text-on-info dark:focus-visible:outline-info">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-info dark:fill-on-info" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- danger Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-danger border border-danger dark:border-danger px-4 py-2 text-sm font-medium tracking-wide text-on-danger transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-danger dark:text-on-danger dark:focus-visible:outline-danger">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-danger dark:fill-on-danger" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- warning Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-warning border border-warning dark:border-warning px-4 py-2 text-sm font-medium tracking-wide text-on-warning transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-warning active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-warning dark:text-on-warning dark:focus-visible:outline-warning">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-warning dark:fill-on-warning" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
<!-- success Button with Icon -->
|
||||
<button type="button" class="inline-flex justify-center items-center gap-2 whitespace-nowrap rounded-radius bg-success border border-success dark:border-success px-4 py-2 text-sm font-medium tracking-wide text-on-success transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-success active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-success dark:text-on-success dark:focus-visible:outline-success">
|
||||
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 fill-on-success dark:fill-on-success" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Create
|
||||
</button>
|
||||
|
||||
24
assets/views/penguinui/buttons/default-button.html
Normal file
24
assets/views/penguinui/buttons/default-button.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!-- primary Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-primary border border-primary px-4 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-primary-dark dark:border-primary-dark dark:text-on-primary-dark dark:focus-visible:outline-primary-dark">Primary</button>
|
||||
|
||||
<!-- secondary Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-secondary border border-secondary px-4 py-2 text-sm font-medium tracking-wide text-on-secondary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-secondary-dark dark:border-secondary-dark dark:text-on-secondary-dark dark:focus-visible:outline-secondary-dark">Secondary</button>
|
||||
|
||||
<!-- alternate Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-surface-alt border border-surface-alt px-4 py-2 text-sm font-medium tracking-wide text-on-surface-strong transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-alt active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-surface-dark-alt dark:border-surface-dark-alt dark:text-on-surface-dark-strong dark:focus-visible:outline-surface-dark-alt">Alternate</button>
|
||||
|
||||
<!-- inverse Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-surface-dark border border-surface-dark px-4 py-2 text-sm font-medium tracking-wide text-on-surface-dark transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-dark active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-surface dark:border-surface dark:text-on-surface dark:focus-visible:outline-surface">Inverse</button>
|
||||
|
||||
<!-- info Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-info border border-info px-4 py-2 text-sm font-medium tracking-wide text-onInfo transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-info active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-info dark:border-info dark:text-onInfo dark:focus-visible:outline-info">Info</button>
|
||||
|
||||
<!-- danger Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-danger border border-danger px-4 py-2 text-sm font-medium tracking-wide text-onDanger transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-danger dark:border-danger dark:text-onDanger dark:focus-visible:outline-danger">Danger</button>
|
||||
|
||||
<!-- warning Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-warning border border-warning px-4 py-2 text-sm font-medium tracking-wide text-onWarning transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-warning active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-warning dark:border-warning dark:text-onWarning dark:focus-visible:outline-warning">Warning</button>
|
||||
|
||||
<!-- success Button -->
|
||||
<button type="button" class="whitespace-nowrap rounded-radius bg-success border border-success px-4 py-2 text-sm font-medium tracking-wide text-onSuccess transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-success active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-success dark:border-success dark:text-onSuccess dark:focus-visible:outline-success">Success</button>
|
||||
|
||||
24
assets/views/penguinui/buttons/ghost-button.html
Normal file
24
assets/views/penguinui/buttons/ghost-button.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!-- primary Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-primary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-primary-dark dark:focus-visible:outline-primary-dark">Primary</button>
|
||||
|
||||
<!-- secondary Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-secondary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-secondary-dark dark:focus-visible:outline-secondary-dark">Secondary</button>
|
||||
|
||||
<!-- alternate Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-outline transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-outline active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-outline-dark dark:focus-visible:outline-outline-dark">Alternate</button>
|
||||
|
||||
<!-- inverse Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-surface-dark transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-dark active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-surface dark:focus-visible:outline-surface">Inverse</button>
|
||||
|
||||
<!-- info Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-info transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-info active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-info dark:focus-visible:outline-info">Info</button>
|
||||
|
||||
<!-- danger Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-danger transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-danger dark:focus-visible:outline-danger">Danger</button>
|
||||
|
||||
<!-- warning Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-warning transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-warning active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-warning dark:focus-visible:outline-warning">Warning</button>
|
||||
|
||||
<!-- success Ghost Button -->
|
||||
<button type="button" class="bg-transparent rounded-radius px-4 py-2 text-sm font-medium tracking-wide text-success transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-success active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:text-success dark:focus-visible:outline-success">Success</button>
|
||||
|
||||
24
assets/views/penguinui/buttons/outline-button.html
Normal file
24
assets/views/penguinui/buttons/outline-button.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!-- primary Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-primary px-4 py-2 text-sm font-medium tracking-wide text-primary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-primary-dark dark:text-primary-dark dark:focus-visible:outline-primary-dark">Primary</button>
|
||||
|
||||
<!-- secondary Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-secondary px-4 py-2 text-sm font-medium tracking-wide text-secondary transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-secondary-dark dark:text-secondary-dark dark:focus-visible:outline-secondary-dark">Secondary</button>
|
||||
|
||||
<!-- alternate Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-outline px-4 py-2 text-sm font-medium tracking-wide text-outline transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-outline active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-outline-dark dark:text-outline-dark dark:focus-visible:outline-outline-dark">Alternate</button>
|
||||
|
||||
<!-- inverse Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-surface-dark px-4 py-2 text-sm font-medium tracking-wide text-surface-dark transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-surface-dark active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-surface dark:text-surface dark:focus-visible:outline-surface">Inverse</button>
|
||||
|
||||
<!-- info Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-info px-4 py-2 text-sm font-medium tracking-wide text-info transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-info active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-info dark:text-info dark:focus-visible:outline-info">Info</button>
|
||||
|
||||
<!-- danger Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-danger px-4 py-2 text-sm font-medium tracking-wide text-danger transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-danger dark:text-danger dark:focus-visible:outline-danger">Danger</button>
|
||||
|
||||
<!-- warning Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-warning px-4 py-2 text-sm font-medium tracking-wide text-warning transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-warning active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-warning dark:text-warning dark:focus-visible:outline-warning">Warning</button>
|
||||
|
||||
<!-- success Outline Button -->
|
||||
<button type="button" class="whitespace-nowrap bg-transparent rounded-radius border border-success px-4 py-2 text-sm font-medium tracking-wide text-success transition hover:opacity-75 text-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-success active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:border-success dark:text-success dark:focus-visible:outline-success">Success</button>
|
||||
|
||||
16
assets/views/penguinui/dropdowns/dropdown-with-click.html
Normal file
16
assets/views/penguinui/dropdowns/dropdown-with-click.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div x-data="{ isOpen: false, openedWithKeyboard: false }" class="relative w-fit" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
|
||||
<!-- Toggle Button -->
|
||||
<button type="button" x-on:click="isOpen = ! isOpen" class="inline-flex items-center gap-2 whitespace-nowrap rounded-radius border border-outline bg-surface-alt px-4 py-2 text-sm font-medium tracking-wide transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-outline-strong dark:border-outline-dark dark:bg-surface-dark-alt dark:focus-visible:outline-outline-dark-strong" aria-haspopup="true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.down.prevent="openedWithKeyboard = true" x-bind:class="isOpen || openedWithKeyboard ? 'text-on-surface-strong dark:text-on-surface-dark-strong' : 'text-on-surface dark:text-on-surface-dark'" x-bind:aria-expanded="isOpen || openedWithKeyboard">
|
||||
Actions Menu
|
||||
<svg aria-hidden="true" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-4 rotate-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Dropdown Menu -->
|
||||
<div x-cloak x-show="isOpen || openedWithKeyboard" x-transition x-trap="openedWithKeyboard" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" class="absolute top-11 left-0 flex w-fit min-w-48 flex-col overflow-hidden rounded-radius border border-outline bg-surface-alt dark:border-outline-dark dark:bg-surface-dark-alt" role="menu">
|
||||
<a href="#" class="bg-surface-alt px-4 py-2 text-sm text-on-surface hover:bg-surface-dark-alt/5 hover:text-on-surface-strong focus-visible:bg-surface-dark-alt/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:bg-surface-dark-alt dark:text-on-surface-dark dark:hover:bg-surface-alt/5 dark:hover:text-on-surface-dark-strong dark:focus-visible:bg-surface-alt/10 dark:focus-visible:text-on-surface-dark-strong" role="menuitem">Dashboard</a>
|
||||
<a href="#" class="bg-surface-alt px-4 py-2 text-sm text-on-surface hover:bg-surface-dark-alt/5 hover:text-on-surface-strong focus-visible:bg-surface-dark-alt/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:bg-surface-dark-alt dark:text-on-surface-dark dark:hover:bg-surface-alt/5 dark:hover:text-on-surface-dark-strong dark:focus-visible:bg-surface-alt/10 dark:focus-visible:text-on-surface-dark-strong" role="menuitem">Subscription</a>
|
||||
<a href="#" class="bg-surface-alt px-4 py-2 text-sm text-on-surface hover:bg-surface-dark-alt/5 hover:text-on-surface-strong focus-visible:bg-surface-dark-alt/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:bg-surface-dark-alt dark:text-on-surface-dark dark:hover:bg-surface-alt/5 dark:hover:text-on-surface-dark-strong dark:focus-visible:bg-surface-alt/10 dark:focus-visible:text-on-surface-dark-strong" role="menuitem">Settings</a>
|
||||
<a href="#" class="bg-surface-alt px-4 py-2 text-sm text-on-surface hover:bg-surface-dark-alt/5 hover:text-on-surface-strong focus-visible:bg-surface-dark-alt/10 focus-visible:text-on-surface-strong focus-visible:outline-hidden dark:bg-surface-dark-alt dark:text-on-surface-dark dark:hover:bg-surface-alt/5 dark:hover:text-on-surface-dark-strong dark:focus-visible:bg-surface-alt/10 dark:focus-visible:text-on-surface-dark-strong" role="menuitem">Sign Out</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,7 @@
|
||||
{# Cart contents, swapped in via htmx on quantity change / removal so the page
|
||||
never does a full reload. Rendered inside <div id="cart-body"> in cart.html
|
||||
and returned on its own by /cart/update and /cart/remove. #}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
{% if items | length > 0 %}
|
||||
<div class="overflow-hidden rounded-radius border border-outline dark:border-outline-dark">
|
||||
<table class="w-full text-left text-sm">
|
||||
@@ -60,12 +61,12 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-wrap justify-between gap-3">
|
||||
<a href="/shop" class="inline-flex items-center rounded-radius border border-outline px-4 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cart-continue", lang=lang | default(value='sk')) }}</a>
|
||||
<a href="/checkout" class="inline-flex items-center justify-center rounded-radius bg-primary px-5 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">{{ t(key="cart-checkout", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_outline(label=t(key="cart-continue", lang=lang | default(value='sk')), href="/shop") }}
|
||||
{{ ui::button_primary(label=t(key="cart-checkout", lang=lang | default(value='sk')), href="/checkout") }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="rounded-radius border border-outline px-6 py-16 text-center dark:border-outline-dark">
|
||||
<p class="text-on-surface/70 dark:text-on-surface-dark/70">{{ t(key="cart-empty", lang=lang | default(value='sk')) }}</p>
|
||||
<a href="/shop" class="mt-4 inline-flex items-center justify-center rounded-radius bg-primary px-4 py-2 text-sm font-medium text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">{{ t(key="cart-continue", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_primary(label=t(key="cart-continue", lang=lang | default(value='sk')), href="/shop", extra="mt-4") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="cart-title", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="checkout-title", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
|
||||
@@ -211,10 +212,7 @@
|
||||
<span>{{ t(key="cart-total", lang=lang | default(value='sk')) }}</span>
|
||||
<span class="tabular-nums text-primary dark:text-primary-dark" x-text="fmt(subtotal + carrierPrice) + ' {{ currency }}'"></span>
|
||||
</div>
|
||||
<button type="submit" :disabled="!canSubmit"
|
||||
class="inline-flex w-full items-center justify-center rounded-radius bg-primary px-6 py-2.5 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 disabled:cursor-not-allowed disabled:opacity-40 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="checkout-place-order", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
{{ ui::button_primary(label=t(key="checkout-place-order", lang=lang | default(value='sk')), type="submit", attrs=':disabled="!canSubmit"', extra="w-full disabled:opacity-40") }}
|
||||
</aside>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ t(key="order-confirmed-title", lang=lang | default(value='sk')) }}{% endblock title %}
|
||||
|
||||
@@ -55,7 +56,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="text-center">
|
||||
<a href="/shop" class="inline-flex items-center justify-center rounded-radius border border-outline px-5 py-2 text-sm font-medium text-on-surface transition hover:bg-surface-alt dark:border-outline-dark dark:text-on-surface-dark dark:hover:bg-surface-dark-alt">{{ t(key="cart-continue", lang=lang | default(value='sk')) }}</a>
|
||||
{{ ui::button_outline(label=t(key="cart-continue", lang=lang | default(value='sk')), href="/shop") }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/ui.html" as ui %}
|
||||
|
||||
{% block title %}{{ product.name }}{% endblock title %}
|
||||
|
||||
@@ -47,10 +48,7 @@
|
||||
<input id="quantity" name="quantity" type="number" min="1" max="{{ product.stock }}" value="1"
|
||||
class="w-24 rounded-radius border border-outline bg-surface px-3 py-2 text-sm text-on-surface focus:outline-2 focus:outline-primary dark:border-outline-dark dark:bg-surface-dark dark:text-on-surface-dark">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center rounded-radius bg-primary px-5 py-2 text-sm font-medium tracking-wide text-on-primary transition hover:opacity-75 dark:bg-primary-dark dark:text-on-primary-dark">
|
||||
{{ t(key="add-to-cart", lang=lang | default(value='sk')) }}
|
||||
</button>
|
||||
{{ ui::button_primary(label=t(key="add-to-cart", lang=lang | default(value='sk')), type="submit") }}
|
||||
</form>
|
||||
<p class="text-sm text-on-surface/60 dark:text-on-surface-dark/60">{{ t(key="in-stock", lang=lang | default(value='sk')) }}: {{ product.stock }}</p>
|
||||
{% else %}
|
||||
|
||||
Reference in New Issue
Block a user