-
- ${o.badge ? `
${String(o.badge).toUpperCase()}` : ''}
- ${o.domain ? `
${o.domain}
` : ''}
+ ${o.badge
+ ? `
+ ${String(o.badge).toUpperCase()}
+ `
+ : ''}
+ ${o.domain
+ ? `
${o.domain}
`
+ : ''}
@@ -140,6 +167,79 @@
`;
}
+// function buildHTML(o){
+// const st = statusMap(o.state);
+// const progress = (o.state === 'running' || o.state === 'queued')
+// ? `
` : '';
+//
+// const closeBtn = (o.close !== false)
+// ? `
`
+// : '
';
+//
+// return `
+//
+//
+//
+//
+// ${o.badge ? `
${String(o.badge).toUpperCase()}` : ''}
+// ${o.domain ? `
${o.domain}
` : ''}
+//
+//
+//
+//
+// Status
+//
+//
+// ${st.text}
+//
+// ${closeBtn}
+//
+//
+//
+// ${o.message ? `
${o.message}
` : ''}
+//
+// ${progress}
+//
+// ${o.finalNote ? `
${o.finalNote}
` : ''}
+//
+// `;
+// // return `
+// //
+// //
+// //
+// //
+// //
+// // ${o.badge ? `
${String(o.badge).toUpperCase()}` : ''}
+// // ${o.domain ? `
${o.domain}
` : ''}
+// //
+// //
+// //
+// //
+// // Status
+// //
+// //
+// // ${st.text}
+// //
+// // ${closeBtn}
+// //
+// //
+// //
+// // ${o.message ? `
${o.message}
` : ''}
+// //
+// // ${progress}
+// //
+// // ${o.finalNote ? `
${o.finalNote}
` : ''}
+// //
`;
+// }
+
function remove(wrapper) {
if (!wrapper) return;
diff --git a/resources/js/ui/command.js b/resources/js/ui/command.js
new file mode 100644
index 0000000..95c2f85
--- /dev/null
+++ b/resources/js/ui/command.js
@@ -0,0 +1,40 @@
+(function(){
+ // OS erkennen (sehr defensiv)
+ const ua = navigator.userAgent || '';
+ const platform = navigator.platform || '';
+ const isMac = /Mac|Macintosh|Mac OS X/i.test(ua) || /Mac|iPhone|iPad|iPod/i.test(platform);
+
+ // Shortcut-Label setzen
+ const kbd = document.getElementById('searchShortcutKbd');
+ if (kbd) kbd.textContent = isMac ? '⌘ K' : 'Ctrl + K';
+
+ // Fallback: Tastenkombi abfangen, falls global nicht gebunden
+ const open = () => {
+ if (window.Livewire) {
+ window.Livewire.dispatch('openModal', { component: 'ui.search.modal.search-palette-modal' });
+ }
+ };
+
+ document.addEventListener('keydown', (e) => {
+ const k = (e.key || '').toLowerCase();
+ const meta = isMac ? e.metaKey : e.ctrlKey;
+ if (meta && k === 'k' && !e.shiftKey && !e.altKey) {
+ e.preventDefault();
+ open();
+ }
+ });
+
+ // Optional: Button auch via JS öffnen können
+ const btn = document.getElementById('openSearchPaletteBtn');
+ if (btn) btn.addEventListener('click', open);
+})();
+
+// document.addEventListener('keydown', (e) => {
+// const isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
+// const meta = isMac ? e.metaKey : e.ctrlKey;
+// if (meta && e.key.toLowerCase() === 'k') {
+// e.preventDefault();
+// // LivewireUI Modal öffnen
+// Livewire.dispatch('openModal', { component: 'ui.search.modal.search-palette-modal' });
+// }
+// });
diff --git a/resources/js/ui/toast.js b/resources/js/ui/toast.js
index b198013..003b382 100644
--- a/resources/js/ui/toast.js
+++ b/resources/js/ui/toast.js
@@ -1,25 +1,28 @@
-// Minimal-API mit Fallbacks: GlassToastra → toastr → eigener Mini-Toast
-export function showToast({ type = 'success', text = '', title = '' } = {}) {
- const t = (type || 'success').toLowerCase();
- const msg = text || '';
+// Immer die Glas-Toasts verwenden (keine Fallbacks, kein toastr)
+export function showToast(payload = {}) {
+ const {
+ id, type, state, text, message, title, badge, domain,
+ position, duration, close
+ } = payload || {};
- // 1) Dein Glas-Toast
- if (window.GlassToastra && typeof window.GlassToastra[t] === 'function') {
- window.GlassToastra[t](msg, title);
+ // type/state auf deine 4 Zustände mappen
+ const map = { success:'done', ok:'done', forbidden:'forbidden', error:'failed', danger:'failed', info:'queued', warning:'queued' };
+ const stIn = String(state ?? type ?? 'done').toLowerCase();
+ const st = ['done','failed','forbidden','running','queued'].includes(stIn) ? stIn : (map[stIn] || 'queued');
+
+ if (!window.toastraGlass || typeof window.toastraGlass.show !== 'function') {
+ // Optional: console.warn('toastraGlass fehlt');
return;
}
- // 2) toastr
- if (window.toastr && typeof window.toastr[t] === 'function') {
- window.toastr.options = { timeOut: 3500, progressBar: true, closeButton: true };
- window.toastr[t](msg, title);
- return;
- }
- // 3) Fallback
- const box = document.createElement('div');
- box.className =
- 'fixed top-4 right-4 z-[9999] rounded-xl bg-emerald-500/90 text-white ' +
- 'px-4 py-3 backdrop-blur shadow-lg border border-white/10';
- box.textContent = msg;
- document.body.appendChild(box);
- setTimeout(() => box.remove(), 3500);
+
+ window.toastraGlass.show({
+ id: id || ('toast-' + Date.now()), // gleiche id => ersetzt in-place
+ state: st, // steuert Badge/Icon/Farben
+ badge: badge ?? title ?? null, // linke kleine Kapsel
+ domain: domain ?? null, // kleine Überschrift rechts
+ message: (message ?? text ?? ''), // Haupttext
+ position: position ?? 'bottom-right',
+ duration: typeof duration === 'number' ? duration : 6000, // Standard 6s
+ close: close !== false,
+ });
}
diff --git a/resources/js/utils/events.js b/resources/js/utils/events.js
index 1385ebf..9c0f216 100644
--- a/resources/js/utils/events.js
+++ b/resources/js/utils/events.js
@@ -1,11 +1,71 @@
-import { showToast } from '../ui/toast.js'
+// import { showToast } from '../ui/toast.js'
// — Livewire-Hooks (global)
+// document.addEventListener('livewire:init', () => {
+// if (window.Livewire?.on) {
+// window.Livewire.on('toast', (payload = {}) => showToast(payload))
+// }
+// })
+
document.addEventListener('livewire:init', () => {
- if (window.Livewire?.on) {
- window.Livewire.on('toast', (payload = {}) => showToast(payload))
+ // Neu: Livewire v3 Browser-Events
+ window.addEventListener('toast', (e) => {
+ const d = e?.detail || {};
+ showToastGlass(d);
+ });
+
+ // Optional: Update/Dismiss/Clear per Event
+ window.addEventListener('toast.update', (e) => {
+ const d = e?.detail || {};
+ if (d.id) window.toastraGlass?.update(d.id, d);
+ });
+ window.addEventListener('toast.clear', (e) => {
+ window.toastraGlass?.clear(e?.detail?.position);
+ });
+});
+
+// Adapter: normalisiert Payload und ruft toastraGlass
+function showToastGlass({
+ id,
+ type, state, // "success" | "warning" | "error" ODER "done" | "failed" | "running"
+ text, message, title, // Textquellen
+ badge, domain,
+ position = 'bottom-right',
+ duration = 0, // 0 = stehen lassen; bei done/failed auto auf 6000ms
+ } = {}) {
+ // Map: type -> state
+ const t = (type || state || 'done').toLowerCase();
+ const map = { success: 'done', ok: 'done', error: 'failed', danger: 'failed', info: 'queued', warning: 'queued' };
+ const st = ['done','failed','running','queued'].includes(t) ? t : (map[t] || 'queued');
+
+ const msg = message || text || title || '';
+ const _id = id || ('toast-' + Date.now());
+
+ if (window.toastraGlass?.show) {
+ window.toastraGlass.show({
+ id: _id,
+ state: st, // queued|running|done|failed → färbt Badge/Icon
+ badge, // z.B. "DNS", "Signup"
+ domain, // optional: kleine Überschrift rechts
+ message: msg,
+ position,
+ duration, // 0 = stehen lassen; sonst ms
+ });
+ } else if (window.toastr) {
+ // Fallback: alte toastr API
+ const level = (type || (st === 'failed' ? 'error' : st === 'done' ? 'success' : 'info'));
+ window.toastr[level](msg, badge || domain || '');
+ } else {
+ // Minimal-Fallback
+ const box = document.createElement('div');
+ box.className = 'fixed top-4 right-4 z-[9999] rounded-xl bg-emerald-500/90 text-white px-4 py-3 backdrop-blur shadow-lg border border-white/10';
+ box.textContent = msg || 'OK';
+ document.body.appendChild(box);
+ setTimeout(() => box.remove(), 3500);
}
-})
+
+ return _id;
+}
// — Session-Flash vom Backend (einmal pro Page-Load)
function bootstrapFlashFromLayout() {
@@ -36,7 +96,7 @@ function setupEchoToasts() {
document.addEventListener('DOMContentLoaded', setupEchoToasts)
// — Optional: global machen, falls du manuell aus JS/Blade rufen willst
-window.showToast = showToast
+// window.showToast = showToast
diff --git a/resources/views/components/button/copy-btn.blade.php b/resources/views/components/button/copy-btn.blade.php
new file mode 100644
index 0000000..48caa67
--- /dev/null
+++ b/resources/views/components/button/copy-btn.blade.php
@@ -0,0 +1,25 @@
+@props([
+ 'text' => '',
+ 'class' => '',
+ 'label' => '',
+])
+
diff --git a/resources/views/components/button/filter-chip.blade.php b/resources/views/components/button/filter-chip.blade.php
new file mode 100644
index 0000000..fab681c
--- /dev/null
+++ b/resources/views/components/button/filter-chip.blade.php
@@ -0,0 +1,24 @@
+{{-- Filter-Chip als Dropdown (native
) --}}
+@props(['label' => 'Filter'])
+
+
+ {{ $label }}
+
+
+
+ {{ $slot }}
+
+
+
+{{-- Option-Button Klasse --}}
+@once
+
+@endonce
diff --git a/resources/views/components/icons/icon-logo-text.blade.php b/resources/views/components/icons/icon-logo-text.blade.php
new file mode 100644
index 0000000..1bccfbc
--- /dev/null
+++ b/resources/views/components/icons/icon-logo-text.blade.php
@@ -0,0 +1,15 @@
+
diff --git a/resources/views/components/partials/header.blade.php b/resources/views/components/partials/header.blade.php
index 04bfc23..c90b704 100644
--- a/resources/views/components/partials/header.blade.php
+++ b/resources/views/components/partials/header.blade.php
@@ -5,23 +5,45 @@