kofi-stack-template-generator 2.1.27 → 2.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +336 -9
- package/package.json +8 -8
- package/src/templates.generated.ts +70 -11
- package/templates/marketing/payload/src/Footer/config.ts.hbs +178 -0
- package/templates/marketing/payload/src/Footer/hooks/revalidateFooter.ts.hbs +13 -0
- package/templates/marketing/payload/src/Footer/index.ts.hbs +1 -0
- package/templates/marketing/payload/src/Header/RowLabel.tsx.hbs +21 -0
- package/templates/marketing/payload/src/Header/config.ts.hbs +208 -0
- package/templates/marketing/payload/src/Header/hooks/revalidateHeader.ts.hbs +13 -0
- package/templates/marketing/payload/src/Header/index.ts.hbs +1 -0
- package/templates/marketing/payload/src/access/anyone.ts.hbs +3 -0
- package/templates/marketing/payload/src/access/authenticated.ts.hbs +9 -0
- package/templates/marketing/payload/src/access/authenticatedOrPublished.ts.hbs +13 -0
- package/templates/marketing/payload/src/access/index.ts.hbs +3 -0
- package/templates/marketing/payload/src/app/(frontend)/next/seed/route.ts.hbs +31 -0
- package/templates/marketing/payload/src/collections/Categories/index.ts.hbs +28 -0
- package/templates/marketing/payload/src/collections/FAQs/index.ts.hbs +100 -0
- package/templates/marketing/payload/src/collections/Media.ts.hbs +148 -28
- package/templates/marketing/payload/src/collections/Pages/hooks/revalidatePage.ts.hbs +43 -0
- package/templates/marketing/payload/src/collections/Pages/index.ts.hbs +142 -0
- package/templates/marketing/payload/src/collections/Posts/hooks/populateAuthors.ts.hbs +41 -0
- package/templates/marketing/payload/src/collections/Posts/hooks/revalidatePost.ts.hbs +44 -0
- package/templates/marketing/payload/src/collections/Posts/index.ts.hbs +244 -0
- package/templates/marketing/payload/src/collections/Users/index.ts.hbs +26 -0
- package/templates/marketing/payload/src/collections/index.ts.hbs +6 -4
- package/templates/marketing/payload/src/components/BeforeDashboard/SeedButton/index.scss.hbs +12 -0
- package/templates/marketing/payload/src/components/BeforeDashboard/SeedButton/index.tsx.hbs +89 -0
- package/templates/marketing/payload/src/components/BeforeDashboard/index.scss.hbs +24 -0
- package/templates/marketing/payload/src/components/BeforeDashboard/index.tsx.hbs +69 -0
- package/templates/marketing/payload/src/components/BeforeLogin/index.tsx.hbs +14 -0
- package/templates/marketing/payload/src/components/Link/index.tsx.hbs +79 -0
- package/templates/marketing/payload/src/components/Media/index.tsx.hbs +67 -0
- package/templates/marketing/payload/src/components/RichText/index.tsx.hbs +44 -0
- package/templates/marketing/payload/src/endpoints/seed/home.ts.hbs +76 -0
- package/templates/marketing/payload/src/endpoints/seed/image-1.ts.hbs +5 -0
- package/templates/marketing/payload/src/endpoints/seed/image-2.ts.hbs +5 -0
- package/templates/marketing/payload/src/endpoints/seed/image-hero.ts.hbs +5 -0
- package/templates/marketing/payload/src/endpoints/seed/index.ts.hbs +235 -0
- package/templates/marketing/payload/src/endpoints/seed/post-1.ts.hbs +252 -0
- package/templates/marketing/payload/src/fields/defaultLexical.ts.hbs +73 -0
- package/templates/marketing/payload/src/fields/index.ts.hbs +3 -0
- package/templates/marketing/payload/src/fields/link.ts.hbs +139 -0
- package/templates/marketing/payload/src/fields/linkGroup.ts.hbs +28 -0
- package/templates/marketing/payload/src/globals/index.ts.hbs +2 -2
- package/templates/marketing/payload/src/heros/HighImpact/index.tsx.hbs +53 -0
- package/templates/marketing/payload/src/heros/LowImpact/index.tsx.hbs +48 -0
- package/templates/marketing/payload/src/heros/MediumImpact/index.tsx.hbs +46 -0
- package/templates/marketing/payload/src/heros/PostHero/index.tsx.hbs +68 -0
- package/templates/marketing/payload/src/heros/ProductShowcase/index.tsx.hbs +88 -0
- package/templates/marketing/payload/src/heros/RenderHero.tsx.hbs +27 -0
- package/templates/marketing/payload/src/heros/config.ts.hbs +112 -0
- package/templates/marketing/payload/src/heros/index.ts.hbs +7 -0
- package/templates/marketing/payload/src/hooks/index.ts.hbs +2 -0
- package/templates/marketing/payload/src/hooks/populatePublishedAt.ts.hbs +15 -0
- package/templates/marketing/payload/src/hooks/revalidateRedirects.ts.hbs +11 -0
- package/templates/marketing/payload/src/payload.config.ts.hbs +32 -8
- package/templates/marketing/payload/src/providers/HeaderTheme/index.tsx.hbs +34 -0
- package/templates/marketing/payload/src/providers/Theme/InitTheme/index.tsx.hbs +44 -0
- package/templates/marketing/payload/src/providers/Theme/index.tsx.hbs +60 -0
- package/templates/marketing/payload/src/providers/Theme/shared.ts.hbs +17 -0
- package/templates/marketing/payload/src/providers/Theme/types.ts.hbs +10 -0
- package/templates/marketing/payload/src/providers/index.tsx.hbs +18 -0
- package/templates/marketing/payload/src/utilities/canUseDOM.ts.hbs +1 -0
- package/templates/marketing/payload/src/utilities/deepMerge.ts.hbs +35 -0
- package/templates/marketing/payload/src/utilities/formatAuthors.ts.hbs +24 -0
- package/templates/marketing/payload/src/utilities/formatDateTime.ts.hbs +13 -0
- package/templates/marketing/payload/src/utilities/generateMeta.ts.hbs +87 -0
- package/templates/marketing/payload/src/utilities/generatePreviewPath.ts.hbs +33 -0
- package/templates/marketing/payload/src/utilities/getURL.ts.hbs +26 -0
- package/templates/marketing/payload/src/utilities/index.ts.hbs +8 -0
- package/templates/marketing/payload/src/utilities/mergeOpenGraph.ts.hbs +26 -0
- package/templates/marketing/payload/src/collections/Pages.ts.hbs +0 -66
- package/templates/marketing/payload/src/collections/Posts.ts.hbs +0 -65
- package/templates/marketing/payload/src/collections/Users.ts.hbs +0 -25
- package/templates/marketing/payload/src/globals/Navigation.ts.hbs +0 -51
- package/templates/marketing/payload/src/globals/SiteSettings.ts.hbs +0 -49
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CollectionConfig } from "payload"
|
|
2
|
+
|
|
3
|
+
import { authenticated } from "../../access/authenticated"
|
|
4
|
+
|
|
5
|
+
export const Users: CollectionConfig = {
|
|
6
|
+
slug: "users",
|
|
7
|
+
access: {
|
|
8
|
+
admin: authenticated,
|
|
9
|
+
create: authenticated,
|
|
10
|
+
delete: authenticated,
|
|
11
|
+
read: authenticated,
|
|
12
|
+
update: authenticated,
|
|
13
|
+
},
|
|
14
|
+
admin: {
|
|
15
|
+
defaultColumns: ["name", "email"],
|
|
16
|
+
useAsTitle: "name",
|
|
17
|
+
},
|
|
18
|
+
auth: true,
|
|
19
|
+
fields: [
|
|
20
|
+
{
|
|
21
|
+
name: "name",
|
|
22
|
+
type: "text",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
timestamps: true,
|
|
26
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { Users } from
|
|
2
|
-
export { Media } from
|
|
3
|
-
export { Pages } from
|
|
4
|
-
export { Posts } from
|
|
1
|
+
export { Users } from "./Users"
|
|
2
|
+
export { Media } from "./Media"
|
|
3
|
+
export { Pages } from "./Pages"
|
|
4
|
+
export { Posts } from "./Posts"
|
|
5
|
+
export { Categories } from "./Categories"
|
|
6
|
+
export { FAQs } from "./FAQs"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { toast } from "@payloadcms/ui"
|
|
4
|
+
import type React from "react"
|
|
5
|
+
import { Fragment, useCallback, useState } from "react"
|
|
6
|
+
|
|
7
|
+
import "./index.scss"
|
|
8
|
+
|
|
9
|
+
const SuccessMessage: React.FC = () => (
|
|
10
|
+
<div>
|
|
11
|
+
Database seeded! You can now{" "}
|
|
12
|
+
<a target="_blank" href="/" rel="noreferrer">
|
|
13
|
+
visit your website
|
|
14
|
+
</a>
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
export const SeedButton: React.FC = () => {
|
|
19
|
+
const [loading, setLoading] = useState(false)
|
|
20
|
+
const [seeded, setSeeded] = useState(false)
|
|
21
|
+
const [error, setError] = useState<null | string>(null)
|
|
22
|
+
|
|
23
|
+
const handleClick = useCallback(
|
|
24
|
+
async (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
25
|
+
e.preventDefault()
|
|
26
|
+
|
|
27
|
+
if (seeded) {
|
|
28
|
+
toast.info("Database already seeded.")
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
if (loading) {
|
|
32
|
+
toast.info("Seeding already in progress.")
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
if (error) {
|
|
36
|
+
toast.error(`An error occurred, please refresh and try again.`)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setLoading(true)
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
toast.promise(
|
|
44
|
+
new Promise((resolve, reject) => {
|
|
45
|
+
try {
|
|
46
|
+
fetch("/next/seed", { method: "POST", credentials: "include" })
|
|
47
|
+
.then((res) => {
|
|
48
|
+
if (res.ok) {
|
|
49
|
+
resolve(true)
|
|
50
|
+
setSeeded(true)
|
|
51
|
+
} else {
|
|
52
|
+
reject("An error occurred while seeding.")
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.catch((error) => {
|
|
56
|
+
reject(error)
|
|
57
|
+
})
|
|
58
|
+
} catch (error) {
|
|
59
|
+
reject(error)
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
{
|
|
63
|
+
loading: "Seeding with data....",
|
|
64
|
+
success: <SuccessMessage />,
|
|
65
|
+
error: "An error occurred while seeding.",
|
|
66
|
+
},
|
|
67
|
+
)
|
|
68
|
+
} catch (err) {
|
|
69
|
+
const error = err instanceof Error ? err.message : String(err)
|
|
70
|
+
setError(error)
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
[loading, seeded, error],
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
let message = ""
|
|
77
|
+
if (loading) message = " (seeding...)"
|
|
78
|
+
if (seeded) message = " (done!)"
|
|
79
|
+
if (error) message = ` (error: ${error})`
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<Fragment>
|
|
83
|
+
<button className="seedButton" onClick={handleClick}>
|
|
84
|
+
Seed your database
|
|
85
|
+
</button>
|
|
86
|
+
{message}
|
|
87
|
+
</Fragment>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@import '~@payloadcms/ui/scss';
|
|
2
|
+
|
|
3
|
+
.dashboard .before-dashboard {
|
|
4
|
+
margin-bottom: base(1.5);
|
|
5
|
+
|
|
6
|
+
&__banner {
|
|
7
|
+
& h4 {
|
|
8
|
+
margin: 0;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&__instructions {
|
|
13
|
+
list-style: decimal;
|
|
14
|
+
margin-bottom: base(0.5);
|
|
15
|
+
|
|
16
|
+
& li {
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
& a:hover {
|
|
22
|
+
opacity: 0.85;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Banner } from "@payloadcms/ui/elements/Banner"
|
|
2
|
+
import type React from "react"
|
|
3
|
+
|
|
4
|
+
import { SeedButton } from "./SeedButton"
|
|
5
|
+
import "./index.scss"
|
|
6
|
+
|
|
7
|
+
const baseClass = "before-dashboard"
|
|
8
|
+
|
|
9
|
+
const BeforeDashboard: React.FC = () => {
|
|
10
|
+
return (
|
|
11
|
+
<div className={baseClass}>
|
|
12
|
+
<Banner className={`${baseClass}__banner`} type="success">
|
|
13
|
+
<h4>Welcome to your dashboard!</h4>
|
|
14
|
+
</Banner>
|
|
15
|
+
Here's what to do next:
|
|
16
|
+
<ul className={`${baseClass}__instructions`}>
|
|
17
|
+
<li>
|
|
18
|
+
<SeedButton />
|
|
19
|
+
{" with a few pages and posts to jump-start your new site, then "}
|
|
20
|
+
<a href="/" target="_blank" rel="noreferrer">
|
|
21
|
+
visit your website
|
|
22
|
+
</a>
|
|
23
|
+
{" to see the results."}
|
|
24
|
+
</li>
|
|
25
|
+
<li>
|
|
26
|
+
{"Modify your "}
|
|
27
|
+
<a
|
|
28
|
+
href="https://payloadcms.com/docs/configuration/collections"
|
|
29
|
+
rel="noopener noreferrer"
|
|
30
|
+
target="_blank"
|
|
31
|
+
>
|
|
32
|
+
collections
|
|
33
|
+
</a>
|
|
34
|
+
{" and add more "}
|
|
35
|
+
<a
|
|
36
|
+
href="https://payloadcms.com/docs/fields/overview"
|
|
37
|
+
rel="noopener noreferrer"
|
|
38
|
+
target="_blank"
|
|
39
|
+
>
|
|
40
|
+
fields
|
|
41
|
+
</a>
|
|
42
|
+
{" as needed. If you are new to Payload, we also recommend you check out the "}
|
|
43
|
+
<a
|
|
44
|
+
href="https://payloadcms.com/docs/getting-started/what-is-payload"
|
|
45
|
+
rel="noopener noreferrer"
|
|
46
|
+
target="_blank"
|
|
47
|
+
>
|
|
48
|
+
Getting Started
|
|
49
|
+
</a>
|
|
50
|
+
{" docs."}
|
|
51
|
+
</li>
|
|
52
|
+
<li>
|
|
53
|
+
Commit and push your changes to the repository to trigger a redeployment of your project.
|
|
54
|
+
</li>
|
|
55
|
+
</ul>
|
|
56
|
+
{"Pro Tip: This block is a "}
|
|
57
|
+
<a
|
|
58
|
+
href="https://payloadcms.com/docs/custom-components/overview"
|
|
59
|
+
rel="noopener noreferrer"
|
|
60
|
+
target="_blank"
|
|
61
|
+
>
|
|
62
|
+
custom component
|
|
63
|
+
</a>
|
|
64
|
+
, you can remove it at any time by updating your <strong>payload.config</strong>.
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default BeforeDashboard
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
|
|
3
|
+
const BeforeLogin: React.FC = () => {
|
|
4
|
+
return (
|
|
5
|
+
<div>
|
|
6
|
+
<p>
|
|
7
|
+
<b>Welcome to your dashboard!</b>
|
|
8
|
+
{" This is where site admins will log in to manage your website."}
|
|
9
|
+
</p>
|
|
10
|
+
</div>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default BeforeLogin
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils"
|
|
2
|
+
import Link from "next/link"
|
|
3
|
+
import type React from "react"
|
|
4
|
+
|
|
5
|
+
import type { Page, Post } from "@/payload-types"
|
|
6
|
+
|
|
7
|
+
type CMSLinkType = {
|
|
8
|
+
appearance?: "inline" | "default" | "outline" | "link"
|
|
9
|
+
children?: React.ReactNode
|
|
10
|
+
className?: string
|
|
11
|
+
label?: string | null
|
|
12
|
+
newTab?: boolean | null
|
|
13
|
+
reference?: {
|
|
14
|
+
relationTo: "pages" | "posts"
|
|
15
|
+
value: Page | Post | string | number
|
|
16
|
+
} | null
|
|
17
|
+
size?: "default" | "sm" | "lg" | null
|
|
18
|
+
type?: "custom" | "reference" | null
|
|
19
|
+
url?: string | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const CMSLink: React.FC<CMSLinkType> = (props) => {
|
|
23
|
+
const {
|
|
24
|
+
type,
|
|
25
|
+
appearance = "inline",
|
|
26
|
+
children,
|
|
27
|
+
className,
|
|
28
|
+
label,
|
|
29
|
+
newTab,
|
|
30
|
+
reference,
|
|
31
|
+
size = "default",
|
|
32
|
+
url,
|
|
33
|
+
} = props
|
|
34
|
+
|
|
35
|
+
const href =
|
|
36
|
+
type === "reference" && typeof reference?.value === "object" && reference.value.slug
|
|
37
|
+
? `${reference?.relationTo !== "pages" ? `/${reference?.relationTo}` : ""}/${
|
|
38
|
+
reference.value.slug
|
|
39
|
+
}`
|
|
40
|
+
: url
|
|
41
|
+
|
|
42
|
+
if (!href) return null
|
|
43
|
+
|
|
44
|
+
const newTabProps = newTab ? { rel: "noopener noreferrer", target: "_blank" } : {}
|
|
45
|
+
|
|
46
|
+
// Size classes
|
|
47
|
+
const sizeClasses = {
|
|
48
|
+
default: "px-4 py-2",
|
|
49
|
+
sm: "px-3 py-1 text-sm",
|
|
50
|
+
lg: "px-6 py-3 text-lg",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Appearance classes
|
|
54
|
+
const appearanceClasses = {
|
|
55
|
+
inline: "",
|
|
56
|
+
default: cn(
|
|
57
|
+
"inline-flex items-center justify-center rounded-md font-medium transition-colors",
|
|
58
|
+
"bg-primary text-primary-foreground hover:bg-primary/90",
|
|
59
|
+
sizeClasses[size || "default"]
|
|
60
|
+
),
|
|
61
|
+
outline: cn(
|
|
62
|
+
"inline-flex items-center justify-center rounded-md font-medium transition-colors",
|
|
63
|
+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
64
|
+
sizeClasses[size || "default"]
|
|
65
|
+
),
|
|
66
|
+
link: "underline-offset-4 hover:underline",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<Link
|
|
71
|
+
className={cn(appearanceClasses[appearance], className)}
|
|
72
|
+
href={href || url || ""}
|
|
73
|
+
{...newTabProps}
|
|
74
|
+
>
|
|
75
|
+
{label && label}
|
|
76
|
+
{children && children}
|
|
77
|
+
</Link>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
import Image from "next/image"
|
|
5
|
+
import type React from "react"
|
|
6
|
+
|
|
7
|
+
import type { Media as MediaType } from "@/payload-types"
|
|
8
|
+
|
|
9
|
+
export interface MediaProps {
|
|
10
|
+
resource?: MediaType | string | number | null
|
|
11
|
+
alt?: string
|
|
12
|
+
className?: string
|
|
13
|
+
imgClassName?: string
|
|
14
|
+
fill?: boolean
|
|
15
|
+
priority?: boolean
|
|
16
|
+
size?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const Media: React.FC<MediaProps> = ({
|
|
20
|
+
resource,
|
|
21
|
+
alt: altFromProps,
|
|
22
|
+
className,
|
|
23
|
+
imgClassName,
|
|
24
|
+
fill = false,
|
|
25
|
+
priority = false,
|
|
26
|
+
size,
|
|
27
|
+
}) => {
|
|
28
|
+
// If resource is not an object or is null/undefined, return null
|
|
29
|
+
if (!resource || typeof resource !== "object") {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { url, alt: altFromResource, width, height } = resource
|
|
34
|
+
|
|
35
|
+
const alt = altFromProps ?? altFromResource ?? ""
|
|
36
|
+
|
|
37
|
+
if (!url) return null
|
|
38
|
+
|
|
39
|
+
// Handle fill mode
|
|
40
|
+
if (fill) {
|
|
41
|
+
return (
|
|
42
|
+
<div className={cn("relative", className)}>
|
|
43
|
+
<Image
|
|
44
|
+
src={url}
|
|
45
|
+
alt={alt}
|
|
46
|
+
fill
|
|
47
|
+
className={cn("object-cover", imgClassName)}
|
|
48
|
+
priority={priority}
|
|
49
|
+
sizes={size || "100vw"}
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Handle normal mode with width/height
|
|
56
|
+
return (
|
|
57
|
+
<Image
|
|
58
|
+
src={url}
|
|
59
|
+
alt={alt}
|
|
60
|
+
width={width || 800}
|
|
61
|
+
height={height || 600}
|
|
62
|
+
className={cn(className, imgClassName)}
|
|
63
|
+
priority={priority}
|
|
64
|
+
sizes={size}
|
|
65
|
+
/>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DefaultTypedEditorState } from "@payloadcms/richtext-lexical"
|
|
2
|
+
import {
|
|
3
|
+
RichText as ConvertRichText,
|
|
4
|
+
type JSXConvertersFunction,
|
|
5
|
+
LinkJSXConverter,
|
|
6
|
+
} from "@payloadcms/richtext-lexical/react"
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
import type React from "react"
|
|
9
|
+
|
|
10
|
+
const jsxConverters: JSXConvertersFunction = ({ defaultConverters }) => ({
|
|
11
|
+
...defaultConverters,
|
|
12
|
+
...LinkJSXConverter({ internalDocToHref: ({ linkNode }) => {
|
|
13
|
+
const { value, relationTo } = linkNode.fields.doc || {}
|
|
14
|
+
if (typeof value !== "object" || !value) return "/"
|
|
15
|
+
const slug = value.slug
|
|
16
|
+
return relationTo === "posts" ? `/posts/${slug}` : `/${slug}`
|
|
17
|
+
}}),
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
type Props = {
|
|
21
|
+
data: DefaultTypedEditorState
|
|
22
|
+
enableGutter?: boolean
|
|
23
|
+
enableProse?: boolean
|
|
24
|
+
} & React.HTMLAttributes<HTMLDivElement>
|
|
25
|
+
|
|
26
|
+
export default function RichText(props: Props) {
|
|
27
|
+
const { className, enableProse = true, enableGutter = true, ...rest } = props
|
|
28
|
+
return (
|
|
29
|
+
<ConvertRichText
|
|
30
|
+
converters={jsxConverters}
|
|
31
|
+
className={cn(
|
|
32
|
+
"payload-richtext",
|
|
33
|
+
{
|
|
34
|
+
container: enableGutter,
|
|
35
|
+
"prose prose-lg dark:prose-invert prose-headings:font-bold prose-headings:tracking-tight prose-a:text-primary prose-a:no-underline hover:prose-a:underline prose-blockquote:border-l-primary prose-blockquote:not-italic prose-li:marker:text-muted-foreground":
|
|
36
|
+
enableProse,
|
|
37
|
+
},
|
|
38
|
+
!enableGutter && "max-w-none",
|
|
39
|
+
className,
|
|
40
|
+
)}
|
|
41
|
+
{...rest}
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Media } from "@/payload-types"
|
|
2
|
+
import type { RequiredDataFromCollectionSlug } from "payload"
|
|
3
|
+
|
|
4
|
+
type HomeArgs = {
|
|
5
|
+
heroImage: Media
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const home: (args: HomeArgs) => RequiredDataFromCollectionSlug<"pages"> = ({
|
|
9
|
+
heroImage,
|
|
10
|
+
}) => {
|
|
11
|
+
return {
|
|
12
|
+
slug: "home",
|
|
13
|
+
_status: "published",
|
|
14
|
+
title: "Home",
|
|
15
|
+
layout: [
|
|
16
|
+
{
|
|
17
|
+
blockType: "hero",
|
|
18
|
+
heading: "Welcome to {{projectName}}",
|
|
19
|
+
subheading: "Build something amazing with Payload CMS and Next.js",
|
|
20
|
+
primaryCta: {
|
|
21
|
+
label: "Get Started",
|
|
22
|
+
url: "/posts",
|
|
23
|
+
},
|
|
24
|
+
secondaryCta: {
|
|
25
|
+
label: "Learn More",
|
|
26
|
+
url: "/contact",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
blockType: "features",
|
|
31
|
+
heading: "Core Features",
|
|
32
|
+
subheading: "Everything you need to build modern websites",
|
|
33
|
+
features: [
|
|
34
|
+
{
|
|
35
|
+
icon: "layout",
|
|
36
|
+
title: "Page Builder",
|
|
37
|
+
description: "Create beautiful pages with our flexible block-based editor.",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
icon: "zap",
|
|
41
|
+
title: "Lightning Fast",
|
|
42
|
+
description: "Optimized for performance with Next.js and React Server Components.",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
icon: "shield",
|
|
46
|
+
title: "Secure by Default",
|
|
47
|
+
description: "Built-in authentication and role-based access control.",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
icon: "database",
|
|
51
|
+
title: "Flexible Database",
|
|
52
|
+
description: "Works with MongoDB, PostgreSQL, and other databases.",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
blockType: "cta",
|
|
58
|
+
heading: "Ready to get started?",
|
|
59
|
+
subheading: "Start building your next project today.",
|
|
60
|
+
primaryCta: {
|
|
61
|
+
label: "View Posts",
|
|
62
|
+
url: "/posts",
|
|
63
|
+
},
|
|
64
|
+
secondaryCta: {
|
|
65
|
+
label: "Contact Us",
|
|
66
|
+
url: "/contact",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
meta: {
|
|
71
|
+
description: "Welcome to {{projectName}} - Built with Payload CMS and Next.js",
|
|
72
|
+
image: heroImage.id,
|
|
73
|
+
title: "{{projectName}}",
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|