kofi-stack-template-generator 2.1.54 → 2.1.55
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 +5 -5
- package/dist/index.js +51 -271
- package/package.json +2 -2
- package/src/templates.generated.ts +10 -10
- package/templates/marketing/astro/src/components/Footer.astro +9 -27
- package/templates/marketing/astro/src/components/Header.astro +9 -241
- package/templates/marketing/astro/src/pages/index.astro +18 -12
- package/templates/marketing/astro/src/styles/globals.css.hbs +824 -0
- package/templates/marketing/nextjs/src/app/globals.css.hbs +824 -0
- package/templates/marketing/nextjs/src/app/page.tsx.hbs +18 -12
- package/templates/marketing/nextjs/src/components/Footer/index.tsx +12 -33
- package/templates/marketing/nextjs/src/components/Header/MobileMenu.tsx +8 -117
- package/templates/marketing/nextjs/src/components/Header/index.tsx +14 -105
|
@@ -46,10 +46,12 @@ export default function HomePage() {
|
|
|
46
46
|
/>
|
|
47
47
|
|
|
48
48
|
{/* Bento Features */}
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
<section id="features">
|
|
50
|
+
<BentoFeatures
|
|
51
|
+
heading="Discover what SaaSify can do"
|
|
52
|
+
subheading="Everything you need to work smarter and scale faster"
|
|
53
|
+
/>
|
|
54
|
+
</section>
|
|
53
55
|
|
|
54
56
|
{/* Feature Showcase: Integrations */}
|
|
55
57
|
<FeatureShowcase
|
|
@@ -118,10 +120,12 @@ export default function HomePage() {
|
|
|
118
120
|
/>
|
|
119
121
|
|
|
120
122
|
{/* Testimonials */}
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
<section id="testimonials">
|
|
124
|
+
<TestimonialsGrid
|
|
125
|
+
heading="Loved by teams at companies of all sizes"
|
|
126
|
+
subheading="See how leading teams use SaaSify to drive growth and productivity."
|
|
127
|
+
/>
|
|
128
|
+
</section>
|
|
125
129
|
|
|
126
130
|
{/* Trust Columns */}
|
|
127
131
|
<TrustColumns />
|
|
@@ -141,10 +145,12 @@ export default function HomePage() {
|
|
|
141
145
|
/>
|
|
142
146
|
|
|
143
147
|
{/* Pricing */}
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
<section id="pricing">
|
|
149
|
+
<PricingTable
|
|
150
|
+
heading="Simple, transparent pricing"
|
|
151
|
+
subheading="Start free, upgrade as your team grows. No hidden fees."
|
|
152
|
+
/>
|
|
153
|
+
</section>
|
|
148
154
|
|
|
149
155
|
{/* Final CTA */}
|
|
150
156
|
<FinalCTA
|
|
@@ -3,36 +3,28 @@
|
|
|
3
3
|
import Link from "next/link"
|
|
4
4
|
import { Logo } from "@/components/Logo"
|
|
5
5
|
import { ThemeSelector } from "@/components/ThemeSelector"
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
7
6
|
|
|
8
|
-
// Footer navigation structure
|
|
7
|
+
// Footer navigation structure - using anchor links for landing page
|
|
9
8
|
const footerColumns = [
|
|
10
9
|
{
|
|
11
10
|
title: "Product",
|
|
12
11
|
links: [
|
|
13
12
|
{ label: "Home", href: "/" },
|
|
14
|
-
{ label: "
|
|
15
|
-
{ label: "
|
|
13
|
+
{ label: "Features", href: "#features" },
|
|
14
|
+
{ label: "Pricing", href: "#pricing" },
|
|
16
15
|
],
|
|
17
16
|
},
|
|
18
17
|
{
|
|
19
18
|
title: "Resources",
|
|
20
19
|
links: [
|
|
21
|
-
{ label: "
|
|
22
|
-
{ label: "Documentation", href: "/docs" },
|
|
23
|
-
],
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
title: "Company",
|
|
27
|
-
links: [
|
|
28
|
-
{ label: "About", href: "/about" },
|
|
20
|
+
{ label: "Testimonials", href: "#testimonials" },
|
|
29
21
|
],
|
|
30
22
|
},
|
|
31
23
|
{
|
|
32
24
|
title: "Legal",
|
|
33
25
|
links: [
|
|
34
|
-
{ label: "Privacy", href: "
|
|
35
|
-
{ label: "Terms", href: "
|
|
26
|
+
{ label: "Privacy", href: "#" },
|
|
27
|
+
{ label: "Terms", href: "#" },
|
|
36
28
|
],
|
|
37
29
|
},
|
|
38
30
|
]
|
|
@@ -43,10 +35,6 @@ const socialLinks = {
|
|
|
43
35
|
github: "https://github.com/saasify",
|
|
44
36
|
}
|
|
45
37
|
|
|
46
|
-
const bottomLinks = [
|
|
47
|
-
{ label: "Contact Support", href: "/support" },
|
|
48
|
-
]
|
|
49
|
-
|
|
50
38
|
// Social icons as inline SVGs
|
|
51
39
|
const SocialIcons = {
|
|
52
40
|
twitter: (
|
|
@@ -77,7 +65,7 @@ export function Footer() {
|
|
|
77
65
|
<footer className="mt-auto border-t border-border bg-background">
|
|
78
66
|
{/* Main Footer Content */}
|
|
79
67
|
<div className="container mx-auto px-4 py-12 lg:py-16">
|
|
80
|
-
<div className="grid grid-cols-2 gap-8 md:grid-cols-3 lg:grid-cols-
|
|
68
|
+
<div className="grid grid-cols-2 gap-8 md:grid-cols-3 lg:grid-cols-5">
|
|
81
69
|
{/* Link Columns */}
|
|
82
70
|
{footerColumns.map((column) => (
|
|
83
71
|
<div key={column.title} className="col-span-1">
|
|
@@ -86,13 +74,13 @@ export function Footer() {
|
|
|
86
74
|
</h3>
|
|
87
75
|
<ul className="space-y-3">
|
|
88
76
|
{column.links.map((link) => (
|
|
89
|
-
<li key={link.
|
|
90
|
-
<
|
|
77
|
+
<li key={link.label}>
|
|
78
|
+
<a
|
|
91
79
|
href={link.href}
|
|
92
80
|
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
|
|
93
81
|
>
|
|
94
82
|
{link.label}
|
|
95
|
-
</
|
|
83
|
+
</a>
|
|
96
84
|
</li>
|
|
97
85
|
))}
|
|
98
86
|
</ul>
|
|
@@ -100,7 +88,7 @@ export function Footer() {
|
|
|
100
88
|
))}
|
|
101
89
|
|
|
102
90
|
{/* Newsletter Column */}
|
|
103
|
-
<div className="col-span-2
|
|
91
|
+
<div className="col-span-2">
|
|
104
92
|
<h3 className="mb-4 text-sm font-medium text-foreground">
|
|
105
93
|
Newsletter
|
|
106
94
|
</h3>
|
|
@@ -168,17 +156,8 @@ export function Footer() {
|
|
|
168
156
|
</p>
|
|
169
157
|
</div>
|
|
170
158
|
|
|
171
|
-
{/*
|
|
159
|
+
{/* Theme Selector */}
|
|
172
160
|
<div className="flex items-center gap-6">
|
|
173
|
-
{bottomLinks.map((link) => (
|
|
174
|
-
<Link
|
|
175
|
-
key={link.href}
|
|
176
|
-
href={link.href}
|
|
177
|
-
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
|
|
178
|
-
>
|
|
179
|
-
{link.label}
|
|
180
|
-
</Link>
|
|
181
|
-
))}
|
|
182
161
|
<ThemeSelector />
|
|
183
162
|
</div>
|
|
184
163
|
</div>
|
|
@@ -1,111 +1,19 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import { useState } from "react"
|
|
4
|
-
import
|
|
5
|
-
import { Menu, X, ChevronDown, Layout, BarChart3, Shield, Zap, Layers, Target, Rocket, Settings } from "lucide-react"
|
|
4
|
+
import { Menu, X } from "lucide-react"
|
|
6
5
|
import { cn } from "@/lib/utils"
|
|
7
6
|
|
|
8
|
-
interface MenuItem {
|
|
9
|
-
label: string
|
|
10
|
-
description: string
|
|
11
|
-
href: string
|
|
12
|
-
icon: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface MenuColumn {
|
|
16
|
-
title: string
|
|
17
|
-
items: MenuItem[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
7
|
interface MobileMenuProps {
|
|
21
|
-
productMenu: {
|
|
22
|
-
label: string
|
|
23
|
-
columns: MenuColumn[]
|
|
24
|
-
}
|
|
25
|
-
solutionsMenu: {
|
|
26
|
-
label: string
|
|
27
|
-
columns: MenuColumn[]
|
|
28
|
-
}
|
|
29
8
|
navLinks: { label: string; href: string }[]
|
|
30
9
|
ctaLinks: { label: string; href: string; variant: "default" | "ghost" }[]
|
|
31
10
|
}
|
|
32
11
|
|
|
33
|
-
|
|
34
|
-
layout: Layout,
|
|
35
|
-
barChart: BarChart3,
|
|
36
|
-
shield: Shield,
|
|
37
|
-
zap: Zap,
|
|
38
|
-
layers: Layers,
|
|
39
|
-
target: Target,
|
|
40
|
-
rocket: Rocket,
|
|
41
|
-
settings: Settings,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function MobileMenuSection({
|
|
45
|
-
menu,
|
|
46
|
-
isOpen,
|
|
47
|
-
onToggle,
|
|
48
|
-
onClose,
|
|
49
|
-
}: {
|
|
50
|
-
menu: { label: string; columns: MenuColumn[] }
|
|
51
|
-
isOpen: boolean
|
|
52
|
-
onToggle: () => void
|
|
53
|
-
onClose: () => void
|
|
54
|
-
}) {
|
|
55
|
-
return (
|
|
56
|
-
<div className="border-b border-border">
|
|
57
|
-
<button
|
|
58
|
-
type="button"
|
|
59
|
-
className="flex items-center justify-between w-full px-4 py-3 text-sm font-medium"
|
|
60
|
-
onClick={onToggle}
|
|
61
|
-
>
|
|
62
|
-
{menu.label}
|
|
63
|
-
<ChevronDown
|
|
64
|
-
className={cn(
|
|
65
|
-
"h-4 w-4 transition-transform",
|
|
66
|
-
isOpen && "rotate-180"
|
|
67
|
-
)}
|
|
68
|
-
/>
|
|
69
|
-
</button>
|
|
70
|
-
{isOpen && (
|
|
71
|
-
<div className="px-4 pb-4 space-y-4">
|
|
72
|
-
{menu.columns.map((column) => (
|
|
73
|
-
<div key={column.title}>
|
|
74
|
-
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2">
|
|
75
|
-
{column.title}
|
|
76
|
-
</h4>
|
|
77
|
-
<ul className="space-y-1">
|
|
78
|
-
{column.items.map((item) => {
|
|
79
|
-
const Icon = iconMap[item.icon] || Layout
|
|
80
|
-
return (
|
|
81
|
-
<li key={item.href}>
|
|
82
|
-
<Link
|
|
83
|
-
href={item.href}
|
|
84
|
-
className="flex items-center gap-3 p-2 rounded-lg hover:bg-muted"
|
|
85
|
-
onClick={onClose}
|
|
86
|
-
>
|
|
87
|
-
<Icon className="h-4 w-4 text-primary" />
|
|
88
|
-
<span className="text-sm">{item.label}</span>
|
|
89
|
-
</Link>
|
|
90
|
-
</li>
|
|
91
|
-
)
|
|
92
|
-
})}
|
|
93
|
-
</ul>
|
|
94
|
-
</div>
|
|
95
|
-
))}
|
|
96
|
-
</div>
|
|
97
|
-
)}
|
|
98
|
-
</div>
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function MobileMenu({ productMenu, solutionsMenu, navLinks, ctaLinks }: MobileMenuProps) {
|
|
12
|
+
export function MobileMenu({ navLinks, ctaLinks }: MobileMenuProps) {
|
|
103
13
|
const [isOpen, setIsOpen] = useState(false)
|
|
104
|
-
const [openSection, setOpenSection] = useState<string | null>(null)
|
|
105
14
|
|
|
106
15
|
const handleClose = () => {
|
|
107
16
|
setIsOpen(false)
|
|
108
|
-
setOpenSection(null)
|
|
109
17
|
}
|
|
110
18
|
|
|
111
19
|
return (
|
|
@@ -123,40 +31,23 @@ export function MobileMenu({ productMenu, solutionsMenu, navLinks, ctaLinks }: M
|
|
|
123
31
|
{isOpen && (
|
|
124
32
|
<div className="fixed inset-0 top-16 z-50 bg-background">
|
|
125
33
|
<nav className="overflow-y-auto max-h-[calc(100vh-4rem)]">
|
|
126
|
-
|
|
127
|
-
menu={productMenu}
|
|
128
|
-
isOpen={openSection === "product"}
|
|
129
|
-
onToggle={() =>
|
|
130
|
-
setOpenSection(openSection === "product" ? null : "product")
|
|
131
|
-
}
|
|
132
|
-
onClose={handleClose}
|
|
133
|
-
/>
|
|
134
|
-
<MobileMenuSection
|
|
135
|
-
menu={solutionsMenu}
|
|
136
|
-
isOpen={openSection === "solutions"}
|
|
137
|
-
onToggle={() =>
|
|
138
|
-
setOpenSection(openSection === "solutions" ? null : "solutions")
|
|
139
|
-
}
|
|
140
|
-
onClose={handleClose}
|
|
141
|
-
/>
|
|
142
|
-
|
|
143
|
-
{/* Simple nav links */}
|
|
34
|
+
{/* Navigation links */}
|
|
144
35
|
{navLinks.map((link) => (
|
|
145
|
-
<
|
|
36
|
+
<a
|
|
146
37
|
key={link.href}
|
|
147
38
|
href={link.href}
|
|
148
39
|
className="flex items-center px-4 py-3 text-sm font-medium border-b border-border hover:bg-muted"
|
|
149
40
|
onClick={handleClose}
|
|
150
41
|
>
|
|
151
42
|
{link.label}
|
|
152
|
-
</
|
|
43
|
+
</a>
|
|
153
44
|
))}
|
|
154
45
|
|
|
155
46
|
{/* CTA links */}
|
|
156
47
|
<div className="p-4 space-y-2">
|
|
157
48
|
{ctaLinks.map((link) => (
|
|
158
|
-
<
|
|
159
|
-
key={link.
|
|
49
|
+
<a
|
|
50
|
+
key={link.label}
|
|
160
51
|
href={link.href}
|
|
161
52
|
className={cn(
|
|
162
53
|
"flex items-center justify-center w-full px-4 py-3 text-sm font-medium rounded-md transition-colors",
|
|
@@ -167,7 +58,7 @@ export function MobileMenu({ productMenu, solutionsMenu, navLinks, ctaLinks }: M
|
|
|
167
58
|
onClick={handleClose}
|
|
168
59
|
>
|
|
169
60
|
{link.label}
|
|
170
|
-
</
|
|
61
|
+
</a>
|
|
171
62
|
))}
|
|
172
63
|
</div>
|
|
173
64
|
</nav>
|
|
@@ -2,106 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
import Link from "next/link"
|
|
4
4
|
import { Logo } from "@/components/Logo"
|
|
5
|
-
import { MegaMenu } from "./MegaMenu"
|
|
6
5
|
import { MobileMenu } from "./MobileMenu"
|
|
7
6
|
import { cn } from "@/lib/utils"
|
|
8
7
|
|
|
9
|
-
//
|
|
10
|
-
const productMenu = {
|
|
11
|
-
label: "Product",
|
|
12
|
-
columns: [
|
|
13
|
-
{
|
|
14
|
-
title: "Core Features",
|
|
15
|
-
items: [
|
|
16
|
-
{
|
|
17
|
-
label: "Integrations",
|
|
18
|
-
description: "Connect with 100+ tools you already use",
|
|
19
|
-
href: "/features/integrations",
|
|
20
|
-
icon: "layout",
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
label: "Analytics",
|
|
24
|
-
description: "Real-time insights and reporting dashboards",
|
|
25
|
-
href: "/features/analytics",
|
|
26
|
-
icon: "barChart",
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
label: "Security",
|
|
30
|
-
description: "Enterprise-grade protection and compliance",
|
|
31
|
-
href: "/features/security",
|
|
32
|
-
icon: "shield",
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
title: "Productivity",
|
|
38
|
-
items: [
|
|
39
|
-
{
|
|
40
|
-
label: "Dashboard",
|
|
41
|
-
description: "Unified command center for your team",
|
|
42
|
-
href: "/features/dashboard",
|
|
43
|
-
icon: "layout",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
label: "Automation",
|
|
47
|
-
description: "Streamline repetitive tasks instantly",
|
|
48
|
-
href: "/features/automation",
|
|
49
|
-
icon: "zap",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
label: "Workflows",
|
|
53
|
-
description: "Build custom processes without code",
|
|
54
|
-
href: "/features/workflows",
|
|
55
|
-
icon: "layers",
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const solutionsMenu = {
|
|
63
|
-
label: "Solutions",
|
|
64
|
-
columns: [
|
|
65
|
-
{
|
|
66
|
-
title: "By Team",
|
|
67
|
-
items: [
|
|
68
|
-
{
|
|
69
|
-
label: "Sales Teams",
|
|
70
|
-
description: "Close deals faster with smart tools",
|
|
71
|
-
href: "/use-cases/sales",
|
|
72
|
-
icon: "target",
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
label: "Marketing Teams",
|
|
76
|
-
description: "Launch campaigns that convert",
|
|
77
|
-
href: "/use-cases/marketing",
|
|
78
|
-
icon: "rocket",
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
label: "Product Teams",
|
|
82
|
-
description: "Ship features users love",
|
|
83
|
-
href: "/use-cases/product",
|
|
84
|
-
icon: "layers",
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
label: "Operations",
|
|
88
|
-
description: "Scale without the growing pains",
|
|
89
|
-
href: "/use-cases/operations",
|
|
90
|
-
icon: "settings",
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
},
|
|
94
|
-
],
|
|
95
|
-
}
|
|
96
|
-
|
|
8
|
+
// Simplified navigation for landing page
|
|
97
9
|
const navLinks = [
|
|
98
|
-
{ label: "
|
|
99
|
-
{ label: "
|
|
10
|
+
{ label: "Features", href: "#features" },
|
|
11
|
+
{ label: "Testimonials", href: "#testimonials" },
|
|
12
|
+
{ label: "Pricing", href: "#pricing" },
|
|
100
13
|
]
|
|
101
14
|
|
|
102
15
|
const ctaLinks = [
|
|
103
|
-
{ label: "Sign In", href: "
|
|
104
|
-
{ label: "Get Started", href: "
|
|
16
|
+
{ label: "Sign In", href: "#", variant: "ghost" as const },
|
|
17
|
+
{ label: "Get Started", href: "#pricing", variant: "default" as const },
|
|
105
18
|
]
|
|
106
19
|
|
|
107
20
|
export function Header() {
|
|
@@ -117,16 +30,14 @@ export function Header() {
|
|
|
117
30
|
|
|
118
31
|
{/* Desktop navigation */}
|
|
119
32
|
<nav className="hidden lg:flex items-center gap-1">
|
|
120
|
-
<MegaMenu menu={productMenu} />
|
|
121
|
-
<MegaMenu menu={solutionsMenu} />
|
|
122
33
|
{navLinks.map((link) => (
|
|
123
|
-
<
|
|
34
|
+
<a
|
|
124
35
|
key={link.href}
|
|
125
36
|
href={link.href}
|
|
126
37
|
className="px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
|
|
127
38
|
>
|
|
128
39
|
{link.label}
|
|
129
|
-
</
|
|
40
|
+
</a>
|
|
130
41
|
))}
|
|
131
42
|
</nav>
|
|
132
43
|
</div>
|
|
@@ -136,8 +47,8 @@ export function Header() {
|
|
|
136
47
|
{/* Desktop CTAs */}
|
|
137
48
|
<div className="hidden lg:flex items-center gap-3">
|
|
138
49
|
{ctaLinks.map((link) => (
|
|
139
|
-
<
|
|
140
|
-
key={link.
|
|
50
|
+
<a
|
|
51
|
+
key={link.label}
|
|
141
52
|
href={link.href}
|
|
142
53
|
className={cn(
|
|
143
54
|
"px-4 py-2 text-sm font-medium rounded-md transition-colors",
|
|
@@ -147,21 +58,19 @@ export function Header() {
|
|
|
147
58
|
)}
|
|
148
59
|
>
|
|
149
60
|
{link.label}
|
|
150
|
-
</
|
|
61
|
+
</a>
|
|
151
62
|
))}
|
|
152
63
|
</div>
|
|
153
64
|
|
|
154
65
|
{/* Mobile: Primary CTA + Hamburger */}
|
|
155
|
-
<
|
|
156
|
-
href="
|
|
66
|
+
<a
|
|
67
|
+
href="#pricing"
|
|
157
68
|
className="lg:hidden px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90"
|
|
158
69
|
>
|
|
159
70
|
Get Started
|
|
160
|
-
</
|
|
71
|
+
</a>
|
|
161
72
|
|
|
162
73
|
<MobileMenu
|
|
163
|
-
productMenu={productMenu}
|
|
164
|
-
solutionsMenu={solutionsMenu}
|
|
165
74
|
navLinks={navLinks}
|
|
166
75
|
ctaLinks={ctaLinks}
|
|
167
76
|
/>
|