Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

V2 #7

Draft
wants to merge 41 commits into
base: master
Choose a base branch
from
Draft

V2 #7

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
25e5c2c
add new landing page
vincanger Nov 8, 2023
c383435
improve features and pricing section
vincanger Nov 9, 2023
997750b
fix pricing section
vincanger Nov 10, 2023
3354093
add nav stuff and adjust styles
vincanger Nov 10, 2023
314a8b8
add admin dashboard
vincanger Nov 13, 2023
5a96ae8
Update useReferrer.tsx
vincanger Nov 13, 2023
1a999bb
create job to calc stripe and user stats
vincanger Nov 14, 2023
9a37ece
add dropdown to navbars
vincanger Nov 15, 2023
17cba4e
update ref and users table
vincanger Nov 17, 2023
af979e2
stripe webhook sig & more
vincanger Nov 20, 2023
b6fd33f
improve user table filters
vincanger Nov 21, 2023
3e69555
add docs
vincanger Nov 23, 2023
d9034fb
fix shared import and user admin access
vincanger Nov 23, 2023
eb940e7
add analytics & more docs
vincanger Nov 24, 2023
c894ed1
referrer refactor and add sources stats
vincanger Nov 27, 2023
646e33f
analytics
vincanger Nov 28, 2023
7850db1
fix seed, stats, footer, etc
vincanger Nov 30, 2023
da0d79e
add menu items to mobile nav
vincanger Nov 30, 2023
3fe74e4
check for customer portal link
vincanger Nov 30, 2023
b10fd40
check for stripe customer portal link in prod
vincanger Nov 30, 2023
0013fab
Update AccountPage.tsx
vincanger Nov 30, 2023
546a5eb
Update AccountPage.tsx
vincanger Nov 30, 2023
fefe37a
update doc intro
vincanger Dec 1, 2023
41bcd70
update analytics
vincanger Dec 1, 2023
8d5ab0d
fixes
vincanger Dec 1, 2023
2d3bacc
Create LICENSE
vincanger Dec 1, 2023
277fce6
update readme add contributing
vincanger Dec 1, 2023
0298dcb
fix contributing
vincanger Dec 1, 2023
289c484
fix readme
vincanger Dec 1, 2023
6535a9d
fix deploy issues
vincanger Dec 4, 2023
87cc259
wasp version bump
vincanger Dec 4, 2023
21365e5
update landing page
vincanger Dec 4, 2023
0ed1c60
docs blog consts
vincanger Dec 4, 2023
c8c0b81
Update LandingPage.tsx
vincanger Dec 4, 2023
1182ef0
Update constants.ts
vincanger Dec 4, 2023
2f776e4
Update actions.ts
vincanger Dec 4, 2023
502f87c
add banner and improve LP
vincanger Dec 5, 2023
665b3dc
Update constants.ts
vincanger Dec 6, 2023
c089283
Update LandingPage.tsx
vincanger Dec 5, 2023
8c52e6c
fix docs header and links
vincanger Dec 6, 2023
7369dba
use Astro.site for header url
vincanger Dec 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.client.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# learn more about client side env vars https://wasp-lang.dev/docs/project/env-vars
REACT_APP_SOME_VAR_NAME=foo
36 changes: 30 additions & 6 deletions .env.server.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
# NOTE: if you setup your DB using `wasp start db` then you DO NOT need to add a DATABASE_URL env.
# NOTE: you can let Wasp set up your Postgres DB by running `wasp start db` in a separate terminal window.
# then, in a new terminal window, run `wasp db migrate-dev` and finally `wasp start`.
# If you use `wasp start db` then you DO NOT need to add a DATABASE_URL env variable here.
# DATABASE_URL=

# for testing, go to https://dashboard.stripe.com/test/apikeys and get a test stripe key that starts with "sk_test_..."
STRIPE_KEY=
STRIPE_KEY=sk_test_...
# to create a test subscription, go to https://dashboard.stripe.com/test/products and click on + Add Product
SUBSCRIPTION_PRICE_ID=
HOBBY_SUBSCRIPTION_PRICE_ID=price_...
PRO_SUBSCRIPTION_PRICE_ID=price_...
# after downloading starting the stripe cli (https://stripe.com/docs/stripe-cli) with `stripe listen --forward-to localhost:3001/stripe-webhook` it will output your signing secret
STRIPE_WEBHOOK_SECRET=whsec_...

# set this as a comma-separated list of emails you want to give admin privileges to upon registeration
[email protected],[email protected],[email protected]

# this needs to be a string at least 32 characters long
JWT_SECRET=

# see our guide for setting up google auth: https://wasp-lang.dev/docs/auth/social-auth/google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

# (OPTIONAL) get your openai api key at https://platform.openai.com/account
OPENAI_API_KEY=

# get your sendgrid api key at https://app.sendgrid.com/settings/api_keys
SENDGRID_API_KEY=
# if not explicitly set to true, emails be logged to console but not actually sent
SEND_EMAILS_IN_DEVELOPMENT=true

# (OPTIONAL) get your openai api key at https://platform.openai.com/account
OPENAI_API_KEY=

# (OPTIONAL) get your plausible api key at https://plausible.io/login or https://your-plausible-instance.com/login
PLAUSIBLE_API_KEY=
# You will find your site id in the Plausible dashboard. It will look like 'opensaas.sh'
PLAUSIBLE_SITE_ID=
PLAUSIBLE_BASE_URL=https://plausible.io/api/v1 # if you are self-hosting plausible, change this to your plausible instance's base url

# (OPTIONAL) get your google service account key at https://console.cloud.google.com/iam-admin/serviceaccounts
GOOGLE_ANALYTICS_CLIENT_EMAIL=
# Make sure you convert the private key within the JSON file to base64 first with `echo -n "PRIVATE_KEY" | base64`. see the docs for more info.
GOOGLE_ANALYTICS_PRIVATE_KEY=
# You will find your Property ID in the Google Analytics dashboard. It will look like '987654321'
GOOGLE_ANALYTICS_PROPERTY_ID=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ fly config/fly-client.toml
fly config/fly-server.toml
fly-client.toml
fly-server.toml
# TODO: create a clean version for the user to fill in
# replace with your own Google Analytics service account json file
saastemplate-381911-6dc3caae2204.json
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Thanks so much for considering contributing to Open SaaS 🙏

## How to contribute
Contributing is simple:
1. Make sure you've installed and run the app.
2. Find something you'd like to work on. Check out the [issues](https://github.com/wasp-lang/open-saas/issues) or contact us on the [Wasp Discord](https://discord.gg/aCamt5wCpS) to discuss.
3. If the issue doesn't already exist, create a new one and assign yourself to it.
4. Create a new branch for your work.
5. Make your changes.
6. Commit your changes.
7. Push your changes.
8. Create a pull request.
9. Pray to "Da Boi" while you wait for us to review your PR.
10. If you don't know who "Da Boi" is, head back to the [Wasp Discord](https://discord.gg/aCamt5wCpS) and ask around.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 wasp-lang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
82 changes: 28 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,41 @@
# SaaS Template w/ GPT API, Google Auth, Tailwind, & Stripe Payments
## Welcome to your new SaaS App!

<img src='src/client/static/gptsaastemplate.png' width='700px'/>
You've decided to build a SaaS app with the Open SaaS template. Great choice! 🎉

<br/>
<a href="https://www.producthunt.com/posts/free-saas-template-gpt-stripe-auth?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-free&#0045;saas&#0045;template&#0045;gpt&#0045;stripe&#0045;auth" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=389763&theme=neutral" alt="Free&#0032;SaaS&#0032;Template&#0032;&#0040;GPT&#0044;&#0032;Stripe&#0044;&#0032;Auth&#0041; - A&#0032;free&#0032;React&#0047;NodeJS&#0032;SaaS&#0032;template&#0032;for&#0032;quick&#0032;idea&#0032;execution | Product Hunt" style="width: 200px;" width="200" /></a>
<br/>
This template is:

## What is it?
Entirely free SaaS template built with Prisma/Postgres, Express, React, Node (PERN stack). Use it as a springboard to build great products!
1. fully open-source
2. completely free to use and distribute
3. comes with a ton of features out of the box!
4. focused on free, open-source services, where possible

It has pre-configured:
- 🔐 Authentication (email + social)
- 📩 Emailing
- 🤑 Payments (Stripe)
- 🤖 GPT API,
Try it out here: [OpenSaaS.sh](https://opensaas.sh)
Check out the Docs here: [Open SaaS Docs](https://docs.opensaas.sh)

and leverages:
- ⌨️ TypeScript
- 🎨 Tailwind CSS
## What's inside?

Test it out here: [https://saas-template-gpt-client.fly.dev/](https://saas-template-gpt-client.fly.dev/)
The template itself is built on top of some very powerful tools and frameworks, including:

## Running it locally
- 🐝 [Wasp](https://wasp-lang.dev) - a full-stack React, NodeJS, Prisma framework with superpowers
- 🚀 [Astro](https://starlight.astro.build/) - Astro's lightweight "Starlight" template for documentation and blog
- 💸 [Stripe](https://stripe.com) - for products and payments
- 📈 [Plausible](https://plausible.io) or [Google](https://analytics.google.com/) Analytics
- 🤖 [OpenAI](https://openai.com) - OpenAI API integrated into the app
- 📧 [SendGrid](https://sendgrid.com), [MailGun](https://mailgun.com), or SMTP - for email sending
- 💅 [TailwindCSS](https://tailwindcss.com) - for styling
- 🧑‍💼 [TailAdmin](https://tailadmin.com/) - admin dashboard & components for TailwindCSS

1. Make sure you have the latest version of [Wasp](https://wasp-lang.dev) installed by running `curl -sSL https://get.wasp-lang.dev/installer.sh | sh` in your terminal.
2. Run `wasp new <project-name> -t saas` to create a new app using this template.
3. Rename the `env.server.example` file to `.env.server` and fill in your API keys according to the instructions in the file.
4. Make sure you have a Database connected and running. Here are two quick options:
- run `wasp start db` if you have Docker installed and running (if not, on MacOS run `brew install docker-machine docker` then find and run the app from your launchpad). This will start a Postgres database for you. No need to do anything else! 🤯
- or provision a Postgres database on [Railway](https://railway.app), go to settings and copy the `connection url`. Paste it as `DATABASE_URL=<your-postgres-connection-url>` into your `env.server` file.
5. Run `wasp db migrate-dev`
6. Run `wasp start`. This will install all dependencies and start the client and server for you :)
7. Go to `localhost:3000` in your browser (your NodeJS server will be running on port `3001`)
8. Install the [Wasp extension for VSCode](https://marketplace.visualstudio.com/items?itemName=wasp-lang.wasp) to get the best DX
9. Check the files for comments containing specific instructions.
10. If you would like to test Stripe Webhooks locally, download the [Stripe CLI](https://stripe.com/docs/stripe-cli#install). This [YouTube video](https://youtu.be/Psq5N5C-FGo?si=CzRy3kizF20RFiSK&t=1041) does a great job explaining how to test webhooks locally with the Stripe CLI (watch until 27:00).
11. Enjoy and Have fun. When you create an App with this template, be kind and let me know by tagging me on twitter [@hot_town](https://twitter.com/hot_town)
Because we're using Wasp as the full-stack framework, we can leverage a lot of its features to build our SaaS in record time, including:

## Deploying it quickly to Fly.io
- 🔐 [Full-stack Authentication](https://wasp-lang.dev/docs/auth/overview) - Email verified + social Auth in a few lines of code.
- ⛑ [End-to-end Type Safety](https://wasp-lang.dev/docs/data-model/operations/overview) - Type your backend functions and get inferred types on the front-end automatically, without the need to install or configure any third-party libraries. Oh, and type-safe Links, too!
- 🤖 [Jobs](https://wasp-lang.dev/docs/language/features#jobs) - Run cron jobs in the background or set up queues simply by defining a function in the config file.
- 🚀 [One-command Deploy](https://wasp-lang.dev/docs/advanced/deployment/overview) - Easily deploy via the CLI to [Fly.io](https://fly.io), or to other provides like [Railway](https://railway.app) and [Netlify](https://netlify.com).

1. Create an account on Fly.io
2. Install the Fly CLI by running `curl -L https://fly.io/install.sh | sh` on Linux/MacOS
3. Run `wasp deploy fly setup my-wasp-app mia`
4. Run `wasp deploy fly cmd secrets set ENV_VAR_EXAMPLE=<your-env-var> --context=server`, making sure to fill in all of your env vars
5. Run `wasp deploy fly create-db mia`
6. Run `wasp deploy fly deploy`
7. Make sure you've updated your Stripe webhook URL in your [Stripe dashboard](https://dashboard.stripe.com/) to point to your Fly app's URL
8. Also make sure you've updated your [Google Auth callback URL](https://wasp-lang.dev/docs/integrations/google#google-auth) to point to your Fly app's URL
You also get access to Wasp's diverse, helpful community if you get stuck or need help.
- 🤝 [Wasp Discord](https://discord.gg/aCamt5wCpS)

You can also see the guides for deploying manually to Fly, Railway, and Netlify [here](https://wasp-lang.dev/docs/deploying).

## How it works
Note that we've tried to get as many of the core features of a SaaS app into this template as possible, but there still might be some missing features or functionality.

- 🐝 [Wasp](https://wasp-lang.dev) - allows you to build full-stack apps with 10x less boilerplate
- 🎨 [Tailwind CSS](https://tailwindcss.com/) - CSS that's easy to work with
- 🤖 [OpenAI](https://openai.com/) - GPT-3.5 turbo API
- 💸 [Stripe](https://stripe.com/) - for payments
- 📧 [SendGrid](https://sendgrid.com/) - for email

[Wasp](https://wasp-lang.dev) as the full-stack framework allows you to describe your app’s core features in the `main.wasp` config file in the root directory. Then it builds and glues these features into a React-Express-Prisma app for you so that you can focus on writing the client and server-side logic instead of configuring. For example, I did not have to use any third-party libraries for Google Authentication. I just wrote a couple lines of code in the config file stating that I want to use Google Auth, and Wasp configures it for me. Check out the comments `main.wasp` file for more.

[Stripe](https://stripe.com/) makes the payment functionality super easy. I just used their `Subscription` feature. After the user pays, their `hasPaid` and `datePaid` fields are updated in the database via the webhook found in the `src/server/webhooks.ts` file.

[Wasp's integrated Jobs](https://wasp-lang.dev/docs/language/features#jobs) feature is used to run a cron job every week to send an newsletter email. I used [SendGrid](https://sendgrid.com/) for the email service.

If you have any other questions, feel free to reach out to me on [twitter](https://twitter.com/hot_town) or in the [Wasp discord server](https://discord.gg/rzdnErX).
We could always use some help tying up loose ends, so consider [contributing](https://github.com/wasp-lang/open-saas/blob/main/CONTRIBUTING.md)!
21 changes: 21 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*


# environment variables
.env
.env.production

# macOS-specific files
.DS_Store
4 changes: 4 additions & 0 deletions docs/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
11 changes: 11 additions & 0 deletions docs/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
53 changes: 53 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Starlight Starter Kit: Basics

[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build)

```
npm create astro@latest -- --template starlight
```

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)

> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!

## 🚀 Project Structure

Inside of your Astro + Starlight project, you'll see the following folders and files:

```
.
├── public/
├── src/
│ ├── assets/
│ ├── content/
│ │ ├── docs/
│ │ └── config.ts
│ └── env.d.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json
```

Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.

Images can be added to `src/assets/` and embedded in Markdown with a relative link.

Static assets, like favicons, can be placed in the `public/` directory.

## 🧞 Commands

All commands are run from the root of the project, from a terminal:

| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |

## 👀 Want to learn more?

Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
71 changes: 71 additions & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import starlightBlog from 'starlight-blog';

// https://astro.build/config
export default defineConfig({
site: 'https://opensaas.sh',
integrations: [
starlightBlog({
title: 'Blog',
authors: {
vince: {
name: 'Vince',
title: 'Dev Rel @ Wasp',
picture: '/CRAIG_ROCK.png', // Images in the `public` directory are supported.
url: 'https://wasp-lang.dev',
},
},
}),
starlight({
title: 'OpenSaaS.sh',
description: 'Open SaaS is a free, open-source, full-stack SaaS starter kit for React + NodeJS.',
logo: {
src: '/src/assets/logo.png',
alt: 'Open SaaS',
},
editLink: {
baseUrl: 'https://github.com/wasp-lang/open-saas/edit/main',
},
components: {
SiteTitle: './src/components/MyHeader.astro',
MarkdownContent: 'starlight-blog/overrides/MarkdownContent.astro',
Sidebar: 'starlight-blog/overrides/Sidebar.astro',
// ThemeSelect: 'starlight-blog/overrides/ThemeSelect.astro',
},
social: {
github: 'https://github.com/wasp-lang/open-saas',
twitter: 'https://twitter.com/wasp_lang',
discord: 'https://discord.gg/aCamt5wCpS',
},
sidebar: [
{
label: 'Start Here',
items: [
{ label: 'Introduction', link: '/' },
{ label: 'Getting Started', link: '/start/getting-started/' },
],
},
{
label: 'Guides',
items: [
{ label: 'Authentication', link: '/guides/authentication/' },
{ label: 'Authorization', link: '/guides/authorization/' },
{ label: 'Stripe Integration', link: '/guides/stripe-integration/' },
{ label: 'Stripe Testing', link: '/guides/stripe-testing/' },
{ label: 'Analytics', link: '/guides/analytics/' },
{ label: 'Email Sending', link: '/guides/email-sending/' },
{ label: 'Deploying', link: '/guides/deploying/' },
],
},
{
label: 'General',
items: [
{ label: 'Admin Dashboard', link: '/general/admin-dashboard/' },
{ label: 'User Permissions', link: '/general/user-permissions/' },
],
},
],
}),
],
});
Loading