kofi-stack-template-generator 2.1.46 → 2.1.48
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/.turbo/turbo-build.log +4 -4
- package/dist/index.js +10 -10
- package/package.json +2 -2
- package/src/templates.generated.ts +11 -11
- package/templates/marketing/payload/src/Footer/Component.client.tsx +15 -1
- package/templates/marketing/payload/src/Footer/Component.tsx +1 -1
- package/templates/marketing/payload/src/Header/Component.client.tsx +17 -1
- package/templates/marketing/payload/src/Header/Component.tsx +1 -1
- package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/seo.ts +1 -1
- package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/templates.ts +2 -2
- package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/b2b-vendor-hubs.ts +2 -2
- package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/communities.ts +1 -1
- package/templates/marketing/payload/src/payload.config.ts.hbs +3 -3
- package/templates/marketing/payload/src/utilities/getGlobals.ts +13 -6
|
@@ -13,7 +13,7 @@ import { ThemeSelector } from "@/providers/Theme/ThemeSelector"
|
|
|
13
13
|
import { cn } from "@/utilities/ui"
|
|
14
14
|
|
|
15
15
|
interface FooterClientProps {
|
|
16
|
-
data: Footer
|
|
16
|
+
data: Footer | null
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// Social icons as inline SVGs for flexibility
|
|
@@ -82,6 +82,20 @@ export const FooterClient: React.FC<FooterClientProps> = ({ data }) => {
|
|
|
82
82
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
83
83
|
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null)
|
|
84
84
|
|
|
85
|
+
// Show minimal footer when database isn't initialized yet
|
|
86
|
+
if (!data) {
|
|
87
|
+
return (
|
|
88
|
+
<footer className="mt-auto border-t border-border bg-background">
|
|
89
|
+
<div className="container mx-auto flex flex-col items-center justify-between gap-4 px-4 py-6 sm:flex-row">
|
|
90
|
+
<p className="text-sm text-muted-foreground">
|
|
91
|
+
Site not configured yet. Visit <Link href="/admin" className="underline hover:text-foreground">/admin</Link> to set up.
|
|
92
|
+
</p>
|
|
93
|
+
<ThemeSelector />
|
|
94
|
+
</div>
|
|
95
|
+
</footer>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
85
99
|
const { columns, socialLinks, newsletter, copyrightText, bottomLinks } = data
|
|
86
100
|
|
|
87
101
|
const handleNewsletterSubmit = async (e: React.FormEvent) => {
|
|
@@ -5,7 +5,7 @@ import type { Footer as FooterType } from "@/payload-types"
|
|
|
5
5
|
import { FooterClient } from "./Component.client"
|
|
6
6
|
|
|
7
7
|
export async function Footer() {
|
|
8
|
-
const footerData
|
|
8
|
+
const footerData = (await getCachedGlobal("footer", 1)()) as FooterType | null
|
|
9
9
|
|
|
10
10
|
return <FooterClient data={footerData} />
|
|
11
11
|
}
|
|
@@ -12,7 +12,7 @@ import { MobileMenu } from "./MobileMenu"
|
|
|
12
12
|
import { HeaderNav } from "./Nav"
|
|
13
13
|
|
|
14
14
|
interface HeaderClientProps {
|
|
15
|
-
data: Header
|
|
15
|
+
data: Header | null
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// Helper to get href from link data
|
|
@@ -57,6 +57,22 @@ export const HeaderClient: React.FC<HeaderClientProps> = ({ data }) => {
|
|
|
57
57
|
return rightButtonItems?.[0]
|
|
58
58
|
}, [data?.navItems])
|
|
59
59
|
|
|
60
|
+
// Show setup header when database isn't initialized yet
|
|
61
|
+
if (!data) {
|
|
62
|
+
return (
|
|
63
|
+
<header className="sticky top-0 z-20 border-b border-border bg-background">
|
|
64
|
+
<div className="container mx-auto px-4 h-16 flex justify-between items-center">
|
|
65
|
+
<div className="flex items-center gap-2">
|
|
66
|
+
<span className="text-xl font-semibold">Welcome</span>
|
|
67
|
+
</div>
|
|
68
|
+
<Button asChild size="sm">
|
|
69
|
+
<Link href="/admin">Setup Site →</Link>
|
|
70
|
+
</Button>
|
|
71
|
+
</div>
|
|
72
|
+
</header>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
60
76
|
return (
|
|
61
77
|
<header
|
|
62
78
|
className="sticky top-0 z-20 border-b border-border bg-background"
|
|
@@ -4,7 +4,7 @@ import { HeaderClient } from "./Component.client"
|
|
|
4
4
|
import type { Header as HeaderType } from "@/payload-types"
|
|
5
5
|
|
|
6
6
|
export async function Header() {
|
|
7
|
-
const headerData
|
|
7
|
+
const headerData = (await getCachedGlobal("header", 1)()) as HeaderType | null
|
|
8
8
|
|
|
9
9
|
return <HeaderClient data={headerData} />
|
|
10
10
|
}
|
|
@@ -131,7 +131,7 @@ export const integrationsPage = (): Partial<Page> => {
|
|
|
131
131
|
{
|
|
132
132
|
size: "small",
|
|
133
133
|
style: "gradient",
|
|
134
|
-
icon: "
|
|
134
|
+
icon: "globe",
|
|
135
135
|
title: "Communication",
|
|
136
136
|
description: createParagraph(
|
|
137
137
|
"Slack, Microsoft Teams, Discord, and email integrations.",
|
|
@@ -149,7 +149,7 @@ export const integrationsPage = (): Partial<Page> => {
|
|
|
149
149
|
{
|
|
150
150
|
size: "small",
|
|
151
151
|
style: "default",
|
|
152
|
-
icon: "
|
|
152
|
+
icon: "layers",
|
|
153
153
|
title: "Project Management",
|
|
154
154
|
description: createParagraph(
|
|
155
155
|
"Jira, Asana, Monday.com, Trello integrations.",
|
package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/b2b-vendor-hubs.ts
CHANGED
|
@@ -160,7 +160,7 @@ export const marketingPage = (): Partial<Page> => {
|
|
|
160
160
|
{
|
|
161
161
|
size: "small",
|
|
162
162
|
style: "accent",
|
|
163
|
-
icon: "
|
|
163
|
+
icon: "layers",
|
|
164
164
|
title: "Project Templates",
|
|
165
165
|
description: createParagraph("Pre-built templates for common campaigns."),
|
|
166
166
|
},
|
|
@@ -188,7 +188,7 @@ export const marketingPage = (): Partial<Page> => {
|
|
|
188
188
|
{
|
|
189
189
|
size: "small",
|
|
190
190
|
style: "default",
|
|
191
|
-
icon: "
|
|
191
|
+
icon: "globe",
|
|
192
192
|
title: "Collaboration",
|
|
193
193
|
description: createParagraph("Comments, feedback, and approvals in context."),
|
|
194
194
|
},
|
package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/communities.ts
CHANGED
|
@@ -188,7 +188,7 @@ export const productPage = (): Partial<Page> => {
|
|
|
188
188
|
{
|
|
189
189
|
size: "small",
|
|
190
190
|
style: "default",
|
|
191
|
-
icon: "
|
|
191
|
+
icon: "users",
|
|
192
192
|
title: "Stakeholder Updates",
|
|
193
193
|
description: createParagraph("Keep leadership informed automatically."),
|
|
194
194
|
},
|
|
@@ -64,9 +64,9 @@ export default buildConfig({
|
|
|
64
64
|
pool: {
|
|
65
65
|
connectionString: process.env.DATABASE_URL || "",
|
|
66
66
|
},
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
push:
|
|
67
|
+
// Auto-sync schema in development for better DX (first launch works immediately)
|
|
68
|
+
// In production, use explicit migrations: pnpm payload migrate
|
|
69
|
+
push: process.env.NODE_ENV !== "production",
|
|
70
70
|
}),
|
|
71
71
|
collections: [Pages, Posts, Media, Categories, FAQs, Users],
|
|
72
72
|
cors: [getServerSideURL()].filter(Boolean),
|
|
@@ -7,14 +7,21 @@ import { getPayload } from "payload"
|
|
|
7
7
|
type Global = keyof Config["globals"]
|
|
8
8
|
|
|
9
9
|
async function getGlobal(slug: Global, depth = 0) {
|
|
10
|
-
|
|
10
|
+
try {
|
|
11
|
+
const payload = await getPayload({ config: configPromise })
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const global = await payload.findGlobal({
|
|
14
|
+
slug,
|
|
15
|
+
depth,
|
|
16
|
+
})
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
return global
|
|
19
|
+
} catch (error) {
|
|
20
|
+
// Database tables may not exist yet on first launch
|
|
21
|
+
// Return null so components can show a setup UI instead of crashing
|
|
22
|
+
console.warn(`Could not fetch global "${String(slug)}". Database may not be initialized yet.`)
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
/**
|