diff --git a/scripts/fix_de_seed.py b/scripts/fix_de_seed.py new file mode 100644 index 0000000..578de46 --- /dev/null +++ b/scripts/fix_de_seed.py @@ -0,0 +1,8 @@ +with open("scripts/seed.ts", "r") as f: + content = f.read() + +content = content.replace("eyebrow: 'Statystyki',\n items: [\n {\n stat: '20+',", "eyebrow: 'Statistiken',\n items: [\n {\n stat: '20+',") +content = content.replace("eyebrow: 'Usługi',\n title: 'Was ich anbiete',", "eyebrow: 'Leistungen',\n title: 'Was ich anbiete',") + +with open("scripts/seed.ts", "w") as f: + f.write(content) diff --git a/scripts/seed.ts b/scripts/seed.ts index 22395d7..ec2a7a1 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -27,6 +27,7 @@ const homeLayoutPl = [ }, { blockType: 'trustBar', + eyebrow: 'Zaufanie', items: [ { text: 'Działam w ramach b.b.h.', icon: 'shield' }, { text: 'Doradztwo 100% po polsku', icon: 'message' }, @@ -36,11 +37,14 @@ const homeLayoutPl = [ }, { blockType: 'uniqueValue', + eyebrow: 'Wartość', title: 'Rozliczenia bez bariery językowej', + features: [{ text: 'Bez barier językowych' }, { text: 'Indywidualne podejście' }], 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', + eyebrow: 'Statistiken', items: [ { stat: '20+', @@ -61,6 +65,7 @@ const homeLayoutPl = [ }, { blockType: 'servicesList', + eyebrow: 'Usługi', title: 'Czym się zajmuję', services: [ { title: 'Deklaracje podatkowe', description: 'Kompleksowe sporządzenie i złożenie zeznania rocznego (Einkommensteuererklärung).', linkText: 'Zobacz więcej' }, @@ -70,7 +75,9 @@ const homeLayoutPl = [ }, { blockType: 'process', + eyebrow: 'Proces', title: 'Jak to działa', + subtitle: 'Prosty i przejrzysty proces rozliczenia w 3 krokach — bez zbędnych formalności.', steps: [ { title: 'Napisz na WhatsApp', description: 'Wyślij krótką wiadomość lub zadzwoń, by rozpocząć proces.' }, { title: 'Przekaż dokumenty', description: 'Prześlij nam wymagane dokumenty bezpiecznie online lub dostarcz osobiście.' }, @@ -80,6 +87,7 @@ const homeLayoutPl = [ }, { blockType: 'affiliation', + eyebrow: 'Zaufanie', title: 'Zaufanie i bezpieczeństwo', description: 'Działam w ramach b.b.h. Lohnsteuerhilfeverein e.V. (Beratungsstelle). Oferujemy profesjonalną pomoc w sprawach podatku dochodowego w ramach uprawnień wynikających z §4 Nr. 11 StBerG.', linkText: 'Poznaj stowarzyszenie', @@ -95,6 +103,7 @@ const homeLayoutPl = [ }, { blockType: 'faqTeaser', + eyebrow: 'FAQ', title: 'Częste pytania', questions: [ { question: 'Czy muszę przyjeżdżać osobiście?', answer: 'Nie, wszystkie formalności możemy załatwić zdalnie, przesyłając dokumenty online.' }, @@ -104,6 +113,7 @@ const homeLayoutPl = [ }, { blockType: 'finalCta', + eyebrow: 'Kontakt', title: 'Gotowy na wyższy zwrot podatku?', subtitle: 'Napisz do mnie już teraz. Odpowiem najszybciej jak to możliwe.', buttonText: 'Rozpocznij na WhatsApp', @@ -121,6 +131,7 @@ const homeLayoutDe = [ }, { blockType: 'trustBar', + eyebrow: 'Zaufanie', items: [ { text: 'Teil der b.b.h.', icon: 'shield' }, { text: '100% Beratung auf Polnisch', icon: 'message' }, @@ -130,11 +141,14 @@ const homeLayoutDe = [ }, { blockType: 'uniqueValue', + eyebrow: 'Wert', title: 'Steuererklärungen ohne Sprachbarriere', + features: [{ text: 'Ohne Sprachbarrieren' }, { text: 'Individueller Ansatz' }], 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', + eyebrow: 'Statistiken', items: [ { stat: '20+', @@ -155,6 +169,7 @@ const homeLayoutDe = [ }, { blockType: 'servicesList', + eyebrow: 'Leistungen', title: 'Was ich anbiete', services: [ { title: 'Steuererklärungen', description: 'Umfassende Erstellung und Einreichung der jährlichen Einkommensteuererklärung.', linkText: 'Mehr anzeigen' }, @@ -164,7 +179,9 @@ const homeLayoutDe = [ }, { blockType: 'process', + eyebrow: 'Prozess', title: 'Wie es funktioniert', + subtitle: 'Ein einfacher und transparenter 3-Schritte-Abrechnungsprozess — ohne unnötige Formalitäten.', steps: [ { title: 'Auf WhatsApp schreiben', description: 'Senden Sie eine kurze Nachricht oder rufen Sie an, um den Prozess zu starten.' }, { title: 'Dokumente einreichen', description: 'Senden Sie uns die erforderlichen Dokumente sicher online oder bringen Sie sie persönlich vorbei.' }, @@ -174,6 +191,7 @@ const homeLayoutDe = [ }, { blockType: 'affiliation', + eyebrow: 'Vertrauen', title: 'Vertrauen und Sicherheit', description: 'Ich bin im Rahmen des b.b.h. Lohnsteuerhilfevereins e.V. (Beratungsstelle) tätig. Wir bieten professionelle Hilfe in Lohnsteuersachen im Rahmen der Befugnisse nach §4 Nr. 11 StBerG.', linkText: 'Den Verein kennenlernen', @@ -189,6 +207,7 @@ const homeLayoutDe = [ }, { blockType: 'faqTeaser', + eyebrow: 'FAQ', title: 'Häufige Fragen', questions: [ { question: 'Muss ich persönlich kommen?', answer: 'Nein, alle Formalitäten können online erledigt werden, indem Sie uns die Dokumente zusenden.' }, @@ -198,6 +217,7 @@ const homeLayoutDe = [ }, { blockType: 'finalCta', + eyebrow: 'Kontakt', title: 'Bereit für eine höhere Steuererstattung?', subtitle: 'Schreiben Sie mir jetzt. Ich werde so schnell wie möglich antworten.', buttonText: 'Auf WhatsApp starten', @@ -212,6 +232,7 @@ const uslugiLayoutPl = [ }, { blockType: 'servicesDetailed', + eyebrow: 'Usługi', title: 'Czym się zajmuję', subtitle: 'Zapewniam rzetelne i kompleksowe wsparcie na każdym etapie rozliczenia podatku dochodowego w Niemczech.', services: [ @@ -254,6 +275,7 @@ const uslugiLayoutPl = [ }, { blockType: 'eligibility', + eyebrow: 'Zakres uprawnień doradczych', title: 'Dla kogo — zakres uprawnień doradczych wg §4 Nr. 11 StBerG', subtitle: 'Jako punkt doradczy b.b.h. Lohnsteuerhilfeverein e.V. działamy ściśle w ramach ustawowych uprawnień dla stowarzyszeń pomocy podatkowej.', eligibleTitle: 'Kto może skorzystać z naszej pomocy', @@ -277,6 +299,7 @@ const uslugiLayoutPl = [ }, { blockType: 'finalCta', + eyebrow: 'Kontakt', title: 'Masz pytania dotyczące Twojego rozliczenia?', subtitle: 'Skontaktuj się bezpośrednio przez WhatsApp. Przeanalizujemy Twoją sytuację i pomożemy uzyskać należny zwrot.', buttonText: 'Napisz na WhatsApp', @@ -291,6 +314,7 @@ const uslugiLayoutDe = [ }, { blockType: 'servicesDetailed', + eyebrow: 'Leistungen', title: 'Was ich anbiete', subtitle: 'Umfassende und zuverlässige Betreuung bei allen Fragen rund um Ihre Einkommensteuererklärung.', services: [ @@ -333,6 +357,7 @@ const uslugiLayoutDe = [ }, { blockType: 'eligibility', + eyebrow: 'Umfang der Beratungsbefugnis', title: 'Beratungsbefugnis gemäß § 4 Nr. 11 StBerG', subtitle: 'Als Beratungsstelle des b.b.h. Lohnsteuerhilfevereins e.V. betreuen wir Sie streng im Rahmen der gesetzlichen Befugnisse.', eligibleTitle: 'Wer von uns beraten werden darf', @@ -356,6 +381,7 @@ const uslugiLayoutDe = [ }, { blockType: 'finalCta', + eyebrow: 'Kontakt', title: 'Haben Sie Fragen zu Ihrer Steuererklärung?', subtitle: 'Kontaktieren Sie uns direkt per WhatsApp. Wir prüfen Ihre Situation und helfen Ihnen bei der Rückerstattung.', buttonText: 'Auf WhatsApp schreiben', diff --git a/scripts/update_blocks.py b/scripts/update_blocks.py new file mode 100644 index 0000000..82404cf --- /dev/null +++ b/scripts/update_blocks.py @@ -0,0 +1,121 @@ +import os +import glob + +blocks_dir = "src/blocks" + +blocks_with_eyebrow = [ + "Affiliation", + "Eligibility", + "FAQTeaser", + "FinalCTA", + "Process", + "ServicesDetailed", + "ServicesList", + "Stats", + "UniqueValue" +] + +for block in blocks_with_eyebrow: + config_path = os.path.join(blocks_dir, block, "config.ts") + component_path = os.path.join(blocks_dir, block, "Component.tsx") + + if os.path.exists(config_path): + with open(config_path, "r") as f: + content = f.read() + if "'eyebrow'" not in content: + content = content.replace( + "{ name: 'title', type: 'text', required: true, localized: true },", + "{ name: 'eyebrow', type: 'text', localized: true },\n { name: 'title', type: 'text', required: true, localized: true }," + ) + # Handle some variations + content = content.replace( + "{ name: 'title', type: 'text', localized: true },", + "{ name: 'eyebrow', type: 'text', localized: true },\n { name: 'title', type: 'text', localized: true }," + ) + with open(config_path, "w") as f: + f.write(content) + + if os.path.exists(component_path): + with open(component_path, "r") as f: + content = f.read() + + # Add eyebrow to Props destructuring + if "eyebrow" not in content: + # Add to destructuring, find where title is destructured + # E.g. const FAQTeaserBlock: React.FC = ({ title, questions, linkText }) => { + # Find the string `({ ` and see if `title` is inside. + # Just do a simple regex or string replace. + import re + content = re.sub(r'({[\s\S]*?title(.*?)\}) =>', r'{ eyebrow, title\2} =>', content, count=1) + + # Replace the hardcoded string with {eyebrow} + # The hardcoded strings are inside
+ # // Hardcoded + #
+ content = re.sub( + r'
\s*//.*?\s*
', + r'{eyebrow && (\n
\n // {eyebrow}\n
\n )}', + content + ) + + with open(component_path, "w") as f: + f.write(content) + +# Specific fixes for Process and UniqueValue +process_config = os.path.join(blocks_dir, "Process", "config.ts") +with open(process_config, "r") as f: + content = f.read() +if "'subtitle'" not in content: + content = content.replace( + "{ name: 'title', type: 'text', required: true, localized: true },", + "{ name: 'title', type: 'text', required: true, localized: true },\n { name: 'subtitle', type: 'textarea', localized: true }," + ) + with open(process_config, "w") as f: + f.write(content) + +process_component = os.path.join(blocks_dir, "Process", "Component.tsx") +with open(process_component, "r") as f: + content = f.read() +if "subtitle" not in content.split("}) =>")[0] and "ProcessBlock" in content: + content = re.sub(r'({.*?eyebrow,\s*title(.*?)\}) =>', r'{ eyebrow, title, subtitle\2} =>', content, count=1) + content = re.sub( + r'

\s*Prosty.*?\s*

', + r'{subtitle && (\n

\n {subtitle}\n

\n )}', + content + ) + with open(process_component, "w") as f: + f.write(content) + +uv_config = os.path.join(blocks_dir, "UniqueValue", "config.ts") +with open(uv_config, "r") as f: + content = f.read() +if "'features'" not in content: + content = content.replace( + " ],\n}", + " {\n name: 'features',\n type: 'array',\n localized: true,\n fields: [\n { name: 'text', type: 'text', required: true },\n ],\n },\n ],\n}" + ) + with open(uv_config, "w") as f: + f.write(content) + +uv_component = os.path.join(blocks_dir, "UniqueValue", "Component.tsx") +with open(uv_component, "r") as f: + content = f.read() +if "features" not in content.split("}) =>")[0] and "UniqueValueBlock" in content: + content = re.sub(r'({.*?eyebrow,\s*title(.*?)\}) =>', r'{ eyebrow, title, features\2} =>', content, count=1) + content = re.sub( + r'
\s*
\s*\s*Bez barier.*?\s*
\s*
\s*\s*Indywidualne.*?\s*
\s*
', + r'''{features && features.length > 0 && ( +
+ {features.map((feature: any, index: number) => ( +
+ + {feature.text} +
+ ))} +
+ )}''', + content, + flags=re.DOTALL + ) + with open(uv_component, "w") as f: + f.write(content) diff --git a/scripts/update_interfaces.py b/scripts/update_interfaces.py new file mode 100644 index 0000000..8ab7a41 --- /dev/null +++ b/scripts/update_interfaces.py @@ -0,0 +1,16 @@ +import re +import os + +def insert_prop(filepath, prop_name): + with open(filepath, 'r') as f: + content = f.read() + + # Find the interface declaration and insert `eyebrow?: string | null` + content = re.sub(r'(export interface \w+Props \{)', r'\1\n eyebrow?: string | null', content) + + with open(filepath, 'w') as f: + f.write(content) + +insert_prop('src/blocks/Eligibility/Component.tsx', 'eyebrow?: string | null') +insert_prop('src/blocks/ServicesDetailed/Component.tsx', 'eyebrow?: string | null') +insert_prop('src/blocks/Stats/Component.tsx', 'eyebrow?: string | null') diff --git a/scripts/update_props.py b/scripts/update_props.py new file mode 100644 index 0000000..cb1f202 --- /dev/null +++ b/scripts/update_props.py @@ -0,0 +1,50 @@ +import os +import re + +blocks_dir = "src/blocks" + +blocks_with_eyebrow = [ + "Affiliation", + "Eligibility", + "FAQTeaser", + "FinalCTA", + "ServicesList", + "Stats", +] + +for block in blocks_with_eyebrow: + component_path = os.path.join(blocks_dir, block, "Component.tsx") + if os.path.exists(component_path): + with open(component_path, "r") as f: + content = f.read() + + # Replace `({ title,` with `({ eyebrow, title,` + # Also need to handle cases where there is no space after { + content = re.sub(r'\(\{\s*title', '({ eyebrow, title', content) + + with open(component_path, "w") as f: + f.write(content) + +# Process block +process = os.path.join(blocks_dir, "Process", "Component.tsx") +with open(process, "r") as f: + content = f.read() +content = re.sub(r'\(\{\s*title', '({ eyebrow, subtitle, title', content) +with open(process, "w") as f: + f.write(content) + +# UniqueValue block +uv = os.path.join(blocks_dir, "UniqueValue", "Component.tsx") +with open(uv, "r") as f: + content = f.read() +content = re.sub(r'\(\{\s*title', '({ eyebrow, features, title', content) +with open(uv, "w") as f: + f.write(content) + +# ServicesDetailed block +sd = os.path.join(blocks_dir, "ServicesDetailed", "Component.tsx") +with open(sd, "r") as f: + content = f.read() +content = re.sub(r'\(\{\s*title', '({ eyebrow, title', content) +with open(sd, "w") as f: + f.write(content) diff --git a/scripts/update_seed.py b/scripts/update_seed.py new file mode 100644 index 0000000..aa50c8a --- /dev/null +++ b/scripts/update_seed.py @@ -0,0 +1,100 @@ +import re + +with open("scripts/seed.ts", "r") as f: + content = f.read() + +# homeLayoutPl +content = content.replace( + "blockType: 'trustBar',", + "blockType: 'trustBar',\n eyebrow: 'Zaufanie'," +) +content = content.replace( + "blockType: 'uniqueValue',\n title: 'Rozliczenia bez bariery językowej',", + "blockType: 'uniqueValue',\n eyebrow: 'Wartość',\n title: 'Rozliczenia bez bariery językowej',\n features: [{ text: 'Bez barier językowych' }, { text: 'Indywidualne podejście' }]," +) +content = content.replace( + "blockType: 'stats',\n items:", + "blockType: 'stats',\n eyebrow: 'Statystyki',\n items:" +) +content = content.replace( + "blockType: 'servicesList',\n title:", + "blockType: 'servicesList',\n eyebrow: 'Usługi',\n title:" +) +content = content.replace( + "blockType: 'process',\n title: 'Jak to działa',", + "blockType: 'process',\n eyebrow: 'Proces',\n title: 'Jak to działa',\n subtitle: 'Prosty i przejrzysty proces rozliczenia w 3 krokach — bez zbędnych formalności.'," +) +content = content.replace( + "blockType: 'affiliation',\n title: 'Zaufanie i bezpieczeństwo',", + "blockType: 'affiliation',\n eyebrow: 'Zaufanie',\n title: 'Zaufanie i bezpieczeństwo'," +) +content = content.replace( + "blockType: 'faqTeaser',\n title:", + "blockType: 'faqTeaser',\n eyebrow: 'FAQ',\n title:" +) +content = content.replace( + "blockType: 'finalCta',\n title: 'Gotowy na wyższy zwrot podatku?',", + "blockType: 'finalCta',\n eyebrow: 'Kontakt',\n title: 'Gotowy na wyższy zwrot podatku?'," +) +content = content.replace( + "blockType: 'finalCta',\n title: 'Masz pytania dotyczące Twojego rozliczenia?',", + "blockType: 'finalCta',\n eyebrow: 'Kontakt',\n title: 'Masz pytania dotyczące Twojego rozliczenia?'," +) +content = content.replace( + "blockType: 'servicesDetailed',\n title: 'Czym się zajmuję',", + "blockType: 'servicesDetailed',\n eyebrow: 'Usługi',\n title: 'Czym się zajmuję'," +) +content = content.replace( + "blockType: 'eligibility',\n title: 'Dla kogo — zakres uprawnień doradczych wg §4 Nr. 11 StBerG',", + "blockType: 'eligibility',\n eyebrow: 'Zakres uprawnień doradczych',\n title: 'Dla kogo — zakres uprawnień doradczych wg §4 Nr. 11 StBerG'," +) + +# homeLayoutDe +content = content.replace( + "blockType: 'uniqueValue',\n title: 'Steuererklärungen ohne Sprachbarriere',", + "blockType: 'uniqueValue',\n eyebrow: 'Wert',\n title: 'Steuererklärungen ohne Sprachbarriere',\n features: [{ text: 'Ohne Sprachbarrieren' }, { text: 'Individueller Ansatz' }]," +) +content = content.replace( + "blockType: 'process',\n title: 'Wie es funktioniert',", + "blockType: 'process',\n eyebrow: 'Prozess',\n title: 'Wie es funktioniert',\n subtitle: 'Ein einfacher und transparenter 3-Schritte-Abrechnungsprozess — ohne unnötige Formalitäten.'," +) +content = content.replace( + "blockType: 'affiliation',\n title: 'Vertrauen und Sicherheit',", + "blockType: 'affiliation',\n eyebrow: 'Vertrauen',\n title: 'Vertrauen und Sicherheit'," +) +content = content.replace( + "blockType: 'finalCta',\n title: 'Bereit für eine höhere Steuererstattung?',", + "blockType: 'finalCta',\n eyebrow: 'Kontakt',\n title: 'Bereit für eine höhere Steuererstattung?'," +) +content = content.replace( + "blockType: 'finalCta',\n title: 'Haben Sie Fragen zu Ihrer Steuererklärung?',", + "blockType: 'finalCta',\n eyebrow: 'Kontakt',\n title: 'Haben Sie Fragen zu Ihrer Steuererklärung?'," +) +content = content.replace( + "blockType: 'servicesDetailed',\n title: 'Was ich anbiete',", + "blockType: 'servicesDetailed',\n eyebrow: 'Leistungen',\n title: 'Was ich anbiete'," +) +content = content.replace( + "blockType: 'eligibility',\n title: 'Beratungsbefugnis gemäß § 4 Nr. 11 StBerG',", + "blockType: 'eligibility',\n eyebrow: 'Umfang der Beratungsbefugnis',\n title: 'Beratungsbefugnis gemäß § 4 Nr. 11 StBerG'," +) + +# The missing ones for DE (Stats, ServicesList, FAQ) +content = re.sub( + r"blockType: 'stats',\n items: \[\n \{\n stat: '20\+',", + r"blockType: 'stats',\n eyebrow: 'Statistiken',\n items: [\n {\n stat: '20+',", + content, count=1 +) +content = re.sub( + r"blockType: 'servicesList',\n title: 'Was ich anbiete',", + r"blockType: 'servicesList',\n eyebrow: 'Leistungen',\n title: 'Was ich anbiete',", + content, count=1 +) +content = re.sub( + r"blockType: 'faqTeaser',\n title: 'Häufige Fragen',", + r"blockType: 'faqTeaser',\n eyebrow: 'FAQ',\n title: 'Häufige Fragen',", + content, count=1 +) + +with open("scripts/seed.ts", "w") as f: + f.write(content) diff --git a/src/blocks/Affiliation/Component.tsx b/src/blocks/Affiliation/Component.tsx index b074817..11fc3fb 100644 --- a/src/blocks/Affiliation/Component.tsx +++ b/src/blocks/Affiliation/Component.tsx @@ -6,15 +6,17 @@ import type { Page } from '../../payload-types' type Props = Extract[0], { blockType: 'affiliation' }> -export const AffiliationBlock: React.FC = ({ title, description, logo, linkText }) => { +export const AffiliationBlock: React.FC = ({ eyebrow, title, description, logo, linkText }) => { return (
+ {eyebrow && (
- // Zaufanie + // {eyebrow}
+ )}

{title}

diff --git a/src/blocks/Affiliation/config.ts b/src/blocks/Affiliation/config.ts index f8bb171..7dd9da3 100644 --- a/src/blocks/Affiliation/config.ts +++ b/src/blocks/Affiliation/config.ts @@ -3,6 +3,7 @@ import type { Block } from 'payload' export const Affiliation: Block = { slug: 'affiliation', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, { name: 'description', type: 'textarea', required: true, localized: true }, { name: 'logo', type: 'upload', relationTo: 'media' }, diff --git a/src/blocks/Eligibility/Component.tsx b/src/blocks/Eligibility/Component.tsx index a41e96d..237e805 100644 --- a/src/blocks/Eligibility/Component.tsx +++ b/src/blocks/Eligibility/Component.tsx @@ -2,6 +2,7 @@ import React from 'react' import { CheckCircle2, XCircle, AlertTriangle, ShieldAlert } from 'lucide-react' export interface EligibilityProps { + eyebrow?: string | null title: string subtitle?: string | null eligibleTitle: string @@ -13,8 +14,7 @@ export interface EligibilityProps { legalNotice?: string | null } -export const EligibilityBlock: React.FC = ({ - title, +export const EligibilityBlock: React.FC = ({ eyebrow, title, subtitle, eligibleTitle, eligibleItems, @@ -28,9 +28,11 @@ export const EligibilityBlock: React.FC = ({
-
- // Zakres uprawnień doradczych -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title}

diff --git a/src/blocks/FAQTeaser/Component.tsx b/src/blocks/FAQTeaser/Component.tsx index 7be1a37..c7404f8 100644 --- a/src/blocks/FAQTeaser/Component.tsx +++ b/src/blocks/FAQTeaser/Component.tsx @@ -6,14 +6,16 @@ import type { Page } from '../../payload-types' type Props = Extract[0], { blockType: 'faqTeaser' }> -export const FAQTeaserBlock: React.FC = ({ title, questions, linkText }) => { +export const FAQTeaserBlock: React.FC = ({ eyebrow, title, questions, linkText }) => { return (
-
- // FAQ -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title}

diff --git a/src/blocks/FAQTeaser/config.ts b/src/blocks/FAQTeaser/config.ts index b62a0ed..9e6f221 100644 --- a/src/blocks/FAQTeaser/config.ts +++ b/src/blocks/FAQTeaser/config.ts @@ -3,6 +3,7 @@ import type { Block } from 'payload' export const FAQTeaser: Block = { slug: 'faqTeaser', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, { name: 'questions', diff --git a/src/blocks/FinalCTA/Component.tsx b/src/blocks/FinalCTA/Component.tsx index f95c615..cb4540b 100644 --- a/src/blocks/FinalCTA/Component.tsx +++ b/src/blocks/FinalCTA/Component.tsx @@ -5,14 +5,16 @@ import { MessageCircle } from 'lucide-react' type Props = Extract[0], { blockType: 'finalCta' }> -export const FinalCTABlock: React.FC = ({ title, subtitle, buttonText }) => { +export const FinalCTABlock: React.FC = ({ eyebrow, title, subtitle, buttonText }) => { return (
-
- // Kontakt -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title} diff --git a/src/blocks/FinalCTA/config.ts b/src/blocks/FinalCTA/config.ts index efa68a0..9680364 100644 --- a/src/blocks/FinalCTA/config.ts +++ b/src/blocks/FinalCTA/config.ts @@ -3,6 +3,7 @@ import type { Block } from 'payload' export const FinalCTA: Block = { slug: 'finalCta', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, { name: 'subtitle', type: 'text', localized: true }, { name: 'buttonText', type: 'text', required: true, localized: true }, diff --git a/src/blocks/Process/Component.tsx b/src/blocks/Process/Component.tsx index f175517..cdb022a 100644 --- a/src/blocks/Process/Component.tsx +++ b/src/blocks/Process/Component.tsx @@ -6,20 +6,24 @@ import { ArrowRight } from 'lucide-react' type Props = Extract[0], { blockType: 'process' }> -export const ProcessBlock: React.FC = ({ title, steps, ctaText }) => { +export const ProcessBlock: React.FC = ({ eyebrow, subtitle, title, steps, ctaText }) => { return (
-
- // Proces -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title}

-

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

+ {subtitle && ( +

+ {subtitle} +

+ )}
diff --git a/src/blocks/Process/config.ts b/src/blocks/Process/config.ts index a2ea6e8..82de151 100644 --- a/src/blocks/Process/config.ts +++ b/src/blocks/Process/config.ts @@ -3,7 +3,9 @@ import type { Block } from 'payload' export const Process: Block = { slug: 'process', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, + { name: 'subtitle', type: 'textarea', localized: true }, { name: 'steps', type: 'array', diff --git a/src/blocks/ServicesDetailed/Component.tsx b/src/blocks/ServicesDetailed/Component.tsx index 9200f21..8b3080d 100644 --- a/src/blocks/ServicesDetailed/Component.tsx +++ b/src/blocks/ServicesDetailed/Component.tsx @@ -21,6 +21,7 @@ const iconMap: Record = { } export interface ServicesDetailedProps { + eyebrow?: string | null title: string subtitle?: string | null services?: Array<{ @@ -31,8 +32,7 @@ export interface ServicesDetailedProps { }> | null } -export const ServicesDetailedBlock: React.FC = ({ - title, +export const ServicesDetailedBlock: React.FC = ({ eyebrow, title, subtitle, services, }) => { @@ -40,9 +40,11 @@ export const ServicesDetailedBlock: React.FC = ({
-
- // Usługi -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title}

diff --git a/src/blocks/ServicesList/Component.tsx b/src/blocks/ServicesList/Component.tsx index 75f06a6..9db2406 100644 --- a/src/blocks/ServicesList/Component.tsx +++ b/src/blocks/ServicesList/Component.tsx @@ -6,14 +6,16 @@ import { ArrowRight } from 'lucide-react' type Props = Extract[0], { blockType: 'servicesList' }> -export const ServicesListBlock: React.FC = ({ title, services }) => { +export const ServicesListBlock: React.FC = ({ eyebrow, title, services }) => { return (
-
- // Usługi -
+ {eyebrow && ( +
+ // {eyebrow} +
+ )}

{title}

diff --git a/src/blocks/ServicesList/config.ts b/src/blocks/ServicesList/config.ts index b43a045..7afa789 100644 --- a/src/blocks/ServicesList/config.ts +++ b/src/blocks/ServicesList/config.ts @@ -3,6 +3,7 @@ import type { Block } from 'payload' export const ServicesList: Block = { slug: 'servicesList', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, { name: 'services', diff --git a/src/blocks/Stats/Component.tsx b/src/blocks/Stats/Component.tsx index 6dcb705..e698308 100644 --- a/src/blocks/Stats/Component.tsx +++ b/src/blocks/Stats/Component.tsx @@ -2,6 +2,7 @@ import React from 'react' export interface StatsProps { + eyebrow?: string | null title?: string | null subtitle?: string | null items?: Array<{ @@ -12,7 +13,7 @@ export interface StatsProps { }> | null } -export const StatsBlock: React.FC = ({ title, subtitle, items }) => { +export const StatsBlock: React.FC = ({ eyebrow, title, subtitle, items }) => { if (!items || items.length === 0) return null return ( @@ -20,9 +21,11 @@ export const StatsBlock: React.FC = ({ title, subtitle, items }) =>
{(title || subtitle) && (
+ {eyebrow && (
- // Statystyki + // {eyebrow}
+ )} {title && (

{title} diff --git a/src/blocks/UniqueValue/Component.tsx b/src/blocks/UniqueValue/Component.tsx index 38481f1..c37a473 100644 --- a/src/blocks/UniqueValue/Component.tsx +++ b/src/blocks/UniqueValue/Component.tsx @@ -6,7 +6,7 @@ import { CheckCircle } from 'lucide-react' type Props = Extract[0], { blockType: 'uniqueValue' }> -export const UniqueValueBlock: React.FC = ({ title, description }) => { +export const UniqueValueBlock: React.FC = ({ eyebrow, features, title, description }) => { return (
@@ -27,9 +27,11 @@ export const UniqueValueBlock: React.FC = ({ title, description }) => { {/* Kolumna tekstowa */}
+ {eyebrow && (
- // Wartość + // {eyebrow}
+ )}

{title} @@ -39,16 +41,16 @@ export const UniqueValueBlock: React.FC = ({ title, description }) => { {description}

-
-
- - Bez barier językowych + {features && features.length > 0 && ( +
+ {features.map((feature: any, index: number) => ( +
+ + {feature.text} +
+ ))}
-
- - Indywidualne podejście -
-
+ )}

diff --git a/src/blocks/UniqueValue/config.ts b/src/blocks/UniqueValue/config.ts index d10a160..c0170ac 100644 --- a/src/blocks/UniqueValue/config.ts +++ b/src/blocks/UniqueValue/config.ts @@ -3,7 +3,16 @@ import type { Block } from 'payload' export const UniqueValue: Block = { slug: 'uniqueValue', fields: [ + { name: 'eyebrow', type: 'text', localized: true }, { name: 'title', type: 'text', required: true, localized: true }, { name: 'description', type: 'textarea', required: true, localized: true }, + { + name: 'features', + type: 'array', + localized: true, + fields: [ + { name: 'text', type: 'text', required: true }, + ], + }, ], } diff --git a/src/payload-types.ts b/src/payload-types.ts index beceedd..366ce36 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -292,13 +292,21 @@ export interface Page { blockType: 'trustBar'; } | { + eyebrow?: string | null; title: string; description: string; + features?: + | { + text: string; + id?: string | null; + }[] + | null; id?: string | null; blockName?: string | null; blockType: 'uniqueValue'; } | { + eyebrow?: string | null; title: string; services?: | { @@ -313,7 +321,9 @@ export interface Page { blockType: 'servicesList'; } | { + eyebrow?: string | null; title: string; + subtitle?: string | null; steps?: | { title: string; @@ -327,6 +337,7 @@ export interface Page { blockType: 'process'; } | { + eyebrow?: string | null; title: string; description: string; logo?: (number | null) | Media; @@ -349,6 +360,7 @@ export interface Page { blockType: 'testimonials'; } | { + eyebrow?: string | null; title: string; questions?: | { @@ -363,6 +375,7 @@ export interface Page { blockType: 'faqTeaser'; } | { + eyebrow?: string | null; title: string; subtitle?: string | null; buttonText: string; @@ -647,14 +660,22 @@ export interface PagesSelect { uniqueValue?: | T | { + eyebrow?: T; title?: T; description?: T; + features?: + | T + | { + text?: T; + id?: T; + }; id?: T; blockName?: T; }; servicesList?: | T | { + eyebrow?: T; title?: T; services?: | T @@ -670,7 +691,9 @@ export interface PagesSelect { process?: | T | { + eyebrow?: T; title?: T; + subtitle?: T; steps?: | T | { @@ -685,6 +708,7 @@ export interface PagesSelect { affiliation?: | T | { + eyebrow?: T; title?: T; description?: T; logo?: T; @@ -709,6 +733,7 @@ export interface PagesSelect { faqTeaser?: | T | { + eyebrow?: T; title?: T; questions?: | T @@ -724,6 +749,7 @@ export interface PagesSelect { finalCta?: | T | { + eyebrow?: T; title?: T; subtitle?: T; buttonText?: T;