@@ -138,16 +139,19 @@ export default function JamboxChannelsSearch() {
Dostępny w:
{c.packages.map((p, i) => (
-
+
))}
)}
@@ -156,7 +160,7 @@ export default function JamboxChannelsSearch() {
))}
{q.trim().length >= 2 && !loading && items.length === 0 && (
-
+
Brak wyników dla: {q}
)}
diff --git a/src/pages/api/jambox/channels-search.js b/src/pages/api/jambox/channels-search.js
index 52dad8b..3a8f87f 100644
--- a/src/pages/api/jambox/channels-search.js
+++ b/src/pages/api/jambox/channels-search.js
@@ -14,7 +14,7 @@ export function GET({ url }) {
const q = (url.searchParams.get("q") || "").trim();
const limit = clamp(Number(url.searchParams.get("limit") || 50), 1, 200);
- if (q.length < 2) {
+ if (q.length < 0) {
return new Response(JSON.stringify({ ok: true, data: [] }), {
status: 200,
headers: { "Content-Type": "application/json; charset=utf-8" },
@@ -27,9 +27,6 @@ export function GET({ url }) {
const db = getDb();
try {
- // ✅ 1 rekord na kanał (grupujemy po name+logo_url)
- // ✅ pakiety zbieramy do jednego pola packages_blob
- // UWAGA: zakładam, że jambox_base_packages ma kolumnę "name"
const rows = db
.prepare(
`
diff --git a/src/styles/channels-search.css b/src/styles/channels-search.css
index 88beb2c..a3fa8b7 100644
--- a/src/styles/channels-search.css
+++ b/src/styles/channels-search.css
@@ -27,8 +27,8 @@
@apply opacity-100;
}
- .f-chsearch__meta {
- @apply text-sm opacity-70 pl-1;
+ .f-chsearch-meta {
+ @apply text-sm opacity-70 pl-1 ml-2;
}
/* =========================
@@ -110,8 +110,8 @@
/* =========================
Empty state
========================== */
- .f-chsearch__empty {
- @apply mt-2 p-4 rounded-2xl border border-slate-200 dark:border-slate-700 opacity-80;
+ .f-chsearch-empty {
+ @apply mt-2 p-4 text-lg;
}
.f-chsearch__input::-webkit-search-cancel-button {
diff --git a/src/styles/offers/offers-table.css b/src/styles/offers/offers-table.css
index 2338cee..5ac31da 100644
--- a/src/styles/offers/offers-table.css
+++ b/src/styles/offers/offers-table.css
@@ -1,333 +1,285 @@
-/* GŁÓWNE SEKCJE */
-.f-offers {
- @apply my-6;
-}
+ .f-offers {
+ @apply my-6;
+ }
-/* GRID FLEX — zawsze centrowany */
-.f-offers-grid {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- gap: 2rem;
- padding: 0 1rem;
-}
+ /* GRID FLEX — zawsze centrowany */
+ .f-offers-grid {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 2rem;
+ padding: 0 1rem;
+ }
-/* -----------------------------
- KARTA – MOBILE FIRST
------------------------------- */
-
-/* MOBILE: każda karta ~pełna szerokość */
-.f-card {
- flex: 1 1 100%;
- max-width: 26rem; /* możesz dać 100%, jeśli chcesz naprawdę full */
- @apply bg-[--f-bg] text-[--f-text] border border-[--f-offers-border]
- rounded-2xl shadow-md p-6 relative flex flex-col gap-4;
-}
-
-.f-card:hover {
- @apply shadow-lg;
- transform: translateY(-3px);
-}
-
-/* POPULARNY PLAN */
-.f-card-popular {
- border: 2px solid var(--f-offers-popular);
- background: var(--f-offers-popular-bg);
-}
-
-.f-card-badge {
- @apply absolute top-3 right-3 bg-[--btn-background]
- text-[--btn-text] text-sm font-semibold px-3 py-1 rounded-full;
-}
-
-/* HEADER */
-.f-card-header {
- @apply flex flex-col items-start gap-1;
-}
-
-.f-card-name {
- @apply text-xl font-semibold;
-}
-
-.f-card-price {
- @apply text-3xl font-extrabold text-[--f-offers-price];
-}
-
-/* FEATURES */
-.f-card-features {
- @apply list-none p-0 m-0;
-}
-
-.f-card-row {
- display: grid;
- grid-template-columns: 2fr 1fr;
- gap: 0.75rem;
- padding: 0.5rem 0;
- border-bottom: 1px solid var(--f-offers-border);
- align-items: center;
-}
-
-.f-card-row:last-child {
- border-bottom: none;
-}
-
-.f-card-label {
- @apply text-base font-medium opacity-80;
-}
-
-.f-card-value {
- @apply text-base font-semibold text-right;
-}
-
-.f-card-value.yes {
- @apply text-green-600;
-}
-
-.f-card-value.no {
- @apply text-red-600 opacity-60;
-}
-
-/* -----------------------------
- INTELIGENTNY UKŁAD – OD MD↑
------------------------------- */
-
-@media (min-width: 768px) {
- /* DOMYŚLNE: responsywnie */
+ /* MOBILE: każda karta prawie pełna szerokość */
.f-card {
- flex: 1 1 300px;
- max-width: 360px;
+ /* przewijanie uwzględnia sticky navbar */
+ scroll-margin-top: calc(var(--f-navbar-height, 64px) + 16px);
+
+ flex: 1 1 100%;
+ max-width: 26rem;
+
+ @apply bg-[--f-bg] text-[--f-text] border border-[--f-offers-border] rounded-2xl shadow-md p-6 relative flex flex-col gap-4;
+
+ transition: transform 220ms ease, box-shadow 220ms ease;
}
- /* 4 karty → 2 + 2 */
- .f-count-4 .f-card {
- flex: 0 1 calc(50% - 2rem);
- max-width: 420px;
+ .f-card:hover {
+ @apply shadow-lg;
+ transform: translateY(-3px);
}
- /* 5 kart → 3 + 2 */
- .f-count-5 .f-card {
- flex: 0 1 calc(33% - 2rem);
- }
- .f-count-5 .f-card:nth-child(n + 4) {
- flex: 0 1 calc(50% - 2rem);
- max-width: 420px;
+ /* POPULARNY PLAN */
+ .f-card-popular {
+ border: 2px solid var(--f-offers-popular);
+ background: var(--f-offers-popular-bg);
}
- /* 7 kart → 3 + 3 + 1 (środek) */
- .f-count-7 .f-card {
- flex: 0 1 calc(33% - 2rem);
- }
- .f-count-7 .f-card:last-child {
- flex: 0 1 calc(33% - 2rem);
- margin-left: auto;
- margin-right: auto;
+ .f-card-badge {
+ @apply absolute top-3 right-3 bg-[--btn-background] text-[--btn-text] text-sm font-semibold px-3 py-1 rounded-full;
}
- /* 8 kart → 3 + 3 + 2 */
- .f-count-8 .f-card {
- flex: 0 1 calc(33% - 2rem);
- }
- .f-count-8 .f-card:nth-child(n + 7) {
- flex: 0 1 calc(50% - 2rem);
- max-width: 420px;
+ /* HEADER */
+ .f-card-header {
+ @apply flex flex-col items-start gap-1;
}
- /* 10 kart → 3 + 3 + 3 + 1 */
- .f-count-10 .f-card:last-child {
- flex: 0 1 calc(33% - 2rem);
- margin-left: auto;
- margin-right: auto;
+ .f-card-name {
+ @apply text-xl font-semibold;
}
-}
+ .f-card-price {
+ @apply text-3xl font-extrabold text-[--f-offers-price];
+ }
+ /* FEATURES */
+ .f-card-features {
+ @apply list-none p-0 m-0;
+ }
+ .f-card-row {
+ display: grid;
+ grid-template-columns: 2fr 1fr;
+ gap: 0.75rem;
+ padding: 0.5rem 0;
+ border-bottom: 1px solid var(--f-offers-border);
+ align-items: center;
+ }
+ .f-card-row:last-child {
+ border-bottom: none;
+ }
-/*
-obszar ze scrollem wewnątrz modala
-.jmb-channels-scroll {
- margin-top: 1rem;
- padding-right: 0.25rem;
- max-height: 72vh;
- overflow-y: auto;
-} */
+ .f-card-label {
+ @apply text-base font-medium opacity-80;
+ }
-/* dużo kart w wierszu */
-.jmb-channels-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
- gap: 0.9rem;
-}
+ .f-card-value {
+ @apply text-base font-semibold text-right;
+ }
-/* pojedyncza karta kanału */
-.jmb-channel-card {
- background: var(--fuz-bg);
- border-radius: 0.75rem;
- padding: 0.75rem 0.5rem;
- text-align: center;
- border: 1px solid rgba(148, 163, 184, 0.25);
- box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
+ .f-card-value.yes {
+ @apply text-green-600;
+ }
-/* logo kanału */
-.jmb-channel-logo {
- max-width: 90px;
- max-height: 60px;
- margin: 0 auto 0.5rem auto;
- display: block;
- object-fit: contain;
-}
+ .f-card-value.no {
+ @apply text-red-600 opacity-60;
+ }
-/* podpisy pod logo */
-.jmb-channel-name {
- font-size: 0.85rem;
- font-weight: 600;
- margin-bottom: 0.15rem;
-}
+ /* INTELIGENTNY UKŁAD – OD MD↑ */
+ @media (min-width: 768px) {
+ .f-card {
+ flex: 1 1 300px;
+ max-width: 360px;
+ }
-.jmb-channel-number {
- font-size: 0.75rem;
- color: #94a3b8;
-}
+ /* 4 karty → 2 + 2 */
+ .f-count-4 .f-card {
+ flex: 0 1 calc(50% - 2rem);
+ max-width: 420px;
+ }
-/* badge "gwarantowany" */
-.jmb-channel-tag {
- margin-top: 0.35rem;
- font-size: 0.7rem;
- display: inline-block;
- padding: 0.1rem 0.5rem;
- border-radius: 9999px;
- background: rgba(34, 197, 94, 0.08);
- color: #22c55e;
-}
+ /* 5 kart → 3 + 2 */
+ .f-count-5 .f-card {
+ flex: 0 1 calc(33% - 2rem);
+ }
+ .f-count-5 .f-card:nth-child(n + 4) {
+ flex: 0 1 calc(50% - 2rem);
+ max-width: 420px;
+ }
+ /* 7 kart → 3 + 3 + 1 (środek) */
+ .f-count-7 .f-card {
+ flex: 0 1 calc(33% - 2rem);
+ }
+ .f-count-7 .f-card:last-child {
+ flex: 0 1 calc(33% - 2rem);
+ margin-left: auto;
+ margin-right: auto;
+ }
+ /* 8 kart → 3 + 3 + 2 */
+ .f-count-8 .f-card {
+ flex: 0 1 calc(33% - 2rem);
+ }
+ .f-count-8 .f-card:nth-child(n + 7) {
+ flex: 0 1 calc(50% - 2rem);
+ max-width: 420px;
+ }
+ /* 10 kart → 3 + 3 + 3 + 1 */
+ .f-count-10 .f-card:last-child {
+ flex: 0 1 calc(33% - 2rem);
+ margin-left: auto;
+ margin-right: auto;
+ }
+ }
+ /* =========================================
+ TARGET — PODŚWIETLENIE PAKIETU PO KLIKNIĘCIU
+ ========================================== */
-/* === FIX: stabilny grid + flip (nie rozjeżdża kart) === */
+ .f-card.is-target {
+ outline: none;
+ box-shadow:
+ 0 0 0 3px rgba(59, 130, 246, 0.45),
+ 0 10px 25px rgba(15, 23, 42, 0.18);
+ transform: translateY(-6px) scale(1.01);
+ position: relative;
+ background-color: var(--f-navbar-background);
+ z-index: 2;
+ }
-.jmb-channels-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
- gap: 0.9rem;
- align-items: stretch; /* ważne: równe wysokości w wierszu */
-}
+ .f-card.is-target:hover {
+ transform: translateY(-6px) scale(1.01);
+ }
-.jmb-channel-card {
- position: relative;
- perspective: 1000px;
+ /* JAMBOX — GRID KANAŁÓW (MODAL) */
- /* zostawiamy Twój wygląd */
- background: var(--fuz-bg);
- border-radius: 0.75rem;
- border: 1px solid rgba(148, 163, 184, 0.25);
- box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
+ .jmb-channels-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 0.9rem;
+ align-items: stretch;
+ }
- /* kluczowe: karta ma “ramę” */
- min-height: 170px; /* dopasuj: 160–200 */
- height: 100%;
- padding: 0; /* padding przenosimy na face */
- overflow: hidden; /* żeby back nie wystawał */
-}
+ .jmb-channel-card {
+ position: relative;
+ perspective: 1000px;
-.jmb-channel-inner {
- position: relative;
- width: 100%;
- height: 100%;
- transform-style: preserve-3d;
- transition: transform 0.6s ease;
-}
+ background: var(--f-bg);
+ color: var(--f-text);
-@media (hover: hover) and (pointer: fine) {
- .jmb-channel-card:hover .jmb-channel-inner {
+ border-radius: 0.75rem;
+ border: 1px solid rgba(148, 163, 184, 0.25);
+ box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
+
+ min-height: 170px;
+ height: 100%;
+ padding: 0;
+ overflow: hidden;
+
+ -webkit-tap-highlight-color: transparent;
+ touch-action: manipulation;
+ cursor: pointer;
+ }
+
+ .jmb-channel-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ transform-style: preserve-3d;
+ -webkit-transform-style: preserve-3d;
+ transition: transform 0.6s ease;
+ }
+
+ /* DESKTOP: flip na hover */
+ @media (hover: hover) and (pointer: fine) {
+ .jmb-channel-card:hover .jmb-channel-inner {
+ transform: rotateY(180deg);
+ }
+ }
+
+ /* MOBILE/TAP: flip po klasie */
+ .jmb-channel-card.is-flipped .jmb-channel-inner {
transform: rotateY(180deg);
}
-}
-/* front + back */
-.jmb-channel-face {
- position: absolute;
- inset: 0;
- padding: 0.75rem 0.5rem; /* to był Twój padding z card */
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- text-align: center;
+ .jmb-channel-face {
+ position: absolute;
+ inset: 0;
- backface-visibility: hidden;
- -webkit-backface-visibility: hidden;
-}
+ padding: 0.75rem 0.5rem;
-.jmb-channel-front {
- transform: rotateY(0deg);
-}
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ text-align: center;
-.jmb-channel-back {
- transform: rotateY(180deg);
- text-align: left;
- justify-content: flex-start;
- gap: 0.5rem;
-}
+ backface-visibility: hidden;
+ -webkit-backface-visibility: hidden;
+ }
-.jmb-channel-back-title {
- font-size: 0.9rem;
- font-weight: 700;
-}
+ .jmb-channel-front {
+ transform: rotateY(0deg);
+ }
-.jmb-channel-desc {
- font-size: 0.85rem;
- line-height: 1.35;
- opacity: 0.9;
- overflow: auto; /* długi opis nie rozwala karty */
-}
+ .jmb-channel-back {
+ transform: rotateY(180deg);
+ text-align: left;
+ justify-content: flex-start;
+ gap: 0.5rem;
+ }
-.jmb-search {
- display: flex;
- gap: 0.5rem;
- align-items: center;
- margin: 0.75rem 0 0.25rem;
-}
+ .jmb-channel-logo {
+ max-width: 90px;
+ max-height: 60px;
+ margin: 0 auto 0.5rem auto;
+ display: block;
+ object-fit: contain;
+ }
-.jmb-search-input {
- flex: 1;
- padding: 0.6rem 0.75rem;
- border-radius: 0.75rem;
- border: 1px solid rgba(148, 163, 184, 0.35);
- background: var(--fuz-bg);
- color: var(--fuz-text);
- outline: none;
-}
+ .jmb-channel-name {
+ font-size: 0.85rem;
+ font-weight: 600;
+ margin-bottom: 0.15rem;
+ }
-.jmb-search-input:focus {
- border-color: rgba(59, 130, 246, 0.55);
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
-}
+ .jmb-channel-number {
+ font-size: 0.75rem;
+ color: rgba(148, 163, 184, 0.95);
+ }
-.jmb-search-clear {
- padding: 0.55rem 0.7rem;
- border-radius: 0.75rem;
- border: 1px solid rgba(148, 163, 184, 0.35);
- background: transparent;
-}
+ .jmb-channel-back-title {
+ font-size: 0.9rem;
+ font-weight: 700;
+ }
-.jmb-search-meta {
- font-size: 0.85rem;
- opacity: 0.75;
- margin-bottom: 0.5rem;
-}
+ .jmb-channel-desc {
+ font-size: 0.85rem;
+ line-height: 1.35;
+ opacity: 0.92;
+ overflow: auto;
-.f-card.is-target {
- outline: 2px solid rgba(59, 130, 246, 0.55);
- /* var(--f-link); */
- outline-offset: 4px;
-}
+ scrollbar-width: thin;
+ scrollbar-color: rgba(148, 163, 184, 0.55) transparent;
+ }
+ .jmb-channel-desc::-webkit-scrollbar {
+ width: 10px;
+ }
+
+ .jmb-channel-desc::-webkit-scrollbar-thumb {
+ background: rgba(148, 163, 184, 0.45);
+ border-radius: 9999px;
+ border: 3px solid transparent;
+ background-clip: content-box;
+ }
+
+ .jmb-channel-desc::-webkit-scrollbar-track {
+ background: transparent;
+ }
\ No newline at end of file