feat: add Bio block and setup /o-nas and /uber-uns pages

This commit is contained in:
MichalC
2026-09-03 11:44:37 +02:00
parent e32f907625
commit 0a16cb1dc3
5 changed files with 171 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
'use client'
import React from 'react'
import { motion } from 'framer-motion'
import type { Page, Media } from '../../payload-types'
import Image from 'next/image'
type Props = Extract<NonNullable<Page['layout']>[0], { blockType: 'bio' }>
const customEase = [0.22, 1, 0.36, 1] as const
const sectionVariants = {
hidden: { opacity: 0, y: 24 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.6,
ease: customEase,
},
},
}
export const BioBlock: React.FC<Props> = ({ title, paragraphs, credentials, image }) => {
const bioMedia = typeof image === 'object' && image !== null ? (image as Media) : null
// PLACEHOLDER - do podmiany na realne zdjęcie Janusza Kędzierskiego (bez twarzy na etapie placeholderu)
const imageUrl = bioMedia?.url || 'https://images.unsplash.com/photo-1554224155-8d04cb21cd6c?auto=format&fit=crop&w=1200&q=80'
const imageAlt = bioMedia?.alt || 'Janusz Kędzierski - Doradztwo podatkowe'
return (
<motion.section
initial="hidden"
animate="visible"
variants={sectionVariants}
className="py-20 md:py-32 bg-background border-y border-border overflow-hidden"
>
<div className="container-premium">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-14 lg:gap-20 items-center">
{/* Kolumna ze zdjęciem */}
<div className="lg:col-span-5 order-2 lg:order-1">
<div className="relative aspect-[4/5] overflow-hidden border border-border rounded-none shadow-sm">
<Image
src={imageUrl}
alt={imageAlt}
fill
sizes="(max-width: 1024px) 100vw, 42vw"
className="object-cover grayscale hover:grayscale-0 transition-all duration-700"
/>
</div>
</div>
{/* Kolumna tekstowa */}
<div className="lg:col-span-7 order-1 lg:order-2 flex flex-col items-start max-w-3xl">
<h2 className="font-heading text-3xl sm:text-4xl md:text-5xl font-extrabold text-foreground tracking-tight mb-8 text-balance">
{title}
</h2>
{paragraphs && paragraphs.length > 0 && (
<div className="space-y-5 text-foreground/80 text-lg md:text-xl font-light leading-relaxed mb-10">
{paragraphs.map((p: any, index: number) => (
<p key={p.id || index}>
{p.text}
</p>
))}
</div>
)}
{credentials && credentials.length > 0 && (
<div className="flex flex-col gap-3.5 w-full pt-8 border-t border-border">
{credentials.map((cred: any, index: number) => (
<div key={cred.id || index} className="flex items-start gap-3 text-foreground/85 text-base">
<span className="w-2 h-2 rounded-full bg-accent mt-2 shrink-0" />
<span className="font-medium">{cred.text}</span>
</div>
))}
</div>
)}
</div>
</div>
</div>
</motion.section>
)
}
+46
View File
@@ -0,0 +1,46 @@
import type { Block } from 'payload'
export const Bio: Block = {
slug: 'bio',
fields: [
{
name: 'title',
type: 'text',
required: true,
localized: true,
defaultValue: 'Janusz Kędzierski',
},
{
name: 'paragraphs',
type: 'array',
required: true,
minRows: 1,
localized: true,
fields: [
{
name: 'text',
type: 'textarea',
required: true,
},
],
},
{
name: 'credentials',
type: 'array',
localized: true,
fields: [
{
name: 'text',
type: 'text',
required: true,
},
],
},
{
name: 'image',
type: 'upload',
relationTo: 'media',
required: true,
},
],
}
+2
View File
@@ -14,6 +14,7 @@ import { FinalCTABlock } from './FinalCTA/Component'
import { PageHeaderBlock } from './PageHeader/Component'
import { ContactInfoBlock } from './ContactInfo/Component'
import { BioBlock } from './Bio/Component'
import { ServicesDetailedBlock } from './ServicesDetailed/Component'
import { EligibilityBlock } from './Eligibility/Component'
import { StatsBlock } from './Stats/Component'
@@ -21,6 +22,7 @@ import { StatsBlock } from './Stats/Component'
const blockComponents = {
pageHeader: PageHeaderBlock,
contactInfo: ContactInfoBlock,
bio: BioBlock,
servicesDetailed: ServicesDetailedBlock,
eligibility: EligibilityBlock,
hero: HeroBlock,