diff --git a/scripts/seed.ts b/scripts/seed.ts index 2b7f004..22395d7 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -39,6 +39,26 @@ const homeLayoutPl = [ title: 'Rozliczenia bez bariery językowej', description: 'Niemieckie prawo podatkowe bywa skomplikowane. Przeprowadzę Cię przez cały proces w Twoim ojczystym języku, dbając o maksymalny zwrot i zero stresu.', }, + { + blockType: 'stats', + items: [ + { + stat: '20+', + label: 'Lat doświadczenia', + description: 'w prawie podatkowym i rozliczeniach dla Polaków w Niemczech', + }, + { + stat: '100%', + label: 'Obsługa po polsku', + description: 'bezpośredni kontakt i wyjaśnienie każdej kwestii podatkowej', + }, + { + stat: '§4 Nr. 11', + label: 'Stowarzyszenie b.b.h.', + description: 'oficjalna podstawa prawna doradztwa zgodnie ze StBerG', + }, + ], + }, { blockType: 'servicesList', title: 'Czym się zajmuję', @@ -113,6 +133,26 @@ const homeLayoutDe = [ title: 'Steuererklärungen ohne Sprachbarriere', description: 'Das deutsche Steuerrecht kann kompliziert sein. Ich begleite Sie durch den gesamten Prozess in Ihrer Muttersprache, sorge für die maximale Erstattung und garantiere null Stress.', }, + { + blockType: 'stats', + items: [ + { + stat: '20+', + label: 'Jahre Erfahrung', + description: 'in der Steuerberatung für in Deutschland arbeitende Polen', + }, + { + stat: '100%', + label: 'Auf Polnisch', + description: 'direkte Kommunikation in Ihrer vertrauten Muttersprache', + }, + { + stat: '§4 Nr. 11', + label: 'b.b.h. e.V.', + description: 'gesetzliche Beratungsbefugnis nach dem Steuerberatungsgesetz', + }, + ], + }, { blockType: 'servicesList', title: 'Was ich anbiete', diff --git a/src/blocks/Hero/Component.tsx b/src/blocks/Hero/Component.tsx index e35cdf6..f06031c 100644 --- a/src/blocks/Hero/Component.tsx +++ b/src/blocks/Hero/Component.tsx @@ -1,6 +1,5 @@ 'use client' -import React from 'react' -import { motion } from 'framer-motion' +import React, { useState, useEffect } from 'react' import type { Page } from '../../payload-types' import Link from 'next/link' import Image from 'next/image' @@ -8,7 +7,32 @@ import { Shield, MessageCircle } from 'lucide-react' type Props = Extract[0], { blockType: 'hero' }> +/* PLACEHOLDER - do podmiany na realne zdjęcia klienta */ +const heroImages = [ + { + url: 'https://images.unsplash.com/photo-1554224155-8d04cb21cd6c?auto=format&fit=crop&w=1200&q=80', + alt: 'Dokumenty podatkowe i praca biurowa', + }, + { + url: 'https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&w=1200&q=80', + alt: 'Profesjonalne biuro doradztwa podatkowego', + }, + { + url: 'https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?auto=format&fit=crop&w=1200&q=80', + alt: 'Praca z rozliczeniami podatkowymi', + }, +] + export const HeroBlock: React.FC = ({ title, subtitle, primaryCta, secondaryCta, yearsOfExperience }) => { + const [currentSlide, setCurrentSlide] = useState(0) + + useEffect(() => { + const timer = setInterval(() => { + setCurrentSlide((prev) => (prev + 1) % heroImages.length) + }, 5000) + return () => clearInterval(timer) + }, []) + return (
@@ -51,23 +75,46 @@ export const HeroBlock: React.FC = ({ title, subtitle, primaryCta, second
- {/* Kolumna ze zdjęciem */} + {/* Kolumna ze sliderem zdjęć */}
- {/* PLACEHOLDER - do podmiany na realne zdjęcia klienta */} - Biuro doradztwa podatkowego + {heroImages.map((img, idx) => ( +
+ {/* PLACEHOLDER - do podmiany na realne zdjęcia klienta */} + {img.alt} +
+ ))} + + {/* Kropki nawigacji slidera */} +
+ {heroImages.map((_, idx) => ( +
{/* Subtelna plakietka informacyjna */} -
+
JK
diff --git a/src/blocks/Process/Component.tsx b/src/blocks/Process/Component.tsx index 78a1ac3..a3fb370 100644 --- a/src/blocks/Process/Component.tsx +++ b/src/blocks/Process/Component.tsx @@ -1,61 +1,60 @@ 'use client' import React from 'react' -import { motion } from 'framer-motion' import Link from 'next/link' import type { Page } from '../../payload-types' +import { ArrowRight } from 'lucide-react' type Props = Extract[0], { blockType: 'process' }> export const ProcessBlock: React.FC = ({ title, steps, ctaText }) => { return ( -
-
- - {title} - - -
-
- {/* Linia łącząca na desktopie */} -
- - {steps?.map((step: NonNullable[0], index: number) => ( - -
- {index + 1} -
-

{step.title}

-

{step.description}

-
- ))} -
- - {ctaText && ( - - - {ctaText} - - - )} +
+
+
+

+ {title} +

+

+ Prosty i przejrzysty proces rozliczenia w 3 krokach — bez zbędnych formalności. +

+ +
+ {steps?.map((step: NonNullable[0], index: number) => { + const stepNumber = String(index + 1).padStart(2, '0') + + return ( +
+
+
+ {stepNumber} +
+

+ {step.title} +

+

+ {step.description} +

+
+
+ ) + })} +
+ + {ctaText && ( +
+ + {ctaText} + + +
+ )}
) diff --git a/src/blocks/RenderBlocks.tsx b/src/blocks/RenderBlocks.tsx index ccf89e7..91d8048 100644 --- a/src/blocks/RenderBlocks.tsx +++ b/src/blocks/RenderBlocks.tsx @@ -14,12 +14,14 @@ import { FinalCTABlock } from './FinalCTA/Component' import { PageHeaderBlock } from './PageHeader/Component' import { ServicesDetailedBlock } from './ServicesDetailed/Component' import { EligibilityBlock } from './Eligibility/Component' +import { StatsBlock } from './Stats/Component' const blockComponents = { pageHeader: PageHeaderBlock, servicesDetailed: ServicesDetailedBlock, eligibility: EligibilityBlock, hero: HeroBlock, + stats: StatsBlock, trustBar: TrustBarBlock, uniqueValue: UniqueValueBlock, servicesList: ServicesListBlock, diff --git a/src/blocks/Stats/Component.tsx b/src/blocks/Stats/Component.tsx new file mode 100644 index 0000000..0a41738 --- /dev/null +++ b/src/blocks/Stats/Component.tsx @@ -0,0 +1,58 @@ +import React from 'react' + +export interface StatsProps { + title?: string | null + subtitle?: string | null + items?: Array<{ + id?: string | null + stat: string + label: string + description?: string | null + }> | null +} + +export const StatsBlock: React.FC = ({ title, subtitle, items }) => { + if (!items || items.length === 0) return null + + return ( +
+
+ {(title || subtitle) && ( +
+ {title && ( +

+ {title} +

+ )} + {subtitle && ( +

+ {subtitle} +

+ )} +
+ )} + +
+ {items.map((item, index) => ( +
+
+ {item.stat} +
+
+ {item.label} +
+ {item.description && ( +

+ {item.description} +

+ )} +
+ ))} +
+
+
+ ) +} diff --git a/src/blocks/Stats/config.ts b/src/blocks/Stats/config.ts new file mode 100644 index 0000000..fa7e817 --- /dev/null +++ b/src/blocks/Stats/config.ts @@ -0,0 +1,21 @@ +import type { Block } from 'payload' + +export const Stats: Block = { + slug: 'stats', + fields: [ + { name: 'title', type: 'text' }, + { name: 'subtitle', type: 'textarea' }, + { + name: 'items', + type: 'array', + minRows: 1, + maxRows: 4, + required: true, + fields: [ + { name: 'stat', type: 'text', required: true }, + { name: 'label', type: 'text', required: true }, + { name: 'description', type: 'text' }, + ], + }, + ], +} diff --git a/src/collections/Pages.ts b/src/collections/Pages.ts index 5ca8d59..7f15714 100644 --- a/src/collections/Pages.ts +++ b/src/collections/Pages.ts @@ -13,6 +13,7 @@ import { FinalCTA } from '../blocks/FinalCTA/config' import { PageHeader } from '../blocks/PageHeader/config' import { ServicesDetailed } from '../blocks/ServicesDetailed/config' import { Eligibility } from '../blocks/Eligibility/config' +import { Stats } from '../blocks/Stats/config' export const Pages: CollectionConfig = { slug: 'pages', @@ -40,6 +41,7 @@ export const Pages: CollectionConfig = { ServicesDetailed, Eligibility, Hero, + Stats, TrustBar, UniqueValue, ServicesList, diff --git a/src/payload-types.ts b/src/payload-types.ts index 6f8cd7e..beceedd 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -266,6 +266,19 @@ export interface Page { blockName?: string | null; blockType: 'hero'; } + | { + title?: string | null; + subtitle?: string | null; + items: { + stat: string; + label: string; + description?: string | null; + id?: string | null; + }[]; + id?: string | null; + blockName?: string | null; + blockType: 'stats'; + } | { items?: | { @@ -602,6 +615,22 @@ export interface PagesSelect { id?: T; blockName?: T; }; + stats?: + | T + | { + title?: T; + subtitle?: T; + items?: + | T + | { + stat?: T; + label?: T; + description?: T; + id?: T; + }; + id?: T; + blockName?: T; + }; trustBar?: | T | {