commit fff986ea064c70b9a6b81cabd7f4a57e64f173cc Author: Krystie Date: Wed Apr 15 19:56:21 2026 -0700 DashCaddy.net marketing website with Stripe integration diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..517252d --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..88aea70 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,5 @@ + +# This is NOT the Next.js you know + +This version has breaking changes โ€” APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fd25442 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..45752a2 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# DashCaddy.net - Marketing Website + +Marketing and sales website for [DashCaddy](https://git.dashcaddy.net/sami7777/dashcaddy), the self-hosted Docker dashboard with automatic SSL, DNS, and reverse proxy configuration. + +## Tech Stack + +- **Next.js 16** with App Router and TypeScript +- **Tailwind CSS** for styling +- **Stripe** for subscription payments ($20/mo or $99/yr) + +## Getting Started + +```bash +# Install dependencies +npm install + +# Copy environment file and configure +cp .env.example .env.local + +# Run development server +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to see the site. + +## Pages + +| Route | Description | +|-------|-------------| +| `/` | Landing page with hero, features, app showcase | +| `/features` | Detailed feature breakdown | +| `/pricing` | Pricing plans with Stripe Checkout | +| `/docs` | Getting started guide and documentation | +| `/about` | About page and company info | +| `/success` | Post-checkout success page | + +## Stripe Integration + +See [STRIPE_SETUP.md](./STRIPE_SETUP.md) for detailed setup instructions. + +**API Routes:** +- `POST /api/checkout` - Creates Stripe Checkout session +- `POST /api/webhooks/stripe` - Handles Stripe webhook events + +## Logo Setup + +Place your `samiahmed7777-logo.png` file in `public/images/` for the footer copyright branding. + +## Deployment + +```bash +# Build for production +npm run build + +# Start production server +npm start +``` + +The site can be deployed to Vercel, your own server (with Node.js), or any platform that supports Next.js. + +## License + +Proprietary - DashCaddy diff --git a/STRIPE_SETUP.md b/STRIPE_SETUP.md new file mode 100644 index 0000000..dca2f8f --- /dev/null +++ b/STRIPE_SETUP.md @@ -0,0 +1,83 @@ +# Stripe Setup Guide for DashCaddy.net + +## 1. Create a Stripe Account + +Go to [stripe.com](https://stripe.com) and create an account (or log in). + +## 2. Create Your Product and Prices + +In the Stripe Dashboard: + +1. Go to **Products** > **Add Product** +2. Name: `DashCaddy Premium` +3. Description: `Premium license for DashCaddy - Self-hosting dashboard` +4. Create two prices: + - **Monthly**: $20.00 USD / month (recurring) + - **Yearly**: $99.00 USD / year (recurring) +5. Note down both **Price IDs** (they look like `price_1234...`) + +## 3. Get Your API Keys + +1. Go to **Developers** > **API Keys** +2. Copy your **Publishable key** (`pk_test_...` or `pk_live_...`) +3. Copy your **Secret key** (`sk_test_...` or `sk_live_...`) + +## 4. Set Up Webhooks + +1. Go to **Developers** > **Webhooks** +2. Click **Add endpoint** +3. URL: `https://dashcaddy.net/api/webhooks/stripe` +4. Select these events: + - `checkout.session.completed` + - `customer.subscription.updated` + - `customer.subscription.deleted` + - `invoice.payment_failed` +5. Copy the **Webhook signing secret** (`whsec_...`) + +## 5. Configure Environment Variables + +Copy `.env.example` to `.env.local` and fill in your values: + +```bash +cp .env.example .env.local +``` + +Edit `.env.local`: + +```env +STRIPE_SECRET_KEY=sk_live_your_actual_secret_key +NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_your_actual_publishable_key +STRIPE_WEBHOOK_SECRET=whsec_your_actual_webhook_secret +STRIPE_PRICE_MONTHLY=price_your_monthly_price_id +STRIPE_PRICE_YEARLY=price_your_yearly_price_id +NEXT_PUBLIC_APP_URL=https://dashcaddy.net +``` + +## 6. Test with Stripe CLI (Optional) + +For local development, use Stripe CLI to forward webhooks: + +```bash +stripe listen --forward-to localhost:3000/api/webhooks/stripe +``` + +Use test card `4242 4242 4242 4242` with any future date and any CVC. + +## 7. License Key Delivery + +The webhook handler at `src/app/api/webhooks/stripe/route.ts` has TODO comments +where you need to implement: + +1. **Generate license key** using the same format as DashCaddy's license-keygen + (DC-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX) +2. **Store it** in a database (Stripe metadata can also hold it) +3. **Email it** to the customer (use Stripe's receipt email or a service like + SendGrid/Resend) +4. **Link it** to the Stripe subscription ID so you can manage renewals/cancellations + +## Pricing Strategy Notes + +- **Monthly ($20/mo)**: Positioned as the flexibility option +- **Yearly ($99/yr)**: ~$8.25/mo โ€” 58% savings, this will be the primary seller +- **14-day free trial**: Enabled on both plans via `trial_period_days: 14` +- **Promotion codes**: Enabled via `allow_promotion_codes: true` diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..88d5fc3 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..f20f687 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..3178994 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "dashcaddy-site", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "@stripe/stripe-js": "^9.2.0", + "next": "16.2.4", + "react": "19.2.4", + "react-dom": "19.2.4", + "stripe": "^22.0.1" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.2.4", + "tailwindcss": "^4", + "typescript": "^5" + } +} diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..bc52b4a --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,7 @@ +const config = { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; + +export default config; diff --git a/public/file.svg b/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/.gitkeep b/public/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/public/images/README.txt b/public/images/README.txt new file mode 100644 index 0000000..ab91e6f --- /dev/null +++ b/public/images/README.txt @@ -0,0 +1 @@ +Place your samiahmed7777-logo.png file in this directory diff --git a/public/images/samiahmed7777-logo.png b/public/images/samiahmed7777-logo.png new file mode 100644 index 0000000..11c97b1 Binary files /dev/null and b/public/images/samiahmed7777-logo.png differ diff --git a/public/next.svg b/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/window.svg b/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx new file mode 100644 index 0000000..2652dee --- /dev/null +++ b/src/app/about/page.tsx @@ -0,0 +1,197 @@ +import Navbar from "@/components/Navbar"; +import Footer from "@/components/Footer"; +import Link from "next/link"; + +export default function AboutPage() { + return ( + <> + +
+ {/* Hero */} +
+
+
+

+ Built for the{" "} + Self-Hosting Community +

+

+ DashCaddy was born from the frustration of managing dozens of + Docker containers, SSL certificates, and DNS records by hand. We + built the tool we wished existed. +

+
+
+ + {/* Story */} +
+
+

Our Story

+
+

+ Self-hosting is powerful. You own your data, you control your + infrastructure, and you're not at the mercy of SaaS + providers who can change their terms, raise prices, or shut down + overnight. But let's be honest — it can also be a + pain. +

+

+ Every new service means editing Caddyfiles, creating DNS + records, configuring SSL certificates, writing Docker Compose + files, and hoping everything plays nicely together. Multiply that + by 20, 30, or 50 services, and you've got a full-time + operations job on your hands. +

+

+ DashCaddy was built to solve this. One click to deploy an app. + SSL, DNS, and reverse proxy configuration happen automatically. + A beautiful dashboard to monitor everything. And when something + goes wrong, you know about it immediately — not when a + family member texts you that Plex is down. +

+

+ We believe self-hosting should be accessible to everyone, not + just people who enjoy writing YAML at 2 AM. DashCaddy makes it + beautiful and effortless. +

+
+
+
+ + {/* Values */} +
+
+

+ What We Believe In +

+
+ {[ + { + icon: "๐Ÿ”“", + title: "Open Core", + description: + "The core of DashCaddy is free and always will be. Premium features fund development, but the essentials are open to everyone.", + }, + { + icon: "๐Ÿ ", + title: "Your Data, Your Server", + description: + "DashCaddy runs entirely on your hardware. No cloud dependency, no telemetry, no phoning home. Your data never leaves your network.", + }, + { + icon: "๐Ÿ› ๏ธ", + title: "Built to Last", + description: + "We use proven technologies โ€” Caddy, Docker, Node.js. No bleeding-edge frameworks that break every six months. Stable, reliable, boring (in the best way).", + }, + ].map((value) => ( +
+
{value.icon}
+

+ {value.title} +

+

{value.description}

+
+ ))} +
+
+
+ + {/* Tech Stack */} +
+
+

+ Built With +

+
+ {[ + { + name: "Caddy", + role: "Reverse Proxy & SSL", + icon: "๐Ÿ”’", + }, + { + name: "Docker", + role: "Container Runtime", + icon: "๐Ÿณ", + }, + { + name: "Node.js", + role: "API Backend", + icon: "๐ŸŸข", + }, + { + name: "Technitium", + role: "DNS Server", + icon: "๐ŸŒ", + }, + ].map((tech) => ( +
+
{tech.icon}
+
{tech.name}
+
{tech.role}
+
+ ))} +
+
+
+ + {/* Contact / Support */} +
+
+

Get In Touch

+

+ Have questions, feedback, or want to contribute? We'd love to + hear from you. +

+ +
+
+ + {/* CTA */} +
+
+

+ Ready to simplify your homelab? +

+

+ Start with the free tier. Upgrade when you're ready. +

+ + View Pricing + +
+
+
+