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,
+2
View File
@@ -16,6 +16,7 @@ import { ServicesDetailed } from '../blocks/ServicesDetailed/config'
import { Eligibility } from '../blocks/Eligibility/config'
import { Stats } from '../blocks/Stats/config'
import { TestimonialsGrid } from '../blocks/TestimonialsGrid/config'
import { Bio } from '../blocks/Bio/config'
export const Pages: CollectionConfig = {
slug: 'pages',
@@ -41,6 +42,7 @@ export const Pages: CollectionConfig = {
blocks: [
PageHeader,
ContactInfo,
Bio,
ServicesDetailed,
Eligibility,
Hero,
+37
View File
@@ -229,6 +229,23 @@ export interface Page {
blockName?: string | null;
blockType: 'contactInfo';
}
| {
title: string;
paragraphs: {
text: string;
id?: string | null;
}[];
credentials?:
| {
text: string;
id?: string | null;
}[]
| null;
image: number | Media;
id?: string | null;
blockName?: string | null;
blockType: 'bio';
}
| {
title: string;
subtitle?: string | null;
@@ -617,6 +634,26 @@ export interface PagesSelect<T extends boolean = true> {
id?: T;
blockName?: T;
};
bio?:
| T
| {
title?: T;
paragraphs?:
| T
| {
text?: T;
id?: T;
};
credentials?:
| T
| {
text?: T;
id?: T;
};
image?: T;
id?: T;
blockName?: T;
};
servicesDetailed?:
| T
| {