diff --git a/CLAUDE.md b/CLAUDE.md
index 6fcfca3..727df25 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,1799 +1,219 @@
-# Claude Fable 5 — System Prompt
+## SEO — JSON-LD Schema.org
+
+Każda nowa strona (`src/app/*/page.jsx`) musi mieć odpowiedni JSON-LD w `
`.
+
+- Strona główna → `WebSite` + `WebPage` + `Organization` + `blogPost[]` (komponent `SchemaOrg` w `layout.jsx`)
+- Strona artykułu → `BlogPosting` (headline, url, datePublished, author, image)
+- Strona kontakt → `ContactPage`
+- Strona "wkrótce" → `WebPage` z `name` i `description`
+
+JSON-LD idzie do `` przez `
+
+
+
+ )
+}
diff --git a/src/app/page.jsx b/src/app/page.jsx
new file mode 100644
index 0000000..fa4f868
--- /dev/null
+++ b/src/app/page.jsx
@@ -0,0 +1,94 @@
+import Hero from '../sections/Hero'
+import Benefits from '../sections/Benefits'
+import ProductsPreview from '../sections/ProductsPreview'
+import BentoCard from '../components/BentoCard'
+import BentoSlideshow from '../components/BentoSlideshow'
+import SubscribeBox from '../components/SubscribeBox'
+import { fetchLaboratoriumData, mapDirectusToContent } from '../lib/directus'
+import { newsData, videosData } from '../data/content'
+
+export const revalidate = 0
+
+async function getContent() {
+ try {
+ const items = await fetchLaboratoriumData()
+ return mapDirectusToContent(items)
+ } catch {
+ return null
+ }
+}
+
+export default async function HomePage() {
+ const content = await getContent()
+
+ return (
+ <>
+
+
+
+
+
+ {!content ? (
+
+ W tej chwili brak wpisów.
+
+ ) : (
+ <>
+
+ {content.articles.map((article, index) => (
+
+ ))}
+ >
+ )}
+
+
+
+
+ >
+ )
+}
diff --git a/src/app/produkty/page.jsx b/src/app/produkty/page.jsx
new file mode 100644
index 0000000..cd92f15
--- /dev/null
+++ b/src/app/produkty/page.jsx
@@ -0,0 +1,48 @@
+import ProductCard from '../../components/ProductCard'
+import { productSchema } from '../../lib/productSchema'
+
+const DIRECTUS = 'https://cms.dexterlab.pl'
+
+export const revalidate = 300
+
+export const metadata = {
+ title: 'Produkty — Laboratorium AI',
+ description: 'Moduły AI-RaaS — gotowe automatyzacje dla mikroprzedsiębiorców.',
+}
+
+async function getProducts() {
+ try {
+ const res = await fetch(
+ `${DIRECTUS}/items/products?filter[site][_eq]=labai.pro&filter[status][_eq]=published&sort=sort`,
+ { next: { revalidate: 300 } }
+ )
+ if (!res.ok) return []
+ return (await res.json()).data ?? []
+ } catch {
+ return []
+ }
+}
+
+export default async function ProduktyPage() {
+ const products = await getProducts()
+
+ return (
+ <>
+ {products.map((p) => (
+
+ ))}
+
+
+
Moduły AI-RaaS
+
Wybierz swój moduł AI
+
Gotowe automatyzacje dla mikroprzedsiębiorców i twórców treści.
+
+
+ {products.map((p) =>
)}
+
+
+ >
+ )
+}
diff --git a/src/components/SchemaOrg.jsx b/src/components/SchemaOrg.jsx
new file mode 100644
index 0000000..5f3e2e9
--- /dev/null
+++ b/src/components/SchemaOrg.jsx
@@ -0,0 +1,104 @@
+const DIRECTUS_URL = 'https://cms.dexterlab.pl'
+const DOMAIN = 'labai.pro'
+const BASE_URL = `https://${DOMAIN}`
+
+const FALLBACK = {
+ name: 'Laboratorium AI',
+ description: 'Automatyzacja procesów biznesowych bez programowania. Wdrażamy AI i no-code w 48h.',
+ logo: `${BASE_URL}/logo.webp`,
+ sameAs: [
+ 'https://linkedin.com/company/dexterlab',
+ 'https://x.com/dexterlab_pl',
+ 'https://facebook.com/dexterlab',
+ ],
+}
+
+async function fetchSiteData() {
+ try {
+ const res = await fetch(
+ `${DIRECTUS_URL}/items/sites?filter[domain][_eq]=${DOMAIN}`,
+ { next: { revalidate: 3600 } }
+ )
+ if (!res.ok) return null
+ const json = await res.json()
+ return json.data?.[0] ?? null
+ } catch {
+ return null
+ }
+}
+
+async function fetchArticles() {
+ try {
+ const res = await fetch(
+ `${DIRECTUS_URL}/items/LabAI?sort=-date_published&limit=5&fields=Title,Slug`,
+ { next: { revalidate: 300 } }
+ )
+ if (!res.ok) return []
+ const json = await res.json()
+ return json.data ?? []
+ } catch {
+ return []
+ }
+}
+
+function buildSchema(site, articles) {
+ const s = site ?? {}
+ const baseUrl = (s.url ?? BASE_URL).replace(/\/$/, '')
+ const name = s.site_name ?? FALLBACK.name
+ const description = s.site_description ?? FALLBACK.description
+ const logo = s.logo ?? { '@type': 'ImageObject', url: FALLBACK.logo }
+ const sameAs = Array.isArray(s.social_links) && s.social_links.length
+ ? s.social_links
+ : FALLBACK.sameAs
+
+ const blogPostings = articles.map((a) => ({
+ '@type': 'BlogPosting',
+ '@id': `${baseUrl}/blog/${a.Slug}`,
+ headline: a.Title,
+ url: `${baseUrl}/blog/${a.Slug}`,
+ isPartOf: { '@id': `${baseUrl}/#webpage` },
+ }))
+
+ return {
+ '@context': 'https://schema.org',
+ '@graph': [
+ {
+ '@type': 'WebSite',
+ '@id': `${baseUrl}/#website`,
+ url: `${baseUrl}/`,
+ name,
+ publisher: { '@id': `${baseUrl}/#organization` },
+ },
+ {
+ '@type': 'WebPage',
+ '@id': `${baseUrl}/#webpage`,
+ url: `${baseUrl}/`,
+ name,
+ isPartOf: { '@id': `${baseUrl}/#website` },
+ description,
+ },
+ {
+ '@type': 'Organization',
+ '@id': `${baseUrl}/#organization`,
+ name: s.company_name ?? name,
+ url: `${baseUrl}/`,
+ logo,
+ sameAs,
+ ...(s.contact && { contactPoint: s.contact }),
+ },
+ ...blogPostings,
+ ],
+ }
+}
+
+export default async function SchemaOrg() {
+ const [site, articles] = await Promise.all([fetchSiteData(), fetchArticles()])
+ const schema = buildSchema(site, articles)
+
+ return (
+
+ )
+}
diff --git a/src/index.css b/src/index.css
index baac9ba..4fc7098 100644
--- a/src/index.css
+++ b/src/index.css
@@ -13,6 +13,7 @@
--card-radius: 1.25rem;
--grid-gap: 1.5rem;
+ --content-width: 1200px;
/* Badges */
--badge-hot: #e11d48;
@@ -181,7 +182,7 @@ h1, h2, h3, h4, h5, h6 {
/* ===== PAGE WRAPPER ===== */
.page-wrapper {
- max-width: 1600px;
+ max-width: var(--content-width);
margin: 0 auto;
padding: 2rem;
display: grid;
@@ -663,7 +664,7 @@ h1, h2, h3, h4, h5, h6 {
}
.footer-container {
- max-width: 1200px;
+ max-width: var(--content-width);
margin: 0 auto;
display: flex;
justify-content: space-between;
@@ -681,6 +682,31 @@ h1, h2, h3, h4, h5, h6 {
line-height: 1.5;
}
+.footer-social {
+ display: flex;
+ gap: 0.75rem;
+ margin-top: 1.25rem;
+}
+
+.footer-social__link {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid var(--border-color);
+ color: var(--text-muted);
+ transition: color 0.2s, background 0.2s, border-color 0.2s;
+}
+
+.footer-social__link:hover {
+ color: var(--text-main);
+ background: rgba(79, 70, 229, 0.15);
+ border-color: rgba(79, 70, 229, 0.4);
+}
+
.footer-links {
display: flex;
flex-wrap: wrap;
@@ -711,7 +737,7 @@ h1, h2, h3, h4, h5, h6 {
}
.footer-bottom {
- max-width: 1200px;
+ max-width: var(--content-width);
margin: 0 auto;
padding-top: 2rem;
text-align: center;
@@ -818,7 +844,6 @@ h1, h2, h3, h4, h5, h6 {
padding: 0.75rem;
gap: 0.75rem;
}
-}
.cookie-banner {
bottom: 1rem;
right: 1rem;
@@ -827,14 +852,257 @@ h1, h2, h3, h4, h5, h6 {
}
}
+/* ===== PRODUCTS PAGE ===== */
+.products-page {
+ max-width: var(--content-width);
+ margin: 0 auto;
+ padding: 4rem 2rem;
+}
+
+.products-header {
+ text-align: center;
+ margin-bottom: 3rem;
+}
+
+.products-title {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--text-main);
+ margin: 1rem 0 0.5rem;
+}
+
+.products-subtitle {
+ color: var(--text-muted);
+ font-size: 1rem;
+}
+
+.products-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1.5rem;
+}
+
+.product-card {
+ background: var(--bg-accent);
+ border: 1px solid var(--border-color);
+ border-radius: var(--card-radius);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ transition: border-color 0.2s;
+}
+
+.product-card:hover { border-color: rgba(79, 70, 229, 0.4); }
+
+.product-img {
+ height: 220px;
+ background-size: cover;
+ background-position: center;
+}
+
+.product-body {
+ padding: 1.5rem;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ gap: 0.5rem;
+}
+
+.product-card--featured { border-color: rgba(79, 70, 229, 0.5); }
+
+.product-featured-badge {
+ position: absolute;
+ top: 0.75rem;
+ right: 0.75rem;
+ background: var(--accent-color);
+ color: #fff;
+ font-size: 0.7rem;
+ font-weight: 600;
+ padding: 0.2rem 0.6rem;
+ border-radius: 999px;
+}
+
+.product-card { position: relative; }
+
+.product-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.35rem;
+ margin-bottom: 0.25rem;
+}
+
+.product-tag {
+ font-size: 0.7rem;
+ background: rgba(79, 70, 229, 0.12);
+ color: #818cf8;
+ padding: 0.15rem 0.5rem;
+ border-radius: 999px;
+}
+
+.product-type {
+ font-size: 0.7rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ color: var(--accent-color);
+}
+
+.product-name {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--text-main);
+}
+
+.product-desc {
+ font-size: 0.875rem;
+ color: var(--text-muted);
+ line-height: 1.6;
+ flex: 1;
+}
+
+.product-footer {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: 1rem;
+ gap: 1rem;
+}
+
+.product-price { display: flex; align-items: baseline; gap: 0.5rem; }
+
+.product-price--promo {
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: var(--text-main);
+}
+
+.product-price--old {
+ font-size: 0.875rem;
+ color: var(--text-muted);
+ text-decoration: line-through;
+}
+
+.product-price--regular {
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: var(--text-main);
+}
+
+@media (max-width: 900px) { .products-grid { grid-template-columns: repeat(2, 1fr); } }
+@media (max-width: 600px) { .products-grid { grid-template-columns: 1fr; } }
+
+.products-preview {
+ max-width: var(--content-width);
+ margin: 0 auto;
+ padding: 4rem 2rem;
+}
+
+/* ===== BENEFITS SECTION ===== */
+.benefits {
+ padding: 5rem 2rem;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.benefits__header {
+ max-width: 720px;
+ margin: 0 auto 3rem;
+ text-align: center;
+}
+
+.benefits__title {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--text-main);
+ margin-bottom: 1rem;
+}
+
+.benefits__subtitle {
+ color: var(--text-muted);
+ font-size: 1rem;
+ line-height: 1.7;
+}
+
+.benefits__grid {
+ max-width: var(--content-width);
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 1.5rem;
+}
+
+.benefits__card {
+ background: var(--bg-accent);
+ border: 1px solid var(--border-color);
+ border-radius: var(--card-radius);
+ padding: 1.75rem;
+ transition: border-color 0.2s;
+}
+
+.benefits__card:hover {
+ border-color: rgba(79, 70, 229, 0.4);
+}
+
+.benefits__icon {
+ width: 40px;
+ height: 40px;
+ color: var(--accent-color);
+ margin-bottom: 1rem;
+}
+
+.benefits__icon svg {
+ width: 100%;
+ height: 100%;
+}
+
+.benefits__card-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--text-main);
+ margin-bottom: 0.5rem;
+}
+
+.benefits__card-desc {
+ font-size: 0.875rem;
+ color: var(--text-muted);
+ line-height: 1.6;
+}
+
+.benefits__cta {
+ text-align: center;
+ margin-top: 3rem;
+}
+
+@media (max-width: 1100px) {
+ .benefits__grid { grid-template-columns: repeat(2, 1fr); }
+}
+
+@media (max-width: 640px) {
+ .benefits__grid { grid-template-columns: 1fr; }
+ .benefits__title { font-size: 1.5rem; }
+}
+
/* ===== HERO SECTION ===== */
.hero {
position: relative;
overflow: hidden;
- padding: 5rem 2rem 4rem;
+ padding: 4rem 2rem 4rem;
border-bottom: 1px solid var(--border-color);
}
+.hero__eyebrow-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ margin-top: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.hero__eyebrow-list li {
+ list-style: none;
+}
+
.hero__bg {
position: absolute;
inset: 0;
@@ -847,10 +1115,10 @@ h1, h2, h3, h4, h5, h6 {
.hero__inner {
position: relative;
z-index: 1;
- max-width: 1200px;
+ max-width: var(--content-width);
margin: 0 auto;
display: grid;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 2fr 1fr;
gap: 4rem;
align-items: center;
}
@@ -925,6 +1193,7 @@ h1, h2, h3, h4, h5, h6 {
background: var(--accent-color);
color: #fff;
border: none;
+ text-decoration: none;
padding: 0.9rem 2rem;
border-radius: 10px;
font-size: 1rem;
@@ -1011,6 +1280,8 @@ h1, h2, h3, h4, h5, h6 {
/* ── Prawa strona (zdjęcie) ── */
.hero__image-wrap {
position: relative;
+ transform: scale(1.56);
+ transform-origin: center center;
}
/* warstwa 2: float — wszystko lata razem */
@@ -1030,7 +1301,7 @@ h1, h2, h3, h4, h5, h6 {
/* warstwa 4: obraz z blaskiem żarówki (żółty drop-shadow kierunkowy) */
.hero__robot-layers {
width: 100%;
- max-width: 600px;
+ max-width: 1350px;
aspect-ratio: 1 / 1;
position: relative;
z-index: 1;
@@ -1193,6 +1464,114 @@ h1, h2, h3, h4, h5, h6 {
font-size: 1rem;
}
+.coming-soon-page {
+ min-height: 80vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2rem;
+}
+
+.coming-soon-content {
+ text-align: center;
+ max-width: 480px;
+}
+
+.coming-soon-badge {
+ display: inline-block;
+ background: rgba(79, 70, 229, 0.15);
+ border: 1px solid rgba(79, 70, 229, 0.4);
+ color: #818cf8;
+ font-size: 0.75rem;
+ font-weight: 600;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ padding: 0.35rem 0.9rem;
+ border-radius: 999px;
+ margin-bottom: 1.5rem;
+}
+
+.coming-soon-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: var(--text-main);
+ margin-bottom: 1rem;
+}
+
+.coming-soon-desc {
+ color: var(--text-muted);
+ font-size: 1rem;
+ line-height: 1.7;
+ margin-bottom: 2rem;
+}
+
+.contact-content {
+ text-align: center;
+ max-width: 480px;
+ width: 100%;
+}
+
+.contact-form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ text-align: left;
+}
+
+.contact-form input,
+.contact-form textarea {
+ background: var(--bg-accent);
+ border: 1px solid var(--border-color);
+ border-radius: 0.5rem;
+ color: var(--text-main);
+ font-family: inherit;
+ font-size: 0.9rem;
+ padding: 0.75rem 1rem;
+ transition: border-color 0.2s;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.contact-form input::placeholder,
+.contact-form textarea::placeholder {
+ color: var(--text-muted);
+}
+
+.contact-form input:focus,
+.contact-form textarea:focus {
+ border-color: var(--accent-color);
+ outline: none;
+}
+
+.contact-form textarea {
+ resize: vertical;
+}
+
+.contact-success {
+ background: rgba(16, 185, 129, 0.1);
+ border: 1px solid rgba(16, 185, 129, 0.3);
+ border-radius: 0.5rem;
+ color: #6ee7b7;
+ padding: 1rem 1.5rem;
+ margin-bottom: 1rem;
+}
+
+.coming-soon-back {
+ background: none;
+ border: 1px solid var(--border-hover);
+ color: var(--text-muted);
+ padding: 0.6rem 1.4rem;
+ border-radius: 0.5rem;
+ font-size: 0.9rem;
+ cursor: pointer;
+ transition: color 0.2s, border-color 0.2s;
+}
+
+.coming-soon-back:hover {
+ color: var(--text-main);
+ border-color: var(--accent-color);
+}
+
.error-banner {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
diff --git a/src/lib/directus.js b/src/lib/directus.js
index 23f7719..df8f2d6 100644
--- a/src/lib/directus.js
+++ b/src/lib/directus.js
@@ -1,145 +1,72 @@
-/**
- * Directus API Client
- * Źródło danych: https://cms.dexterlab.pl/ - kolekcja Laboratorium_AI
- */
+const DIRECTUS_URL = 'https://cms.dexterlab.pl'
+const COLLECTION = 'LabAI'
-const DIRECTUS_URL = import.meta.env.DEV ? '/api' : 'https://cms.dexterlab.pl';
-const COLLECTION = 'Laboratorium_AI';
-
-// Cache storage
-let dataCache = null;
-let cacheTimestamp = 0;
-const CACHE_DURATION = 5 * 60 * 1000; // 5 minut
-
-/**
- * Pobiera wszystkie elementy z kolekcji Laboratorium_AI
- */
export async function fetchLaboratoriumData() {
- // Sprawdź cache
- if (dataCache && Date.now() - cacheTimestamp < CACHE_DURATION) {
- return dataCache;
- }
-
- try {
- const response = await fetch(
- `${DIRECTUS_URL}/items/${COLLECTION}?sort=-date_published&limit=-1`,
- {
- headers: {
- 'Content-Type': 'application/json',
- 'Origin': window.location.origin,
- },
- }
- );
-
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
-
- const result = await response.json();
-
- dataCache = result.data;
- cacheTimestamp = Date.now();
-
- return result.data;
- } catch (error) {
- console.error('Błąd pobierania danych z Directus:', error);
- throw error;
- }
+ const url = `${DIRECTUS_URL}/items/${COLLECTION}?filter[status][_eq]=published&sort=-date_published&limit=-1`
+ const headers = process.env.DIRECTUS_TOKEN
+ ? { Authorization: `Bearer ${process.env.DIRECTUS_TOKEN}` }
+ : {}
+ const response = await fetch(url, { headers })
+ if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
+ const result = await response.json()
+ return result.data
}
-/**
- * Pobiera pojedynczy element po ID
- */
-export async function fetchLaboratoriumItem(id) {
- try {
- const response = await fetch(`${DIRECTUS_URL}/items/${COLLECTION}/${id}`);
-
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
-
- const result = await response.json();
- return result.data;
- } catch (error) {
- console.error(`Błąd pobierania elementu ${id}:`, error);
- return null;
- }
-}
-
-/**
- * Czyści cache - wymusza odświeżenie
- */
-export function clearCache() {
- dataCache = null;
- cacheTimestamp = 0;
-}
-
-/**
- * Mapuje dane z Directus na format strony
- */
export function mapDirectusToContent(items) {
- if (!items || items.length === 0) return null;
+ if (!items || items.length === 0) return null
- // Preferuj published, fallback na wszystkie
- const published = items.filter(item => item.status === 'published');
- const sourceItems = published.length > 0 ? published : items;
+ const sourceItems = items
- // Slideshow - featured lub pierwsze 3
- const featured = sourceItems.filter(item => item.is_featured === true);
+ const featured = sourceItems.filter(item => item.Is_Featured === true)
const slideshow = (featured.length > 0 ? featured : sourceItems.slice(0, 3)).map(item => ({
type: 'hot',
- badge: item.badge || null,
- title: item.title,
- category: item.category || 'AI',
+ badge: item.Badge || null,
+ title: item.Title,
+ category: item.Category || 'AI',
readTime: '5 min read',
- bgImage: item.cover_image ? `${DIRECTUS_URL}/assets/${item.cover_image}` : '',
- }));
+ bgImage: item.Cover_Image ? `${DIRECTUS_URL}/assets/${item.Cover_Image}` : '',
+ }))
- const slideshowTitles = new Set(slideshow.map(s => s.title));
+ const slideshowTitles = new Set(slideshow.map(s => s.title))
- // Pozostałe jako articles (max 8)
const articles = sourceItems
- .filter(item => !slideshowTitles.has(item.title))
+ .filter(item => !slideshowTitles.has(item.Title))
.slice(0, 8)
.map((item, index) => ({
- type: item.badge?.toLowerCase() || 'article',
- badge: item.badge || null,
- title: item.title,
- category: item.category || 'AI',
- readTime: item.read_time || '5 min read',
- bgImage: item.cover_image ? `${DIRECTUS_URL}/assets/${item.cover_image}` : '',
+ type: item.Badge?.toLowerCase() || 'article',
+ badge: item.Badge || null,
+ title: item.Title,
+ category: item.Category || 'AI',
+ readTime: '5 min read',
+ bgImage: item.Cover_Image ? `${DIRECTUS_URL}/assets/${item.Cover_Image}` : '',
gridColumn: getGridColumn(index),
gridRow: getGridRow(index),
hero: index === 0,
- }));
+ }))
- return { slideshow, articles };
+ return { slideshow, articles }
}
function getGridColumn(index) {
- // Jasny układ dla 4-kolumnowej siatki
- // 1: 2/3 (2 kol), 2: 3/4 (1 kol), 3: 4/5 (1 kol), 4: 4/5 (1 kol)
- // 5: 1/2 (1 kol), 6: 2/3 (1 kol), 7: 3/4 (1 kol), 8: 4/5 (1 kol)
- if (index === 0) return '1 / 3'; // 2 kolumny
- if (index === 1) return '3 / 4'; // 1 kolumna
- if (index === 2) return '4 / 5'; // 1 kolumna
- if (index === 3) return '4 / 5'; // 1 kolumna
- if (index === 4) return '1 / 2'; // 1 kolumna
- if (index === 5) return '2 / 3'; // 1 kolumna
- if (index === 6) return '3 / 4'; // 1 kolumna
- if (index === 7) return '4 / 5'; // 1 kolumna
- return '1 / 2';
+ if (index === 0) return '1 / 3'
+ if (index === 1) return '3 / 4'
+ if (index === 2) return '4 / 5'
+ if (index === 3) return '4 / 5'
+ if (index === 4) return '1 / 2'
+ if (index === 5) return '2 / 3'
+ if (index === 6) return '3 / 4'
+ if (index === 7) return '4 / 5'
+ return '1 / 2'
}
function getGridRow(index) {
- // Wiersze dla układu: 2 duże na górze (2/4), reszta po 1 (3/4, 4/5)
- if (index === 0) return '2 / 4'; // 2 rzędy
- if (index === 1) return '2 / 4'; // 2 rzędy
- if (index === 2) return '2 / 3'; // 1 rząd
- if (index === 3) return '3 / 4'; // 1 rząd
- if (index === 4) return '4 / 5'; // 1 rząd
- if (index === 5) return '4 / 5'; // 1 rząd
- if (index === 6) return '4 / 5'; // 1 rząd
- if (index === 7) return '4 / 5'; // 1 rząd
- return '4 / 5';
-}
\ No newline at end of file
+ if (index === 0) return '2 / 4'
+ if (index === 1) return '2 / 4'
+ if (index === 2) return '2 / 3'
+ if (index === 3) return '3 / 4'
+ if (index === 4) return '4 / 5'
+ if (index === 5) return '4 / 5'
+ if (index === 6) return '4 / 5'
+ if (index === 7) return '4 / 5'
+ return '4 / 5'
+}