- Restructure from single filament table to multi-category product catalog (filamenti, stampaci, ploce, mlaznice, delovi, oprema) - Add shared layout components (SiteHeader, SiteFooter, CategoryNav, Breadcrumb) - Add reusable UI primitives (Badge, Button, Card, Modal, PriceDisplay, EmptyState) - Add catalog components (CatalogPage, ProductTable, ProductGrid, FilamentCard, ProductCard) - Add admin dashboard with sidebar navigation and category management - Add product API endpoints and database migrations - Add SEO pages (politika-privatnosti, uslovi-koriscenja, robots.txt, sitemap.xml) - Fix light mode: gradient text contrast, category nav accessibility, surface tokens, card shadows, CTA section theming
96 lines
3.0 KiB
TypeScript
96 lines
3.0 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import '../src/styles/index.css'
|
|
import { BackToTop } from '../src/components/BackToTop'
|
|
import { MatomoAnalytics } from '../src/components/MatomoAnalytics'
|
|
|
|
export const metadata: Metadata = {
|
|
metadataBase: new URL('https://filamenteka.rs'),
|
|
title: {
|
|
default: 'Bambu Lab Oprema Srbija | Filamenteka',
|
|
template: '%s | Filamenteka',
|
|
},
|
|
description: 'Privatna prodaja originalne Bambu Lab opreme u Srbiji. Filamenti, 3D stampaci, build plate podloge, mlaznice, rezervni delovi i oprema.',
|
|
openGraph: {
|
|
type: 'website',
|
|
locale: 'sr_RS',
|
|
siteName: 'Filamenteka',
|
|
title: 'Bambu Lab Oprema Srbija | Filamenteka',
|
|
description: 'Privatna prodaja originalne Bambu Lab opreme u Srbiji.',
|
|
url: 'https://filamenteka.rs',
|
|
},
|
|
robots: {
|
|
index: true,
|
|
follow: true,
|
|
},
|
|
alternates: {
|
|
canonical: 'https://filamenteka.rs',
|
|
},
|
|
}
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode
|
|
}) {
|
|
const jsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'LocalBusiness',
|
|
name: 'Filamenteka',
|
|
description: 'Privatna prodaja originalne Bambu Lab opreme u Srbiji',
|
|
url: 'https://filamenteka.rs',
|
|
telephone: '+381631031048',
|
|
address: {
|
|
'@type': 'PostalAddress',
|
|
addressCountry: 'RS',
|
|
},
|
|
priceRange: 'RSD',
|
|
}
|
|
|
|
return (
|
|
<html lang="sr" suppressHydrationWarning>
|
|
<head>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
(function() {
|
|
document.documentElement.classList.add('no-transitions');
|
|
if (window.location.pathname.startsWith('/upadaj') || window.location.pathname.startsWith('/dashboard')) {
|
|
document.documentElement.classList.add('dark');
|
|
} else {
|
|
try {
|
|
var darkMode = localStorage.getItem('darkMode');
|
|
if (darkMode === 'true') {
|
|
document.documentElement.classList.add('dark');
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
window.addEventListener('load', function() {
|
|
setTimeout(function() {
|
|
document.documentElement.classList.remove('no-transitions');
|
|
}, 100);
|
|
});
|
|
})();
|
|
`,
|
|
}}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
|
/>
|
|
</head>
|
|
<body suppressHydrationWarning>
|
|
{children}
|
|
<BackToTop />
|
|
{process.env.NEXT_PUBLIC_MATOMO_URL && process.env.NEXT_PUBLIC_MATOMO_SITE_ID && (
|
|
<MatomoAnalytics
|
|
matomoUrl={process.env.NEXT_PUBLIC_MATOMO_URL}
|
|
siteId={process.env.NEXT_PUBLIC_MATOMO_SITE_ID}
|
|
/>
|
|
)}
|
|
</body>
|
|
</html>
|
|
)
|
|
}
|