kofi-stack-template-generator 2.1.51 → 2.1.53

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.
Files changed (54) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/dist/index.js +1906 -146
  3. package/package.json +2 -2
  4. package/src/generator.ts +9 -0
  5. package/src/templates.generated.ts +51 -5
  6. package/templates/marketing/astro/astro.config.ts.hbs +12 -0
  7. package/templates/marketing/astro/package.json.hbs +31 -0
  8. package/templates/marketing/astro/postcss.config.mjs.hbs +5 -0
  9. package/templates/marketing/astro/public/favicon.svg +4 -0
  10. package/templates/marketing/astro/public/media/hero-bg.png +1 -0
  11. package/templates/marketing/astro/src/components/Footer.astro +167 -0
  12. package/templates/marketing/astro/src/components/Header.astro +378 -0
  13. package/templates/marketing/astro/src/components/Logo.astro +30 -0
  14. package/templates/marketing/astro/src/components/ThemeSelector.astro +64 -0
  15. package/templates/marketing/astro/src/components/blocks/BentoFeatures.astro +209 -0
  16. package/templates/marketing/astro/src/components/blocks/FeatureShowcase.astro +102 -0
  17. package/templates/marketing/astro/src/components/blocks/FinalCTA.astro +82 -0
  18. package/templates/marketing/astro/src/components/blocks/IndustryTabs.astro +177 -0
  19. package/templates/marketing/astro/src/components/blocks/LogoBanner.astro +95 -0
  20. package/templates/marketing/astro/src/components/blocks/PricingTable.astro +176 -0
  21. package/templates/marketing/astro/src/components/blocks/ProofBanner.astro +56 -0
  22. package/templates/marketing/astro/src/components/blocks/TestimonialsGrid.astro +106 -0
  23. package/templates/marketing/astro/src/components/blocks/TrustColumns.astro +88 -0
  24. package/templates/marketing/astro/src/components/heros/AnimatedMockup.astro +711 -0
  25. package/templates/marketing/astro/src/components/heros/ProductShowcaseHero.astro +111 -0
  26. package/templates/marketing/astro/src/layouts/Layout.astro +37 -0
  27. package/templates/marketing/astro/src/lib/utils.ts +6 -0
  28. package/templates/marketing/astro/src/pages/index.astro +163 -0
  29. package/templates/marketing/astro/src/styles/globals.css.hbs +353 -0
  30. package/templates/marketing/astro/tsconfig.json.hbs +11 -0
  31. package/templates/marketing/nextjs/package.json.hbs +6 -1
  32. package/templates/marketing/nextjs/src/app/layout.tsx.hbs +19 -5
  33. package/templates/marketing/nextjs/src/app/page.tsx.hbs +160 -164
  34. package/templates/marketing/nextjs/src/components/Footer/index.tsx +188 -0
  35. package/templates/marketing/nextjs/src/components/Header/MegaMenu.tsx +117 -0
  36. package/templates/marketing/nextjs/src/components/Header/MobileMenu.tsx +178 -0
  37. package/templates/marketing/nextjs/src/components/Header/index.tsx +172 -0
  38. package/templates/marketing/nextjs/src/components/Logo.tsx +46 -0
  39. package/templates/marketing/nextjs/src/components/ThemeProvider.tsx +8 -0
  40. package/templates/marketing/nextjs/src/components/ThemeSelector.tsx +69 -0
  41. package/templates/marketing/nextjs/src/components/blocks/BentoFeatures.tsx +249 -0
  42. package/templates/marketing/nextjs/src/components/blocks/FeatureShowcase.tsx +110 -0
  43. package/templates/marketing/nextjs/src/components/blocks/FinalCTA.tsx +91 -0
  44. package/templates/marketing/nextjs/src/components/blocks/IndustryTabs.tsx +137 -0
  45. package/templates/marketing/nextjs/src/components/blocks/LogoBanner.tsx +80 -0
  46. package/templates/marketing/nextjs/src/components/blocks/PricingTable.tsx +210 -0
  47. package/templates/marketing/nextjs/src/components/blocks/ProofBanner.tsx +72 -0
  48. package/templates/marketing/nextjs/src/components/blocks/TestimonialsGrid.tsx +119 -0
  49. package/templates/marketing/nextjs/src/components/blocks/TrustColumns.tsx +110 -0
  50. package/templates/marketing/nextjs/src/components/blocks/index.ts +9 -0
  51. package/templates/marketing/nextjs/src/components/heros/AnimatedMockup.tsx +242 -0
  52. package/templates/marketing/nextjs/src/components/heros/ProductShowcaseHero.tsx +84 -0
  53. package/templates/marketing/nextjs/src/components/heros/index.ts +2 -0
  54. package/templates/marketing/nextjs/src/lib/utils.ts +6 -0
@@ -0,0 +1,242 @@
1
+ "use client"
2
+
3
+ import { useEffect, useState } from "react"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ interface MockupState {
7
+ id: number
8
+ label: string
9
+ sidebarActive: string
10
+ previewTitle: string
11
+ previewDescription: string
12
+ previewCategory: string
13
+ previewStatus: "draft" | "published" | "featured"
14
+ previewUrl?: string
15
+ }
16
+
17
+ const mockupStates: MockupState[] = [
18
+ {
19
+ id: 1,
20
+ label: "Setup & styling",
21
+ sidebarActive: "templates",
22
+ previewTitle: "Atlas Directory",
23
+ previewDescription: "Apply your brand, typography, and layout in minutes.",
24
+ previewCategory: "Design systems",
25
+ previewStatus: "draft",
26
+ previewUrl: "atlas.directory/home",
27
+ },
28
+ {
29
+ id: 2,
30
+ label: "Plans & pricing",
31
+ sidebarActive: "billing",
32
+ previewTitle: "Pro Listing Plan",
33
+ previewDescription: "Recurring billing, featured placements, and add-ons configured.",
34
+ previewCategory: "Monetization",
35
+ previewStatus: "draft",
36
+ previewUrl: "atlas.directory/billing",
37
+ },
38
+ {
39
+ id: 3,
40
+ label: "SEO & publishing",
41
+ sidebarActive: "seo",
42
+ previewTitle: "Atlas Directory",
43
+ previewDescription: "Schema, sitemap, and custom domain are ready to publish.",
44
+ previewCategory: "SEO & domains",
45
+ previewStatus: "published",
46
+ previewUrl: "atlas.directory/launch",
47
+ },
48
+ {
49
+ id: 4,
50
+ label: "Payouts live",
51
+ sidebarActive: "overview",
52
+ previewTitle: "Atlas Directory",
53
+ previewDescription: "Subscribers active, payouts scheduled to Stripe, featured slots sold.",
54
+ previewCategory: "Revenue",
55
+ previewStatus: "featured",
56
+ previewUrl: "atlas.directory/analytics",
57
+ },
58
+ ]
59
+
60
+ interface SidebarItemProps {
61
+ icon: string
62
+ label: string
63
+ active?: boolean
64
+ badge?: number
65
+ }
66
+
67
+ function SidebarItem({ icon, label, active, badge }: SidebarItemProps) {
68
+ return (
69
+ <div className={cn("sidebar-item", active && "sidebar-item--active")}>
70
+ <span className="sidebar-icon">{icon}</span>
71
+ <span className="sidebar-label">{label}</span>
72
+ {badge && <span className="sidebar-badge">{badge}</span>}
73
+ </div>
74
+ )
75
+ }
76
+
77
+ export function AnimatedMockup() {
78
+ const [currentState, setCurrentState] = useState(0)
79
+ const [isPaused, setIsPaused] = useState(false)
80
+
81
+ useEffect(() => {
82
+ if (isPaused) return
83
+
84
+ const interval = setInterval(() => {
85
+ setCurrentState((prev) => (prev + 1) % mockupStates.length)
86
+ }, 3000)
87
+
88
+ return () => clearInterval(interval)
89
+ }, [isPaused])
90
+
91
+ const state = mockupStates[currentState]
92
+
93
+ return (
94
+ <div
95
+ className="mockup-wrapper"
96
+ onMouseEnter={() => setIsPaused(true)}
97
+ onMouseLeave={() => setIsPaused(false)}
98
+ >
99
+ {/* Browser Chrome */}
100
+ <div className="mockup-chrome">
101
+ <div className="mockup-chrome-dots">
102
+ <span className="dot dot-red" />
103
+ <span className="dot dot-yellow" />
104
+ <span className="dot dot-green" />
105
+ </div>
106
+ <div className="mockup-chrome-title">SaaSify</div>
107
+ <div className="mockup-chrome-actions" />
108
+ </div>
109
+
110
+ {/* App Content */}
111
+ <div className="mockup-content">
112
+ {/* Sidebar */}
113
+ <div className="mockup-sidebar">
114
+ <div className="sidebar-header">
115
+ <div className="sidebar-logo">
116
+ <span className="logo-icon">D</span>
117
+ <span className="logo-text">My Directory</span>
118
+ </div>
119
+ </div>
120
+ <nav className="sidebar-nav">
121
+ <SidebarItem icon="📊" label="Overview" active={state.sidebarActive === "overview"} />
122
+ <SidebarItem icon="🖼️" label="Templates" active={state.sidebarActive === "templates"} />
123
+ <SidebarItem
124
+ icon="📋"
125
+ label="Listings"
126
+ active={state.sidebarActive === "listings"}
127
+ badge={24}
128
+ />
129
+ <SidebarItem
130
+ icon="💳"
131
+ label="Plans & Billing"
132
+ active={state.sidebarActive === "billing"}
133
+ />
134
+ <SidebarItem
135
+ icon="⚡"
136
+ label="Automations"
137
+ active={state.sidebarActive === "automations"}
138
+ />
139
+ <SidebarItem icon="🔎" label="SEO" active={state.sidebarActive === "seo"} />
140
+ <SidebarItem icon="⚙️" label="Settings" active={state.sidebarActive === "settings"} />
141
+ </nav>
142
+ </div>
143
+
144
+ {/* Main Content Area */}
145
+ <div className="mockup-main">
146
+ {/* Header */}
147
+ <div className="main-header">
148
+ <div className="header-title">
149
+ <h2>{state.label}</h2>
150
+ <span className="header-breadcrumb">SaaSify / {state.previewTitle}</span>
151
+ </div>
152
+ <div className="header-actions">
153
+ <button
154
+ type="button"
155
+ className={cn(
156
+ "action-btn",
157
+ state.previewStatus === "published" && "action-btn--success",
158
+ state.previewStatus === "featured" && "action-btn--featured"
159
+ )}
160
+ >
161
+ {state.previewStatus === "draft" && "Save Draft"}
162
+ {state.previewStatus === "published" && "✓ Published"}
163
+ {state.previewStatus === "featured" && "⭐ Featured"}
164
+ </button>
165
+ </div>
166
+ </div>
167
+
168
+ {/* Split View: Editor + Preview */}
169
+ <div className="main-split">
170
+ {/* Editor Panel */}
171
+ <div className="editor-panel">
172
+ <div className="editor-section">
173
+ <span className="editor-label">Listing Name</span>
174
+ <div className="editor-input">
175
+ <span className="input-text">{state.previewTitle}</span>
176
+ <span className="input-cursor" />
177
+ </div>
178
+ </div>
179
+ <div className="editor-section">
180
+ <span className="editor-label">Category</span>
181
+ <div className="editor-select">
182
+ <span>{state.previewCategory}</span>
183
+ <span className="select-arrow">▼</span>
184
+ </div>
185
+ </div>
186
+ <div className="editor-section">
187
+ <span className="editor-label">Description</span>
188
+ <div className="editor-textarea">
189
+ <span className={cn("textarea-text", state.id >= 2 && "textarea-text--complete")}>
190
+ {state.previewDescription}
191
+ </span>
192
+ </div>
193
+ </div>
194
+ </div>
195
+
196
+ {/* Preview Panel */}
197
+ <div className="preview-panel">
198
+ <div className="preview-header">
199
+ <span className="preview-label">Live Preview</span>
200
+ <span className="preview-url">{state.previewUrl ?? "saasify.app/live"}</span>
201
+ </div>
202
+ <div className="preview-card">
203
+ {state.previewStatus === "featured" && (
204
+ <div className="preview-badge">⭐ Featured</div>
205
+ )}
206
+ <div className="preview-image">
207
+ <div className="preview-image-placeholder">
208
+ <span>🏢</span>
209
+ </div>
210
+ </div>
211
+ <div className="preview-content">
212
+ <span className="preview-category-tag">{state.previewCategory}</span>
213
+ <h3 className="preview-title">{state.previewTitle}</h3>
214
+ <p className="preview-description">{state.previewDescription}</p>
215
+ <div className="preview-meta">
216
+ <span className="meta-rating">★★★★★</span>
217
+ <span className="meta-reviews">24 reviews</span>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+
226
+ {/* State Indicator */}
227
+ <div className="mockup-indicators">
228
+ {mockupStates.map((s, i) => (
229
+ <button
230
+ type="button"
231
+ key={s.id}
232
+ onClick={() => setCurrentState(i)}
233
+ className={cn("indicator", i === currentState && "indicator--active")}
234
+ >
235
+ <span className="indicator-dot" />
236
+ <span className="indicator-label">{s.label}</span>
237
+ </button>
238
+ ))}
239
+ </div>
240
+ </div>
241
+ )
242
+ }
@@ -0,0 +1,84 @@
1
+ "use client"
2
+
3
+ import Link from "next/link"
4
+ import Image from "next/image"
5
+ import { AnimatedMockup } from "./AnimatedMockup"
6
+ import { cn } from "@/lib/utils"
7
+
8
+ interface HeroLink {
9
+ label: string
10
+ href: string
11
+ variant: "default" | "outline"
12
+ }
13
+
14
+ interface ProductShowcaseHeroProps {
15
+ headline: string
16
+ description: string
17
+ links?: HeroLink[]
18
+ }
19
+
20
+ export function ProductShowcaseHero({
21
+ headline = "The modern platform for growing teams",
22
+ description = "Streamline workflows, boost productivity, and scale your business with one powerful platform.",
23
+ links = [
24
+ { label: "Start free trial", href: "/sign-up", variant: "default" },
25
+ { label: "Watch demo", href: "/demo", variant: "outline" },
26
+ ],
27
+ }: ProductShowcaseHeroProps) {
28
+ return (
29
+ <div className="relative overflow-hidden">
30
+ {/* Hero Content - Left Aligned */}
31
+ <div className="container mx-auto px-4 pt-8 pb-16 md:pt-16 md:pb-24">
32
+ <div className="max-w-2xl">
33
+ <h1 className="text-4xl font-bold tracking-tight text-foreground sm:text-5xl md:text-6xl">
34
+ {headline}
35
+ </h1>
36
+ <p className="mt-6 text-lg text-muted-foreground md:text-xl">
37
+ {description}
38
+ </p>
39
+ {links && links.length > 0 && (
40
+ <div className="mt-8 flex flex-wrap gap-4">
41
+ {links.map((link) => (
42
+ <Link
43
+ key={link.href}
44
+ href={link.href}
45
+ className={cn(
46
+ "inline-flex items-center justify-center px-6 py-3 text-sm font-medium rounded-md transition-colors",
47
+ link.variant === "default"
48
+ ? "bg-primary text-primary-foreground hover:bg-primary/90"
49
+ : "border border-border bg-background hover:bg-muted"
50
+ )}
51
+ >
52
+ {link.label}
53
+ </Link>
54
+ ))}
55
+ </div>
56
+ )}
57
+ </div>
58
+ </div>
59
+
60
+ {/* Product Mockup Section */}
61
+ <div className="container mx-auto px-4">
62
+ <div className="hero-showcase">
63
+ {/* Background Image */}
64
+ <div className="hero-bg-image">
65
+ <Image
66
+ src="/media/hero-bg.png"
67
+ alt=""
68
+ fill
69
+ sizes="(max-width: 1280px) 100vw, 1280px"
70
+ className="object-cover"
71
+ priority
72
+ quality={75}
73
+ />
74
+ </div>
75
+
76
+ {/* Mockup - centered within background */}
77
+ <div className="hero-mockup-centered">
78
+ <AnimatedMockup />
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ )
84
+ }
@@ -0,0 +1,2 @@
1
+ export { ProductShowcaseHero } from "./ProductShowcaseHero"
2
+ export { AnimatedMockup } from "./AnimatedMockup"
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }