feat: add Bio block and setup /o-nas and /uber-uns pages
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
| {
|
||||
|
||||
Reference in New Issue
Block a user