feat: complete website implementation
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Dostawa i Płatności | AirProject',
|
||||
description: 'Koszty, formy i szacowane czasy dostawy urządzeń w sklepie AirProject.',
|
||||
alternates: {
|
||||
canonical: '/dostawa',
|
||||
}
|
||||
};
|
||||
|
||||
export default function DostawaPage() {
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-4xl font-extrabold mb-8">Dostawa i Płatności</h1>
|
||||
|
||||
<p className="lead">
|
||||
Sprawdź dostępne metody wysyłki urządzeń oraz formy płatności akceptowane w naszym sklepie.
|
||||
</p>
|
||||
|
||||
{/* TODO: treść prawna do uzupełnienia przez właściciela */}
|
||||
|
||||
<h2 id="dostawa">1. Metody i koszty dostawy</h2>
|
||||
<p>Dla wygody naszych klientów przygotowaliśmy kilka opcji odbioru towaru:</p>
|
||||
|
||||
<div className="not-prose overflow-x-auto my-8 border border-border rounded-xl">
|
||||
<table className="w-full text-left text-sm">
|
||||
<thead className="bg-slate-50 border-b border-border text-primary font-semibold">
|
||||
<tr>
|
||||
<th className="p-4">Opcja dostawy</th>
|
||||
<th className="p-4">Czas realizacji</th>
|
||||
<th className="p-4">Koszt brutto</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-border">
|
||||
<tr className="hover:bg-slate-50 transition-colors">
|
||||
<td className="p-4 font-medium">Kurier Paletowy (Klimatyzatory)</td>
|
||||
<td className="p-4 text-text-muted">2-3 dni robocze</td>
|
||||
<td className="p-4 font-bold text-primary">0 zł (Darmowa)</td>
|
||||
</tr>
|
||||
<tr className="hover:bg-slate-50 transition-colors">
|
||||
<td className="p-4 font-medium">Kurier Standard (Mniejsze elementy)</td>
|
||||
<td className="p-4 text-text-muted">1-2 dni robocze</td>
|
||||
<td className="p-4 font-bold text-primary">19 zł</td>
|
||||
</tr>
|
||||
<tr className="hover:bg-slate-50 transition-colors">
|
||||
<td className="p-4 font-medium">Dostawa przez naszych Instalatorów</td>
|
||||
<td className="p-4 text-text-muted">W dniu montażu</td>
|
||||
<td className="p-4 font-bold text-primary">0 zł</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="instalatorzy">2. Dostawa podczas montażu</h2>
|
||||
<p>
|
||||
Jeśli wybierzesz wariant zakupu "Z montażem", urządzenie nie jest wysyłane z wyprzedzeniem za pośrednictwem zewnętrznej firmy kurierskiej. Sprzęt w dniu umówionej instalacji przywozi nasza własna ekipa monterska, dzięki czemu minimalizujemy ryzyko uszkodzenia urządzenia w transporcie i zdejmujemy z Ciebie obowiązek składowania gabarytowych kartonów.
|
||||
</p>
|
||||
|
||||
<h2 id="platnosci">3. Metody płatności</h2>
|
||||
<ul>
|
||||
<li><strong>Przelew tradycyjny</strong> – po złożeniu zamówienia otrzymasz fakturę pro forma do opłacenia.</li>
|
||||
<li><strong>Szybkie płatności (Przelewy24/PayU)</strong> – natychmiastowe księgowanie wpłaty.</li>
|
||||
<li><strong>Płatność u instalatora</strong> – gotówką po zakończonym montażu i uruchomieniu sprzętu (opcja dostępna po wpłaceniu zaliczki 20%).</li>
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { ShieldCheck } from 'lucide-react';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Gwarancja na Klimatyzatory i Montaż | AirProject',
|
||||
description: 'Szczegółowe informacje dotyczące warunków gwarancji na instalowane urządzenia oraz usługi montażowe.',
|
||||
alternates: {
|
||||
canonical: '/gwarancja',
|
||||
}
|
||||
};
|
||||
|
||||
export default function GwarancjaPage() {
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center gap-4 mb-6 text-green-600">
|
||||
<ShieldCheck className="w-12 h-12" />
|
||||
<h1 className="text-4xl font-extrabold m-0 text-primary">Gwarancja i Serwis</h1>
|
||||
</div>
|
||||
|
||||
<p className="lead">
|
||||
Jesteśmy autoryzowanym partnerem wszystkich sprzedawanych przez nas urządzeń, co oznacza pełne bezpieczeństwo Twojej inwestycji i bezproblemową realizację świadczeń gwarancyjnych.
|
||||
</p>
|
||||
|
||||
{/* TODO: treść prawna do uzupełnienia przez właściciela */}
|
||||
|
||||
<h2 id="gwarancja-urzadzenia">1. Gwarancja na urządzenia</h2>
|
||||
<p>Czas trwania gwarancji zależy od wybranego producenta:</p>
|
||||
<ul>
|
||||
<li><strong>Daikin</strong> – 3 lata gwarancji</li>
|
||||
<li><strong>Rotenso</strong> – 5 lat gwarancji</li>
|
||||
<li><strong>Mitsubishi Electric</strong> – 5 lat gwarancji</li>
|
||||
<li><strong>Gree</strong> – 5 lat gwarancji</li>
|
||||
<li><strong>LG</strong> – do 10 lat gwarancji na sprężarkę, 3 lata na urządzenie</li>
|
||||
</ul>
|
||||
|
||||
<div className="bg-primary-light/10 border-l-4 border-primary p-4 my-8 rounded-r-lg">
|
||||
<strong>Ważne:</strong> Warunkiem zachowania gwarancji jest wykonywanie regularnych (płatnych) przeglądów technicznych zgodnie z zaleceniami producenta – zazwyczaj dwa razy do roku.
|
||||
</div>
|
||||
|
||||
<h2 id="gwarancja-montaz">2. Gwarancja na usługę montażu</h2>
|
||||
<p>
|
||||
Bierzemy pełną odpowiedzialność za wykonaną przez nas pracę. Udzielamy <strong>5-letniej rękojmi</strong> na poprawność działania całej instalacji chłodniczej i odpływu skroplin. Jeśli jakikolwiek problem wynika z błędu montażowego, naprawimy go na własny koszt.
|
||||
</p>
|
||||
|
||||
<h2 id="serwis">3. Autoryzowany Serwis</h2>
|
||||
<p>
|
||||
Posiadamy pełne zaplecze techniczne, własnych wykwalifikowanych serwisantów i uprawnienia UDT oraz certyfikaty F-GAZ. Co to oznacza dla Ciebie?
|
||||
W przypadku awarii, nie odsyłamy Cię do producenta. Przyjeżdżamy na miejsce diagnozując usterkę, a w razie konieczności zamawiamy części i realizujemy naprawę, oszczędzając Twój czas i nerwy.
|
||||
</p>
|
||||
|
||||
<h2 id="przeglady">4. Zleć nam przegląd gwarancyjny</h2>
|
||||
<p>
|
||||
Oferujemy atrakcyjne pakiety stałej opieki serwisowej. Przy stałej współpracy koszty serwisu są niższe, a my sami pilnujemy za Ciebie terminów obowiązkowych przeglądów narzucanych przez producentów sprzętu.
|
||||
<br/><br/>
|
||||
<Link href="/kontakt" className="font-bold text-accent hover:underline">Skontaktuj się z nami</Link>, aby zarezerwować termin wizyty serwisowej.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function FormalneLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<main className="bg-slate-50 min-h-screen py-24 md:py-32">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="bg-white p-8 md:p-16 rounded-3xl border border-border shadow-sm prose prose-slate max-w-none prose-headings:font-heading prose-headings:text-primary prose-a:text-accent hover:prose-a:text-accent-hover prose-a:font-semibold">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Polityka Prywatności i Cookies | AirProject',
|
||||
description: 'Zasady przetwarzania danych osobowych oraz wykorzystania plików cookies w serwisie AirProject.',
|
||||
alternates: {
|
||||
canonical: '/polityka-prywatnosci',
|
||||
}
|
||||
};
|
||||
|
||||
export default function PolitykaPrywatnosciPage() {
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-4xl font-extrabold mb-8">Polityka Prywatności i Cookies</h1>
|
||||
|
||||
<p className="lead">
|
||||
Twoja prywatność jest dla nas ważna. W tym dokumencie opisujemy, jakie dane zbieramy, w jakim celu je wykorzystujemy oraz jakie masz w związku z tym prawa.
|
||||
</p>
|
||||
|
||||
{/* TODO: treść prawna do uzupełnienia przez właściciela i weryfikacji z inspektorem ochrony danych / radcą prawnym */}
|
||||
|
||||
<h2 id="administrator">1. Administrator danych</h2>
|
||||
<p>
|
||||
Administratorem Twoich danych osobowych jest:
|
||||
<strong> [TUTAJ WPISZ DANE FIRMY: Nazwa, Adres, NIP, e-mail kontaktowy]</strong>.
|
||||
</p>
|
||||
|
||||
<h2 id="zakres-cel">2. Zakres i cele przetwarzania</h2>
|
||||
<p>Przetwarzamy dane osobowe podane przez Ciebie w formularzu kontaktowym oraz w procesie składania zamówienia w celu:</p>
|
||||
<ul>
|
||||
<li>Realizacji zamówień i usług (np. dojazdu instalatorów na wskazany adres).</li>
|
||||
<li>Komunikacji (odpowiedzi na zapytania z formularza).</li>
|
||||
<li>Celów księgowych i podatkowych.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="prawa">3. Twoje prawa</h2>
|
||||
<p>Zgodnie z przepisami RODO masz prawo do:</p>
|
||||
<ul>
|
||||
<li>Dostępu do swoich danych oraz otrzymania ich kopii.</li>
|
||||
<li>Sprostowania (poprawienia) swoich danych.</li>
|
||||
<li>Usunięcia danych lub ograniczenia przetwarzania.</li>
|
||||
<li>Przenoszenia danych.</li>
|
||||
<li>Wniesienia sprzeciwu wobec przetwarzania.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="cookies">4. Pliki Cookies</h2>
|
||||
<p>
|
||||
Nasza strona wykorzystuje pliki cookies (ciasteczka) w celu zapewnienia prawidłowego działania serwisu (np. zapamiętania zawartości koszyka) oraz w celach analitycznych. Możesz zarządzać ustawieniami cookies z poziomu przeglądarki internetowej.
|
||||
</p>
|
||||
|
||||
<p className="text-sm text-text-muted mt-12 pt-8 border-t border-border">
|
||||
Ostatnia aktualizacja dokumentu: 1 stycznia 2026 r.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Regulamin Sklepu i Usług | AirProject',
|
||||
description: 'Regulamin świadczenia usług, zasady korzystania ze sklepu, prawa i obowiązki klienta.',
|
||||
alternates: {
|
||||
canonical: '/regulamin',
|
||||
}
|
||||
};
|
||||
|
||||
export default function RegulaminPage() {
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-4xl font-extrabold mb-8">Regulamin Serwisu i Sklepu Internetowego</h1>
|
||||
|
||||
<p className="lead">
|
||||
Niniejszy dokument określa zasady korzystania z serwisu AirProject oraz dokonywania w nim zakupów urządzeń i usług montażu.
|
||||
</p>
|
||||
|
||||
{/* TODO: treść prawna do uzupełnienia przez właściciela i weryfikacji przez radcę prawnego */}
|
||||
|
||||
<h2 id="postanowienia-ogolne">§ 1. Postanowienia ogólne</h2>
|
||||
<p>
|
||||
1. Sklep internetowy działający pod adresem internetowym airproject.pl prowadzony jest przez:
|
||||
<strong> [TUTAJ WPISZ DANE FIRMY: Nazwa, Adres, NIP, REGON]</strong>.
|
||||
</p>
|
||||
<p>
|
||||
2. Niniejszy Regulamin określa zasady zawierania umów sprzedaży i świadczenia usług za pośrednictwem serwisu.
|
||||
</p>
|
||||
|
||||
<h2 id="definicje">§ 2. Definicje</h2>
|
||||
<ul>
|
||||
<li><strong>Klient</strong> – osoba fizyczna, osoba prawna lub jednostka organizacyjna nie posiadająca osobowości prawnej.</li>
|
||||
<li><strong>Konsument</strong> – Klient będący osobą fizyczną, dokonujący zakupów w celu niezwiązanym bezpośrednio z jego działalnością gospodarczą lub zawodową.</li>
|
||||
<li><strong>Sklep</strong> – platforma e-commerce pod adresem airproject.pl.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="zamowienia">§ 3. Zasady składania i realizacji zamówień</h2>
|
||||
<p>
|
||||
1. Informacje zawarte na Stronie Internetowej Sklepu nie stanowią oferty w rozumieniu Kodeksu Cywilnego, a jedynie zaproszenie do zawarcia umowy.
|
||||
<br />
|
||||
2. Klient może składać zamówienia 24 godziny na dobę przez 7 dni w tygodniu.
|
||||
<br />
|
||||
3. Realizacja usług montażowych odbywa się po uprzednim kontakcie i ustaleniu terminu.
|
||||
</p>
|
||||
|
||||
<h2 id="platnosci">§ 4. Płatności i ceny</h2>
|
||||
<p>
|
||||
1. Wszystkie ceny na stronie są cenami brutto (zawierają podatek VAT).
|
||||
<br />
|
||||
2. Podatek VAT na urządzenia sprzedawane z usługą montażu dla osób fizycznych w budynkach mieszkalnych o powierzchni do 300 m² rozliczany jest zgodnie z odpowiednimi przepisami podatkowymi (np. stawką 8%).
|
||||
</p>
|
||||
|
||||
<h2 id="odstapienie">§ 5. Odstąpienie od umowy</h2>
|
||||
<p>
|
||||
1. Konsument ma prawo odstąpić od umowy zawartej na odległość bez podania przyczyny w terminie 14 dni od dnia dostarczenia towaru.
|
||||
<br />
|
||||
2. Prawo odstąpienia nie przysługuje w odniesieniu do usług, które zostały w pełni wykonane za wyraźną zgodą Konsumenta.
|
||||
</p>
|
||||
|
||||
<p className="text-sm text-text-muted mt-12 pt-8 border-t border-border">
|
||||
Ostatnia aktualizacja regulaminu: 1 stycznia 2026 r.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Reklamacje i Zwroty | AirProject',
|
||||
description: 'Zasady i procedury składania reklamacji oraz zwrotów produktów i usług w sklepie AirProject.',
|
||||
alternates: {
|
||||
canonical: '/reklamacje',
|
||||
}
|
||||
};
|
||||
|
||||
export default function ReklamacjePage() {
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-4xl font-extrabold mb-8">Reklamacje i Zwroty</h1>
|
||||
|
||||
<p className="lead">
|
||||
Dokładamy wszelkich starań, aby nasze produkty i usługi były najwyższej jakości. Jeśli jednak cokolwiek nie spełnia Twoich oczekiwań, masz pełne prawo złożyć reklamację lub dokonać zwrotu.
|
||||
</p>
|
||||
|
||||
{/* TODO: treść prawna do uzupełnienia przez właściciela */}
|
||||
|
||||
<h2 id="zwroty">1. Zwroty (Odstąpienie od umowy)</h2>
|
||||
<p>
|
||||
Zgodnie z polskim prawem konsument ma prawo zwrócić zakupiony produkt bez podania przyczyny w ciągu 14 dni od dnia jego otrzymania. Pamiętaj jednak, że:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Zwracany towar nie może nosić śladów montażu i używania.</li>
|
||||
<li>Koszty odesłania urządzenia ponosi kupujący.</li>
|
||||
<li>W przypadku wykonania usługi montażu urządzenia za uprzednią zgodą konsumenta, prawo do odstąpienia od umowy może zostać wyłączone.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="jak-zwrocic">Jak dokonać zwrotu?</h2>
|
||||
<ol>
|
||||
<li>Powiadom nas drogą mailową na adres: <strong>kontakt@twoj-sklep.pl</strong>.</li>
|
||||
<li>Zapakuj bezpiecznie produkt w oryginalne opakowanie.</li>
|
||||
<li>Odeślij go na wskazany przez nas adres magazynu.</li>
|
||||
<li>Po weryfikacji sprzętu, środki zwrócimy Ci w ciągu 14 dni roboczych.</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="reklamacje">2. Procedura Reklamacyjna (Rękojmia i Gwarancja)</h2>
|
||||
<p>
|
||||
Wszystkie wady urządzeń mogą być zgłaszane z tytułu gwarancji producenta lub rękojmi.
|
||||
Gwarancje na poszczególne urządzenia mogą wynosić od 2 do 5 lat (szczegóły w karcie produktu i zakładce <Link href="/gwarancja">Gwarancja</Link>).
|
||||
</p>
|
||||
|
||||
<h2 id="jak-reklamowac">Jak zgłosić usterkę?</h2>
|
||||
<p>
|
||||
W razie awarii sprzętu zamontowanego przez naszą firmę, zalecamy kontakt telefoniczny lub poprzez e-mail:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Opisz rodzaj usterki i kod błędu wyświetlający się na urządzeniu (jeśli występuje).</li>
|
||||
<li>Dołącz zdjęcia instalacji lub uszkodzonego elementu.</li>
|
||||
<li>Nasz serwisant skontaktuje się z Tobą w celu ustalenia terminu darmowej diagnozy i naprawy (w okresie gwarancyjnym).</li>
|
||||
</ul>
|
||||
|
||||
<div className="mt-8 p-6 bg-slate-50 border border-border rounded-xl">
|
||||
<p className="mb-0 font-semibold text-primary">Masz dodatkowe pytania?</p>
|
||||
<p className="mb-0 mt-2 text-sm">Zadzwoń do nas pod numer +48 000 000 000 lub skorzystaj z <Link href="/kontakt">formularza kontaktowego</Link>.</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
import { Metadata } from 'next';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getPosts, getPostBySlug, getRelatedPosts } from '@/content/posts';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { Calendar, User, ArrowLeft, ArrowRight } from 'lucide-react';
|
||||
import { companyDetails } from '@/content/company';
|
||||
|
||||
interface BlogPostPageProps {
|
||||
params: {
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Generowanie ścieżek statycznych dla wpisów
|
||||
export async function generateStaticParams() {
|
||||
const posts = getPosts();
|
||||
return posts.map((post) => ({
|
||||
slug: post.slug,
|
||||
}));
|
||||
}
|
||||
|
||||
// Generowanie metadanych dla danego wpisu
|
||||
export async function generateMetadata({ params }: BlogPostPageProps): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return {
|
||||
title: 'Nie znaleziono wpisu',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${post.title} | Blog AirProject`,
|
||||
description: post.excerpt,
|
||||
alternates: {
|
||||
canonical: `/blog/${post.slug}`,
|
||||
},
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
type: 'article',
|
||||
publishedTime: post.date,
|
||||
authors: [post.author || companyDetails.shortName],
|
||||
images: [
|
||||
{
|
||||
url: post.image || '/hero.jpg',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function BlogPostPage({ params }: BlogPostPageProps) {
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const relatedPosts = getRelatedPosts(post.slug, post.category, 3);
|
||||
|
||||
const dateObj = new Date(post.date);
|
||||
const formattedDate = dateObj.toLocaleDateString('pl-PL', {
|
||||
day: 'numeric', month: 'long', year: 'numeric'
|
||||
});
|
||||
|
||||
const categoryLabels: Record<string, string> = {
|
||||
'klimatyzacja': 'Klimatyzacja',
|
||||
'pompy-ciepla': 'Pompy Ciepła',
|
||||
'remonty': 'Remonty',
|
||||
'hydraulika': 'Hydraulika',
|
||||
'porady': 'Porady'
|
||||
};
|
||||
|
||||
// Ustawienie CTA dopasowanego do kategorii wpisu
|
||||
const getCtaLink = () => {
|
||||
switch(post.category) {
|
||||
case 'klimatyzacja': return '/klimatyzacja';
|
||||
case 'pompy-ciepla': return '/pompy-ciepla';
|
||||
case 'remonty': return '/uslugi-domowe/remonty';
|
||||
case 'hydraulika': return '/uslugi-domowe/hydraulika';
|
||||
default: return '/kontakt';
|
||||
}
|
||||
};
|
||||
|
||||
// --- JSON-LD ---
|
||||
const jsonLdArticle = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BlogPosting',
|
||||
headline: post.title,
|
||||
image: post.image,
|
||||
datePublished: post.date,
|
||||
dateModified: post.date,
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: post.author || companyDetails.name,
|
||||
},
|
||||
publisher: {
|
||||
'@type': 'Organization',
|
||||
name: companyDetails.name,
|
||||
logo: {
|
||||
'@type': 'ImageObject',
|
||||
url: 'https://aeroservice-demo.pl/logo.png', // MOCK URL
|
||||
},
|
||||
},
|
||||
description: post.excerpt,
|
||||
};
|
||||
|
||||
const jsonLdBreadcrumb = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: [
|
||||
{
|
||||
'@type': 'ListItem',
|
||||
position: 1,
|
||||
name: 'Strona Główna',
|
||||
item: 'https://aeroservice-demo.pl',
|
||||
},
|
||||
{
|
||||
'@type': 'ListItem',
|
||||
position: 2,
|
||||
name: 'Blog',
|
||||
item: 'https://aeroservice-demo.pl/blog',
|
||||
},
|
||||
{
|
||||
'@type': 'ListItem',
|
||||
position: 3,
|
||||
name: post.title,
|
||||
item: `https://aeroservice-demo.pl/blog/${post.slug}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="bg-slate-50 pt-24 pb-16">
|
||||
{/* Skrypty JSON-LD dla SEO */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdArticle) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdBreadcrumb) }}
|
||||
/>
|
||||
|
||||
<article className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* Powrót */}
|
||||
<Link
|
||||
href="/blog"
|
||||
className="inline-flex items-center gap-2 text-sm font-semibold text-primary/70 hover:text-primary transition-colors mb-8"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
Wróć do listy artykułów
|
||||
</Link>
|
||||
|
||||
{/* Header artykułu */}
|
||||
<header className="mb-10 text-center md:text-left">
|
||||
<div className="flex flex-wrap items-center justify-center md:justify-start gap-4 mb-6 text-sm font-medium text-text-muted">
|
||||
<span className="px-3 py-1 bg-accent/10 text-accent font-bold rounded-full uppercase tracking-wider">
|
||||
{categoryLabels[post.category] || post.category}
|
||||
</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Calendar className="w-4 h-4" />
|
||||
<time dateTime={post.date}>{formattedDate}</time>
|
||||
</div>
|
||||
{post.author && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<User className="w-4 h-4" />
|
||||
<span>{post.author}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<h1 className="text-3xl md:text-5xl font-extrabold text-primary font-heading leading-tight mb-6">
|
||||
{post.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-lg md:text-xl text-text-muted leading-relaxed max-w-3xl">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{/* Główny obraz */}
|
||||
<div className="relative w-full aspect-video rounded-2xl overflow-hidden mb-12 shadow-md">
|
||||
<Image
|
||||
src={post.image || 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=1600&q=80'}
|
||||
alt={post.title}
|
||||
fill
|
||||
priority
|
||||
className="object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Treść */}
|
||||
<div className="prose prose-lg md:prose-xl prose-slate max-w-none mb-16
|
||||
prose-headings:font-heading prose-headings:text-primary prose-headings:font-bold
|
||||
prose-a:text-accent hover:prose-a:text-accent-hover prose-a:font-semibold
|
||||
prose-img:rounded-xl prose-img:shadow-md
|
||||
marker:text-accent"
|
||||
>
|
||||
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
||||
{/* CTA do usługi */}
|
||||
<CtaBanner
|
||||
title="Podobał Ci się ten artykuł?"
|
||||
subtitle="Jeśli potrzebujesz pomocy specjalistów w podobnej sprawie, sprawdź naszą ofertę lub skontaktuj się z nami bezpośrednio."
|
||||
ctaText="Zobacz naszą ofertę"
|
||||
ctaLink={getCtaLink()}
|
||||
/>
|
||||
|
||||
{/* Powiązane artykuły */}
|
||||
{relatedPosts.length > 0 && (
|
||||
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-16 md:mt-24">
|
||||
<div className="flex items-center justify-between border-b border-border pb-4 mb-8">
|
||||
<h2 className="text-2xl font-bold text-primary font-heading">Powiązane artykuły</h2>
|
||||
<Link href="/blog" className="text-sm font-semibold text-accent hover:text-accent-hover flex items-center gap-1">
|
||||
Więcej wpisów <ArrowRight className="w-4 h-4" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{relatedPosts.map(related => (
|
||||
<Link key={related.slug} href={`/blog/${related.slug}`} className="group block">
|
||||
<div className="relative aspect-[16/10] rounded-xl overflow-hidden mb-4">
|
||||
<Image
|
||||
src={related.image || 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=800&q=80'}
|
||||
alt={related.title}
|
||||
fill
|
||||
className="object-cover transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-primary font-heading group-hover:text-accent transition-colors mb-2 line-clamp-2">
|
||||
{related.title}
|
||||
</h3>
|
||||
<p className="text-sm text-text-muted line-clamp-2">
|
||||
{related.excerpt}
|
||||
</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { FeaturedPost } from '@/components/sections/FeaturedPost';
|
||||
import { PostsGrid } from '@/components/sections/PostsGrid';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { getPosts, getFeaturedPost } from '@/content/posts';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Blog i Porady | AirProject',
|
||||
description: 'Baza wiedzy na temat klimatyzacji, pomp ciepła i remontów. Czytaj nasze poradniki i bądź na bieżąco z nowościami w branży.',
|
||||
alternates: {
|
||||
canonical: '/blog',
|
||||
}
|
||||
};
|
||||
|
||||
export default function BlogPage() {
|
||||
const allPosts = getPosts();
|
||||
const featuredPost = getFeaturedPost();
|
||||
|
||||
// Usuwamy z głównej siatki artykuł wyróżniony, żeby się nie powielał (chyba że chcemy, ale zazwyczaj się usuwa)
|
||||
const remainingPosts = allPosts.filter(post => post.slug !== featuredPost.slug);
|
||||
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Baza Wiedzy"
|
||||
title="Blog i poradniki"
|
||||
subtitle="Dzielimy się naszą wiedzą i doświadczeniem. Zobacz, jak dbać o domowe instalacje, na co uważać podczas remontu i jak uzyskać dofinansowanie."
|
||||
ctaText="Skontaktuj się z nami"
|
||||
ctaLink="/kontakt"
|
||||
secondaryCtaText="Nasze usługi"
|
||||
secondaryCtaLink="/uslugi-domowe"
|
||||
backgroundImage="https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<section className="py-16 md:py-24 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="mb-16">
|
||||
<h2 className="text-2xl font-bold text-primary font-heading mb-8">Artykuł wyróżniony</h2>
|
||||
<FeaturedPost post={featuredPost} />
|
||||
</div>
|
||||
|
||||
<PostsGrid posts={remainingPosts} />
|
||||
</section>
|
||||
|
||||
<CtaBanner
|
||||
title="Potrzebujesz indywidualnej porady?"
|
||||
subtitle="Zadaj nam pytanie, a z przyjemnością udzielimy darmowej konsultacji i doradzimy najlepsze rozwiązanie."
|
||||
ctaText="Zadaj pytanie"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
+186
-14
@@ -1,26 +1,198 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "daisyui";
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--color-text: var(--foreground);
|
||||
--color-text-muted: var(--muted-foreground);
|
||||
--font-sans: var(--font-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-heading: var(--font-heading);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-border: var(--theme-border);
|
||||
--color-input: var(--input);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-light: var(--accent-light);
|
||||
--color-cta: var(--cta);
|
||||
--color-cta-foreground: var(--cta-foreground);
|
||||
--color-cta-hover: var(--cta-hover);
|
||||
--color-primary-light: var(--primary-light);
|
||||
--color-success: var(--success);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) * 0.6);
|
||||
--radius-md: calc(var(--radius) * 0.8);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) * 1.4);
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #1a2230;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #1a2230;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #1a2230;
|
||||
--primary: #0f2a47;
|
||||
--primary-foreground: #ffffff;
|
||||
--primary-light: #1b3d63;
|
||||
--secondary: #f5f7fa;
|
||||
--secondary-foreground: #0f2a47;
|
||||
--muted: #f5f7fa;
|
||||
--muted-foreground: #5a6678;
|
||||
--accent: #2ba8e0;
|
||||
--accent-foreground: #ffffff;
|
||||
--accent-light: #e3f4fc;
|
||||
--cta: #1e293b;
|
||||
--cta-foreground: #ffffff;
|
||||
--cta-hover: #0f172a;
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--theme-border: #e2e8f0;
|
||||
--input: #e2e8f0;
|
||||
--ring: #2ba8e0;
|
||||
--success: #16a34a;
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--radius: 0.75rem;
|
||||
--sidebar: #ffffff;
|
||||
--sidebar-foreground: #1a2230;
|
||||
--sidebar-primary: #0f2a47;
|
||||
--sidebar-primary-foreground: #ffffff;
|
||||
--sidebar-accent: #f5f7fa;
|
||||
--sidebar-accent-foreground: #0f2a47;
|
||||
--sidebar-border: #e2e8f0;
|
||||
--sidebar-ring: #2ba8e0;
|
||||
|
||||
/* DaisyUI Overrides */
|
||||
--color-primary: var(--accent);
|
||||
--color-primary-content: #ffffff;
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-content: var(--secondary-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-content: var(--accent-foreground);
|
||||
--color-neutral: #1a2230;
|
||||
--color-neutral-content: #ffffff;
|
||||
--color-base-100: var(--background);
|
||||
--color-base-200: var(--muted);
|
||||
--color-base-300: var(--theme-border);
|
||||
--color-base-content: var(--foreground);
|
||||
--color-success: var(--success);
|
||||
--color-error: var(--destructive);
|
||||
--radius-selector: var(--radius);
|
||||
--radius-field: var(--radius);
|
||||
--radius-box: var(--radius);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: #0f2a47;
|
||||
--foreground: #f5f7fa;
|
||||
--card: #1b3d63;
|
||||
--card-foreground: #f5f7fa;
|
||||
--popover: #1b3d63;
|
||||
--popover-foreground: #f5f7fa;
|
||||
--primary: #2ba8e0;
|
||||
--primary-foreground: #0f2a47;
|
||||
--secondary: #1b3d63;
|
||||
--secondary-foreground: #f5f7fa;
|
||||
--muted: #1b3d63;
|
||||
--muted-foreground: #e3f4fc;
|
||||
--accent: #2ba8e0;
|
||||
--accent-foreground: #0f2a47;
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--theme-border: rgba(226, 232, 240, 0.1);
|
||||
--input: rgba(226, 232, 240, 0.15);
|
||||
--ring: #2ba8e0;
|
||||
|
||||
/* DaisyUI Overrides */
|
||||
--color-primary: var(--accent);
|
||||
--color-primary-content: #ffffff;
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-content: var(--secondary-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-content: var(--accent-foreground);
|
||||
--color-neutral: #1a2230;
|
||||
--color-neutral-content: #ffffff;
|
||||
--color-base-100: var(--background);
|
||||
--color-base-200: var(--muted);
|
||||
--color-base-300: var(--theme-border);
|
||||
--color-base-content: var(--foreground);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply font-sans;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@apply font-heading;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
@layer components {
|
||||
.btn {
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
.btn:hover {
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.08), 0 10px 15px rgba(0, 0, 0, 0.05);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.btn.btn-outline.bg-white {
|
||||
background-color: #ffffff !important;
|
||||
color: var(--accent) !important;
|
||||
border-color: var(--accent) !important;
|
||||
}
|
||||
.btn.btn-outline.bg-white:hover {
|
||||
background-color: var(--accent) !important;
|
||||
color: #ffffff !important;
|
||||
border-color: var(--accent) !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { CtaBanner } from "@/components/sections/CtaBanner";
|
||||
import { Wrench, Phone, ArrowRight } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { companyDetails } from "@/content/company";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Kalkulator - W przygotowaniu | AIR Project",
|
||||
description: "Kalkulator doboru klimatyzacji i pomp ciepła w przygotowaniu.",
|
||||
};
|
||||
|
||||
export default function KalkulatorPage() {
|
||||
return (
|
||||
<main className="flex-1">
|
||||
<section className="py-24 md:py-32 bg-muted">
|
||||
<div className="container mx-auto px-4 max-w-3xl text-center">
|
||||
<div className="w-24 h-24 bg-primary rounded-full flex items-center justify-center mx-auto mb-8 text-white shadow-xl">
|
||||
<Wrench className="w-12 h-12" />
|
||||
</div>
|
||||
<h1 className="text-4xl md:text-5xl font-heading font-bold text-primary mb-6 leading-tight">
|
||||
Narzędzie w przygotowaniu
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl text-muted-foreground mb-10 leading-relaxed">
|
||||
Pracujemy nad zaawansowanym konfiguratorem, który krok po kroku pomoże Ci dobrać sprzęt i natychmiast oszacuje koszty montażu. Narzędzie zostanie udostępnione już wkrótce!
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<a href={`tel:${companyDetails.phoneRaw}`} className="w-full sm:w-auto">
|
||||
<button className="btn btn-primary font-bold w-full sm:w-auto text-white flex items-center justify-center gap-2">
|
||||
<Phone className="size-5" />
|
||||
<span>Zadzwoń: {companyDetails.phone}</span>
|
||||
</button>
|
||||
</a>
|
||||
<Link href="/kontakt" className="w-full sm:w-auto">
|
||||
<button className="btn btn-outline btn-primary bg-white font-bold w-full sm:w-auto flex items-center justify-center gap-2">
|
||||
<span>Napisz do nas</span>
|
||||
<ArrowRight className="size-5" />
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CtaBanner
|
||||
title="Skorzystaj z naszej darmowej wyceny od ręki"
|
||||
subtitle="Zadzwoń do nas lub wypełnij krótki formularz na stronie kontaktu. Przygotujemy dla Ciebie indywidualną, niezobowiązującą i darmową ofertę szybciej, niż myślisz."
|
||||
ctaText="Przejdź do kontaktu"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { InfoHighlights } from '@/components/sections/InfoHighlights';
|
||||
import { AcTypesSection } from '@/components/sections/AcTypesSection';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { ConfiguratorTeaser } from '@/components/sections/ConfiguratorTeaser';
|
||||
import { PricingTable } from '@/components/sections/PricingTable';
|
||||
import { BrandsGrid } from '@/components/sections/BrandsGrid';
|
||||
import { FeaturedProducts } from '@/components/sections/FeaturedProducts';
|
||||
import { WhyUs } from '@/components/sections/WhyUs';
|
||||
import { FaqAccordion } from '@/components/sections/FaqAccordion';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { acProcessSteps } from '@/content/process';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Montaż i Serwis Klimatyzacji | AirProject',
|
||||
description: 'Profesjonalny montaż klimatyzacji typu split i multisplit. Posiadamy uprawnienia F-gaz. Bezpłatny audyt, dobór urządzeń i sprawdzony serwis.',
|
||||
alternates: {
|
||||
canonical: '/klimatyzacja',
|
||||
}
|
||||
};
|
||||
|
||||
export default function KlimatyzacjaPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="15+ lat doświadczenia · Split i multisplit · Uprawnienia F-gaz"
|
||||
title="Montaż klimatyzacji — dobór, instalacja, serwis"
|
||||
subtitle="Zapewnij sobie idealny klimat w domu i biurze. Oferujemy kompleksowe usługi od bezpłatnego audytu po montaż i opiekę serwisową."
|
||||
ctaText="Dobierz klimatyzator"
|
||||
ctaLink="/sklep"
|
||||
secondaryCtaText="Sprawdź cennik"
|
||||
secondaryCtaLink="#cennik"
|
||||
backgroundImage="https://images.unsplash.com/photo-1527689638836-411945a2b57c?w=1600&q=80"
|
||||
features={[
|
||||
'Bezpłatny audyt',
|
||||
'Estetyczny montaż',
|
||||
'Zgodność z F-gaz',
|
||||
'Serwis gwarancyjny'
|
||||
]}
|
||||
/>
|
||||
|
||||
<InfoHighlights
|
||||
description="Montaż klimatyzacji to inwestycja w komfort na lata. Dlatego kładziemy nacisk na precyzję, estetykę wykonania i czystość w miejscu pracy. Nasza ekipa używa profesjonalnych narzędzi, a każdy montaż kończymy szkoleniem z obsługi."
|
||||
highlights={[
|
||||
{
|
||||
icon: 'clock',
|
||||
title: 'Czas montażu',
|
||||
description: 'Standardowy montaż jednostki typu split trwa zazwyczaj od 4 do 8 godzin.'
|
||||
},
|
||||
{
|
||||
icon: 'price',
|
||||
title: 'Ceny od 1200 zł',
|
||||
description: 'Jasny cennik usług bez ukrytych opłat. Ostateczna wycena zawsze przed rozpoczęciem prac.'
|
||||
},
|
||||
{
|
||||
icon: 'map',
|
||||
title: 'Zasięg działania',
|
||||
description: 'Świadczymy usługi na terenie miasta i w promieniu 50 km z bezpłatnym dojazdem.'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
<AcTypesSection />
|
||||
|
||||
<ProcessSteps
|
||||
steps={acProcessSteps}
|
||||
eyebrow="Krok po Kroku"
|
||||
title="Jak wygląda proces montażu?"
|
||||
subtitle="Od pierwszej wizyty do pełnego uruchomienia — zobacz, jak działamy u naszych klientów."
|
||||
/>
|
||||
|
||||
<ConfiguratorTeaser />
|
||||
|
||||
<PricingTable />
|
||||
|
||||
<BrandsGrid />
|
||||
|
||||
<FeaturedProducts />
|
||||
|
||||
<WhyUs />
|
||||
|
||||
<FaqAccordion category="klimatyzacja" />
|
||||
|
||||
<CtaBanner
|
||||
title="Niestandardowa instalacja?"
|
||||
subtitle="Potrzebujesz klimatyzacji w zabytkowym budynku lub masz specyficzne wymagania architektoniczne? Skontaktuj się z nami po indywidualną wycenę."
|
||||
ctaText="Zamów wycenę"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
"use server";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_API_KEY);
|
||||
|
||||
// Schemat walidacji zgodny z tym po stronie klienta
|
||||
const contactFormSchema = z.object({
|
||||
name: z.string().min(2, "Imię musi mieć min. 2 znaki"),
|
||||
phone: z.string().min(9, "Wprowadź poprawny numer telefonu"),
|
||||
email: z.string().email("Niepoprawny adres e-mail"),
|
||||
subject: z.string().min(1, "Wybierz temat"),
|
||||
message: z.string().min(10, "Wiadomość musi mieć min. 10 znaków"),
|
||||
consent: z.boolean().refine((val) => val === true, "Zgoda RODO jest wymagana"),
|
||||
});
|
||||
|
||||
export async function submitContactForm(prevState: any, formData: FormData) {
|
||||
try {
|
||||
// 1. Walidacja danych z formularza
|
||||
const rawData = {
|
||||
name: formData.get("name"),
|
||||
phone: formData.get("phone"),
|
||||
email: formData.get("email"),
|
||||
subject: formData.get("subject"),
|
||||
message: formData.get("message"),
|
||||
consent: formData.get("consent") === "true" || formData.get("consent") === "on",
|
||||
};
|
||||
|
||||
const validatedData = contactFormSchema.parse(rawData);
|
||||
|
||||
// 2. Wysłanie e-maila przez Resend
|
||||
const { data, error } = await resend.emails.send({
|
||||
from: process.env.RESEND_FROM_EMAIL || "[email protected]",
|
||||
to: process.env.RESEND_TO_EMAIL || "[email protected]", // Docelowy e-mail (odbiorca)
|
||||
replyTo: validatedData.email,
|
||||
subject: `Nowa wiadomość ze strony: ${validatedData.subject}`,
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; background-color: #ffffff;">
|
||||
<div style="background-color: #0F2A47; padding: 20px; text-align: center;">
|
||||
<h1 style="color: #ffffff; margin: 0; font-size: 24px;">Nowe zapytanie z formularza</h1>
|
||||
<p style="color: #2BA8E0; margin: 5px 0 0 0; font-size: 14px;">Domena: thermcool.pl</p>
|
||||
</div>
|
||||
<div style="padding: 24px; color: #1e293b;">
|
||||
<h2 style="font-size: 18px; margin-top: 0; border-bottom: 2px solid #f1f5f9; padding-bottom: 10px;">Dane kontaktowe:</h2>
|
||||
<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
|
||||
<tr>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9; width: 120px;"><strong>Imię:</strong></td>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Telefon:</strong></td>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><a href="tel:${validatedData.phone}" style="color: #0F2A47; text-decoration: none;">${validatedData.phone}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>E-mail:</strong></td>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><a href="mailto:${validatedData.email}" style="color: #0F2A47; text-decoration: none;">${validatedData.email}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Temat:</strong></td>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.subject}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 style="font-size: 18px; border-bottom: 2px solid #f1f5f9; padding-bottom: 10px;">Treść wiadomości:</h2>
|
||||
<div style="background-color: #f8fafc; padding: 15px; border-radius: 6px; font-size: 15px; line-height: 1.6; white-space: pre-wrap;">
|
||||
${validatedData.message}
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 24px; font-size: 12px; color: #64748b; text-align: center;">
|
||||
Zgoda RODO została zaakceptowana: <strong>${validatedData.consent ? "Tak" : "Nie"}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div style="background-color: #f1f5f9; padding: 15px; text-align: center; font-size: 12px; color: #64748b;">
|
||||
Wiadomość wygenerowana automatycznie z formularza kontaktowego na stronie thermcool.pl
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error("Resend Error:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "Nie udało się wysłać wiadomości ze względu na błąd serwera pocztowego.",
|
||||
};
|
||||
}
|
||||
|
||||
console.log("Wysłano e-mail (ID):", data?.id);
|
||||
|
||||
// 3. Zwrotka o sukcesie
|
||||
return {
|
||||
success: true,
|
||||
message: "Dziękujemy za wiadomość! Skontaktujemy się z Tobą najszybciej jak to możliwe.",
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Wystąpił błąd walidacji. Sprawdź poprawność danych.",
|
||||
errors: error.flatten().fieldErrors,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: "Wystąpił nieoczekiwany błąd serwera. Spróbuj ponownie później.",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ContactSection } from '@/components/sections/ContactSection';
|
||||
import { MapEmbed } from '@/components/sections/MapEmbed';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Kontakt | AirProject',
|
||||
description: 'Skontaktuj się z nami! Odpowiemy na Twoje pytania, doradzimy w wyborze urządzeń i przygotujemy bezpłatną wycenę. Jesteśmy do Twojej dyspozycji.',
|
||||
alternates: {
|
||||
canonical: '/kontakt',
|
||||
}
|
||||
};
|
||||
|
||||
export default function KontaktPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Kontakt"
|
||||
title="Jesteśmy do Twojej dyspozycji"
|
||||
subtitle="Zastanawiasz się nad montażem klimatyzacji? Planujesz remont? A może masz awarię, która wymaga natychmiastowej interwencji hydraulika? Napisz lub zadzwoń."
|
||||
ctaText="Zadzwoń do nas"
|
||||
ctaLink="tel:+48123456789" // TODO: Use real phone from config
|
||||
secondaryCtaText="Napisz maila"
|
||||
secondaryCtaLink="mailto:[email protected]" // TODO: Use real email
|
||||
backgroundImage="https://images.unsplash.com/photo-1516387938699-a93567ec168e?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<ContactSection />
|
||||
|
||||
<MapEmbed />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { CartItems } from '@/components/shop/CartItems';
|
||||
import { CartSummary } from '@/components/shop/CartSummary';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Twój Koszyk | AirProject',
|
||||
description: 'Przejrzyj swoje zamówienie na klimatyzatory i usługi montażu przed finalizacją zakupów.',
|
||||
alternates: {
|
||||
canonical: '/koszyk',
|
||||
}
|
||||
};
|
||||
|
||||
export default function KoszykPage() {
|
||||
return (
|
||||
<main className="bg-slate-50 min-h-screen">
|
||||
<HeroSection
|
||||
eyebrow="Sklep"
|
||||
title="Twój koszyk"
|
||||
subtitle="Zanim przejdziesz do płatności, sprawdź szczegóły swojego zamówienia. Możesz łatwo zmienić liczbę urządzeń lub dodać profesjonalny montaż dla wybranych pozycji."
|
||||
ctaText="Wróc do sklepu"
|
||||
ctaLink="/sklep"
|
||||
backgroundImage="https://images.unsplash.com/photo-1556740714-a8395b3bf30f?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<section className="py-16 md:py-24 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-12 items-start">
|
||||
<div className="lg:col-span-2">
|
||||
<h2 className="text-2xl font-bold text-primary font-heading mb-8">Lista produktów</h2>
|
||||
<CartItems />
|
||||
</div>
|
||||
<div className="lg:col-span-1">
|
||||
<CartSummary />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
+32
-12
@@ -1,20 +1,29 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import { Inter, Poppins } from "next/font/google";
|
||||
import { Header } from "@/components/layout/Header";
|
||||
import { TrustBar } from "@/components/layout/TrustBar";
|
||||
import { Footer } from "@/components/layout/Footer";
|
||||
import { GoogleAnalytics, GoogleTagManager } from "@next/third-parties/google";
|
||||
import "./globals.css";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
const fontSans = Inter({
|
||||
variable: "--font-sans",
|
||||
subsets: ["latin", "latin-ext"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
const fontHeading = Poppins({
|
||||
variable: "--font-heading",
|
||||
weight: ["400", "500", "600", "700", "800"],
|
||||
subsets: ["latin", "latin-ext"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: {
|
||||
default: "Klimatyzacja, pompy ciepła i usługi domowe",
|
||||
template: "%s | HVAC & Usługi Domowe",
|
||||
},
|
||||
description: "Montaż klimatyzacji, pompy ciepła, remonty i hydraulika. Dobór, montaż i serwis. Darmowa konsultacja.",
|
||||
metadataBase: new URL("http://localhost:3000"),
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
@@ -24,10 +33,21 @@ export default function RootLayout({
|
||||
}>) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||
lang="pl"
|
||||
className={`${fontSans.variable} ${fontHeading.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col">{children}</body>
|
||||
{process.env.NEXT_PUBLIC_GTM_ID && (
|
||||
<GoogleTagManager gtmId={process.env.NEXT_PUBLIC_GTM_ID} />
|
||||
)}
|
||||
<body className="min-h-full flex flex-col bg-background text-foreground">
|
||||
<Header />
|
||||
<main className="flex-grow">{children}</main>
|
||||
<TrustBar />
|
||||
<Footer />
|
||||
{process.env.NEXT_PUBLIC_GA_ID && (
|
||||
<GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID} />
|
||||
)}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { AboutStory } from '@/components/sections/AboutStory';
|
||||
import { StatsBar } from '@/components/sections/StatsBar';
|
||||
import { ValuesGrid } from '@/components/sections/ValuesGrid';
|
||||
import { CertificatesSection } from '@/components/sections/CertificatesSection';
|
||||
import { Testimonials } from '@/components/sections/Testimonials';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { companyDetails } from '@/content/company';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'O Nas | AirProject',
|
||||
description: 'Poznaj zespół specjalistów z AirProject. Zobacz naszą historię, wartości oraz certyfikaty poświadczające najwyższą jakość usług instalacyjnych i remontowych.',
|
||||
alternates: {
|
||||
canonical: '/o-nas',
|
||||
}
|
||||
};
|
||||
|
||||
export default function ONasPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Poznaj Nas"
|
||||
title={`O firmie ${companyDetails.shortName}`}
|
||||
subtitle="Jesteśmy zgranym zespołem inżynierów, instalatorów i serwisantów. Od lat dostarczamy sprawdzone rozwiązania z zakresu klimatyzacji, ogrzewania i wykończeń."
|
||||
ctaText="Skontaktuj się z nami"
|
||||
ctaLink="/kontakt"
|
||||
secondaryCtaText="Nasze realizacje"
|
||||
secondaryCtaLink="/realizacje"
|
||||
backgroundImage="https://images.unsplash.com/photo-1504307651254-35680f356f12?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<AboutStory />
|
||||
|
||||
<StatsBar />
|
||||
|
||||
<ValuesGrid />
|
||||
|
||||
<CertificatesSection />
|
||||
|
||||
<Testimonials />
|
||||
|
||||
<CtaBanner
|
||||
title="Szukasz sprawdzonej ekipy do swojego projektu?"
|
||||
subtitle="Dołącz do grona naszych zadowolonych klientów. Gwarantujemy rzetelność, czystość prowadzonych prac i profesjonalne doradztwo."
|
||||
ctaText="Napisz do nas"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
+62
-60
@@ -1,65 +1,67 @@
|
||||
import Image from "next/image";
|
||||
import { HeroSection } from "@/components/sections/HeroSection";
|
||||
import { AdvantagesBar } from "@/components/sections/AdvantagesBar";
|
||||
import { ServicesGrid } from "@/components/sections/ServicesGrid";
|
||||
import { WhyUs } from "@/components/sections/WhyUs";
|
||||
import { FeaturedProducts } from "@/components/sections/FeaturedProducts";
|
||||
import { Testimonials } from "@/components/sections/Testimonials";
|
||||
import { BlogPreview } from "@/components/sections/BlogPreview";
|
||||
import { CtaBanner } from "@/components/sections/CtaBanner";
|
||||
import { companyDetails } from "@/content/company";
|
||||
|
||||
export default function Home() {
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "LocalBusiness",
|
||||
"name": companyDetails.name,
|
||||
"image": "http://localhost:3000/logo.png",
|
||||
"telephone": companyDetails.phone,
|
||||
"email": companyDetails.email,
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": companyDetails.address.street,
|
||||
"addressLocality": companyDetails.address.city,
|
||||
"postalCode": companyDetails.address.zipCode,
|
||||
"addressCountry": "PL",
|
||||
},
|
||||
"priceRange": "$$",
|
||||
"openingHoursSpecification": [
|
||||
{
|
||||
"@type": "OpeningHoursSpecification",
|
||||
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
|
||||
"opens": "08:00",
|
||||
"closes": "18:00",
|
||||
},
|
||||
{
|
||||
"@type": "OpeningHoursSpecification",
|
||||
"dayOfWeek": ["Saturday"],
|
||||
"opens": "09:00",
|
||||
"closes": "14:00",
|
||||
},
|
||||
],
|
||||
"areaServed": {
|
||||
"@type": "State",
|
||||
"name": companyDetails.address.region,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
||||
<main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js logo"
|
||||
width={100}
|
||||
height={20}
|
||||
priority
|
||||
/>
|
||||
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
||||
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
||||
To get started, edit the page.tsx file.
|
||||
</h1>
|
||||
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
||||
Looking for a starting point or more instructions? Head over to{" "}
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Templates
|
||||
</a>{" "}
|
||||
or the{" "}
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Learning
|
||||
</a>{" "}
|
||||
center.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/vercel.svg"
|
||||
alt="Vercel logomark"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Deploy Now
|
||||
</a>
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<>
|
||||
{/* LocalBusiness Schema for Google Search SEO */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
|
||||
<HeroSection />
|
||||
<AdvantagesBar />
|
||||
<ServicesGrid />
|
||||
{/* BrandsBar will go here in Group B */}
|
||||
<FeaturedProducts />
|
||||
<WhyUs />
|
||||
{/* ProjectsSection will go here in Group B */}
|
||||
<Testimonials />
|
||||
<BlogPreview />
|
||||
<CtaBanner bgVariant="accent-light" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { BenefitsGrid } from '@/components/sections/BenefitsGrid';
|
||||
import { HeatPumpTypes } from '@/components/sections/HeatPumpTypes';
|
||||
import { UseCases } from '@/components/sections/UseCases';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { FundingSection } from '@/components/sections/FundingSection';
|
||||
import { ProjectsGallery } from '@/components/sections/ProjectsGallery';
|
||||
import { FaqAccordion } from '@/components/sections/FaqAccordion';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { heatPumpProcessSteps } from '@/content/process';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Pompy Ciepła — Montaż i Dobór | AirProject',
|
||||
description: 'Zmniejsz rachunki za ogrzewanie dzięki pompie ciepła. Dobór urządzeń, profesjonalny montaż i pomoc w uzyskaniu dofinansowania z programu Czyste Powietrze.',
|
||||
alternates: {
|
||||
canonical: '/pompy-ciepla',
|
||||
}
|
||||
};
|
||||
|
||||
export default function PompyCieplaPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
title="Pompy ciepła — niższe rachunki, niezależność, dofinansowanie"
|
||||
subtitle="Zainwestuj w nowoczesne i ekologiczne ogrzewanie domu. Pomagamy na każdym kroku: od audytu, przez uzyskanie dotacji, aż po montaż."
|
||||
ctaText="Darmowa konsultacja"
|
||||
ctaLink="/kontakt"
|
||||
secondaryCtaText="Sprawdź dofinansowanie"
|
||||
secondaryCtaLink="#dofinansowanie"
|
||||
backgroundImage="https://images.unsplash.com/photo-1584622650111-993a426fbf0a?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<BenefitsGrid />
|
||||
|
||||
<HeatPumpTypes />
|
||||
|
||||
<UseCases />
|
||||
|
||||
<ProcessSteps
|
||||
steps={heatPumpProcessSteps}
|
||||
eyebrow="Wdrożenie"
|
||||
title="Jak wygląda proces instalacji pompy ciepła?"
|
||||
subtitle="Kompleksowo zajmiemy się całą inwestycją, abyś mógł szybko cieszyć się tanim ogrzewaniem."
|
||||
/>
|
||||
|
||||
<div id="dofinansowanie">
|
||||
<FundingSection />
|
||||
</div>
|
||||
|
||||
<ProjectsGallery
|
||||
category="pompy-ciepla"
|
||||
title="Nasze realizacje pomp ciepła"
|
||||
description="Zobacz, jak wyglądają kotłownie i jednostki zewnętrzne zamontowane przez nasz zespół."
|
||||
/>
|
||||
|
||||
<FaqAccordion category="pompy-ciepla" />
|
||||
|
||||
<CtaBanner
|
||||
title="Gotowy na niezależność energetyczną?"
|
||||
subtitle="Skontaktuj się z nami, a przygotujemy dla Ciebie bezpłatny audyt oraz szacunkową kalkulację oszczędności."
|
||||
ctaText="Zadzwoń do nas"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ProjectsGrid } from '@/components/sections/ProjectsGrid';
|
||||
import { StatsBar } from '@/components/sections/StatsBar';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Realizacje | AirProject',
|
||||
description: 'Zobacz nasze wybrane realizacje z zakresu klimatyzacji, pomp ciepła, remontów i usług hydraulicznych.',
|
||||
alternates: {
|
||||
canonical: '/realizacje',
|
||||
}
|
||||
};
|
||||
|
||||
export default function RealizacjePage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Portfolio"
|
||||
title="Nasze realizacje"
|
||||
subtitle="Zobacz wybrane projekty, które zrealizowaliśmy dla naszych klientów. Każde zlecenie traktujemy indywidualnie, dbając o najwyższą jakość wykonania."
|
||||
ctaText="Zobacz ofertę"
|
||||
ctaLink="/uslugi-domowe"
|
||||
secondaryCtaText="Skontaktuj się"
|
||||
secondaryCtaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1503387762-592deb58ef4e?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<ProjectsGrid />
|
||||
|
||||
<StatsBar />
|
||||
|
||||
<CtaBanner
|
||||
title="Chcesz uzyskać podobny efekt?"
|
||||
subtitle="Umów się na bezpłatną konsultację. Doradzimy, przygotujemy projekt i wycenimy prace bez żadnych zobowiązań."
|
||||
ctaText="Zamów darmową wycenę"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: {
|
||||
userAgent: '*',
|
||||
allow: '/',
|
||||
// Możemy tu dodać disallow np. do panelu admina, jeśli by powstał w przyszłości
|
||||
},
|
||||
sitemap: 'https://aeroservice-demo.pl/sitemap.xml',
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import { getProducts } from '@/content/products';
|
||||
import { getPosts } from '@/content/posts';
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const baseUrl = 'https://aeroservice-demo.pl';
|
||||
|
||||
// Statyczne trasy (Główne)
|
||||
const staticRoutes = [
|
||||
'',
|
||||
'/klimatyzacja',
|
||||
'/pompy-ciepla',
|
||||
'/uslugi-domowe',
|
||||
'/uslugi-domowe/remonty',
|
||||
'/uslugi-domowe/hydraulika',
|
||||
'/uslugi-domowe/serwis-agd',
|
||||
'/realizacje',
|
||||
'/blog',
|
||||
'/o-nas',
|
||||
'/kontakt',
|
||||
'/sklep',
|
||||
'/koszyk',
|
||||
'/regulamin',
|
||||
'/polityka-prywatnosci',
|
||||
'/reklamacje',
|
||||
'/dostawa',
|
||||
'/gwarancja',
|
||||
].map((route) => ({
|
||||
url: `${baseUrl}${route}`,
|
||||
lastModified: new Date().toISOString(),
|
||||
changeFrequency: 'weekly' as const,
|
||||
priority: route === '' ? 1 : 0.8,
|
||||
}));
|
||||
|
||||
// Dynamiczne produkty
|
||||
const products = getProducts();
|
||||
const productRoutes = products.map((product) => ({
|
||||
url: `${baseUrl}/sklep/${product.slug}`,
|
||||
lastModified: new Date().toISOString(),
|
||||
changeFrequency: 'weekly' as const,
|
||||
priority: 0.9,
|
||||
}));
|
||||
|
||||
// Dynamiczne artykuły na blogu
|
||||
const posts = getPosts();
|
||||
const postRoutes = posts.map((post) => ({
|
||||
url: `${baseUrl}/blog/${post.slug}`,
|
||||
lastModified: post.date, // Używamy daty publikacji jako lastModified
|
||||
changeFrequency: 'monthly' as const,
|
||||
priority: 0.7,
|
||||
}));
|
||||
|
||||
return [...staticRoutes, ...productRoutes, ...postRoutes];
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getProducts, getProductBySlug } from '@/content/products';
|
||||
import { ProductGallery } from '@/components/shop/ProductGallery';
|
||||
import { ProductInfo } from '@/components/shop/ProductInfo';
|
||||
import { Tabs } from '@/components/shop/Tabs';
|
||||
import { ProductCard } from '@/components/shop/ProductCard';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface ProductPageProps {
|
||||
params: {
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const products = getProducts();
|
||||
return products.map((product) => ({
|
||||
slug: product.slug,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: ProductPageProps): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const product = getProductBySlug(slug);
|
||||
|
||||
if (!product) {
|
||||
return { title: 'Produkt nie znaleziony' };
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${product.brand} ${product.name} | Sklep AirProject`,
|
||||
description: product.description,
|
||||
alternates: {
|
||||
canonical: `/sklep/${product.slug}`,
|
||||
},
|
||||
openGraph: {
|
||||
title: `${product.brand} ${product.name}`,
|
||||
description: product.description,
|
||||
type: 'website',
|
||||
images: [
|
||||
{
|
||||
url: product.image || '/hero.jpg',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ProductPage({ params }: ProductPageProps) {
|
||||
const { slug } = await params;
|
||||
const product = getProductBySlug(slug);
|
||||
|
||||
if (!product) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const allProducts = getProducts();
|
||||
// Dobieramy 4 podobne produkty
|
||||
const relatedProducts = allProducts
|
||||
.filter(p => p.category === product.category && p.slug !== product.slug)
|
||||
.slice(0, 4);
|
||||
|
||||
// JSON-LD
|
||||
const jsonLdProduct = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Product',
|
||||
name: `${product.brand} ${product.name}`,
|
||||
image: product.image,
|
||||
description: product.description,
|
||||
brand: {
|
||||
'@type': 'Brand',
|
||||
name: product.brand,
|
||||
},
|
||||
offers: {
|
||||
'@type': 'Offer',
|
||||
url: `https://aeroservice-demo.pl/sklep/${product.slug}`,
|
||||
priceCurrency: 'PLN',
|
||||
price: product.price,
|
||||
itemCondition: 'https://schema.org/NewCondition',
|
||||
availability: 'https://schema.org/InStock',
|
||||
},
|
||||
};
|
||||
|
||||
const jsonLdBreadcrumb = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: [
|
||||
{
|
||||
'@type': 'ListItem',
|
||||
position: 1,
|
||||
name: 'Sklep',
|
||||
item: 'https://aeroservice-demo.pl/sklep',
|
||||
},
|
||||
{
|
||||
'@type': 'ListItem',
|
||||
position: 2,
|
||||
name: product.name,
|
||||
item: `https://aeroservice-demo.pl/sklep/${product.slug}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="bg-slate-50 pt-24 pb-16 min-h-screen">
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdProduct) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdBreadcrumb) }}
|
||||
/>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* Nawigacja powrotu */}
|
||||
<Link
|
||||
href="/sklep"
|
||||
className="inline-flex items-center gap-2 text-sm font-semibold text-text-muted hover:text-primary transition-colors mb-8"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
Wróć do sklepu
|
||||
</Link>
|
||||
|
||||
{/* Górna sekcja */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16">
|
||||
<ProductGallery image={product.image || ''} name={product.name} />
|
||||
<ProductInfo product={product} />
|
||||
</div>
|
||||
|
||||
{/* Zakładki z detalami */}
|
||||
<Tabs product={product} />
|
||||
|
||||
{/* Podobne produkty */}
|
||||
{relatedProducts.length > 0 && (
|
||||
<section className="mt-24">
|
||||
<h2 className="text-2xl font-bold text-primary font-heading mb-8">Podobne produkty</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{relatedProducts.map(relProduct => (
|
||||
<ProductCard key={relProduct.slug} product={relProduct} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ProductsGrid } from '@/components/shop/ProductsGrid';
|
||||
import { getProducts } from '@/content/products';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Sklep z klimatyzatorami | AirProject',
|
||||
description: 'Wybierz idealny klimatyzator do swojego domu. Oferujemy urządzenia renomowanych marek z możliwością profesjonalnego montażu.',
|
||||
alternates: {
|
||||
canonical: '/sklep',
|
||||
}
|
||||
};
|
||||
|
||||
export default function SklepPage() {
|
||||
const products = getProducts();
|
||||
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="E-commerce"
|
||||
title="Sklep z klimatyzatorami"
|
||||
subtitle="Znajdź urządzenie idealnie dopasowane do Twoich potrzeb. Zamów samo urządzenie lub wybierz kompleksową usługę z naszym profesjonalnym montażem."
|
||||
ctaText="Skontaktuj się z doradcą"
|
||||
ctaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1527689638836-411945a2b57c?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<ProductsGrid products={products} />
|
||||
</section>
|
||||
|
||||
{/* SEO Blok na dole */}
|
||||
<section className="bg-slate-50 py-16 border-t border-border mt-12">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 prose prose-slate">
|
||||
<h2 className="text-2xl font-bold font-heading text-primary">Klimatyzatory ścienne, multisplit i przenośne</h2>
|
||||
<p>
|
||||
Wybór odpowiedniego klimatyzatora to decyzja na lata. W naszym sklepie oferujemy wyłącznie sprawdzone modele od liderów rynku, takich jak Rotenso, Daikin, Mitsubishi, Gree czy LG. Niezależnie od tego, czy szukasz prostego urządzenia ściennego (split), zaawansowanego systemu dla kilku pomieszczeń (multisplit), czy rozwiązania do biura (klimatyzatory kasetonowe), znajdziesz je u nas w atrakcyjnych cenach.
|
||||
</p>
|
||||
<p>
|
||||
Pamiętaj, że gwarancją niezawodności jest nie tylko sam sprzęt, ale przede wszystkim jego <strong>poprawny montaż</strong>. Zachęcamy do wyboru opcji "Kup z montażem" – nasi certyfikowani instalatorzy F-gaz zapewnią pełen profesjonalizm i bezpieczeństwo Twojej nowej instalacji, a Ty zyskasz spokój i pełną gwarancję producenta.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ServicesGrid } from '@/components/sections/ServicesGrid';
|
||||
import { EmergencyBlock } from '@/components/sections/EmergencyBlock';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { WhyUs } from '@/components/sections/WhyUs';
|
||||
import { FaqAccordion } from '@/components/sections/FaqAccordion';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { homeProcessSteps } from '@/content/process';
|
||||
import { companyDetails } from '@/content/company';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Usługi Hydrauliczne i Pogotowie | AirProject',
|
||||
description: 'Szybkie i rzetelne usługi hydrauliczne. Usuwanie awarii, naprawa wycieków, instalacje wod-kan, podłączanie sprzętu AGD. Pogotowie hydrauliczne 24/7.',
|
||||
alternates: {
|
||||
canonical: '/uslugi-domowe/hydraulika',
|
||||
}
|
||||
};
|
||||
|
||||
const hydraulikaServices = [
|
||||
{
|
||||
title: 'Usuwanie awarii',
|
||||
description: 'Szybko lokalizujemy i usuwamy przecieki, pęknięte rury oraz nieszczelności w instalacjach wodnych i CO.',
|
||||
icon: 'AlertTriangle',
|
||||
},
|
||||
{
|
||||
title: 'Udrażnianie rur',
|
||||
description: 'Skuteczne przepychanie zapchanych odpływów, zlewów, toalet oraz głównych pionów kanalizacyjnych.',
|
||||
icon: 'Waves',
|
||||
},
|
||||
{
|
||||
title: 'Biały montaż',
|
||||
description: 'Profesjonalny montaż wanien, kabin prysznicowych, umywalek, toalet oraz baterii i paneli natryskowych.',
|
||||
icon: 'Bath',
|
||||
},
|
||||
{
|
||||
title: 'Nowe instalacje wod-kan',
|
||||
description: 'Projektowanie i wykonywanie całych instalacji wodno-kanalizacyjnych w nowo budowanych lub remontowanych obiektach.',
|
||||
icon: 'Droplets',
|
||||
},
|
||||
{
|
||||
title: 'Przeróbki instalacji',
|
||||
description: 'Przenoszenie punktów wodnych i kanalizacyjnych, np. przy okazji remontu kuchni lub łazienki.',
|
||||
icon: 'Wrench',
|
||||
},
|
||||
{
|
||||
title: 'Podłączanie sprzętu',
|
||||
description: 'Zgodne ze sztuką podłączanie pralek, zmywarek oraz kostkarek do lodu, z zachowaniem gwarancji na sprzęt.',
|
||||
icon: 'WashingMachine',
|
||||
}
|
||||
];
|
||||
|
||||
export default function HydraulikaPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
title="Usługi hydrauliczne — instalacje, naprawy, awarie"
|
||||
subtitle="Twój sprawdzony hydraulik. Zajmujemy się wszystkim: od wymiany uszczelki i montażu baterii, po kompleksowe wykonanie nowej instalacji wod-kan."
|
||||
ctaText={`Zadzwoń: ${companyDetails.phone}`}
|
||||
ctaLink={`tel:${companyDetails.phoneRaw}`}
|
||||
secondaryCtaText="Napisz do nas"
|
||||
secondaryCtaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1585704032915-c3400ca199e7?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<EmergencyBlock />
|
||||
|
||||
<ServicesGrid
|
||||
services={hydraulikaServices}
|
||||
eyebrow="Zakres Usług"
|
||||
title="W czym dokładnie pomożemy?"
|
||||
/>
|
||||
|
||||
<ProcessSteps
|
||||
steps={homeProcessSteps}
|
||||
eyebrow="Realizacja"
|
||||
title="Szybko i bez stresu"
|
||||
/>
|
||||
|
||||
<WhyUs />
|
||||
|
||||
<FaqAccordion category="hydraulika" />
|
||||
|
||||
<CtaBanner
|
||||
title="Planujesz remont lub nową instalację?"
|
||||
subtitle="Zostaw nam numer telefonu, oddzwonimy i omówimy szczegóły zlecenia."
|
||||
ctaText="Zamów bezpłatną wycenę"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ServicesGrid } from '@/components/sections/ServicesGrid';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { WhyUs } from '@/components/sections/WhyUs';
|
||||
import { ProjectsGallery } from '@/components/sections/ProjectsGallery';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { homeProcessSteps } from '@/content/process';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Usługi Domowe — Remonty i Hydraulika | AirProject',
|
||||
description: 'Zaufaj specjalistom. Wykonujemy remonty, usługi hydrauliczne oraz serwis AGD z gwarancją jakości. Darmowa wycena i szybkie terminy realizacji.',
|
||||
alternates: {
|
||||
canonical: '/uslugi-domowe',
|
||||
}
|
||||
};
|
||||
|
||||
const domoweServices = [
|
||||
{
|
||||
title: 'Remonty i wykończenia',
|
||||
description: 'Kompleksowe remonty mieszkań, domów i biur. Malowanie, układanie płytek, gładzie, zabudowy GK i adaptacje poddaszy.',
|
||||
icon: 'PaintBucket',
|
||||
href: '/uslugi-domowe/remonty'
|
||||
},
|
||||
{
|
||||
title: 'Usługi hydrauliczne',
|
||||
description: 'Biały montaż, naprawa wycieków, instalacje wod-kan. Pogotowie hydrauliczne 24/7 dla naszych stałych klientów.',
|
||||
icon: 'Wrench',
|
||||
href: '/uslugi-domowe/hydraulika'
|
||||
},
|
||||
{
|
||||
title: 'Serwis AGD / Lodówki',
|
||||
description: 'Szybka i skuteczna naprawa lodówek, chłodziarek i zamrażarek w Twoim domu. Diagnoza usterki od ręki.',
|
||||
icon: 'Refrigerator',
|
||||
href: '/uslugi-domowe/serwis-agd'
|
||||
},
|
||||
{
|
||||
title: 'Drobne naprawy',
|
||||
description: 'Usługi "Złotej Rączki". Pomożemy w montażu mebli, wieszaniu telewizorów, rolet i innych drobnych pracach domowych.',
|
||||
icon: 'Hammer',
|
||||
href: '/kontakt'
|
||||
}
|
||||
];
|
||||
|
||||
export default function UslugiDomowePage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
title="Usługi domowe — remonty, hydraulika i naprawy w jednym miejscu"
|
||||
subtitle="Szukasz solidnej ekipy wykończeniowej lub doświadczonego hydraulika? Oferujemy najwyższą jakość prac instalacyjno-remontowych podpartą gwarancją."
|
||||
ctaText="Darmowa konsultacja"
|
||||
ctaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1581094794329-c8112a89af12?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<ServicesGrid
|
||||
services={domoweServices}
|
||||
eyebrow="Zakres Prac"
|
||||
title="W czym możemy Ci pomóc?"
|
||||
subtitle="Wybierz interesującą Cię usługę, aby poznać szczegóły, cennik oraz nasze dotychczasowe realizacje."
|
||||
/>
|
||||
|
||||
<ProcessSteps
|
||||
steps={homeProcessSteps}
|
||||
eyebrow="Współpraca"
|
||||
title="Jak pracujemy?"
|
||||
subtitle="Przejrzyste zasady i terminowość to fundamenty naszej pracy."
|
||||
/>
|
||||
|
||||
<WhyUs />
|
||||
|
||||
<ProjectsGallery
|
||||
category="remonty"
|
||||
title="Nasze realizacje"
|
||||
description="Przejrzyj galerię naszych prac wykończeniowych i instalacyjnych."
|
||||
/>
|
||||
|
||||
<CtaBanner
|
||||
title="Potrzebujesz pomocy fachowca?"
|
||||
subtitle="Zadzwoń do nas lub napisz. Odpowiadamy najszybciej jak to możliwe."
|
||||
ctaText="Skontaktuj się z nami"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ServicesGrid } from '@/components/sections/ServicesGrid';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { BeforeAfterSlider } from '@/components/sections/BeforeAfterSlider';
|
||||
import { WhyUs } from '@/components/sections/WhyUs';
|
||||
import { Testimonials } from '@/components/sections/Testimonials';
|
||||
import { FaqAccordion } from '@/components/sections/FaqAccordion';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { homeProcessSteps } from '@/content/process';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Remonty i Wykończenia Wnętrz | AirProject',
|
||||
description: 'Kompleksowe remonty i wykończenia wnętrz pod klucz. Gładzie, malowanie, układanie płytek, zabudowy GK. Własna, sprawdzona ekipa i gwarancja terminowości.',
|
||||
alternates: {
|
||||
canonical: '/uslugi-domowe/remonty',
|
||||
}
|
||||
};
|
||||
|
||||
const remontyServices = [
|
||||
{
|
||||
title: 'Wykończenia pod klucz',
|
||||
description: 'Realizujemy pełne adaptacje mieszkań deweloperskich, domów oraz przestrzeni biurowych od stanu surowego do wprowadzenia.',
|
||||
icon: 'Key',
|
||||
},
|
||||
{
|
||||
title: 'Remonty łazienek i kuchni',
|
||||
description: 'Najtrudniejsze pomieszczenia to nasza specjalność. Układamy glazurę, instalujemy biały montaż i przerabiamy instalacje.',
|
||||
icon: 'Bath',
|
||||
},
|
||||
{
|
||||
title: 'Malowanie i gładzie',
|
||||
description: 'Szpachlowanie natryskowe, gładzie gipsowe oraz perfekcyjne malowanie farbami tradycyjnymi i dekoracyjnymi.',
|
||||
icon: 'PaintRoller',
|
||||
},
|
||||
{
|
||||
title: 'Zabudowy G-K',
|
||||
description: 'Wykonujemy sufity podwieszane, ściany działowe, adaptacje poddaszy i nietypowe zabudowy z płyt kartonowo-gipsowych.',
|
||||
icon: 'Grid',
|
||||
},
|
||||
{
|
||||
title: 'Układanie podłóg',
|
||||
description: 'Montaż paneli podłogowych, deski barlineckiej, wykładzin oraz listew przypodłogowych.',
|
||||
icon: 'Layers',
|
||||
},
|
||||
{
|
||||
title: 'Prace wyburzeniowe',
|
||||
description: 'Bezpieczne wyburzanie ścian działowych, skuwanie starych posadzek i tynków wraz z wywozem gruzu.',
|
||||
icon: 'Hammer',
|
||||
}
|
||||
];
|
||||
|
||||
export default function RemontyPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
title="Remonty i wykończenia wnętrz"
|
||||
subtitle="Zmieniamy puste przestrzenie w wymarzone domy, a stare mieszkania poddajemy całkowitej metamorfozie. Solidnie, czysto i na czas."
|
||||
ctaText="Bezpłatna wycena"
|
||||
ctaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1505691938895-1758d7feb511?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<ServicesGrid
|
||||
services={remontyServices}
|
||||
eyebrow="Zakres Prac"
|
||||
title="Co możemy dla Ciebie zrobić?"
|
||||
subtitle="Wykonujemy praktycznie każdy rodzaj prac remontowo-budowlanych wewnątrz budynków."
|
||||
/>
|
||||
|
||||
<ProcessSteps
|
||||
steps={homeProcessSteps}
|
||||
eyebrow="Współpraca"
|
||||
title="Proces realizacji remontu"
|
||||
subtitle="Remont nie musi być stresujący. Dzięki naszemu doświadczeniu przeprowadzimy Cię przez niego gładko."
|
||||
/>
|
||||
|
||||
<BeforeAfterSlider />
|
||||
|
||||
<WhyUs />
|
||||
|
||||
<Testimonials />
|
||||
|
||||
<FaqAccordion category="remonty" />
|
||||
|
||||
<CtaBanner
|
||||
title="Masz w planach remont?"
|
||||
subtitle="Umów się na niezobowiązujące oględziny. Przygotujemy dla Ciebie darmowy kosztorys."
|
||||
ctaText="Zamów wycenę"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ServicesGrid } from '@/components/sections/ServicesGrid';
|
||||
import { SymptomsList } from '@/components/sections/SymptomsList';
|
||||
import { ProcessSteps } from '@/components/sections/ProcessSteps';
|
||||
import { WhyUs } from '@/components/sections/WhyUs';
|
||||
import { FaqAccordion } from '@/components/sections/FaqAccordion';
|
||||
import { CtaBanner } from '@/components/sections/CtaBanner';
|
||||
import { homeProcessSteps } from '@/content/process';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Serwis AGD, Naprawa Lodówek i Zamrażarek | AirProject',
|
||||
description: 'Mobilny serwis sprzętu chłodniczego. Dojeżdżamy do klienta i naprawiamy większość usterek na miejscu. Oryginalne części i gwarancja na naprawę.',
|
||||
alternates: {
|
||||
canonical: '/uslugi-domowe/serwis-agd',
|
||||
}
|
||||
};
|
||||
|
||||
const agdServices = [
|
||||
{
|
||||
title: 'Lodówki i chłodziarki',
|
||||
description: 'Naprawiamy wolnostojące i zabudowane lodówki wszystkich wiodących marek (Samsung, LG, Beko, Bosch, Indesit i inne).',
|
||||
icon: 'Refrigerator',
|
||||
},
|
||||
{
|
||||
title: 'Zamrażarki',
|
||||
description: 'Serwis zamrażarek skrzyniowych i szufladowych. Uzupełnianie czynnika chłodniczego, wymiana termostatów.',
|
||||
icon: 'Snowflake',
|
||||
},
|
||||
{
|
||||
title: 'Urządzenia No Frost',
|
||||
description: 'Znamy specyfikę nowoczesnych systemów bezszronowych. Diagnozujemy problemy z grzałkami, czujnikami i wentylatorami.',
|
||||
icon: 'Wind',
|
||||
},
|
||||
{
|
||||
title: 'Lady i witryny chłodnicze',
|
||||
description: 'Oferujemy wsparcie również dla mniejszych firm z branży gastro i handlu. Szybka reakcja, aby uratować towar.',
|
||||
icon: 'Store',
|
||||
},
|
||||
{
|
||||
title: 'Wymiana uszczelek',
|
||||
description: 'Dopasowanie i montaż nowych uszczelek drzwiowych, co pozwala obniżyć rachunki za prąd i zredukować oszranianie.',
|
||||
icon: 'ScanLine',
|
||||
},
|
||||
{
|
||||
title: 'Wymiana sprężarek',
|
||||
description: 'Nawet najpoważniejsze usterki agregatów nie są dla nas problemem. Wymieniamy kompresory i lutujemy układ.',
|
||||
icon: 'Settings',
|
||||
}
|
||||
];
|
||||
|
||||
export default function SerwisAgdPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
title="Serwis lodówek i urządzeń chłodniczych"
|
||||
subtitle="Twoja lodówka przestała chłodzić? Wydaje dziwne dźwięki? Naprawiamy sprzęt chłodniczy bezpośrednio w domu klienta."
|
||||
ctaText="Zgłoś naprawę"
|
||||
ctaLink="/kontakt"
|
||||
backgroundImage="https://images.unsplash.com/photo-1584269600464-37b1b58a9fe7?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<SymptomsList />
|
||||
|
||||
<ServicesGrid
|
||||
services={agdServices}
|
||||
eyebrow="Co naprawiamy?"
|
||||
title="Naprawimy każdy sprzęt chłodniczy"
|
||||
subtitle="Nie musisz martwić się o transport gabarytów. W 90% przypadków usterkę da się usunąć na miejscu."
|
||||
/>
|
||||
|
||||
<ProcessSteps
|
||||
steps={homeProcessSteps}
|
||||
eyebrow="Przebieg naprawy"
|
||||
title="Jak wygląda wezwanie serwisu?"
|
||||
/>
|
||||
|
||||
<WhyUs />
|
||||
|
||||
<FaqAccordion category="serwis-agd" />
|
||||
|
||||
<CtaBanner
|
||||
title="Masz problem ze swoim sprzętem?"
|
||||
subtitle="Podaj markę i objawy usterki, a postaramy się wycenić naprawę już przez telefon."
|
||||
ctaText="Napisz do nas"
|
||||
ctaLink="/kontakt"
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ContactSection } from '@/components/sections/ContactSection';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Zamówienie | AirProject',
|
||||
description: 'Dokończ swoje zamówienie na urządzenia i montaż, zostawiając nam swoje dane.',
|
||||
alternates: {
|
||||
canonical: '/zamowienie',
|
||||
}
|
||||
};
|
||||
|
||||
export default function CheckoutPage() {
|
||||
return (
|
||||
<main className="bg-slate-50 min-h-screen">
|
||||
<HeroSection
|
||||
eyebrow="Sklep"
|
||||
title="Dokończ zamówienie"
|
||||
subtitle="Zgodnie z wymogami prawnymi (F-Gazy) oraz chęcią zapewnienia najwyższej jakości obsługi, wszystkie zamówienia finalizujemy po krótkim kontakcie. Zostaw swoje dane, a my zajmiemy się resztą!"
|
||||
ctaText="Wróć do koszyka"
|
||||
ctaLink="/koszyk"
|
||||
backgroundImage="https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<div className="py-16 md:py-24 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="mb-12 text-center max-w-3xl mx-auto">
|
||||
<h2 className="text-3xl font-extrabold text-primary font-heading mb-4">Wypełnij formularz</h2>
|
||||
<p className="text-text-muted text-lg">
|
||||
Nasz doradca skontaktuje się z Tobą w ciągu maksymalnie 24 godzin, aby potwierdzić
|
||||
dostępność urządzeń z Twojego koszyka, omówić szczegóły montażu oraz zorganizować wysyłkę.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ContactSection />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user