fix: ui tweaks including button styles, texts, and missing account link

This commit is contained in:
Radosław Smoliński
2026-06-22 00:45:57 +02:00
parent 25a0734a80
commit 6bdfe18e18
10 changed files with 129 additions and 32 deletions
+7 -12
View File
@@ -4,27 +4,23 @@ import { Header } from "@/components/layout/Header";
import { TrustBar } from "@/components/layout/TrustBar";
import { Footer } from "@/components/layout/Footer";
import { CookieBanner } from "@/components/ui/CookieBanner";
import { GoogleAnalytics, GoogleTagManager } from "@next/third-parties/google";
import { AnalyticsWrapper } from "@/components/ui/AnalyticsWrapper";
import "./globals.css";
const fontSans = Inter({
subsets: ["latin"],
variable: "--font-sans",
subsets: ["latin", "latin-ext"],
});
const fontHeading = Poppins({
variable: "--font-heading",
subsets: ["latin"],
weight: ["400", "500", "600", "700", "800"],
subsets: ["latin", "latin-ext"],
variable: "--font-heading",
});
export const metadata: Metadata = {
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"),
title: "ThermCool | Klimatyzacja i Pompy Ciepła",
description: "Zapewniamy profesjonalny montaż klimatyzacji, pomp ciepła oraz kompleksowe usługi remontowo-wykończeniowe. Sprawdź naszą ofertę!",
};
export default function RootLayout({
@@ -37,14 +33,13 @@ export default function RootLayout({
lang="pl"
className={`${fontSans.variable} ${fontHeading.variable} h-full antialiased`}
>
<GoogleTagManager gtmId="GTM-MBMRCD2N" />
<body className="min-h-full flex flex-col bg-background text-foreground">
<Header />
<main className="flex-grow">{children}</main>
<TrustBar />
<Footer />
<CookieBanner />
<GoogleAnalytics gaId="G-1NGTSR4TWD" />
<AnalyticsWrapper />
</body>
</html>
);
+1 -2
View File
@@ -176,11 +176,10 @@ export function ContactForm() {
{errors.consent && <p className="text-red-500 text-xs font-medium">{errors.consent.message}</p>}
</div>
{/* Button */}
<button
type="submit"
disabled={isSubmitting}
className="w-full bg-cta hover:bg-cta-hover text-white font-bold py-4 rounded-xl transition-colors flex items-center justify-center gap-2 disabled:opacity-70 disabled:cursor-not-allowed shadow-md"
className="btn btn-primary w-full text-white font-bold py-4 h-auto rounded-xl flex items-center justify-center gap-2 shadow-md"
>
{isSubmitting ? (
<>
+9 -5
View File
@@ -1,6 +1,7 @@
import Link from "next/link";
import { Phone, Mail, MapPin, Clock, Facebook, Instagram, ShieldCheck } from "lucide-react";
import { companyDetails } from "@/content/company";
import { CookieSettingsTrigger } from "@/components/ui/CookieSettingsTrigger";
export function Footer() {
const currentYear = new Date().getFullYear();
@@ -136,10 +137,10 @@ export function Footer() {
</ul>
</div>
{/* Column 4: Account */}
{/* Column 4: Obsługa Klienta */}
<div>
<h3 className="text-base font-semibold font-heading text-white mb-6 uppercase tracking-wider">
Twoje Konto
Obsługa Klienta
</h3>
<ul className="flex flex-col gap-3 text-sm text-slate-300">
<li>
@@ -165,9 +166,12 @@ export function Footer() {
{/* Bottom Bar */}
<div className="border-t border-slate-800 bg-slate-950/40 py-6">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row justify-between items-center gap-4">
<p className="text-xs text-slate-400 text-center sm:text-left">
© {currentYear} {companyDetails.name}. Wszelkie prawa zastrzeżone. Projekt strony i wdrożenie ThermCool.
</p>
<div className="flex flex-col gap-2">
<p className="text-xs text-slate-400 text-center sm:text-left">
© {currentYear} {companyDetails.name}. Wszelkie prawa zastrzeżone. Projekt strony i wdrożenie ThermCool.
</p>
<CookieSettingsTrigger />
</div>
<div className="flex items-center gap-6">
{/* Social Icons */}
-8
View File
@@ -140,14 +140,6 @@ export function Header() {
<div className="flex items-center gap-1">
<GlobalSearch />
<Link
href="/konto"
className="p-2 text-primary hover:text-accent hover:bg-background rounded-lg transition-colors outline-none"
aria-label="Konto użytkownika"
>
<User className="size-5" />
</Link>
<Link
href="/koszyk"
className="p-2 text-primary hover:text-accent hover:bg-background rounded-lg transition-colors relative outline-none"
+2 -2
View File
@@ -70,7 +70,7 @@ export function HeroSection({
<ul className="mt-6 grid grid-cols-2 gap-3 text-white/90 font-medium">
{features.map((feature, idx) => (
<li key={idx} className="flex items-center gap-2">
<Star className="size-4 text-accent fill-accent" />
<Star className="size-4 text-yellow-400 fill-yellow-400" />
{feature}
</li>
))}
@@ -98,7 +98,7 @@ export function HeroSection({
{/* Trust Bar (Hero specific) */}
<div className="mt-8 flex items-center gap-3 text-sm font-medium text-white/80">
<div className="flex items-center text-cta">
<div className="flex items-center text-yellow-400">
<Star className="size-4 fill-current" />
<Star className="size-4 fill-current" />
<Star className="size-4 fill-current" />
+2 -2
View File
@@ -25,9 +25,9 @@ export function Testimonials() {
<div className="relative z-10 flex flex-col gap-4">
{/* Stars */}
<div className="flex gap-1 text-cta">
<div className="flex gap-1 mb-4">
{Array.from({ length: test.rating }).map((_, iIdx) => (
<Star key={iIdx} className="size-4 fill-cta text-cta" />
<Star key={iIdx} className="size-4 fill-yellow-400 text-yellow-400" />
))}
</div>
+26
View File
@@ -0,0 +1,26 @@
"use client";
import { useEffect } from "react";
import { useConsentStore } from "@/lib/consent-store";
import { GoogleAnalytics, GoogleTagManager } from "@next/third-parties/google";
export function AnalyticsWrapper() {
const { analytics, marketing, isInitialized, initialize } = useConsentStore();
useEffect(() => {
initialize();
}, [initialize]);
if (!isInitialized) return null;
return (
<>
{/* Ładujemy GTM tylko jeśli zgoda na marketing ATAK LUB analitykę,
w zależności od rygorystyczności, zazwyczaj GTM potrzebuje analityki/marketingu */}
{(analytics || marketing) && <GoogleTagManager gtmId="GTM-MBMRCD2N" />}
{/* Ładujemy GA4 tylko jeśli użytkownik zgodził się na analitykę */}
{analytics && <GoogleAnalytics gaId="G-1NGTSR4TWD" />}
</>
);
}
+16
View File
@@ -0,0 +1,16 @@
"use client";
import { useConsentStore } from "@/lib/consent-store";
export function CookieSettingsTrigger() {
const openBanner = useConsentStore((state) => state.openBanner);
return (
<button
onClick={openBanner}
className="text-slate-400 hover:text-accent transition-colors text-xs text-center sm:text-left underline underline-offset-2"
>
Zarządzaj plikami cookies
</button>
);
}
+1 -1
View File
@@ -126,7 +126,7 @@ export const homeProcessSteps: ProcessStep[] = [
{
number: 3,
title: "Terminowa realizacja",
description: "Wchodzimy na budowę w umówionym terminie. Dbamy o porządek i przestrzeganie norm budowlanych.",
description: "Rozpoczynamy prace u klienta w umówionym terminie. Zabezpieczamy przestrzeń, dbamy o porządek i najwyższą jakość wykonania.",
},
{
number: 4,
+65
View File
@@ -0,0 +1,65 @@
import { create } from 'zustand';
interface ConsentState {
isInitialized: boolean;
isOpen: boolean;
analytics: boolean;
marketing: boolean;
initialize: () => void;
openBanner: () => void;
closeBanner: () => void;
setConsent: (analytics: boolean, marketing: boolean) => void;
acceptAll: () => void;
rejectOptional: () => void;
}
const CONSENT_KEY = 'airproject_cookie_consent_v2';
export const useConsentStore = create<ConsentState>((set) => ({
isInitialized: false,
isOpen: false,
analytics: false,
marketing: false,
initialize: () => {
if (typeof window !== 'undefined') {
const stored = localStorage.getItem(CONSENT_KEY);
if (stored) {
try {
const parsed = JSON.parse(stored);
set({
isInitialized: true,
isOpen: false,
analytics: !!parsed.analytics,
marketing: !!parsed.marketing,
});
} catch (e) {
// If parsing fails, show banner
set({ isInitialized: true, isOpen: true });
}
} else {
// No consent found, show banner
set({ isInitialized: true, isOpen: true });
}
}
},
openBanner: () => set({ isOpen: true }),
closeBanner: () => set({ isOpen: false }),
setConsent: (analytics, marketing) => {
localStorage.setItem(CONSENT_KEY, JSON.stringify({ essential: true, analytics, marketing }));
set({ analytics, marketing, isOpen: false });
},
acceptAll: () => {
localStorage.setItem(CONSENT_KEY, JSON.stringify({ essential: true, analytics: true, marketing: true }));
set({ analytics: true, marketing: true, isOpen: false });
},
rejectOptional: () => {
localStorage.setItem(CONSENT_KEY, JSON.stringify({ essential: true, analytics: false, marketing: false }));
set({ analytics: false, marketing: false, isOpen: false });
}
}));