mirror of
https://github.com/wasp-lang/open-saas.git
synced 2025-10-10 17:43:48 +02:00
💅
This commit is contained in:
24
README.md
24
README.md
@@ -8,12 +8,24 @@ After cloning this repo, you can run it locally by following these steps:
|
|||||||
1. Install [Wasp](https://wasp-lang.dev) by running `curl -sSL https://get.wasp-lang.dev/installer.sh | sh` in your terminal.
|
1. Install [Wasp](https://wasp-lang.dev) by running `curl -sSL https://get.wasp-lang.dev/installer.sh | sh` in your terminal.
|
||||||
2. Create a `.env.server` file in the root of the project
|
2. Create a `.env.server` file in the root of the project
|
||||||
3. Copy the `env.example` file contents to `.env.server` and fill in your API keys
|
3. Copy the `env.example` file contents to `.env.server` and fill in your API keys
|
||||||
4. Run `wasp db migrate-dev`
|
4. Make sure you have a Database connected and running. Here are two quick options:
|
||||||
5. Run `wasp start`
|
- Provision a Postgres database on [Railway](https://railway.app), go to settings and copy the `connection url`. Past it as `DATABASE_URL=<your-postgres-connection-url>` into your `env.server` file.
|
||||||
6. Go to `localhost:3000` in your browser (your NodeJS server will be running on port `3001`)
|
- or you can spin up a Postgres docker container with this command:
|
||||||
7. Install the Wasp extension for VSCode to get syntax highlighting on the `main.wasp` file and other features
|
```shell
|
||||||
8. Check the files for comments containing specific instructions
|
docker run \
|
||||||
9. 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)
|
--rm \
|
||||||
|
--publish 5432:5432 \
|
||||||
|
-v my-app-data:/var/lib/postgresql/data \
|
||||||
|
--env POSTGRES_PASSWORD=devpass1234 \
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
and then paste `DATABASE_URL=postgresql://postgres:devpass1234@localhost:5432/postgres` into your `env.server` file
|
||||||
|
5. Run `wasp db migrate-dev`
|
||||||
|
6. Run `wasp start`
|
||||||
|
7. Go to `localhost:3000` in your browser (your NodeJS server will be running on port `3001`)
|
||||||
|
8. Install the Wasp extension for VSCode to get the best DX
|
||||||
|
9. Check the files for comments containing specific instructions
|
||||||
|
10. 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)
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
@@ -102,7 +102,6 @@ page LoginPage {
|
|||||||
|
|
||||||
route GptRoute { path: "/gpt", to: GptPage }
|
route GptRoute { path: "/gpt", to: GptPage }
|
||||||
page GptPage {
|
page GptPage {
|
||||||
authRequired: true,
|
|
||||||
component: import GptPage from "@client/GptPage"
|
component: import GptPage from "@client/GptPage"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ export default function Example({ user }: { user: User }) {
|
|||||||
<div className='py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6'>
|
<div className='py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6'>
|
||||||
<dt className='text-sm font-medium text-gray-500'>Most Recent User RelatedObject</dt>
|
<dt className='text-sm font-medium text-gray-500'>Most Recent User RelatedObject</dt>
|
||||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||||
{!!relatedObjects
|
{!!relatedObjects && relatedObjects.length > 0
|
||||||
? relatedObjects[relatedObjects.length - 1].content
|
? relatedObjects[relatedObjects.length - 1].content
|
||||||
: "You don't have any at this time."}
|
: "You don't have any at this time."}
|
||||||
</dd>
|
</dd>
|
||||||
|
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { RelatedObject } from '@wasp/entities';
|
import { RelatedObject } from '@wasp/entities';
|
||||||
import generateGptResponse from '@wasp/actions/generateGptResponse';
|
import generateGptResponse from '@wasp/actions/generateGptResponse';
|
||||||
|
import useAuth from '@wasp/auth/useAuth';
|
||||||
|
|
||||||
type GptPayload = {
|
type GptPayload = {
|
||||||
instructions: string;
|
instructions: string;
|
||||||
@@ -13,7 +14,14 @@ export default function GptPage() {
|
|||||||
const [temperature, setTemperature] = useState<number>(1);
|
const [temperature, setTemperature] = useState<number>(1);
|
||||||
const [response, setResponse] = useState<string>('');
|
const [response, setResponse] = useState<string>('');
|
||||||
|
|
||||||
|
const { data: user } = useAuth();
|
||||||
|
|
||||||
const onSubmit = async ({ instructions, command, temperature }: any) => {
|
const onSubmit = async ({ instructions, command, temperature }: any) => {
|
||||||
|
console.log('user, ', !!user)
|
||||||
|
if (!user) {
|
||||||
|
alert('You must be logged in to use this feature.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const response = (await generateGptResponse({ instructions, command, temperature })) as RelatedObject;
|
const response = (await generateGptResponse({ instructions, command, temperature })) as RelatedObject;
|
||||||
if (response) {
|
if (response) {
|
||||||
@@ -56,6 +64,7 @@ export default function GptPage() {
|
|||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<span className='text-sm text-red-500'>{formErrors.instructions && formErrors.instructions.message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='col-span-full'>
|
<div className='col-span-full'>
|
||||||
<label htmlFor='command' className='block text-sm font-medium leading-6 text-gray-900'>
|
<label htmlFor='command' className='block text-sm font-medium leading-6 text-gray-900'>
|
||||||
@@ -77,6 +86,7 @@ export default function GptPage() {
|
|||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<span className='text-sm text-red-500'>{formErrors.command && formErrors.command.message}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='h-10 '>
|
<div className='h-10 '>
|
||||||
|
@@ -6,11 +6,14 @@ export default function MainPage() {
|
|||||||
<div className='mx-auto max-w-2xl'>
|
<div className='mx-auto max-w-2xl'>
|
||||||
<div className='max-w-lg'>
|
<div className='max-w-lg'>
|
||||||
<h1 className=' text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl'>SaaS Template</h1>
|
<h1 className=' text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl'>SaaS Template</h1>
|
||||||
<a href='https://wasp-lang.dev'>
|
|
||||||
<h2 className='ml-4 max-w-2xl text-2xl f tracking-tight text-gray-800 slg:col-span-2 xl:col-auto'>
|
<h2 className='ml-4 max-w-2xl text-2xl f tracking-tight text-gray-800 slg:col-span-2 xl:col-auto'>
|
||||||
by Wasp {'= }'}
|
for the PERN stack
|
||||||
</h2>
|
</h2>
|
||||||
</a>
|
<h2 className='ml-4 max-w-2xl text-md f tracking-tight text-gray-600 slg:col-span-2 xl:col-auto'>
|
||||||
|
Postgres/Prisma, Express, React, Node
|
||||||
|
</h2>
|
||||||
|
|
||||||
<p className='mt-4 text-lg leading-8 text-gray-600'>
|
<p className='mt-4 text-lg leading-8 text-gray-600'>
|
||||||
Hey 🧙♂️! This template will help you get a SaaS App up and running in no time. It's got:
|
Hey 🧙♂️! This template will help you get a SaaS App up and running in no time. It's got:
|
||||||
</p>
|
</p>
|
||||||
@@ -21,20 +24,24 @@ export default function MainPage() {
|
|||||||
<li>Managed Server-Side Routes</li>
|
<li>Managed Server-Side Routes</li>
|
||||||
<li>Tailwind styling</li>
|
<li>Tailwind styling</li>
|
||||||
<li>Client-side Caching</li>
|
<li>Client-side Caching</li>
|
||||||
<li>One-command Deploy 🚀</li>
|
<li>
|
||||||
|
One-command{' '}
|
||||||
|
<a href='https://wasp-lang.dev/docs/deploying' className='underline' target='_blank'>
|
||||||
|
Deploy 🚀
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p className='mt-4 text-lg leading-8 text-gray-600'>
|
<p className='mt-4 text-lg leading-8 text-gray-600'>
|
||||||
Make sure to check out the <code>README.md</code> file before you begin
|
Make sure to check out the <code>README.md</code> file and add your <code>env</code> variables before
|
||||||
|
you begin
|
||||||
</p>
|
</p>
|
||||||
<div className='mt-10 flex items-center gap-x-6'>
|
<div className='mt-10 flex items-center gap-x-6'>
|
||||||
|
<span className='text-sm font-semibold leading-6 text-gray-900'>Made with Wasp {' = }'}</span>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='https://wasp-lang.dev/docs'
|
||||||
className='rounded-md bg-yellow-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-yellow-6 00 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500'
|
className='rounded-md bg-yellow-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-yellow-6 00 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500'
|
||||||
>
|
>
|
||||||
Documentation
|
Read the Wasp Docs
|
||||||
</a>
|
|
||||||
<a href='#' className='text-sm font-semibold leading-6 text-gray-900'>
|
|
||||||
View on GitHub <span aria-hidden='true'>→</span>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -6,13 +6,11 @@ import useAuth from '@wasp/auth/useAuth';
|
|||||||
|
|
||||||
const active = 'inline-flex items-center border-b-2 border-indigo-300 px-1 pt-1 text-sm font-medium text-gray-900';
|
const active = 'inline-flex items-center border-b-2 border-indigo-300 px-1 pt-1 text-sm font-medium text-gray-900';
|
||||||
const inactive = 'inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700'
|
const inactive = 'inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700'
|
||||||
|
|
||||||
const current = window.location.pathname;
|
const current = window.location.pathname;
|
||||||
|
|
||||||
export default function NavBar() {
|
export default function NavBar() {
|
||||||
const { data: user } = useAuth();
|
const { data: user } = useAuth();
|
||||||
|
|
||||||
console.log(current);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Disclosure as='nav' className='bg-white shadow sticky top-0 z-50 '>
|
<Disclosure as='nav' className='bg-white shadow sticky top-0 z-50 '>
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
@@ -21,7 +19,7 @@ export default function NavBar() {
|
|||||||
<div className='flex h-16 justify-between'>
|
<div className='flex h-16 justify-between'>
|
||||||
<div className='flex'>
|
<div className='flex'>
|
||||||
<div className='flex flex-shrink-0 items-center'>
|
<div className='flex flex-shrink-0 items-center'>
|
||||||
<a href='https://wasp-lang.dev/docs' target='_blank'>
|
<a href='/'>
|
||||||
<img className='h-8 w-8' src={logo} alt='My SaaS App' />
|
<img className='h-8 w-8' src={logo} alt='My SaaS App' />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 420 KiB After Width: | Height: | Size: 446 KiB |
Reference in New Issue
Block a user