mirror of
https://github.com/wasp-lang/open-saas.git
synced 2025-04-12 22:09:03 +02:00
Extended Dark mode for landing page and user-facing app (#10)
* Extended Dark mode for landing page and user-facing app * Update LandingPage.tsx * Fixed issues with dark mode * Landing Page changes based on comments * removed migrations --------- Co-authored-by: vincanger <70215737+vincanger@users.noreply.github.com>
This commit is contained in:
parent
b2f8fb481f
commit
3d12c73c02
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
*/.env.client
|
||||
*/.DS_Store
|
||||
.DS_Store
|
||||
*/migrations
|
@ -43,14 +43,16 @@ export default function App({ children }: { children: ReactNode }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='min-h-screen dark:text-white dark:bg-boxdark-2'>
|
||||
{isAdminDashboard ? (
|
||||
<>{children}</>
|
||||
) : (
|
||||
<>
|
||||
{shouldDisplayAppNavBar && <AppNavBar />}
|
||||
<div className='mx-auto max-w-7xl sm:px-6 lg:px-8 '>{children}</div>
|
||||
<div className='mx-auto max-w-7xl sm:px-6 lg:px-8'>{children}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -34,20 +34,20 @@ export default function GptPage() {
|
||||
} = useForm();
|
||||
|
||||
return (
|
||||
<div className='my-10 lg:mt-20'>
|
||||
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
|
||||
<div className='my-10 lg:mt-20 dark:bg-boxdark-2'>
|
||||
<div className='mx-auto max-w-7xl px-6 lg:px-8 dark:bg-boxdark'>
|
||||
<div id='pricing' className='mx-auto max-w-4xl text-center'>
|
||||
<h2 className='mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl'>
|
||||
<h2 className='mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl dark:text-white'>
|
||||
Create your AI-powered <span className='text-yellow-500'>SaaS</span>
|
||||
</h2>
|
||||
</div>
|
||||
<p className='mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600'>
|
||||
<p className='mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600 dark:text-white'>
|
||||
Below is an example of integrating the OpenAI API into your SaaS.
|
||||
</p>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className='py-8 mt-10 sm:mt-20 ring-1 ring-gray-200 rounded-lg'>
|
||||
<div className='space-y-6 sm:w-[90%] md:w-[60%] mx-auto border-b border-gray-900/10 px-6 pb-12'>
|
||||
<div className='col-span-full'>
|
||||
<label htmlFor='instructions' className='block text-sm font-medium leading-6 text-gray-900'>
|
||||
<label htmlFor='instructions' className='block text-sm font-medium leading-6 text-gray-900 dark:text-white'>
|
||||
Instructions -- How should GPT behave?
|
||||
</label>
|
||||
<div className='mt-2'>
|
||||
@ -71,7 +71,7 @@ export default function GptPage() {
|
||||
</span>
|
||||
</div>
|
||||
<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 dark:text-white'>
|
||||
Command -- What should GPT do?
|
||||
</label>
|
||||
<div className='mt-2'>
|
||||
@ -95,8 +95,8 @@ export default function GptPage() {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className='h-10 '>
|
||||
<label htmlFor='temperature' className='w-full text-gray-700 text-sm font-semibold'>
|
||||
<div className='h-10'>
|
||||
<label htmlFor='temperature' className='w-full text-gray-700 text-sm font-semibold dark:text-white'>
|
||||
Temperature Input -- Controls How Random GPT's Output is
|
||||
</label>
|
||||
<div className='w-32 mt-2'>
|
||||
@ -133,9 +133,9 @@ export default function GptPage() {
|
||||
<div
|
||||
className={`${
|
||||
isSubmitting && 'animate-pulse'
|
||||
} mt-4 mx-6 flex justify-center rounded-lg border border-dashed border-gray-900/25 sm:w-[90%] md:w-[50%] mx-auto mt-12 px-6 py-10`}
|
||||
} mt-4 mx-6 flex justify-center rounded-lg border border-dashed border-gray-900/25 dark:border-white sm:w-[90%] md:w-[50%] mx-auto mt-12 px-6 py-10`}
|
||||
>
|
||||
<div className='space-y-2 flex flex-col gap-2 text-center text-sm text-gray-500 w-full'>
|
||||
<div className='space-y-2 flex flex-col gap-2 text-center text-sm text-gray-500 w-full dark:text-white'>
|
||||
{response.length > 0 ? response.map((str) => <p key={str}>{str}</p>) : <p>GPT Response will load here</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -57,14 +57,14 @@ const PricingPage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='my-10 lg:mt-20'>
|
||||
<div className='py-10 lg:mt-10'>
|
||||
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
|
||||
<div id='pricing' className='mx-auto max-w-4xl text-center'>
|
||||
<h2 className='mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl'>
|
||||
<h2 className='mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl dark:text-white'>
|
||||
Pick your <span className='text-yellow-500'>pricing</span>
|
||||
</h2>
|
||||
</div>
|
||||
<p className='mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600'>
|
||||
<p className='mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600 dark:text-white'>
|
||||
Stripe subscriptions and secure webhooks are built-in. Just add your Stripe Product IDs! Try it out below with
|
||||
test credit card number{' '}
|
||||
<span className='px-2 py-1 bg-gray-100 rounded-md text-gray-500'>4242 4242 4242 4242 4242</span>
|
||||
@ -80,7 +80,7 @@ const PricingPage = () => {
|
||||
{tier.bestDeal && (
|
||||
<div className='absolute top-0 right-0 -z-10 w-full h-full transform-gpu blur-3xl' aria-hidden='true'>
|
||||
<div
|
||||
className='absolute w-full h-full bg-gradient-to-br from-amber-400 to-purple-300 opacity-30'
|
||||
className='absolute w-full h-full bg-gradient-to-br from-amber-400 to-purple-300 opacity-30 dark:opacity-50'
|
||||
style={{
|
||||
clipPath: 'circle(670% at 50% 50%)',
|
||||
}}
|
||||
@ -89,16 +89,16 @@ const PricingPage = () => {
|
||||
)}
|
||||
<div className='mb-8'>
|
||||
<div className='flex items-center justify-between gap-x-4'>
|
||||
<h3 id={tier.id} className='text-gray-900 text-lg font-semibold leading-8'>
|
||||
<h3 id={tier.id} className='text-gray-900 text-lg font-semibold leading-8 dark:text-white'>
|
||||
{tier.name}
|
||||
</h3>
|
||||
</div>
|
||||
<p className='mt-4 text-sm leading-6 text-gray-600'>{tier.description}</p>
|
||||
<p className='mt-6 flex items-baseline gap-x-1'>
|
||||
<span className='text-4xl font-bold tracking-tight text-gray-900'>{tier.priceMonthly}</span>
|
||||
<span className='text-sm font-semibold leading-6 text-gray-600'>/month</span>
|
||||
<p className='mt-4 text-sm leading-6 text-gray-600 dark:text-white'>{tier.description}</p>
|
||||
<p className='mt-6 flex items-baseline gap-x-1 dark:text-white'>
|
||||
<span className='text-4xl font-bold tracking-tight text-gray-900 dark:text-white'>{tier.priceMonthly}</span>
|
||||
<span className='text-sm font-semibold leading-6 text-gray-600 dark:text-white'>/month</span>
|
||||
</p>
|
||||
<ul role='list' className='mt-8 space-y-3 text-sm leading-6 text-gray-600'>
|
||||
<ul role='list' className='mt-8 space-y-3 text-sm leading-6 text-gray-600 dark:text-white'>
|
||||
{tier.features.map((feature) => (
|
||||
<li key={feature} className='flex gap-x-3'>
|
||||
<AiFillCheckCircle className='h-6 w-5 flex-none text-yellow-500' aria-hidden='true' />
|
||||
@ -127,7 +127,7 @@ const PricingPage = () => {
|
||||
<button
|
||||
onClick={() => handleBuyNowClick(tier.id)}
|
||||
aria-describedby={tier.id}
|
||||
className={`
|
||||
className={`dark:text-white
|
||||
${tier.id === 'enterprise-tier' ? 'opacity-50 cursor-not-allowed' : 'opacity-100 cursor-pointer'}
|
||||
${
|
||||
tier.bestDeal
|
||||
|
@ -20,7 +20,7 @@ export default function Login() {
|
||||
<AuthWrapper>
|
||||
<LoginForm />
|
||||
<br />
|
||||
<span className='text-sm font-medium text-gray-900'>
|
||||
<span className='text-sm font-medium text-gray-900 dark:text-gray-900'>
|
||||
Don't have an account yet?{' '}
|
||||
<Link to='/signup' className='underline'>
|
||||
go to signup
|
||||
|
@ -2,9 +2,9 @@ import { ReactNode } from 'react';
|
||||
|
||||
export function AuthWrapper({children} : {children: ReactNode }) {
|
||||
return (
|
||||
<div className='flex min-h-full flex-col justify-center mt-10 sm:px-6 lg:px-8'>
|
||||
<div className='flex min-h-full flex-col justify-center pt-10 sm:px-6 lg:px-8'>
|
||||
<div className='sm:mx-auto sm:w-full sm:max-w-md'>
|
||||
<div className='bg-white py-8 px-4 shadow-xl ring-1 ring-gray-900/10 sm:rounded-lg sm:px-10'>
|
||||
<div className='bg-white py-8 px-4 shadow-xl ring-1 ring-gray-900/10 sm:rounded-lg sm:px-10 dark:bg-white dark:text-gray-900'>
|
||||
<div className='-mt-8'>
|
||||
{ children }
|
||||
</div>
|
||||
|
@ -5,6 +5,7 @@ import useAuth from '@wasp/auth/useAuth';
|
||||
import logo from '../static/logo.png';
|
||||
import DropdownUser from './DropdownUser';
|
||||
import { DOCS_URL, BLOG_URL } from '@wasp/shared/constants';
|
||||
import DarkModeSwitcher from '../admin/components/DarkModeSwitcher';
|
||||
|
||||
const navigation = [
|
||||
{ name: 'GPT Wrapper', href: '/gpt' },
|
||||
@ -18,7 +19,7 @@ export default function AppNavBar() {
|
||||
|
||||
const { data: user, isLoading: isUserLoading } = useAuth();
|
||||
return (
|
||||
<header className='absolute inset-x-0 top-0 z-50 shadow sticky bg-white bg-opacity-50 backdrop-blur-lg backdrop-filter'>
|
||||
<header className='absolute inset-x-0 top-0 z-50 shadow sticky bg-white bg-opacity-50 backdrop-blur-lg backdrop-filter dark:border-strokedark dark:bg-boxdark-2'>
|
||||
<nav className='flex items-center justify-between p-6 lg:px-8' aria-label='Global'>
|
||||
<div className='flex lg:flex-1'>
|
||||
<a href='/' className='-m-1.5 p-1.5'>
|
||||
@ -40,24 +41,32 @@ export default function AppNavBar() {
|
||||
<a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className='text-sm font-semibold leading-6 text-gray-900 duration-300 ease-in-out hover:text-yellow-500'
|
||||
className='text-sm font-semibold leading-6 text-gray-900 duration-300 ease-in-out hover:text-yellow-500 dark:text-white'
|
||||
>
|
||||
{item.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div className='hidden lg:flex lg:flex-1 lg:justify-end lg:align-end'>
|
||||
<div className='hidden lg:flex lg:flex-1 lg:justify-end items-center'>
|
||||
<div className='flex items-center gap-3 2xsm:gap-7'>
|
||||
<ul className='flex justify-center items-center gap-2 2xsm:gap-4'>
|
||||
<DarkModeSwitcher />
|
||||
</ul>
|
||||
</div>
|
||||
{isUserLoading ? null : !user ? (
|
||||
<a href={!user ? '/login' : '/account'} className='text-sm font-semibold leading-6 '>
|
||||
<div className='flex justify-end items-center duration-300 ease-in-out text-gray-900 hover:text-yellow-500'>
|
||||
<a href={!user ? '/login' : '/account'} 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'>
|
||||
Log in <BiLogIn size='1.1rem' className='ml-1 mt-[0.1rem]' />
|
||||
</div>
|
||||
</a>
|
||||
) : (
|
||||
<DropdownUser user={user} />
|
||||
<div className='ml-4'>
|
||||
<DropdownUser user={user} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
}
|
@ -43,9 +43,9 @@ const DropdownUser = ({ user } : { user: Partial<User> }) => {
|
||||
<span className='hidden text-right lg:block'>
|
||||
<span className='block text-sm font-medium dark:text-white'>{user.username}</span>
|
||||
</span>
|
||||
<CgProfile size='1.1rem' className='ml-1 mt-[0.1rem]' />
|
||||
<CgProfile size='1.1rem' className='ml-1 mt-[0.1rem] dark:text-white' />
|
||||
<svg
|
||||
className={`hidden fill-current sm:block ${dropdownOpen ? 'rotate-180' : ''}`}
|
||||
className={`hidden fill-current dark:fill-white sm:block ${dropdownOpen ? 'rotate-180' : ''}`}
|
||||
width='12'
|
||||
height='8'
|
||||
viewBox='0 0 12 8'
|
||||
@ -64,7 +64,7 @@ const DropdownUser = ({ user } : { user: Partial<User> }) => {
|
||||
{/* <!-- Dropdown --> */}
|
||||
<div
|
||||
ref={dropdown}
|
||||
className={`absolute right-0 mt-4 flex w-62.5 flex-col rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark ${
|
||||
className={`absolute right-0 mt-4 flex w-62.5 flex-col rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark dark:text-white ${
|
||||
dropdownOpen === true ? 'block' : 'hidden'
|
||||
}`}
|
||||
>
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user