Enhanced FDContactFormBlock with dark mode, remove search, add FormBlock to pages

This commit is contained in:
Jeffrey 2026-02-17 17:51:39 +01:00
parent 9038b0c894
commit 5cf9186ee2
14 changed files with 314 additions and 209 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

2
next-env.d.ts vendored
View File

@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@ -3,7 +3,7 @@ import React, { useState, useEffect, useRef } from 'react'
import type { Header as HeaderType } from '@/payload-types'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { SearchIcon, MenuIcon, XIcon, ChevronDownIcon, ChevronRightIcon } from 'lucide-react'
import { MenuIcon, XIcon, ChevronDownIcon, ChevronRightIcon } from 'lucide-react'
// ─── Types ───────────────────────────────────────────────────────────────────
type NavChild = {
@ -258,11 +258,6 @@ export const HeaderNav: React.FC<{ data: HeaderType }> = ({ data }) => {
)
})}
<Link href="/search" className="text-fd-navy hover:text-fd-yellow transition-colors">
<span className="sr-only">Sök</span>
<SearchIcon className="w-5" />
</Link>
<SwedishFlag />
</nav>
@ -351,15 +346,6 @@ export const HeaderNav: React.FC<{ data: HeaderType }> = ({ data }) => {
</Link>
)
})}
<Link
href="/search"
onClick={closeMobile}
className="py-4 text-white font-joey-medium text-xl border-b border-white/10 hover:text-fd-yellow transition-colors flex items-center gap-3"
>
<SearchIcon className="w-5 h-5" />
Sök
</Link>
</nav>
</div>
</>

View File

@ -17,8 +17,6 @@ import { PreviewComponent as PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860 }
import { SlugField as SlugField_2b8867833a34864a02ddf429b0728a40 } from '@payloadcms/next/client'
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { LinkToDoc as LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client'
import { ReindexButton as ReindexButton_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client'
import { RowLabel as RowLabel_ec255a65fa6fa8d1faeb09cf35284224 } from '@/Header/RowLabel'
import { RowLabel as RowLabel_1f6ff6ff633e3695d348f4f3c58f1466 } from '@/Footer/RowLabel'
import { default as default_c1363893506d7ed29a71d1a4da01ddb5 } from '@/components/AdminIcon'
@ -47,8 +45,6 @@ export const importMap = {
"@payloadcms/next/client#SlugField": SlugField_2b8867833a34864a02ddf429b0728a40,
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#BlocksFeatureClient": BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/plugin-search/client#LinkToDoc": LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634,
"@payloadcms/plugin-search/client#ReindexButton": ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
"@/Header/RowLabel#RowLabel": RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
"@/Footer/RowLabel#RowLabel": RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
"@/components/AdminIcon#default": default_c1363893506d7ed29a71d1a4da01ddb5,

View File

@ -5,11 +5,23 @@ import type { FDContactFormBlock as FDContactFormBlockProps } from '@/payload-ty
import type { Media } from '@/payload-types'
import { FDImage } from '@/components/FDImage'
const bgMap: Record<string, string> = {
/* ------------------------------------------------------------------ */
/* Theme maps */
/* ------------------------------------------------------------------ */
const sectionBgMap: Record<string, string> = {
white: 'bg-white',
gray: 'bg-fd-gray-light',
gray: 'bg-[#F0F0F0]',
navy: 'bg-fd-navy',
navyGradient: 'bg-gradient-to-br from-fd-navy via-[#153350] to-fd-navy',
}
const isDark = (bg: string) => bg === 'navy' || bg === 'navyGradient'
/* ------------------------------------------------------------------ */
/* Component */
/* ------------------------------------------------------------------ */
export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
heading,
description,
@ -20,31 +32,35 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
privacyLinkUrl,
sideImage,
background = 'white',
layout = 'standard',
externalApi,
}) => {
const [formData, setFormData] = useState<Record<string, string>>({})
const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')
const media = sideImage as Media | undefined
const hasSideImage = Boolean(media?.url)
const sectionBg = bgMap[background || 'white']
const hasSideImage = layout === 'withImage' && Boolean(media?.url)
const dark = isDark(background || 'white')
const sectionBg = sectionBgMap[background || 'white']
const isCard = layout === 'card'
// Extract form object — could be a populated object or just an ID
// Extract form object
const form = formRelation && typeof formRelation === 'object' ? formRelation : null
const formId = form ? form.id : (formRelation ?? null)
/* ---- Handlers ---- */
const handleChange = (name: string, value: string) => {
setFormData((prev) => ({ ...prev, [name]: value }))
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!formId) {
console.warn('No form ID configured')
return
}
if (!formId) return
setStatus('sending')
try {
// 1. Submit to Payload
const res = await fetch('/api/form-submissions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@ -56,14 +72,55 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
})),
}),
})
// 2. Submit to external API if configured
if (externalApi?.enabled && externalApi?.endpoint) {
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
if (externalApi.authToken) {
headers['Authorization'] = `Bearer ${externalApi.authToken}`
}
// Fire and forget — don't block UX on external API
fetch(externalApi.endpoint, {
method: 'POST',
headers,
body: JSON.stringify({
formId,
formName: form?.title || '',
data: formData,
submittedAt: new Date().toISOString(),
}),
}).catch(() => {}) // silently fail
}
setStatus(res.ok ? 'sent' : 'error')
} catch {
setStatus('error')
}
}
const baseInputClass =
'w-full bg-gray-100 rounded-lg px-4 py-3 font-joey text-fd-navy text-base outline-none focus:ring-2 focus:ring-fd-navy/20 transition-shadow'
/* ---- Input styles (light vs dark) ---- */
const inputBase = 'w-full rounded-xl px-4 py-3 font-joey text-base outline-none transition-all'
const inputLight = `${inputBase} bg-gray-100 text-fd-navy placeholder:text-fd-navy/40 focus:ring-2 focus:ring-fd-navy/20 focus:bg-white`
const inputDark = `${inputBase} bg-white/10 text-white placeholder:text-white/40 border border-white/20 focus:ring-2 focus:ring-fd-yellow/30 focus:bg-white/15 focus:border-fd-yellow/50`
const inputClass = dark ? inputDark : inputLight
const checkboxLight = 'w-5 h-5 rounded border-gray-300 text-fd-navy focus:ring-fd-navy/20'
const checkboxDark = 'w-5 h-5 rounded border-white/30 text-fd-yellow focus:ring-fd-yellow/30'
const checkboxClass = dark ? checkboxDark : checkboxLight
/* ---- Text color helpers ---- */
const headingColor = dark ? 'text-fd-yellow' : 'text-fd-navy'
const bodyColor = dark ? 'text-white/80' : 'text-fd-navy/80'
const labelColor = dark ? 'text-white' : 'text-fd-navy'
const mutedColor = dark ? 'text-white/50' : 'text-fd-navy/60'
const linkColor = dark
? 'underline underline-offset-2 hover:text-fd-yellow transition-colors'
: 'underline underline-offset-2 hover:text-fd-navy transition-colors'
const errorColor = dark ? 'text-red-300' : 'text-red-600'
/* ---- Field renderer ---- */
const renderFormField = (field: any) => {
const blockType = field.blockType
@ -80,7 +137,7 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
name={name}
required={required}
rows={4}
className={`${baseInputClass} resize-y`}
className={`${inputClass} resize-y`}
value={formData[name] || ''}
onChange={(e) => handleChange(name, e.target.value)}
/>
@ -90,7 +147,7 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
<select
name={name}
required={required}
className={baseInputClass}
className={inputClass}
value={formData[name] || ''}
onChange={(e) => handleChange(name, e.target.value)}
>
@ -108,7 +165,8 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
type="email"
name={name}
required={required}
className={baseInputClass}
className={inputClass}
placeholder={field.placeholder || ''}
value={formData[name] || ''}
onChange={(e) => handleChange(name, e.target.value)}
/>
@ -119,23 +177,23 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
type="number"
name={name}
required={required}
className={baseInputClass}
className={inputClass}
value={formData[name] || ''}
onChange={(e) => handleChange(name, e.target.value)}
/>
)
case 'checkbox':
return (
<label className="flex items-center gap-2 cursor-pointer">
<label className="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
name={name}
required={required}
className="w-5 h-5 rounded border-gray-300 text-fd-navy focus:ring-fd-navy/20"
className={checkboxClass}
checked={formData[name] === 'true'}
onChange={(e) => handleChange(name, e.target.checked ? 'true' : 'false')}
/>
<span className="font-joey text-fd-navy text-sm">{label}</span>
<span className={`font-joey text-sm ${labelColor}`}>{label}</span>
</label>
)
case 'country':
@ -147,7 +205,8 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
type="text"
name={name}
required={required}
className={baseInputClass}
className={inputClass}
placeholder={field.placeholder || ''}
value={formData[name] || ''}
onChange={(e) => handleChange(name, e.target.value)}
/>
@ -162,9 +221,9 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
return {
element: (
<div className="flex flex-col gap-1.5">
<label className="font-joey text-fd-navy text-sm md:text-base">
<label className={`font-joey text-sm md:text-base ${labelColor}`}>
{label}
{required && ' *'}
{required && <span className={dark ? 'text-fd-yellow' : 'text-fd-navy'}> *</span>}
</label>
{input}
</div>
@ -173,6 +232,8 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
}
}
/* ---- Fields layout (handles half-width pairing) ---- */
const renderFields = () => {
if (!form?.fields) return null
@ -183,12 +244,9 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
while (i < fields.length) {
const field = fields[i]
// Skip message blocks — render them inline
if (field.blockType === 'message') {
elements.push(
<div key={i} className="font-joey text-fd-navy/70 text-sm">
{/* Message blocks contain rich text, render as simple text for now */}
</div>,
<div key={i} className={`font-joey text-sm ${mutedColor}`} />,
)
i++
continue
@ -199,7 +257,8 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
if (isHalf) {
const nextField = i + 1 < fields.length ? fields[i + 1] : null
const nextResult = nextField && nextField.blockType !== 'message' ? renderFormField(nextField) : null
const nextResult =
nextField && nextField.blockType !== 'message' ? renderFormField(nextField) : null
const nextIsHalf = nextResult && nextResult.width <= 50
if (nextIsHalf && nextResult) {
@ -225,13 +284,19 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
return elements
}
/* ---- Success state ---- */
if (status === 'sent') {
// Use confirmation message from Payload form if available
return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8 text-center">
<h2 className="font-joey-heavy text-fd-navy text-3xl md:text-4xl mb-4">Tack!</h2>
<p className="font-joey text-fd-navy text-lg">
<div className={`inline-flex items-center justify-center w-16 h-16 rounded-full mb-6 ${dark ? 'bg-fd-yellow/20' : 'bg-fd-mint/20'}`}>
<svg className={`w-8 h-8 ${dark ? 'text-fd-yellow' : 'text-fd-mint'}`} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
</div>
<h2 className={`font-joey-heavy text-3xl md:text-4xl mb-4 ${headingColor}`}>Tack!</h2>
<p className={`font-joey text-lg ${bodyColor}`}>
Vi har tagit emot din förfrågan och återkommer snart vi kan.
</p>
</div>
@ -239,79 +304,121 @@ export const FDContactFormBlockComponent: React.FC<FDContactFormBlockProps> = ({
)
}
/* ---- Empty state ---- */
if (!form) {
return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8 text-center">
<p className="font-joey text-fd-navy/60">Inget formulär valt.</p>
<p className={`font-joey ${mutedColor}`}>Inget formulär valt.</p>
</div>
</section>
)
}
return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
<div className={`flex flex-col ${hasSideImage ? 'lg:flex-row' : ''} gap-10 lg:gap-16`}>
<div className={hasSideImage ? 'flex-1' : 'max-w-[800px]'}>
{heading && (
<h2 className="font-joey-heavy text-fd-navy text-3xl md:text-4xl lg:text-5xl leading-tight mb-3">
{heading}
</h2>
)}
{description && (
<p className="font-joey text-fd-navy/80 text-base md:text-lg mb-8">{description}</p>
/* ---- Form content ---- */
const formContent = (
<>
{heading && (
<h2
className={`font-joey-heavy text-3xl md:text-4xl lg:text-5xl leading-tight mb-3 ${headingColor}`}
>
{heading}
</h2>
)}
{description && (
<p className={`font-joey text-base md:text-lg mb-8 ${bodyColor}`}>{description}</p>
)}
<form onSubmit={handleSubmit} className="flex flex-col gap-5">
{renderFields()}
<button
type="submit"
disabled={status === 'sending'}
className={`self-start inline-flex items-center justify-center px-8 py-3 rounded-full font-joey-bold text-lg transition-colors disabled:opacity-60 mt-2 ${
dark
? 'bg-fd-yellow hover:bg-fd-yellow/90 text-fd-navy'
: 'bg-fd-yellow hover:bg-fd-yellow/90 text-fd-navy'
}`}
>
{status === 'sending' ? 'Skickar...' : submitText}
</button>
{status === 'error' && (
<p className={`font-joey text-sm ${errorColor}`}>
Något gick fel. Försök igen eller kontakta oss direkt.
</p>
)}
{privacyText && (
<p className={`font-joey text-xs md:text-sm leading-relaxed mt-2 ${mutedColor}`}>
{privacyText}{' '}
{privacyLinkText && privacyLinkUrl && (
<>
Läs mer i vår{' '}
<a href={privacyLinkUrl} className={linkColor}>
{privacyLinkText}
</a>
.
</>
)}
</p>
)}
</form>
</>
)
<form onSubmit={handleSubmit} className="flex flex-col gap-5">
{renderFields()}
/* ---- Layout: Card ---- */
<button
type="submit"
disabled={status === 'sending'}
className="self-start inline-flex items-center justify-center px-8 py-3 bg-fd-yellow hover:bg-fd-yellow/90 rounded-full font-joey-bold text-fd-navy text-lg transition-colors disabled:opacity-60 mt-2"
>
{status === 'sending' ? 'Skickar...' : submitText}
</button>
{status === 'error' && (
<p className="font-joey text-red-600 text-sm">
Något gick fel. Försök igen eller kontakta oss direkt.
</p>
)}
{privacyText && (
<p className="font-joey text-fd-navy/60 text-xs md:text-sm leading-relaxed mt-2">
{privacyText}{' '}
{privacyLinkText && privacyLinkUrl && (
<>
Läs mer i vår{' '}
<a
href={privacyLinkUrl}
className="underline underline-offset-2 hover:text-fd-navy transition-colors"
>
{privacyLinkText}
</a>
.
</>
)}
</p>
)}
</form>
if (isCard) {
return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
<div
className={`max-w-[720px] mx-auto p-8 md:p-12 rounded-[40px] md:rounded-[70px] ${
dark
? 'bg-white/5 border border-white/10 backdrop-blur-sm'
: 'bg-white shadow-lg border border-gray-100'
}`}
>
{formContent}
</div>
</div>
</section>
)
}
{hasSideImage && (
/* ---- Layout: With image ---- */
if (hasSideImage) {
return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
<div className="flex flex-col lg:flex-row gap-10 lg:gap-16 items-start">
<div className="flex-1">{formContent}</div>
<div className="hidden lg:block flex-shrink-0">
<FDImage
media={media!}
size="medium"
className="w-[380px] h-auto max-h-[500px] object-cover rounded-[20px]"
className="w-[380px] h-auto max-h-[560px] object-cover rounded-[20px]"
sizes="380px"
fallbackAlt={heading || ''}
/>
</div>
)}
</div>
</div>
</section>
)
}
/* ---- Layout: Standard (full width) ---- */
return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
<div className="max-w-[800px]">{formContent}</div>
</div>
</section>
)

View File

@ -4,10 +4,11 @@ export const FDContactFormBlock: Block = {
slug: 'fdContactForm',
interfaceName: 'FDContactFormBlock',
labels: {
singular: 'FD Contact Form',
plural: 'FD Contact Forms',
singular: 'FD Kontaktformulär',
plural: 'FD Kontaktformulär',
},
fields: [
// --- Content ---
{
name: 'form',
type: 'relationship',
@ -30,7 +31,7 @@ export const FDContactFormBlock: Block = {
type: 'textarea',
label: 'Beskrivning',
defaultValue:
'Tell us about your goals, our team will reach out to you and help you achieve the right solution.',
'Berätta om era mål — vårt team kontaktar er och hjälper er hitta rätt lösning.',
},
{
name: 'submitText',
@ -38,6 +39,50 @@ export const FDContactFormBlock: Block = {
label: 'Skicka-knapp text',
defaultValue: 'Skicka förfrågan',
},
// --- Layout ---
{
type: 'row',
fields: [
{
name: 'background',
type: 'select',
label: 'Bakgrund',
defaultValue: 'white',
options: [
{ label: 'Vit', value: 'white' },
{ label: 'Ljusgrå', value: 'gray' },
{ label: 'Navy (mörk)', value: 'navy' },
{ label: 'Navy gradient', value: 'navyGradient' },
],
admin: { width: '50%' },
},
{
name: 'layout',
type: 'select',
label: 'Layout',
defaultValue: 'standard',
options: [
{ label: 'Standard (helbredd)', value: 'standard' },
{ label: 'Med sidobild', value: 'withImage' },
{ label: 'Kort (centrerat)', value: 'card' },
],
admin: { width: '50%' },
},
],
},
{
name: 'sideImage',
type: 'upload',
relationTo: 'media',
label: 'Sidobild',
admin: {
description: 'Visas till höger om formuläret på desktop',
condition: (_, siblingData) => siblingData?.layout === 'withImage',
},
},
// --- Privacy ---
{
name: 'privacyText',
type: 'textarea',
@ -46,34 +91,58 @@ export const FDContactFormBlock: Block = {
'Vi använder din kontaktinformation för att svara på din förfrågan och dela detaljer om våra produkter och tjänster. Du kan när som helst avregistrera dig.',
},
{
name: 'privacyLinkText',
type: 'text',
label: 'Integritetslänk text',
defaultValue: 'integritetspolicy',
type: 'row',
fields: [
{
name: 'privacyLinkText',
type: 'text',
label: 'Integritetslänk text',
defaultValue: 'integritetspolicy',
admin: { width: '50%' },
},
{
name: 'privacyLinkUrl',
type: 'text',
label: 'Integritetslänk URL',
defaultValue: '/integritetspolicy',
admin: { width: '50%' },
},
],
},
// --- External API (optional) ---
{
name: 'privacyLinkUrl',
type: 'text',
label: 'Integritetslänk URL',
defaultValue: '/integritetspolicy',
},
{
name: 'sideImage',
type: 'upload',
relationTo: 'media',
label: 'Sidobild (valfri)',
name: 'externalApi',
type: 'group',
label: 'Extern API-integration (valfri)',
admin: {
description: 'Bild som visas till höger om formuläret',
description: 'Skicka formulärdata till ett externt system (t.ex. Lime CRM) utöver Payload',
},
},
{
name: 'background',
type: 'select',
label: 'Bakgrund',
defaultValue: 'white',
options: [
{ label: 'Vit', value: 'white' },
{ label: 'Grå', value: 'gray' },
fields: [
{
name: 'enabled',
type: 'checkbox',
label: 'Aktivera extern API',
defaultValue: false,
},
{
name: 'endpoint',
type: 'text',
label: 'API-URL',
admin: {
description: 'T.ex. https://api.lime-crm.se/webhook/forms',
condition: (_, siblingData) => Boolean(siblingData?.enabled),
},
},
{
name: 'authToken',
type: 'text',
label: 'Auth-token (Bearer)',
admin: {
description: 'Skickas som Authorization: Bearer {token}',
condition: (_, siblingData) => Boolean(siblingData?.enabled),
},
},
],
},
],

View File

@ -75,7 +75,6 @@ export interface Config {
redirects: Redirect;
forms: Form;
'form-submissions': FormSubmission;
search: Search;
'payload-kv': PayloadKv;
'payload-jobs': PayloadJob;
'payload-locked-documents': PayloadLockedDocument;
@ -92,7 +91,6 @@ export interface Config {
redirects: RedirectsSelect<false> | RedirectsSelect<true>;
forms: FormsSelect<false> | FormsSelect<true>;
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
search: SearchSelect<false> | SearchSelect<true>;
'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>;
'payload-jobs': PayloadJobsSelect<false> | PayloadJobsSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
@ -758,14 +756,29 @@ export interface FDContactFormBlock {
heading: string;
description?: string | null;
submitText?: string | null;
background?: ('white' | 'gray' | 'navy' | 'navyGradient') | null;
layout?: ('standard' | 'withImage' | 'card') | null;
/**
* Visas till höger om formuläret desktop
*/
sideImage?: (number | null) | Media;
privacyText?: string | null;
privacyLinkText?: string | null;
privacyLinkUrl?: string | null;
/**
* Bild som visas till höger om formuläret
* Skicka formulärdata till ett externt system (t.ex. Lime CRM) utöver Payload
*/
sideImage?: (number | null) | Media;
background?: ('white' | 'gray') | null;
externalApi?: {
enabled?: boolean | null;
/**
* T.ex. https://api.lime-crm.se/webhook/forms
*/
endpoint?: string | null;
/**
* Skickas som Authorization: Bearer {token}
*/
authToken?: string | null;
};
id?: string | null;
blockName?: string | null;
blockType: 'fdContactForm';
@ -1364,37 +1377,6 @@ export interface FormSubmission {
updatedAt: string;
createdAt: string;
}
/**
* This is a collection of automatically created search results. These results are used by the global site search and will be updated automatically as documents in the CMS are created or updated.
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "search".
*/
export interface Search {
id: number;
title?: string | null;
priority?: number | null;
doc: {
relationTo: 'posts';
value: number | Post;
};
slug?: string | null;
meta?: {
title?: string | null;
description?: string | null;
image?: (number | null) | Media;
};
categories?:
| {
relationTo?: string | null;
categoryID?: string | null;
title?: string | null;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-kv".
@ -1542,10 +1524,6 @@ export interface PayloadLockedDocument {
| ({
relationTo: 'form-submissions';
value: number | FormSubmission;
} | null)
| ({
relationTo: 'search';
value: number | Search;
} | null);
globalSlug?: string | null;
user: {
@ -1952,11 +1930,19 @@ export interface FDContactFormBlockSelect<T extends boolean = true> {
heading?: T;
description?: T;
submitText?: T;
background?: T;
layout?: T;
sideImage?: T;
privacyText?: T;
privacyLinkText?: T;
privacyLinkUrl?: T;
sideImage?: T;
background?: T;
externalApi?:
| T
| {
enabled?: T;
endpoint?: T;
authToken?: T;
};
id?: T;
blockName?: T;
}
@ -2520,33 +2506,6 @@ export interface FormSubmissionsSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "search_select".
*/
export interface SearchSelect<T extends boolean = true> {
title?: T;
priority?: T;
doc?: T;
slug?: T;
meta?:
| T
| {
title?: T;
description?: T;
image?: T;
};
categories?:
| T
| {
relationTo?: T;
categoryID?: T;
title?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-kv_select".

View File

@ -3,12 +3,9 @@ import { FixedToolbarFeature, HeadingFeature, lexicalEditor } from '@payloadcms/
import { nestedDocsPlugin } from '@payloadcms/plugin-nested-docs'
import { redirectsPlugin } from '@payloadcms/plugin-redirects'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { searchPlugin } from '@payloadcms/plugin-search'
import { Plugin } from 'payload'
import { revalidateRedirects } from '@/hooks/revalidateRedirects'
import { GenerateTitle, GenerateURL } from '@payloadcms/plugin-seo/types'
import { searchFields } from '@/search/fieldOverrides'
import { beforeSyncWithSearch } from '@/search/beforeSync'
import { Page, Post } from '@/payload-types'
import { getServerSideURL } from '@/utilities/getURL'
@ -79,13 +76,4 @@ export const plugins: Plugin[] = [
},
},
}),
searchPlugin({
collections: ['posts'],
beforeSync: beforeSyncWithSearch,
searchOverrides: {
fields: ({ defaultFields }) => {
return [...defaultFields, ...searchFields]
},
},
}),
]