Scaffold webu na Payload CMS 3 + Next.js nad SQLite
Kostra prezentace s vlastní administrací pro Martina Reinera. Obsah: - kolekce Products (obrázky, volné parametry, cena, dostupnost, skrytí), Media se zmenšeninami, Pages, Users bez veřejné registrace - veřejná část: výpis nabídky, detail položky, statické stránky - /api/health pro Docker HEALTHCHECK Provoz: - Dockerfile, docker-compose.yml (vývoj) a docker-compose.prod.yml (nasazení z Gitea registry) - CI v Gitea Actions: lint -> testy -> build -> push image - úvodní migrace databáze Stránky jsou force-dynamic, aby se úprava položky projevila hned; schéma se za běhu nedomýšlí (push: false), migrace se commitují. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { notFound } from 'next/navigation'
|
||||
import { getPayload } from 'payload'
|
||||
import React from 'react'
|
||||
import { RichText } from '@payloadcms/richtext-lexical/react'
|
||||
|
||||
import config from '@/payload.config'
|
||||
import type { Page } from '@/payload-types'
|
||||
import '../styles.css'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
type Props = { params: Promise<{ slug: string }> }
|
||||
|
||||
export async function generateMetadata({ params }: Props) {
|
||||
const stranka = await najdiStranku((await params).slug)
|
||||
return { title: stranka ? `${stranka.nazev} — Reiner zbraně` : 'Stránka nenalezena' }
|
||||
}
|
||||
|
||||
/** Statické stránky z kolekce Pages — /kontakt, /o-nas a podobně. */
|
||||
export default async function StatickaStranka({ params }: Props) {
|
||||
const stranka = await najdiStranku((await params).slug)
|
||||
if (!stranka) notFound()
|
||||
|
||||
return (
|
||||
<article className="stranka">
|
||||
<h1>{stranka.nazev}</h1>
|
||||
{stranka.obsah && <RichText data={stranka.obsah} />}
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
async function najdiStranku(slug: string): Promise<Page | null> {
|
||||
const payload = await getPayload({ config: await config })
|
||||
|
||||
const { docs } = await payload.find({
|
||||
collection: 'pages',
|
||||
where: { slug: { equals: slug } },
|
||||
limit: 1,
|
||||
})
|
||||
|
||||
return docs[0] ?? null
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Endpoint pro Docker HEALTHCHECK.
|
||||
*
|
||||
* Záměrně nesahá do databáze — odpovídá na otázku „stojí server a obsluhuje
|
||||
* požadavky?“. Výpadek databáze pozná až monitoring obsahu, ne healthcheck;
|
||||
* kdyby ho shazoval, restartoval by Docker aplikaci kvůli něčemu, co restart
|
||||
* neopraví.
|
||||
*/
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export function GET() {
|
||||
return Response.json({ status: 'ok' })
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import './styles.css'
|
||||
|
||||
export const metadata = {
|
||||
description: 'Prodej zbraní, střeliva a doplňků — Martin Reiner.',
|
||||
title: 'Reiner — zbraně a střelivo',
|
||||
}
|
||||
|
||||
export default async function RootLayout(props: { children: React.ReactNode }) {
|
||||
const { children } = props
|
||||
|
||||
return (
|
||||
<html lang="cs">
|
||||
<body>
|
||||
<header className="hlavicka">
|
||||
<Link className="znacka" href="/">
|
||||
Reiner <span>zbraně a střelivo</span>
|
||||
</Link>
|
||||
<nav>
|
||||
<Link href="/">Nabídka</Link>
|
||||
<Link href="/kontakt">Kontakt</Link>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>{children}</main>
|
||||
|
||||
<footer className="paticka">
|
||||
<p>© {new Date().getFullYear()} Martin Reiner</p>
|
||||
<p>
|
||||
Prodej zbraní a střeliva pouze osobám s platným zbrojním průkazem podle zákona
|
||||
č. 14/2021 Sb.
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { getPayload } from 'payload'
|
||||
import React from 'react'
|
||||
|
||||
import config from '@/payload.config'
|
||||
import type { Media, Product } from '@/payload-types'
|
||||
import { formatujCenu, popisStavu } from '@/lib/format'
|
||||
import '../../styles.css'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
type Props = { params: Promise<{ slug: string }> }
|
||||
|
||||
export async function generateMetadata({ params }: Props) {
|
||||
const polozka = await najdiPolozku((await params).slug)
|
||||
if (!polozka) return { title: 'Položka nenalezena' }
|
||||
|
||||
return {
|
||||
title: `${polozka.nazev} — Reiner zbraně`,
|
||||
description: polozka.popis ?? undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export default async function DetailPolozky({ params }: Props) {
|
||||
const polozka = await najdiPolozku((await params).slug)
|
||||
if (!polozka) notFound()
|
||||
|
||||
const obrazky = (polozka.obrazky ?? [])
|
||||
.map((radek) => radek.obrazek)
|
||||
.filter((o): o is Media => typeof o === 'object' && o !== null)
|
||||
|
||||
return (
|
||||
<article className="stranka detail">
|
||||
<p className="zpet">
|
||||
<Link href="/">← Zpět na nabídku</Link>
|
||||
</p>
|
||||
|
||||
<h1>{polozka.nazev}</h1>
|
||||
|
||||
<p className="detail__cena">
|
||||
{formatujCenu(polozka.cena)}
|
||||
<span className={`znacka-stavu znacka-stavu--${polozka.stav}`}>
|
||||
{popisStavu(polozka.stav)}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
{obrazky.length > 0 && (
|
||||
<div className="galerie">
|
||||
{obrazky.map((obrazek) => {
|
||||
const varianta = obrazek.sizes?.detail
|
||||
const url = varianta?.url ?? obrazek.url
|
||||
const width = varianta?.width ?? obrazek.width
|
||||
const height = varianta?.height ?? obrazek.height
|
||||
if (!url || !width || !height) return null
|
||||
|
||||
return (
|
||||
<Image
|
||||
key={obrazek.id}
|
||||
alt={obrazek.alt ?? polozka.nazev}
|
||||
src={url}
|
||||
width={width}
|
||||
height={height}
|
||||
sizes="(max-width: 900px) 100vw, 800px"
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{polozka.parametry && polozka.parametry.length > 0 && (
|
||||
<table className="parametry">
|
||||
<tbody>
|
||||
{polozka.parametry.map((parametr) => (
|
||||
<tr key={parametr.id}>
|
||||
<th scope="row">{parametr.nazev}</th>
|
||||
<td>{parametr.hodnota}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
|
||||
{polozka.popis && <div className="popis">{polozka.popis}</div>}
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
async function najdiPolozku(slug: string): Promise<Product | null> {
|
||||
const payload = await getPayload({ config: await config })
|
||||
|
||||
const { docs } = await payload.find({
|
||||
collection: 'products',
|
||||
where: {
|
||||
slug: { equals: slug },
|
||||
skryto: { not_equals: true },
|
||||
},
|
||||
depth: 1,
|
||||
limit: 1,
|
||||
})
|
||||
|
||||
return docs[0] ?? null
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { getPayload } from 'payload'
|
||||
import React from 'react'
|
||||
|
||||
import config from '@/payload.config'
|
||||
import type { Media, Product } from '@/payload-types'
|
||||
import { formatujCenu, popisStavu } from '@/lib/format'
|
||||
import './styles.css'
|
||||
|
||||
// Obsah se čte z CMS při každém požadavku — jinak by se úprava položky
|
||||
// projevila až po přestavění webu.
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
/** Výpis nabídky. Skryté položky se nezobrazují, prodané se řadí nakonec. */
|
||||
export default async function HomePage() {
|
||||
const payload = await getPayload({ config: await config })
|
||||
|
||||
const { docs: polozky } = await payload.find({
|
||||
collection: 'products',
|
||||
where: { skryto: { not_equals: true } },
|
||||
sort: ['stav', '-updatedAt'],
|
||||
depth: 1,
|
||||
limit: 100,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="stranka">
|
||||
<h1>Nabídka</h1>
|
||||
|
||||
{polozky.length === 0 ? (
|
||||
<p className="prazdno">
|
||||
Zatím tu nic není. Položky se přidávají v <Link href="/admin">administraci</Link>.
|
||||
</p>
|
||||
) : (
|
||||
<ul className="mrizka">
|
||||
{polozky.map((polozka) => (
|
||||
<KartaPolozky key={polozka.id} polozka={polozka} />
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function KartaPolozky({ polozka }: { polozka: Product }) {
|
||||
const nahled = prvniObrazek(polozka)
|
||||
|
||||
return (
|
||||
<li className={`karta${polozka.stav === 'prodano' ? ' karta--prodano' : ''}`}>
|
||||
<Link href={`/nabidka/${polozka.slug}`}>
|
||||
<div className="karta__obrazek">
|
||||
{nahled ? (
|
||||
<Image
|
||||
alt={nahled.alt}
|
||||
src={nahled.url}
|
||||
width={nahled.width}
|
||||
height={nahled.height}
|
||||
sizes="(max-width: 700px) 100vw, 320px"
|
||||
/>
|
||||
) : (
|
||||
<div className="karta__bezobrazku">bez fotky</div>
|
||||
)}
|
||||
</div>
|
||||
<h2>{polozka.nazev}</h2>
|
||||
<p className="karta__cena">{formatujCenu(polozka.cena)}</p>
|
||||
<p className="karta__stav">{popisStavu(polozka.stav)}</p>
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Vytáhne z položky první obrázek v podobě použitelné pro `next/image`.
|
||||
* Vrací `null`, pokud položka fotku nemá nebo se nepodařilo načíst rozměry.
|
||||
*/
|
||||
function prvniObrazek(polozka: Product) {
|
||||
const prvni = polozka.obrazky?.[0]?.obrazek
|
||||
if (!prvni || typeof prvni === 'number') return null
|
||||
|
||||
const media = prvni as Media
|
||||
const varianta = media.sizes?.nahled
|
||||
const url = varianta?.url ?? media.url
|
||||
const width = varianta?.width ?? media.width
|
||||
const height = varianta?.height ?? media.height
|
||||
|
||||
if (!url || !width || !height) return null
|
||||
|
||||
return { url, width, height, alt: media.alt ?? polozka.nazev }
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Styly veřejné části. Záměrně jeden soubor bez frameworku — web má tři
|
||||
* typy stránek a Tailwind by sem přinesl build krok navíc bez užitku.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--barva-text: #16181c;
|
||||
--barva-tlumena: #6b7280;
|
||||
--barva-pozadi: #ffffff;
|
||||
--barva-plocha: #f5f5f4;
|
||||
--barva-linka: #e2e0dd;
|
||||
--barva-akcent: #7a5c3e;
|
||||
--sirka: 1100px;
|
||||
--radius: 6px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--barva-text: #ececec;
|
||||
--barva-tlumena: #a1a1aa;
|
||||
--barva-pozadi: #141414;
|
||||
--barva-plocha: #1e1e1e;
|
||||
--barva-linka: #2e2e2e;
|
||||
--barva-akcent: #c9a227;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
font-size: 17px;
|
||||
line-height: 1.6;
|
||||
color: var(--barva-text);
|
||||
background: var(--barva-pozadi);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* ---------- hlavička a patička ---------- */
|
||||
|
||||
.hlavicka {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
max-width: var(--sirka);
|
||||
margin: 0 auto;
|
||||
padding: 1.5rem 1.25rem;
|
||||
border-bottom: 1px solid var(--barva-linka);
|
||||
}
|
||||
|
||||
.znacka {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.znacka span {
|
||||
display: block;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.hlavicka nav {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.hlavicka nav a {
|
||||
text-decoration: none;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.hlavicka nav a:hover {
|
||||
color: var(--barva-text);
|
||||
}
|
||||
|
||||
.paticka {
|
||||
max-width: var(--sirka);
|
||||
margin: 4rem auto 0;
|
||||
padding: 1.5rem 1.25rem 3rem;
|
||||
border-top: 1px solid var(--barva-linka);
|
||||
font-size: 0.85rem;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.paticka p {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
/* ---------- obecná stránka ---------- */
|
||||
|
||||
.stranka {
|
||||
max-width: var(--sirka);
|
||||
margin: 0 auto;
|
||||
padding: 2rem 1.25rem 0;
|
||||
}
|
||||
|
||||
.stranka h1 {
|
||||
margin: 0 0 1.5rem;
|
||||
font-size: clamp(1.6rem, 4vw, 2.2rem);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.prazdno {
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
/* ---------- výpis nabídky ---------- */
|
||||
|
||||
.mrizka {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
|
||||
gap: 1.75rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.karta a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.karta__obrazek {
|
||||
aspect-ratio: 4 / 3;
|
||||
overflow: hidden;
|
||||
background: var(--barva-plocha);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.karta__obrazek img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.karta a:hover .karta__obrazek img {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.karta__bezobrazku {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
height: 100%;
|
||||
font-size: 0.85rem;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.karta h2 {
|
||||
margin: 0.75rem 0 0.25rem;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.karta__cena {
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
color: var(--barva-akcent);
|
||||
}
|
||||
|
||||
.karta__stav {
|
||||
margin: 0.1rem 0 0;
|
||||
font-size: 0.85rem;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
/* Prodané položky zůstávají ve výpisu, ale nekřičí. */
|
||||
.karta--prodano .karta__obrazek img {
|
||||
filter: grayscale(1);
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
/* ---------- detail položky ---------- */
|
||||
|
||||
.zpet {
|
||||
margin: 0 0 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.detail__cena {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
margin: -0.75rem 0 1.75rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 600;
|
||||
color: var(--barva-akcent);
|
||||
}
|
||||
|
||||
.znacka-stavu {
|
||||
padding: 0.15rem 0.6rem;
|
||||
border: 1px solid var(--barva-linka);
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.znacka-stavu--prodano {
|
||||
border-color: transparent;
|
||||
background: var(--barva-plocha);
|
||||
}
|
||||
|
||||
.galerie {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.galerie img {
|
||||
width: 100%;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.parametry {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.parametry th,
|
||||
.parametry td {
|
||||
padding: 0.6rem 0;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid var(--barva-linka);
|
||||
}
|
||||
|
||||
.parametry th {
|
||||
width: 40%;
|
||||
font-weight: 500;
|
||||
color: var(--barva-tlumena);
|
||||
}
|
||||
|
||||
.popis {
|
||||
max-width: 65ch;
|
||||
white-space: pre-line;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) =>
|
||||
NotFoundPage({ config, params, searchParams, importMap })
|
||||
|
||||
export default NotFound
|
||||
@@ -0,0 +1,24 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const Page = ({ params, searchParams }: Args) =>
|
||||
RootPage({ config, params, searchParams, importMap })
|
||||
|
||||
export default Page
|
||||
@@ -0,0 +1,52 @@
|
||||
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc'
|
||||
|
||||
/** @type import('payload').ImportMap */
|
||||
export const importMap = {
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import {
|
||||
REST_DELETE,
|
||||
REST_GET,
|
||||
REST_OPTIONS,
|
||||
REST_PATCH,
|
||||
REST_POST,
|
||||
REST_PUT,
|
||||
} from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = REST_GET(config)
|
||||
export const POST = REST_POST(config)
|
||||
export const DELETE = REST_DELETE(config)
|
||||
export const PATCH = REST_PATCH(config)
|
||||
export const PUT = REST_PUT(config)
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
@@ -0,0 +1,7 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -0,0 +1,8 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
@@ -0,0 +1,31 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import type { ServerFunctionClient } from 'payload'
|
||||
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
|
||||
import React from 'react'
|
||||
|
||||
import { importMap } from './admin/importMap.js'
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const serverFunction: ServerFunctionClient = async function (args) {
|
||||
'use server'
|
||||
return handleServerFunctions({
|
||||
...args,
|
||||
config,
|
||||
importMap,
|
||||
})
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
|
||||
{children}
|
||||
</RootLayout>
|
||||
)
|
||||
|
||||
export default Layout
|
||||
Reference in New Issue
Block a user