feat: extend rate card profiles with brands, terms, and custom HTML, and remove search bar from search index view

This commit is contained in:
I-Fun
2026-04-05 18:28:48 +07:00
parent d6b10f725b
commit 1c2c10d253
22 changed files with 1024 additions and 388 deletions

View File

@@ -9,20 +9,13 @@
<div x-data="notesApp({{ json_encode($notes) }})" x-cloak>
{{-- ── Toolbar ──────────────────────────────────────────────── --}}
<div class="flex items-center gap-2 mb-4">
<div class="flex items-center justify-between mb-4">
<button @click="openNew()" class="btn-sakura text-sm px-4 py-2 flex items-center gap-1.5 shrink-0">
+ New Note
</button>
{{-- Search --}}
<div class="relative flex-1 max-w-xs">
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm pointer-events-none"></span>
<input type="text" x-model="searchQuery" placeholder="🔍Search notes…"
class="input-soft pl-9 text-sm py-2 w-full">
</div>
{{-- Count --}}
<span class="ml-auto text-xs text-gray-400 shrink-0"
<span class="text-xs text-gray-400 shrink-0"
x-text="notes.length + ' note' + (notes.length !== 1 ? 's' : '')"></span>
</div>
@@ -121,7 +114,7 @@
</div>
</template>
{{-- ── Empty state ──────────────────────────────────────────── --}}
{{-- Empty state is only when NO notes exist --}}
<template x-if="notes.length === 0">
<div class="text-center py-20 text-gray-400">
<span class="text-5xl block mb-3">📝</span>
@@ -130,13 +123,6 @@
</div>
</template>
<template x-if="notes.length > 0 && filteredPinned.length === 0 && filteredUnpinned.length === 0">
<div class="text-center py-12 text-gray-400">
<span class="text-3xl block mb-2">🔍</span>
<p class="text-sm">No notes match "<span x-text="searchQuery"></span>"</p>
</div>
</template>
{{-- ════════════════════════════════════════════════════════════
Note Editor Modal
@@ -285,20 +271,11 @@
// ── Computed / Filtered ───────────────────────────────
get filteredPinned() {
return this.filterNotes(this.notes.filter(n => n.is_pinned));
return this.notes.filter(n => n.is_pinned);
},
get filteredUnpinned() {
return this.filterNotes(this.notes.filter(n => !n.is_pinned));
},
filterNotes(list) {
const q = this.searchQuery.trim().toLowerCase();
if (!q) return list;
return list.filter(n =>
(n.title || '').toLowerCase().includes(q) ||
(n.content || []).some(b => (b.text || '').toLowerCase().includes(q))
);
return this.notes.filter(n => !n.is_pinned);
},
// ── Modal open/close ─────────────────────────────────