mirror of
https://github.com/wasp-lang/open-saas.git
synced 2025-06-17 12:21:06 +02:00
Merge branch 'main' of https://github.com/wasp-lang/open-saas
This commit is contained in:
commit
f8f65af004
14
.github/FUNDING.yml
vendored
Normal file
14
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: [ wasp-lang ] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: # Replace with a single Patreon username
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||||
|
polar: # Replace with a single Polar username
|
||||||
|
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
@ -1,24 +1,34 @@
|
|||||||
Thanks so much for considering contributing to Open SaaS 🙏
|
Thanks so much for considering contributing to Open SaaS 🙏
|
||||||
|
|
||||||
## Considerations before Contributing
|
## Considerations before Contributing
|
||||||
|
Check if there is a GitHub issue already for the thing you would like to work on. If there is no issue yet, create a new one.
|
||||||
|
|
||||||
### General Considerations
|
Let us know, in the issue, that you would like to work on it and how you plan to approach it.
|
||||||
1. If there's something you'd like to add, and the issue doesn't already exist, create a new one and assign yourself to it. Wait until we've agreed on a plan of action before beginning your work.
|
This helps, especially with the more complex issues, as it allows us to discuss the solution upfront and make sure it is well planned and fits with the rest of the project.
|
||||||
2. If the issue does already exist, and noone is assigned to it, assign yourself and feel free to begin working on it.
|
|
||||||
|
|
||||||
### How Users Get the Starter Template
|
## How to Contribute
|
||||||
|
1. Make sure you understand the basics of how open-saas works (check out [docs](https://docs.opensaas.sh)).
|
||||||
|
2. Check out this repo (`main` branch) and make sure you are able to get the app in `app/` running (to set it up, follow the same steps as for running a new open-saas app, as explained in the open-saas docs).
|
||||||
|
3. Create a new git branch for your work (aka feature branch) and do your changes on it.
|
||||||
|
4. Update e2e tests in [e2e-tests](/e2e-tests/) if needed and make sure they are passing.
|
||||||
|
5. Create a pull request (towards `main` as a base branch).
|
||||||
|
6. If docs (also) need updating, check out the `deployed-version` branch, make your own feature branch from it, make changes in [blog/src/content/docs](/blog/src/content/docs/), and submit another PR with those changes (towards `deployed-version` as a base branch).
|
||||||
|
7. Make a "Da Boi" meme while you wait for us to review your PR(s).
|
||||||
|
8. If you don't know who "Da Boi" is, head back to the [Wasp Discord](https://discord.gg/aCamt5wCpS) and find out :)
|
||||||
|
|
||||||
We currently have two ways to pull the template:
|
## Additional Info
|
||||||
1. the `use this template` button on the [repo homepage](https://github.com/wasp-lang/open-saas)
|
|
||||||
2. the [Wasp CLI's](https://wasp-lang.dev/docs/quick-start) `wasp new` command
|
|
||||||
|
|
||||||
When pulling the template via `wasp new`, the Wasp CLI looks for a tag `wasp-{CURRENT_VERSION}-template` associated with a specific commit on the Open SaaS repo.
|
### Template Versioning
|
||||||
|
|
||||||
In order to keep this tag up to date, we've created a github action, `.github/workflows/retag-commit.yml`, that automatically reassigns the tag (defined as `TAG_NAME` in the action) to the most recent commit on `main`.
|
Whenever a user starts a new Wasp project with `wasp new -t <template_name>`, Wasp looks for a specific tag on the template repo, and pulls the project at the commit associated with that tag.
|
||||||
|
|
||||||
**This means, that whenever a user pulls the template, they are getting the version present in the most recent commit on `main`**
|
In the case of Open SaaS, which is a Wasp template, the tag is `wasp-v{{version}}-template`, where `{{version}}` is the current version of Wasp, e.g. `wasp-v0.13-template`.
|
||||||
|
|
||||||
Also, If we update Wasp to a new major version, we should also update the `TAG_NAME` in the action.
|
For simplicity, in Open SaaS, we automatically re-apply the tag to the most recent commit on the `main` branch via the `.github/workflows/retag-commit.yml` workflow. This way, users always get the latest version of the template (as on `main` branch) when they start a new project via `wasp new -t saas`.
|
||||||
|
|
||||||
|
**This means, that whenever a user pulls the template via `wasp new -t saas`, they are getting the version present in the most recent commit on `main`.**
|
||||||
|
|
||||||
|
NOTE: When Wasp releases a new major version, we should also make sure to update Open SaaS to work with this new version. In PR that will bring this update, we should also make sure to update the `TAG_NAME` in the GitHub Workflow that does the tagging, to be the template tag used by the newest version of Wasp.
|
||||||
|
|
||||||
### The Default Template vs. the Deployed Site / Docs
|
### The Default Template vs. the Deployed Site / Docs
|
||||||
|
|
||||||
@ -26,16 +36,8 @@ There are two main branches for development:
|
|||||||
- `main`
|
- `main`
|
||||||
- `deployed-version`
|
- `deployed-version`
|
||||||
|
|
||||||
The default, clean template that users get when cloning the starter lives on `main`, while `deployed-version` is what you see when you go to [OpenSaaS.sh](https://opensaas.sh) and the [docs](https://docs.opensaas.sh)
|
The default, clean template that users get when cloning the starter lives on `main`, while `deployed-version` is somewhat modified version of that same template which you see when you go to [OpenSaaS.sh](https://opensaas.sh) and the [docs](https://docs.opensaas.sh).
|
||||||
|
|
||||||
If you want to make changes to the default starter template, base feature branches and Pull Requests off of `main`
|
If you want to make changes to the default starter template, base feature branches and Pull Requests off of `main`.
|
||||||
If you want to make changes to the OpenSaaS.sh site or it's Documentation, base feature branches and Pull Requests off of `deployed-version`
|
If you want to make changes to the OpenSaaS.sh site or it's Documentation, base feature branches and Pull Requests off of `deployed-version`.
|
||||||
|
|
||||||
## 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. Create a new feature branch for your work. See [above](#the-default-template-vs-the-deployed-site--docs) for which branch to base your feature branch off of.
|
|
||||||
4. Create a pull request.
|
|
||||||
5. Make a "Da Boi" meme while you wait for us to review your PR.
|
|
||||||
6. If you don't know who "Da Boi" is, head back to the [Wasp Discord](https://discord.gg/aCamt5wCpS) and find out :)
|
|
||||||
|
24
README.md
24
README.md
@ -63,25 +63,15 @@ For everything you need to know about getting started and using this template, c
|
|||||||
|
|
||||||
We've documented everything in great detail, including installation instructions, pulling updates to the template, guides for integrating services, SEO, deployment, and more. 🚀
|
We've documented everything in great detail, including installation instructions, pulling updates to the template, guides for integrating services, SEO, deployment, and more. 🚀
|
||||||
|
|
||||||
|
|
||||||
## Changes & Contributions
|
|
||||||
|
|
||||||
### Template Versioning
|
|
||||||
|
|
||||||
Whenever a user starts a new Open SaaS project with `wasp new -t saas`, Wasp looks for a specific tag on the repo, and pulls the project at the commit associated with that tag. In the case of Open SaaS, the tag is `wasp-v{{version}}-template`, where `{{version}}` is the current version of Wasp, e.g. `wasp-v0.13-template`.
|
|
||||||
|
|
||||||
For simplicity, we automatically re-apply the tag to the most recent commit on the `main` branch via the `.github/workflows/retag-commit.yml` workflow. This way, users always get the latest version of the template when they start a new project via `wasp new -t saas`.d
|
|
||||||
|
|
||||||
### Contributing
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
We could always use some help tying up loose ends, so consider [contributing](https://github.com/wasp-lang/open-saas/blob/main/CONTRIBUTING.md)!
|
|
||||||
|
|
||||||
As there are a few things to know and consider when contributing, please make sure to read the [CONTRIBUTING.md](https://github.com/wasp-lang/open-saas/blob/main/CONTRIBUTING.md) in this Repo.
|
|
||||||
|
|
||||||
## Getting Help & Providing Feedback
|
## Getting Help & Providing Feedback
|
||||||
|
|
||||||
There are two ways to get help or provide feedback (and we try to always respond quickly!):
|
There are two ways to get help or provide feedback (and we try to always respond quickly!):
|
||||||
1. [Open an issue](https://github.com/wasp-lang/open-saas/issues)
|
1. [Open an issue](https://github.com/wasp-lang/open-saas/issues)
|
||||||
2. [Wasp Discord](https://discord.gg/aCamt5wCpS) -- please direct questions to the #🙋questions forum channel
|
2. [Wasp Discord](https://discord.gg/aCamt5wCpS) -- please direct questions to the #🙋questions forum channel
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
We could always use some help tying up loose ends: contributions are welcome! Check out [CONTRIBUTING.md](/CONTRIBUTING.md) for more details.
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@ app OpenSaaS {
|
|||||||
wasp: {
|
wasp: {
|
||||||
version: "^0.13.2"
|
version: "^0.13.2"
|
||||||
},
|
},
|
||||||
|
|
||||||
title: "My Open SaaS App",
|
title: "My Open SaaS App",
|
||||||
|
|
||||||
head: [
|
head: [
|
||||||
"<meta property='og:type' content='website' />",
|
"<meta property='og:type' content='website' />",
|
||||||
"<meta property='og:title' content='My Open SaaS App' />",
|
"<meta property='og:title' content='My Open SaaS App' />",
|
||||||
@ -13,17 +15,20 @@ app OpenSaaS {
|
|||||||
"<meta name='twitter:image:width' content='800' />",
|
"<meta name='twitter:image:width' content='800' />",
|
||||||
"<meta name='twitter:image:height' content='400' />",
|
"<meta name='twitter:image:height' content='400' />",
|
||||||
"<meta name='twitter:card' content='summary_large_image' />",
|
"<meta name='twitter:card' content='summary_large_image' />",
|
||||||
// you can put your analytics scripts here
|
// TODO: You can put your analytics scripts below (https://docs.opensaas.sh/guides/analytics/):
|
||||||
"<script defer data-domain='<your-site-id>' src='https://plausible.io/js/script.js'></script>",
|
// If you are going with Plausible:
|
||||||
// plausible has script extension `script.local.js` for local development
|
"<script defer data-domain='<your-site-id>' src='https://plausible.io/js/script.js'></script>", // for production
|
||||||
"<script defer data-domain='<your-site-id>' src='https://plausible.io/js/script.local.js'></script>",
|
"<script defer data-domain='<your-site-id>' src='https://plausible.io/js/script.local.js'></script>", // for development
|
||||||
// google analytics only needs one script and will automatically detect if you are in dev mode
|
// If you are going with Google Analytics:
|
||||||
"<!-- Google tag (gtag.js) --><script>...</script>"
|
"<!-- Google tag (gtag.js) --><script>...</script>" // for both production and development
|
||||||
],
|
],
|
||||||
|
|
||||||
// 🔐 Auth out of the box! https://wasp-lang.dev/docs/auth/overview
|
// 🔐 Auth out of the box! https://wasp-lang.dev/docs/auth/overview
|
||||||
auth: {
|
auth: {
|
||||||
userEntity: User,
|
userEntity: User,
|
||||||
methods: {
|
methods: {
|
||||||
|
// NOTE: If you decide to not use email auth, make sure to also delete the related routes and pages below.
|
||||||
|
// (RequestPasswordReset(Route|Page), PasswordReset(Route|Page), EmailVerification(Route|Page))
|
||||||
email: {
|
email: {
|
||||||
fromField: {
|
fromField: {
|
||||||
name: "Open SaaS App",
|
name: "Open SaaS App",
|
||||||
@ -39,10 +44,12 @@ app OpenSaaS {
|
|||||||
},
|
},
|
||||||
userSignupFields: import { getEmailUserFields } from "@src/server/auth/setUsername.js",
|
userSignupFields: import { getEmailUserFields } from "@src/server/auth/setUsername.js",
|
||||||
},
|
},
|
||||||
// google: { // Guide for setting up Auth via Google https://wasp-lang.dev/docs/auth/social-auth/overview
|
// Uncomment to enable Google Auth (check https://wasp-lang.dev/docs/auth/social-auth/google for setup instructions):
|
||||||
|
// google: { // Guide for setting up Auth via Google
|
||||||
// userSignupFields: import { getGoogleUserFields } from "@src/server/auth/setUsername.js",
|
// userSignupFields: import { getGoogleUserFields } from "@src/server/auth/setUsername.js",
|
||||||
// configFn: import { getGoogleAuthConfig } from "@src/server/auth/setUsername.js",
|
// configFn: import { getGoogleAuthConfig } from "@src/server/auth/setUsername.js",
|
||||||
// },
|
// },
|
||||||
|
// Uncomment to enable GitHub Auth (check https://wasp-lang.dev/docs/auth/social-auth/github for setup instructions):
|
||||||
// gitHub: {
|
// gitHub: {
|
||||||
// userSignupFields: import { getGitHubUserFields } from "@src/server/auth/setUsername.js",
|
// userSignupFields: import { getGitHubUserFields } from "@src/server/auth/setUsername.js",
|
||||||
// configFn: import { getGitHubAuthConfig } from "@src/server/auth/setUsername.js",
|
// configFn: import { getGitHubAuthConfig } from "@src/server/auth/setUsername.js",
|
||||||
@ -51,24 +58,28 @@ app OpenSaaS {
|
|||||||
onAuthFailedRedirectTo: "/login",
|
onAuthFailedRedirectTo: "/login",
|
||||||
onAuthSucceededRedirectTo: "/demo-app",
|
onAuthSucceededRedirectTo: "/demo-app",
|
||||||
},
|
},
|
||||||
|
|
||||||
db: {
|
db: {
|
||||||
system: PostgreSQL,
|
system: PostgreSQL,
|
||||||
|
// Run `wasp db seed` to seed the database with the seed functions below:
|
||||||
seeds: [
|
seeds: [
|
||||||
|
// Populates the database with a bunch of fake users to work with during development.
|
||||||
import { devSeedUsers } from "@src/server/scripts/usersSeed.js",
|
import { devSeedUsers } from "@src/server/scripts/usersSeed.js",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
client: {
|
client: {
|
||||||
rootComponent: import App from "@src/client/App",
|
rootComponent: import App from "@src/client/App",
|
||||||
},
|
},
|
||||||
|
|
||||||
emailSender: {
|
emailSender: {
|
||||||
// Note that the "Dummy" provider is just for local development purposes.
|
// NOTE: "Dummy" provider is just for local development purposes.
|
||||||
// Make sure to check the server logs for the confirmation email token (it will not be sent to an address)!
|
// Make sure to check the server logs for the email confirmation url (it will not be sent to an address)!
|
||||||
// Please use SendGrid in production. See: https://docs.opensaas.sh/guides/email-sending/
|
// Once you are ready for production, switch to e.g. "SendGrid" or "MailGun" providers. Check out https://docs.opensaas.sh/guides/email-sending/ .
|
||||||
provider: Dummy,
|
provider: Dummy,
|
||||||
defaultFrom: {
|
defaultFrom: {
|
||||||
name: "Open SaaS App",
|
name: "Open SaaS App",
|
||||||
// When using SendGrid, you must use the same email address that you configured your account to send out emails with!
|
// When using a real provider, e.g. SendGrid, you must use the same email address that you configured your account to send out emails with!
|
||||||
email: "me@example.com"
|
email: "me@example.com"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -80,11 +91,13 @@ app OpenSaaS {
|
|||||||
|
|
||||||
entity User {=psl
|
entity User {=psl
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
email String? @unique
|
email String? @unique
|
||||||
username String? @unique
|
username String? @unique
|
||||||
createdAt DateTime @default(now())
|
|
||||||
lastActiveTimestamp DateTime @default(now())
|
lastActiveTimestamp DateTime @default(now())
|
||||||
isAdmin Boolean @default(false)
|
isAdmin Boolean @default(false)
|
||||||
|
|
||||||
stripeId String?
|
stripeId String?
|
||||||
checkoutSessionId String?
|
checkoutSessionId String?
|
||||||
subscriptionTier String?
|
subscriptionTier String?
|
||||||
@ -92,6 +105,7 @@ entity User {=psl
|
|||||||
sendEmail Boolean @default(false)
|
sendEmail Boolean @default(false)
|
||||||
datePaid DateTime?
|
datePaid DateTime?
|
||||||
credits Int @default(3)
|
credits Int @default(3)
|
||||||
|
|
||||||
gptResponses GptResponse[]
|
gptResponses GptResponse[]
|
||||||
contactFormMessages ContactFormMessage[]
|
contactFormMessages ContactFormMessage[]
|
||||||
tasks Task[]
|
tasks Task[]
|
||||||
@ -100,42 +114,50 @@ psl=}
|
|||||||
|
|
||||||
entity GptResponse {=psl
|
entity GptResponse {=psl
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
content String
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
userId Int
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
userId Int
|
||||||
|
|
||||||
|
content String
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
entity Task {=psl
|
entity Task {=psl
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
userId Int
|
||||||
|
|
||||||
description String
|
description String
|
||||||
time String @default("1")
|
time String @default("1")
|
||||||
isDone Boolean @default(false)
|
isDone Boolean @default(false)
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
userId Int
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
entity File {=psl
|
entity File {=psl
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
userId Int
|
||||||
|
|
||||||
name String
|
name String
|
||||||
type String
|
type String
|
||||||
key String
|
key String
|
||||||
uploadUrl String
|
uploadUrl String
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
userId Int
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
// TODO: add functionality to allow users to send messages to admin
|
// TODO: add functionality to allow users to send messages to admin
|
||||||
// and make them accessible via the admin dashboard
|
// and make them accessible via the admin dashboard
|
||||||
entity ContactFormMessage {=psl
|
entity ContactFormMessage {=psl
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
content String
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id])
|
||||||
userId Int
|
userId Int
|
||||||
createdAt DateTime @default(now())
|
|
||||||
|
content String
|
||||||
isRead Boolean @default(false)
|
isRead Boolean @default(false)
|
||||||
repliedAt DateTime?
|
repliedAt DateTime?
|
||||||
psl=}
|
psl=}
|
||||||
@ -143,6 +165,7 @@ psl=}
|
|||||||
entity DailyStats {=psl
|
entity DailyStats {=psl
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
date DateTime @default(now()) @unique
|
date DateTime @default(now()) @unique
|
||||||
|
|
||||||
totalViews Int @default(0)
|
totalViews Int @default(0)
|
||||||
prevDayViewsChangePercent String @default("0")
|
prevDayViewsChangePercent String @default("0")
|
||||||
userCount Int @default(0)
|
userCount Int @default(0)
|
||||||
@ -151,26 +174,31 @@ entity DailyStats {=psl
|
|||||||
paidUserDelta Int @default(0)
|
paidUserDelta Int @default(0)
|
||||||
totalRevenue Float @default(0)
|
totalRevenue Float @default(0)
|
||||||
totalProfit Float @default(0)
|
totalProfit Float @default(0)
|
||||||
|
|
||||||
sources PageViewSource[]
|
sources PageViewSource[]
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
entity PageViewSource {=psl
|
entity PageViewSource {=psl
|
||||||
date DateTime @default(now())
|
@@id([date, name])
|
||||||
name String
|
name String
|
||||||
visitors Int
|
date DateTime @default(now())
|
||||||
|
|
||||||
dailyStats DailyStats? @relation(fields: [dailyStatsId], references: [id])
|
dailyStats DailyStats? @relation(fields: [dailyStatsId], references: [id])
|
||||||
dailyStatsId Int?
|
dailyStatsId Int?
|
||||||
@@id([date, name])
|
|
||||||
|
visitors Int
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
entity Logs {=psl
|
entity Logs {=psl
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
message String
|
message String
|
||||||
level String
|
level String
|
||||||
psl=}
|
psl=}
|
||||||
|
|
||||||
/* 📡 These are the Wasp Routes (You can protect them easily w/ 'authRequired: true');
|
/* 📡 These are the Wasp client Routes and Pages.
|
||||||
|
* You can easily make them inaccessible to the unauthenticated user w/ 'authRequired: true'.
|
||||||
* https://wasp-lang.dev/docs/tutorial/pages
|
* https://wasp-lang.dev/docs/tutorial/pages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -179,6 +207,7 @@ page LandingPage {
|
|||||||
component: import LandingPage from "@src/client/landing-page/LandingPage"
|
component: import LandingPage from "@src/client/landing-page/LandingPage"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region Auth Pages
|
||||||
route LoginRoute { path: "/login", to: LoginPage }
|
route LoginRoute { path: "/login", to: LoginPage }
|
||||||
page LoginPage {
|
page LoginPage {
|
||||||
component: import Login from "@src/client/auth/LoginPage"
|
component: import Login from "@src/client/auth/LoginPage"
|
||||||
@ -203,6 +232,7 @@ route EmailVerificationRoute { path: "/email-verification", to: EmailVerificatio
|
|||||||
page EmailVerificationPage {
|
page EmailVerificationPage {
|
||||||
component: import { EmailVerification } from "@src/client/auth/EmailVerification",
|
component: import { EmailVerification } from "@src/client/auth/EmailVerification",
|
||||||
}
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
route DemoAppRoute { path: "/demo-app", to: DemoAppPage }
|
route DemoAppRoute { path: "/demo-app", to: DemoAppPage }
|
||||||
page DemoAppPage {
|
page DemoAppPage {
|
||||||
@ -233,6 +263,7 @@ page FileUploadPage {
|
|||||||
component: import FileUpload from "@src/client/app/FileUploadPage"
|
component: import FileUpload from "@src/client/app/FileUploadPage"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region Admin Pages
|
||||||
route AdminRoute { path: "/admin", to: DashboardPage }
|
route AdminRoute { path: "/admin", to: DashboardPage }
|
||||||
page DashboardPage {
|
page DashboardPage {
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
@ -292,8 +323,10 @@ page AdminUIButtonsPage {
|
|||||||
authRequired: true,
|
authRequired: true,
|
||||||
component: import AdminUI from "@src/client/admin/pages/UiElements/Buttons"
|
component: import AdminUI from "@src/client/admin/pages/UiElements/Buttons"
|
||||||
}
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
/* ⛑ These are the Wasp Operations, which allow the client and server to interact:
|
/* ⛑ These are the Wasp Operations: server code that you can easily call
|
||||||
|
* from the client. Queries fetch stuff, Actions modify/do stuff.
|
||||||
* https://wasp-lang.dev/docs/data-model/operations/overview
|
* https://wasp-lang.dev/docs/data-model/operations/overview
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -373,7 +406,8 @@ query getPaginatedUsers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 📡 These are custom Wasp API Endpoints. Use them for callbacks, webhooks, etc.
|
* 📡 These are custom Wasp API Endpoints.
|
||||||
|
* Use them for callbacks, webhooks, API for other services to consume, etc.
|
||||||
* https://wasp-lang.dev/docs/advanced/apis
|
* https://wasp-lang.dev/docs/advanced/apis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -384,7 +418,7 @@ api stripeWebhook {
|
|||||||
httpRoute: (POST, "/stripe-webhook")
|
httpRoute: (POST, "/stripe-webhook")
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 🕵️♂️ These are the Wasp Jobs. Use them to set up recurring tasks and/or queues:
|
/* 🕵️♂️ These are the Wasp Jobs. Use them to set up recurring tasks and/or queues.
|
||||||
* https://wasp-lang.dev/docs/advanced/jobs
|
* https://wasp-lang.dev/docs/advanced/jobs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'wasp/client/router';
|
import { Link, routes } from 'wasp/client/router';
|
||||||
import { useAuth } from 'wasp/client/auth';
|
import { useAuth } from 'wasp/client/auth';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Dialog } from '@headlessui/react';
|
import { Dialog } from '@headlessui/react';
|
||||||
@ -12,9 +12,9 @@ import DarkModeSwitcher from '../admin/components/DarkModeSwitcher';
|
|||||||
import { UserMenuItems } from '../components/UserMenuItems';
|
import { UserMenuItems } from '../components/UserMenuItems';
|
||||||
|
|
||||||
const navigation = [
|
const navigation = [
|
||||||
{ name: 'AI Scheduler (Demo App)', href: '/demo-app' },
|
{ name: 'AI Scheduler (Demo App)', href: routes.DemoAppRoute.build() },
|
||||||
{ name: 'File Upload (AWS S3)', href: '/file-upload' },
|
{ name: 'File Upload (AWS S3)', href: routes.FileUploadRoute.build() },
|
||||||
{ name: 'Pricing', href: '/pricing' },
|
{ name: 'Pricing', href: routes.PricingPageRoute.build() },
|
||||||
{ name: 'Documentation', href: DOCS_URL },
|
{ name: 'Documentation', href: DOCS_URL },
|
||||||
{ name: 'Blog', href: BLOG_URL },
|
{ name: 'Blog', href: BLOG_URL },
|
||||||
];
|
];
|
||||||
@ -26,7 +26,7 @@ export default function AppNavBar() {
|
|||||||
|
|
||||||
const { data: user, isLoading: isUserLoading } = useAuth();
|
const { data: user, isLoading: isUserLoading } = useAuth();
|
||||||
return (
|
return (
|
||||||
<header className='absolute inset-x-0 top-0 z-50 shadow sticky bg-white bg-opacity-50 backdrop-blur-lg backdrop-filter dark:border dark:border-gray-100/10 dark:bg-boxdark-2'>
|
<header className='absolute inset-x-0 top-0 z-50 shadow bg-white bg-opacity-50 backdrop-blur-lg backdrop-filter dark:border dark:border-gray-100/10 dark:bg-boxdark-2'>
|
||||||
<nav className='flex items-center justify-between p-6 lg:px-8' aria-label='Global'>
|
<nav className='flex items-center justify-between p-6 lg:px-8' aria-label='Global'>
|
||||||
<div className='flex lg:flex-1'>
|
<div className='flex lg:flex-1'>
|
||||||
<a href='/' className='-m-1.5 p-1.5'>
|
<a href='/' className='-m-1.5 p-1.5'>
|
||||||
@ -60,7 +60,7 @@ export default function AppNavBar() {
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{isUserLoading ? null : !user ? (
|
{isUserLoading ? null : !user ? (
|
||||||
<a href={!user ? '/login' : '/account'} className='text-sm font-semibold leading-6 ml-4'>
|
<a href={!user ? routes.LoginRoute.build() : routes.AccountRoute.build()} className='text-sm font-semibold leading-6 ml-4'>
|
||||||
<div className='flex items-center duration-300 ease-in-out text-gray-900 hover:text-yellow-500 dark:text-white'>
|
<div className='flex items-center duration-300 ease-in-out text-gray-900 hover:text-yellow-500 dark:text-white'>
|
||||||
Log in <BiLogIn size='1.1rem' className='ml-1 mt-[0.1rem]' />
|
Log in <BiLogIn size='1.1rem' className='ml-1 mt-[0.1rem]' />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { DOCS_URL, BLOG_URL } from '../../shared/constants';
|
import { DOCS_URL, BLOG_URL } from '../../shared/constants';
|
||||||
import daBoiAvatar from '../static/da-boi.png';
|
import daBoiAvatar from '../static/da-boi.png';
|
||||||
import avatarPlaceholder from '../static/avatar-placeholder.png';
|
import avatarPlaceholder from '../static/avatar-placeholder.png';
|
||||||
|
import { routes } from 'wasp/client/router';
|
||||||
|
|
||||||
export const navigation = [
|
export const navigation = [
|
||||||
{ name: 'Features', href: '#features' },
|
{ name: 'Features', href: '#features' },
|
||||||
{ name: 'Pricing', href: '/pricing' },
|
{ name: 'Pricing', href: routes.PricingPageRoute.build() },
|
||||||
{ name: 'Documentation', href: DOCS_URL },
|
{ name: 'Documentation', href: DOCS_URL },
|
||||||
{ name: 'Blog', href: BLOG_URL },
|
{ name: 'Blog', href: BLOG_URL },
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user