shipd 0.1.3 → 0.1.4

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 (115) hide show
  1. package/base-package/app/globals.css +126 -0
  2. package/base-package/app/layout.tsx +53 -0
  3. package/base-package/app/page.tsx +15 -0
  4. package/base-package/base.config.json +57 -0
  5. package/base-package/components/ui/avatar.tsx +53 -0
  6. package/base-package/components/ui/badge.tsx +46 -0
  7. package/base-package/components/ui/button.tsx +59 -0
  8. package/base-package/components/ui/card.tsx +92 -0
  9. package/base-package/components/ui/chart.tsx +353 -0
  10. package/base-package/components/ui/checkbox.tsx +32 -0
  11. package/base-package/components/ui/dialog.tsx +135 -0
  12. package/base-package/components/ui/dropdown-menu.tsx +257 -0
  13. package/base-package/components/ui/form.tsx +167 -0
  14. package/base-package/components/ui/input.tsx +21 -0
  15. package/base-package/components/ui/label.tsx +24 -0
  16. package/base-package/components/ui/progress.tsx +31 -0
  17. package/base-package/components/ui/resizable.tsx +56 -0
  18. package/base-package/components/ui/select.tsx +185 -0
  19. package/base-package/components/ui/separator.tsx +28 -0
  20. package/base-package/components/ui/sheet.tsx +139 -0
  21. package/base-package/components/ui/skeleton.tsx +13 -0
  22. package/base-package/components/ui/sonner.tsx +25 -0
  23. package/base-package/components/ui/switch.tsx +31 -0
  24. package/base-package/components/ui/tabs.tsx +66 -0
  25. package/base-package/components/ui/textarea.tsx +18 -0
  26. package/base-package/components/ui/toggle-group.tsx +73 -0
  27. package/base-package/components/ui/toggle.tsx +47 -0
  28. package/base-package/components/ui/tooltip.tsx +61 -0
  29. package/base-package/components.json +21 -0
  30. package/base-package/eslint.config.mjs +16 -0
  31. package/base-package/lib/utils.ts +6 -0
  32. package/base-package/middleware.ts +12 -0
  33. package/base-package/next.config.ts +27 -0
  34. package/base-package/package.json +49 -0
  35. package/base-package/postcss.config.mjs +5 -0
  36. package/base-package/public/favicon.svg +4 -0
  37. package/base-package/tailwind.config.ts +89 -0
  38. package/base-package/tsconfig.json +27 -0
  39. package/dist/index.js +1858 -956
  40. package/features/ai-chat/README.md +258 -0
  41. package/features/ai-chat/app/api/chat/route.ts +16 -0
  42. package/features/ai-chat/app/dashboard/_components/chatbot.tsx +39 -0
  43. package/features/ai-chat/app/dashboard/chat/page.tsx +73 -0
  44. package/features/ai-chat/feature.config.json +22 -0
  45. package/features/analytics/README.md +308 -0
  46. package/features/analytics/feature.config.json +20 -0
  47. package/features/analytics/lib/posthog.ts +36 -0
  48. package/features/auth/README.md +336 -0
  49. package/features/auth/app/api/auth/[...all]/route.ts +4 -0
  50. package/features/auth/app/dashboard/layout.tsx +15 -0
  51. package/features/auth/app/dashboard/page.tsx +140 -0
  52. package/features/auth/app/sign-in/page.tsx +228 -0
  53. package/features/auth/app/sign-up/page.tsx +243 -0
  54. package/features/auth/auth-schema.ts +47 -0
  55. package/features/auth/components/auth/setup-instructions.tsx +123 -0
  56. package/features/auth/feature.config.json +33 -0
  57. package/features/auth/lib/auth-client.ts +8 -0
  58. package/features/auth/lib/auth.ts +295 -0
  59. package/features/auth/lib/email-stub.ts +55 -0
  60. package/features/auth/lib/email.ts +47 -0
  61. package/features/auth/middleware.patch.ts +43 -0
  62. package/features/database/README.md +256 -0
  63. package/features/database/db/drizzle.ts +48 -0
  64. package/features/database/db/schema.ts +21 -0
  65. package/features/database/drizzle.config.ts +13 -0
  66. package/features/database/feature.config.json +30 -0
  67. package/features/email/README.md +282 -0
  68. package/features/email/emails/components/layout.tsx +181 -0
  69. package/features/email/emails/password-reset.tsx +67 -0
  70. package/features/email/emails/payment-failed.tsx +167 -0
  71. package/features/email/emails/subscription-confirmation.tsx +129 -0
  72. package/features/email/emails/welcome.tsx +100 -0
  73. package/features/email/feature.config.json +22 -0
  74. package/features/email/lib/email.ts +118 -0
  75. package/features/file-upload/README.md +271 -0
  76. package/features/file-upload/app/api/upload-image/route.ts +64 -0
  77. package/features/file-upload/app/dashboard/upload/page.tsx +324 -0
  78. package/features/file-upload/feature.config.json +23 -0
  79. package/features/file-upload/lib/upload-image.ts +28 -0
  80. package/features/marketing-landing/README.md +266 -0
  81. package/features/marketing-landing/app/page.tsx +25 -0
  82. package/features/marketing-landing/components/homepage/cli-workflow-section.tsx +231 -0
  83. package/features/marketing-landing/components/homepage/features-section.tsx +152 -0
  84. package/features/marketing-landing/components/homepage/footer.tsx +53 -0
  85. package/features/marketing-landing/components/homepage/hero-section.tsx +112 -0
  86. package/features/marketing-landing/components/homepage/integrations.tsx +124 -0
  87. package/features/marketing-landing/components/homepage/navigation.tsx +116 -0
  88. package/features/marketing-landing/components/homepage/news-section.tsx +82 -0
  89. package/features/marketing-landing/components/homepage/pricing-section.tsx +98 -0
  90. package/features/marketing-landing/components/homepage/testimonials-section.tsx +34 -0
  91. package/features/marketing-landing/components/logos/BetterAuth.tsx +21 -0
  92. package/features/marketing-landing/components/logos/NeonPostgres.tsx +41 -0
  93. package/features/marketing-landing/components/logos/Nextjs.tsx +72 -0
  94. package/features/marketing-landing/components/logos/Polar.tsx +7 -0
  95. package/features/marketing-landing/components/logos/TailwindCSS.tsx +27 -0
  96. package/features/marketing-landing/components/logos/index.ts +6 -0
  97. package/features/marketing-landing/components/logos/shadcnui.tsx +8 -0
  98. package/features/marketing-landing/feature.config.json +23 -0
  99. package/features/payments/README.md +306 -0
  100. package/features/payments/app/api/subscription/route.ts +25 -0
  101. package/features/payments/app/dashboard/payment/_components/manage-subscription.tsx +22 -0
  102. package/features/payments/app/dashboard/payment/page.tsx +126 -0
  103. package/features/payments/app/success/page.tsx +123 -0
  104. package/features/payments/feature.config.json +31 -0
  105. package/features/payments/lib/polar-products.ts +49 -0
  106. package/features/payments/lib/subscription.ts +148 -0
  107. package/features/payments/payments-schema.ts +30 -0
  108. package/features/seo/README.md +244 -0
  109. package/features/seo/app/blog/[slug]/page.tsx +314 -0
  110. package/features/seo/app/blog/page.tsx +107 -0
  111. package/features/seo/app/robots.txt +13 -0
  112. package/features/seo/app/sitemap.ts +70 -0
  113. package/features/seo/feature.config.json +19 -0
  114. package/features/seo/lib/seo-utils.ts +163 -0
  115. package/package.json +3 -1
@@ -0,0 +1,244 @@
1
+ # SEO Module - Integration Guide
2
+
3
+ ## Overview
4
+
5
+ The SEO module provides a complete SEO foundation for your Next.js application, including automated sitemap generation, robots.txt, blog structure, and structured data utilities.
6
+
7
+ ## What's Included
8
+
9
+ ### Files Added
10
+
11
+ - `app/sitemap.ts` - Automated sitemap generation
12
+ - `app/robots.txt` - Search engine crawler instructions
13
+ - `app/blog/` - Complete blog structure with example posts
14
+ - `lib/seo-utils.ts` - Helper functions for structured data and metadata
15
+
16
+ ### Features
17
+
18
+ ✅ **Automated Sitemap Generation**
19
+ - Dynamically generates sitemap.xml
20
+ - Includes all major routes (home, blog, pricing, docs, etc.)
21
+ - Supports blog posts with proper priorities and change frequencies
22
+
23
+ ✅ **Robots.txt**
24
+ - Allows all crawlers by default
25
+ - Blocks sensitive routes (API, dashboard, auth pages)
26
+ - Points to sitemap location
27
+
28
+ ✅ **Blog Structure**
29
+ - Blog listing page (`/blog`)
30
+ - Individual blog post pages (`/blog/[slug]`)
31
+ - Markdown content support via react-markdown
32
+ - SEO-optimized metadata for each post
33
+
34
+ ✅ **Structured Data Utilities**
35
+ - JSON-LD generation for WebApplication
36
+ - BlogPosting structured data
37
+ - Organization schema
38
+ - OpenGraph and Twitter Card helpers
39
+
40
+ ## Dependencies
41
+
42
+ This module requires:
43
+ - `react-markdown` (for blog content)
44
+ - `remark-gfm` (for GitHub Flavored Markdown)
45
+
46
+ These are automatically added to your `package.json` when you append this module.
47
+
48
+ ## Environment Variables
49
+
50
+ Add to your `.env.local`:
51
+
52
+ ```env
53
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
54
+ ```
55
+
56
+ For production, set this to your actual domain:
57
+ ```env
58
+ NEXT_PUBLIC_APP_URL=https://yourdomain.com
59
+ ```
60
+
61
+ ## Manual Integration Steps
62
+
63
+ ### 1. Verify Files Were Copied
64
+
65
+ After appending, check that these files exist:
66
+ - `app/sitemap.ts`
67
+ - `app/robots.txt`
68
+ - `app/blog/page.tsx`
69
+ - `app/blog/[slug]/page.tsx`
70
+ - `lib/seo-utils.ts`
71
+
72
+ ### 2. Update Sitemap with Your Routes
73
+
74
+ Edit `app/sitemap.ts` to include all your application routes:
75
+
76
+ ```typescript
77
+ // Add your custom routes
78
+ {
79
+ url: `${baseUrl}/your-custom-page`,
80
+ lastModified: new Date(),
81
+ changeFrequency: 'monthly',
82
+ priority: 0.8,
83
+ }
84
+ ```
85
+
86
+ ### 3. Update Blog Posts
87
+
88
+ Edit `app/blog/page.tsx` and `app/blog/[slug]/page.tsx` to use your actual blog content. In production, you might:
89
+ - Fetch from a CMS (Contentful, Sanity, etc.)
90
+ - Read from markdown files
91
+ - Query from a database
92
+
93
+ ### 4. Add Structured Data to Layout
94
+
95
+ In your `app/layout.tsx`, add structured data:
96
+
97
+ ```typescript
98
+ import { generateWebAppStructuredData } from '@/lib/seo-utils';
99
+
100
+ export default function RootLayout({ children }) {
101
+ const jsonLd = generateWebAppStructuredData(
102
+ 'Your App Name',
103
+ 'Your app description',
104
+ 'https://yourdomain.com'
105
+ );
106
+
107
+ return (
108
+ <html>
109
+ <head>
110
+ <script
111
+ type="application/ld+json"
112
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
113
+ />
114
+ </head>
115
+ <body>{children}</body>
116
+ </html>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ### 5. Add Structured Data to Blog Posts
122
+
123
+ In `app/blog/[slug]/page.tsx`, add blog post structured data:
124
+
125
+ ```typescript
126
+ import { generateBlogPostStructuredData } from '@/lib/seo-utils';
127
+
128
+ export default function BlogPost({ params }) {
129
+ const post = getPost(params.slug);
130
+
131
+ const jsonLd = generateBlogPostStructuredData(
132
+ post.title,
133
+ post.description,
134
+ `https://yourdomain.com/blog/${post.slug}`,
135
+ post.date,
136
+ post.dateModified,
137
+ post.author,
138
+ post.image
139
+ );
140
+
141
+ return (
142
+ <>
143
+ <script
144
+ type="application/ld+json"
145
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
146
+ />
147
+ {/* Blog post content */}
148
+ </>
149
+ );
150
+ }
151
+ ```
152
+
153
+ ## Usage Examples
154
+
155
+ ### Generate OpenGraph Metadata
156
+
157
+ ```typescript
158
+ import { generateOpenGraphMetadata } from '@/lib/seo-utils';
159
+
160
+ export const metadata = {
161
+ ...generateOpenGraphMetadata(
162
+ 'Page Title',
163
+ 'Page description',
164
+ 'https://yourdomain.com/page',
165
+ 'https://yourdomain.com/og-image.png'
166
+ ),
167
+ };
168
+ ```
169
+
170
+ ### Generate Twitter Card Metadata
171
+
172
+ ```typescript
173
+ import { generateTwitterCardMetadata } from '@/lib/seo-utils';
174
+
175
+ export const metadata = {
176
+ twitter: generateTwitterCardMetadata(
177
+ 'Page Title',
178
+ 'Page description',
179
+ 'https://yourdomain.com/twitter-image.png',
180
+ 'yourhandle'
181
+ ),
182
+ };
183
+ ```
184
+
185
+ ## Testing
186
+
187
+ 1. **Test Sitemap**: Visit `http://localhost:3000/sitemap.xml`
188
+ 2. **Test Robots.txt**: Visit `http://localhost:3000/robots.txt`
189
+ 3. **Test Blog**: Visit `http://localhost:3000/blog`
190
+ 4. **Test Blog Post**: Visit `http://localhost:3000/blog/getting-started-with-saas`
191
+
192
+ ## Customization
193
+
194
+ ### Update Robots.txt Rules
195
+
196
+ Edit `app/robots.txt` to customize crawler access:
197
+
198
+ ```
199
+ # Disallow specific paths
200
+ Disallow: /admin/
201
+ Disallow: /private/
202
+ ```
203
+
204
+ ### Add More Routes to Sitemap
205
+
206
+ Edit `app/sitemap.ts` and add your routes to the return array.
207
+
208
+ ### Customize Blog Structure
209
+
210
+ The blog pages are fully customizable. Update:
211
+ - `app/blog/page.tsx` - Blog listing page
212
+ - `app/blog/[slug]/page.tsx` - Individual blog post page
213
+
214
+ ## Related Modules
215
+
216
+ - **Marketing Landing Page** - Works great with SEO for discoverability
217
+ - **Documentation Pages** - Can be included in sitemap
218
+
219
+ ## Module Status
220
+
221
+ ✅ **Ready to Use** - Works immediately after append
222
+ ✅ **Template Variables** - Uses {{APP_URL}} in robots.txt
223
+ ✅ **No Conflicts** - Safe to append to any project
224
+
225
+ ## Troubleshooting
226
+
227
+ ### Sitemap Not Generating
228
+
229
+ - Ensure `NEXT_PUBLIC_APP_URL` is set in `.env.local`
230
+ - Check that `app/sitemap.ts` exists
231
+ - Verify Next.js version supports `MetadataRoute.Sitemap`
232
+
233
+ ### Blog Posts Not Showing
234
+
235
+ - Check that blog posts array is populated in `app/blog/page.tsx`
236
+ - Verify markdown content exists in `app/blog/[slug]/page.tsx`
237
+ - Ensure `react-markdown` and `remark-gfm` are installed
238
+
239
+ ### Structured Data Not Validating
240
+
241
+ - Use [Google's Rich Results Test](https://search.google.com/test/rich-results)
242
+ - Verify JSON-LD syntax is correct
243
+ - Check that required fields are present
244
+
@@ -0,0 +1,314 @@
1
+ import { notFound } from "next/navigation";
2
+ import Link from "next/link";
3
+ import { ArrowLeft, Calendar, Clock } from "lucide-react";
4
+ import ReactMarkdown from "react-markdown";
5
+ import remarkGfm from "remark-gfm";
6
+
7
+ // Blog posts content
8
+ // In production, this would come from a CMS, database, or markdown files
9
+ const blogPosts: Record<string, {
10
+ title: string;
11
+ description: string;
12
+ date: string;
13
+ author: string;
14
+ readTime: string;
15
+ category: string;
16
+ content: string;
17
+ }> = {
18
+ "getting-started-with-saas": {
19
+ title: "Getting Started with Your SaaS Journey",
20
+ description: "Learn how to validate your SaaS idea and build your first MVP in record time.",
21
+ date: "2024-12-15",
22
+ author: "{{PROJECT_NAME}} Team",
23
+ readTime: "5 min read",
24
+ category: "Guides",
25
+ content: `
26
+ # Getting Started with Your SaaS Journey
27
+
28
+ Building a successful SaaS product starts with validation. Here's how to get started quickly and efficiently.
29
+
30
+ ## 1. Validate Your Idea
31
+
32
+ Before writing a single line of code, talk to potential customers. Understanding their pain points is crucial.
33
+
34
+ ### Key Questions to Ask:
35
+ - What problem are they currently facing?
36
+ - How are they solving it today?
37
+ - Would they pay for a better solution?
38
+
39
+ ## 2. Build Your MVP
40
+
41
+ Focus on the core features that solve the main problem. Don't get caught up in building everything at once.
42
+
43
+ **Essential MVP features:**
44
+ - User authentication
45
+ - Core functionality
46
+ - Basic payment integration
47
+ - Simple dashboard
48
+
49
+ ## 3. Get Your First Customers
50
+
51
+ Launch early and iterate based on feedback. Your first 10 customers will teach you more than any market research.
52
+
53
+ > "The best way to predict the future is to create it." - Peter Drucker
54
+
55
+ ## Next Steps
56
+
57
+ Ready to build? Check out our comprehensive starter template that includes everything you need to launch your SaaS in days, not months.
58
+ `,
59
+ },
60
+ "optimizing-conversion-rates": {
61
+ title: "10 Proven Ways to Optimize Your SaaS Conversion Rates",
62
+ description: "Discover actionable strategies to convert more visitors into paying customers.",
63
+ date: "2024-12-10",
64
+ author: "{{PROJECT_NAME}} Team",
65
+ readTime: "8 min read",
66
+ category: "Marketing",
67
+ content: `
68
+ # 10 Proven Ways to Optimize Your SaaS Conversion Rates
69
+
70
+ Increasing your conversion rate can dramatically impact your revenue. Here are 10 proven strategies.
71
+
72
+ ## 1. Simplify Your Signup Flow
73
+
74
+ Remove unnecessary fields. Every additional field reduces conversions by an average of 11%.
75
+
76
+ ## 2. Add Social Proof
77
+
78
+ Display customer testimonials, logos, and case studies prominently on your landing page.
79
+
80
+ ## 3. Offer a Free Trial
81
+
82
+ Let users experience your product before asking for payment. Free trials can increase conversions by up to 300%.
83
+
84
+ ## 4. Optimize Your Pricing Page
85
+
86
+ Make your pricing transparent and easy to understand. Highlight the most popular plan.
87
+
88
+ ## 5. Use Clear CTAs
89
+
90
+ Your call-to-action buttons should be specific. Instead of "Submit," use "Start Your Free Trial."
91
+
92
+ ## 6. Implement Exit-Intent Popups
93
+
94
+ Catch users before they leave with a special offer or helpful resource.
95
+
96
+ ## 7. A/B Test Everything
97
+
98
+ Test your headlines, CTAs, colors, and copy. Small changes can lead to big improvements.
99
+
100
+ ## 8. Reduce Page Load Time
101
+
102
+ Every second of delay can cost you 7% in conversions. Optimize for speed.
103
+
104
+ ## 9. Mobile Optimization
105
+
106
+ Over 50% of traffic is mobile. Ensure your site works perfectly on all devices.
107
+
108
+ ## 10. Follow Up Quickly
109
+
110
+ Respond to inquiries within 5 minutes. The odds of qualifying a lead decrease by 400% after that.
111
+
112
+ ## Conclusion
113
+
114
+ Implementing these strategies systematically can double or triple your conversion rates. Start with the quickest wins and iterate from there.
115
+ `,
116
+ },
117
+ "scaling-your-saas": {
118
+ title: "Scaling Your SaaS: Infrastructure Best Practices",
119
+ description: "Technical insights on scaling your application to handle thousands of users.",
120
+ date: "2024-12-05",
121
+ author: "{{PROJECT_NAME}} Team",
122
+ readTime: "10 min read",
123
+ category: "Engineering",
124
+ content: `
125
+ # Scaling Your SaaS: Infrastructure Best Practices
126
+
127
+ As your SaaS grows, you'll need to scale your infrastructure. Here's how to do it right.
128
+
129
+ ## Database Optimization
130
+
131
+ ### Connection Pooling
132
+ Use connection pooling to manage database connections efficiently. Tools like PgBouncer can help.
133
+
134
+ \`\`\`typescript
135
+ // Example: Using connection pooling with Drizzle
136
+ import { drizzle } from 'drizzle-orm/postgres-js';
137
+ import postgres from 'postgres';
138
+
139
+ const client = postgres(process.env.DATABASE_URL!, { max: 10 });
140
+ const db = drizzle(client);
141
+ \`\`\`
142
+
143
+ ## Caching Strategy
144
+
145
+ Implement multi-layer caching:
146
+ 1. **Browser caching** for static assets
147
+ 2. **CDN caching** for global distribution
148
+ 3. **Redis caching** for frequently accessed data
149
+
150
+ ## Load Balancing
151
+
152
+ Distribute traffic across multiple servers to handle increased load and provide redundancy.
153
+
154
+ ## Monitoring & Observability
155
+
156
+ Track these key metrics:
157
+ - Response times
158
+ - Error rates
159
+ - Database query performance
160
+ - Memory usage
161
+ - CPU utilization
162
+
163
+ ## Horizontal Scaling
164
+
165
+ Design your application to scale horizontally by adding more servers rather than upgrading existing ones.
166
+
167
+ ### Stateless Design
168
+ Ensure your application doesn't store session state on individual servers. Use Redis or a database for session management.
169
+
170
+ ## Conclusion
171
+
172
+ Scaling is an ongoing process. Start with good fundamentals and iterate as you grow. Monitor your metrics and optimize bottlenecks as they appear.
173
+ `,
174
+ },
175
+ };
176
+
177
+ export async function generateStaticParams() {
178
+ return Object.keys(blogPosts).map((slug) => ({
179
+ slug,
180
+ }));
181
+ }
182
+
183
+ export async function generateMetadata({ params }: { params: { slug: string } }) {
184
+ const post = blogPosts[params.slug];
185
+
186
+ if (!post) {
187
+ return {
188
+ title: "Post Not Found",
189
+ };
190
+ }
191
+
192
+ return {
193
+ title: post.title,
194
+ description: post.description,
195
+ openGraph: {
196
+ title: post.title,
197
+ description: post.description,
198
+ type: "article",
199
+ publishedTime: post.date,
200
+ authors: [post.author],
201
+ },
202
+ };
203
+ }
204
+
205
+ export default function BlogPost({ params }: { params: { slug: string } }) {
206
+ const post = blogPosts[params.slug];
207
+
208
+ if (!post) {
209
+ notFound();
210
+ }
211
+
212
+ return (
213
+ <div className="min-h-screen bg-black">
214
+ {/* Back Link */}
215
+ <div className="border-b border-[#2a2a2a]">
216
+ <div className="container mx-auto px-4 py-6 sm:px-6 lg:px-8">
217
+ <Link
218
+ href="/blog"
219
+ className="inline-flex items-center text-sm text-gray-400 hover:text-[#ff5722] transition-colors"
220
+ >
221
+ <ArrowLeft className="mr-2 h-4 w-4" />
222
+ Back to Blog
223
+ </Link>
224
+ </div>
225
+ </div>
226
+
227
+ {/* Article Header */}
228
+ <article className="container mx-auto px-4 py-12 sm:px-6 lg:px-8">
229
+ <div className="mx-auto max-w-3xl">
230
+ <header className="mb-12">
231
+ <div className="mb-4">
232
+ <span className="inline-flex items-center rounded-full bg-[#ff5722]/10 px-3 py-1 text-sm font-medium text-[#ff5722] border border-[#ff5722]/20">
233
+ {post.category}
234
+ </span>
235
+ </div>
236
+ <h1 className="mb-4 text-4xl font-bold tracking-tight text-white sm:text-5xl">
237
+ {post.title}
238
+ </h1>
239
+ <p className="text-xl text-gray-400">{post.description}</p>
240
+ <div className="mt-6 flex items-center gap-4 text-sm text-gray-500">
241
+ <div className="flex items-center gap-2">
242
+ <Calendar className="h-4 w-4" />
243
+ <time dateTime={post.date}>
244
+ {new Date(post.date).toLocaleDateString("en-US", {
245
+ year: "numeric",
246
+ month: "long",
247
+ day: "numeric",
248
+ })}
249
+ </time>
250
+ </div>
251
+ <span>•</span>
252
+ <div className="flex items-center gap-2">
253
+ <Clock className="h-4 w-4" />
254
+ <span>{post.readTime}</span>
255
+ </div>
256
+ </div>
257
+ </header>
258
+
259
+ {/* Article Content */}
260
+ <div className="prose prose-invert prose-lg max-w-none">
261
+ <ReactMarkdown
262
+ remarkPlugins={[remarkGfm]}
263
+ components={{
264
+ h1: ({ children }) => (
265
+ <h1 className="text-3xl font-bold text-white mt-8 mb-4">{children}</h1>
266
+ ),
267
+ h2: ({ children }) => (
268
+ <h2 className="text-2xl font-bold text-white mt-8 mb-4">{children}</h2>
269
+ ),
270
+ h3: ({ children }) => (
271
+ <h3 className="text-xl font-bold text-white mt-6 mb-3">{children}</h3>
272
+ ),
273
+ p: ({ children }) => (
274
+ <p className="text-gray-300 mb-4 leading-relaxed">{children}</p>
275
+ ),
276
+ ul: ({ children }) => (
277
+ <ul className="list-disc list-inside text-gray-300 mb-4 space-y-2">{children}</ul>
278
+ ),
279
+ ol: ({ children }) => (
280
+ <ol className="list-decimal list-inside text-gray-300 mb-4 space-y-2">{children}</ol>
281
+ ),
282
+ blockquote: ({ children }) => (
283
+ <blockquote className="border-l-4 border-[#ff5722] pl-4 italic text-gray-400 my-6">
284
+ {children}
285
+ </blockquote>
286
+ ),
287
+ code: ({ children, className }) => {
288
+ const isBlock = className?.includes('language-');
289
+ if (isBlock) {
290
+ return (
291
+ <pre className="bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg p-4 overflow-x-auto my-6">
292
+ <code className="text-sm text-gray-300">{children}</code>
293
+ </pre>
294
+ );
295
+ }
296
+ return (
297
+ <code className="bg-[#1a1a1a] text-[#ff5722] px-1.5 py-0.5 rounded text-sm">
298
+ {children}
299
+ </code>
300
+ );
301
+ },
302
+ strong: ({ children }) => (
303
+ <strong className="font-bold text-white">{children}</strong>
304
+ ),
305
+ }}
306
+ >
307
+ {post.content}
308
+ </ReactMarkdown>
309
+ </div>
310
+ </div>
311
+ </article>
312
+ </div>
313
+ );
314
+ }
@@ -0,0 +1,107 @@
1
+ import Link from "next/link";
2
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
3
+ import { ArrowRight, Calendar } from "lucide-react";
4
+
5
+ // Blog posts metadata
6
+ // In a real app, this would come from a CMS or markdown files
7
+ const blogPosts = [
8
+ {
9
+ slug: "getting-started-with-saas",
10
+ title: "Getting Started with Your SaaS Journey",
11
+ description: "Learn how to validate your SaaS idea and build your first MVP in record time.",
12
+ date: "2024-12-15",
13
+ author: "{{PROJECT_NAME}} Team",
14
+ readTime: "5 min read",
15
+ category: "Guides",
16
+ },
17
+ {
18
+ slug: "optimizing-conversion-rates",
19
+ title: "10 Proven Ways to Optimize Your SaaS Conversion Rates",
20
+ description: "Discover actionable strategies to convert more visitors into paying customers.",
21
+ date: "2024-12-10",
22
+ author: "{{PROJECT_NAME}} Team",
23
+ readTime: "8 min read",
24
+ category: "Marketing",
25
+ },
26
+ {
27
+ slug: "scaling-your-saas",
28
+ title: "Scaling Your SaaS: Infrastructure Best Practices",
29
+ description: "Technical insights on scaling your application to handle thousands of users.",
30
+ date: "2024-12-05",
31
+ author: "{{PROJECT_NAME}} Team",
32
+ readTime: "10 min read",
33
+ category: "Engineering",
34
+ },
35
+ ];
36
+
37
+ export const metadata = {
38
+ title: "Blog",
39
+ description: "Insights, guides, and best practices for building successful SaaS products.",
40
+ };
41
+
42
+ export default function BlogPage() {
43
+ return (
44
+ <div className="min-h-screen bg-black">
45
+ {/* Header */}
46
+ <div className="border-b border-[#2a2a2a] bg-gradient-to-b from-[#0a0a0a] to-black">
47
+ <div className="container mx-auto px-4 py-16 sm:px-6 lg:px-8">
48
+ <div className="max-w-3xl">
49
+ <h1 className="text-4xl font-bold tracking-tight text-white sm:text-5xl md:text-6xl">
50
+ Blog
51
+ </h1>
52
+ <p className="mt-4 text-xl text-gray-400">
53
+ Insights, guides, and best practices for building successful SaaS products.
54
+ </p>
55
+ </div>
56
+ </div>
57
+ </div>
58
+
59
+ {/* Blog Posts Grid */}
60
+ <div className="container mx-auto px-4 py-16 sm:px-6 lg:px-8">
61
+ <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
62
+ {blogPosts.map((post) => (
63
+ <Link key={post.slug} href={`/blog/${post.slug}`}>
64
+ <Card className="h-full bg-[#0a0a0a] border-[#2a2a2a] hover:border-[#ff5722]/30 transition-all duration-300 group">
65
+ <CardHeader>
66
+ <div className="flex items-center gap-2 text-sm text-gray-500 mb-2">
67
+ <Calendar className="h-4 w-4" />
68
+ <time dateTime={post.date}>
69
+ {new Date(post.date).toLocaleDateString("en-US", {
70
+ year: "numeric",
71
+ month: "long",
72
+ day: "numeric",
73
+ })}
74
+ </time>
75
+ <span>•</span>
76
+ <span>{post.readTime}</span>
77
+ </div>
78
+ <CardTitle className="text-white group-hover:text-[#ff5722] transition-colors">
79
+ {post.title}
80
+ </CardTitle>
81
+ <CardDescription className="text-gray-400">
82
+ {post.description}
83
+ </CardDescription>
84
+ </CardHeader>
85
+ <CardContent>
86
+ <div className="flex items-center justify-between">
87
+ <span className="inline-flex items-center rounded-full bg-[#ff5722]/10 px-3 py-1 text-xs font-medium text-[#ff5722] border border-[#ff5722]/20">
88
+ {post.category}
89
+ </span>
90
+ <ArrowRight className="h-4 w-4 text-gray-500 group-hover:text-[#ff5722] group-hover:translate-x-1 transition-all" />
91
+ </div>
92
+ </CardContent>
93
+ </Card>
94
+ </Link>
95
+ ))}
96
+ </div>
97
+
98
+ {/* Coming Soon Message */}
99
+ <div className="mt-12 text-center">
100
+ <p className="text-gray-500">
101
+ More articles coming soon. Subscribe to our newsletter to stay updated!
102
+ </p>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ );
107
+ }
@@ -0,0 +1,13 @@
1
+ # Allow all crawlers
2
+ User-agent: *
3
+ Allow: /
4
+
5
+ # Disallow specific paths
6
+ Disallow: /api/
7
+ Disallow: /dashboard/
8
+ Disallow: /sign-in
9
+ Disallow: /sign-up
10
+
11
+ # Sitemap location
12
+ Sitemap: {{APP_URL}}/sitemap.xml
13
+