feat: open register modal when clicking membership button while logged out

This commit is contained in:
Artur N
2024-08-12 21:51:03 -03:00
parent f164fa8858
commit 5d3e22865e
5 changed files with 145 additions and 69 deletions

View File

@@ -69,6 +69,7 @@ const Header = () => {
<DialogContent>
<LoginFormModal
close={() => setLoginIsOpen(false)}
openRegisterModal={() => setRegisterIsOpen(true)}
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
/>
</DialogContent>
@@ -79,7 +80,10 @@ const Header = () => {
<Button className="w-24">Register</Button>
</DialogTrigger>
<DialogContent>
<RegisterFormModal close={() => setRegisterIsOpen(false)} />
<RegisterFormModal
close={() => setRegisterIsOpen(false)}
openLoginModal={() => setLoginIsOpen(true)}
/>
</DialogContent>
</Dialog>
</>

View File

@@ -6,21 +6,9 @@ import { signIn, useSession } from 'next-auth/react'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import {
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from './ui/dialog'
import { DialogContent, DialogDescription, DialogHeader, DialogTitle } from './ui/dialog'
import { Input } from './ui/input'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from './ui/form'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from './ui/form'
import { Button } from './ui/button'
import { useToast } from './ui/use-toast'
@@ -31,9 +19,13 @@ const schema = z.object({
type LoginFormInputs = z.infer<typeof schema>
type Props = { close: () => void; openPasswordResetModal: () => void }
type Props = {
close: () => void
openPasswordResetModal: () => void
openRegisterModal: () => void
}
function LoginFormModal({ close, openPasswordResetModal }: Props) {
function LoginFormModal({ close, openPasswordResetModal, openRegisterModal }: Props) {
const { toast } = useToast()
const router = useRouter()
const form = useForm<LoginFormInputs>({
@@ -79,11 +71,6 @@ function LoginFormModal({ close, openPasswordResetModal }: Props) {
close()
}
function onIForgotMyPassword() {
close()
openPasswordResetModal()
}
return (
<>
<DialogHeader>
@@ -92,10 +79,7 @@ function LoginFormModal({ close, openPasswordResetModal }: Props) {
</DialogHeader>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col space-y-4"
>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col space-y-4">
<FormField
control={form.control}
name="email"
@@ -127,7 +111,7 @@ function LoginFormModal({ close, openPasswordResetModal }: Props) {
<Button
type="button"
onClick={onIForgotMyPassword}
onClick={() => (openPasswordResetModal(), close())}
variant="link"
className="self-end"
>
@@ -135,12 +119,21 @@ function LoginFormModal({ close, openPasswordResetModal }: Props) {
</Button>
</div>
<Button type="submit" disabled={form.formState.isSubmitting}>
{form.formState.isSubmitting && (
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
)}{' '}
Login
</Button>
<div className="flex flex-row space-x-2">
<Button
className="grow basis-0"
variant="outline"
type="button"
onClick={() => (openRegisterModal(), close())}
>
Register
</Button>
<Button className="grow basis-0" type="submit" disabled={form.formState.isSubmitting}>
{form.formState.isSubmitting && <ReloadIcon className="mr-2 h-4 w-4 animate-spin" />}{' '}
Login
</Button>
</div>
</form>
</Form>
</>

View File

@@ -39,9 +39,9 @@ const schema = z
type RegisterFormInputs = z.infer<typeof schema>
type Props = { close: () => void }
type Props = { close: () => void; openLoginModal: () => void }
function RegisterFormModal({ close }: Props) {
function RegisterFormModal({ close, openLoginModal }: Props) {
const { toast } = useToast()
const form = useForm<RegisterFormInputs>({ resolver: zodResolver(schema) })
const registerMutation = trpc.auth.register.useMutation()
@@ -59,11 +59,7 @@ function RegisterFormModal({ close }: Props) {
const errorMessage = (error as any).message
if (errorMessage === 'EMAIL_TAKEN') {
return form.setError(
'email',
{ message: 'Email is already taken.' },
{ shouldFocus: true }
)
return form.setError('email', { message: 'Email is already taken.' }, { shouldFocus: true })
}
toast({
@@ -77,16 +73,11 @@ function RegisterFormModal({ close }: Props) {
<>
<DialogHeader>
<DialogTitle>Register</DialogTitle>
<DialogDescription>
Start supporting Monero projects today!
</DialogDescription>
<DialogDescription>Start supporting Monero projects today!</DialogDescription>
</DialogHeader>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col space-y-4"
>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col space-y-4">
<FormField
control={form.control}
name="name"
@@ -143,16 +134,26 @@ function RegisterFormModal({ close }: Props) {
)}
/>
<Button type="submit" disabled={form.formState.isSubmitting}>
{form.formState.isSubmitting && (
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
)}{' '}
Register
</Button>
<div className="flex flex-row space-x-2">
<Button
type="button"
variant="link"
className="grow basis-0"
onClick={() => (openLoginModal(), close())}
>
I already have an account
</Button>
<Button type="submit" disabled={form.formState.isSubmitting} className="grow basis-0">
{form.formState.isSubmitting && <ReloadIcon className="mr-2 h-4 w-4 animate-spin" />}{' '}
Register
</Button>
</div>
</form>
</Form>
</>
)
}
1
export default RegisterFormModal

View File

@@ -1,16 +1,20 @@
import { useState } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import { useState } from 'react'
import ProjectList from '../components/ProjectList'
import { useSession } from 'next-auth/react'
import { getAllPosts } from '../utils/md'
import { ProjectItem } from '../utils/types'
import Typing from '../components/Typing'
import CustomLink from '../components/CustomLink'
import { Button } from '../components/ui/button'
import { Dialog, DialogContent } from '../components/ui/dialog'
import { Dialog, DialogContent, DialogTrigger } from '../components/ui/dialog'
import DonationFormModal from '../components/DonationFormModal'
import MembershipFormModal from '../components/MembershipFormModal'
import ProjectList from '../components/ProjectList'
import LoginFormModal from '../components/LoginFormModal'
import RegisterFormModal from '../components/RegisterFormModal'
import PasswordResetFormModal from '../components/PasswordResetFormModal'
// These shouldn't be swept up in the regular list so we hardcode them
const generalFund: ProjectItem = {
@@ -29,6 +33,10 @@ const generalFund: ProjectItem = {
const Home: NextPage<{ projects: any }> = ({ projects }) => {
const [donateModalOpen, setDonateModalOpen] = useState(false)
const [memberModalOpen, setMemberModalOpen] = useState(false)
const [registerIsOpen, setRegisterIsOpen] = useState(false)
const [loginIsOpen, setLoginIsOpen] = useState(false)
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
const session = useSession()
return (
<>
@@ -58,7 +66,11 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
</Button>
<Button
onClick={() => setMemberModalOpen(true)}
onClick={() =>
session.status === 'authenticated'
? setMemberModalOpen(true)
: setRegisterIsOpen(true)
}
variant="outline"
size="lg"
className="px-14 font-semibold text-lg"
@@ -111,6 +123,35 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
<MembershipFormModal project={generalFund} />
</DialogContent>
</Dialog>
{session.status !== 'authenticated' && (
<>
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
<DialogContent>
<LoginFormModal
close={() => setLoginIsOpen(false)}
openRegisterModal={() => setRegisterIsOpen(true)}
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
/>
</DialogContent>
</Dialog>
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
<DialogContent>
<RegisterFormModal
openLoginModal={() => setLoginIsOpen(true)}
close={() => setRegisterIsOpen(false)}
/>
</DialogContent>
</Dialog>
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
<DialogContent>
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
</DialogContent>
</Dialog>
</>
)}
</>
)
}

View File

@@ -1,27 +1,25 @@
import { useState } from 'react'
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/router'
import { NextPage } from 'next/types'
import Head from 'next/head'
import ErrorPage from 'next/error'
import Image from 'next/image'
import xss from 'xss'
import { ProjectDonationStats, ProjectItem } from '../../utils/types'
import { getProjectBySlug, getAllPosts } from '../../utils/md'
import { getProjectBySlug } from '../../utils/md'
import markdownToHtml from '../../utils/markdownToHtml'
import {
fetchPostJSON,
fetchGetJSONAuthedBTCPay,
fetchGetJSONAuthedStripe,
} from '../../utils/api-helpers'
import PageHeading from '../../components/PageHeading'
import SocialIcon from '../../components/social-icons'
import Progress from '../../components/Progress'
import { prisma } from '../../server/services'
import { Button } from '../../components/ui/button'
import { Dialog, DialogContent } from '../../components/ui/dialog'
import DonationFormModal from '../../components/DonationFormModal'
import MembershipFormModal from '../../components/MembershipFormModal'
import Head from 'next/head'
import LoginFormModal from '../../components/LoginFormModal'
import RegisterFormModal from '../../components/RegisterFormModal'
import PasswordResetFormModal from '../../components/PasswordResetFormModal'
type SingleProjectPageProps = {
project: ProjectItem
@@ -31,9 +29,12 @@ type SingleProjectPageProps = {
const Project: NextPage<SingleProjectPageProps> = ({ project, projects, donationStats }) => {
const router = useRouter()
const [donateModalOpen, setDonateModalOpen] = useState(false)
const [memberModalOpen, setMemberModalOpen] = useState(false)
const [registerIsOpen, setRegisterIsOpen] = useState(false)
const [loginIsOpen, setLoginIsOpen] = useState(false)
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
const session = useSession()
const {
slug,
@@ -53,7 +54,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects, donation
function formatBtc(bitcoin: number) {
if (bitcoin > 0.1) {
return `${bitcoin.toFixed(3) || 0.0}`
return `${bitcoin.toFixed(3) || 0.0} BTC`
} else {
return `${Math.floor(bitcoin * 100000000).toLocaleString()} sats`
}
@@ -94,7 +95,14 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects, donation
{!project.isFunded && (
<div className="flex flex-col space-y-2">
<Button onClick={() => setDonateModalOpen(true)}>Donate</Button>
<Button onClick={() => setMemberModalOpen(true)} variant="outline">
<Button
onClick={() =>
session.status === 'authenticated'
? setMemberModalOpen(true)
: setRegisterIsOpen(true)
}
variant="outline"
>
Get Annual Membership
</Button>
</div>
@@ -127,7 +135,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects, donation
</span>
</li>
<li>
{donationStats.btc.amount} BTC{' '}
{formatBtc(donationStats.btc.amount)}{' '}
<span className="font-normal text-sm text-gray">
in {donationStats.btc.count} donations
</span>
@@ -160,6 +168,35 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects, donation
<MembershipFormModal project={project} />
</DialogContent>
</Dialog>
{session.status !== 'authenticated' && (
<>
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
<DialogContent>
<LoginFormModal
close={() => setLoginIsOpen(false)}
openRegisterModal={() => setRegisterIsOpen(true)}
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
/>
</DialogContent>
</Dialog>
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
<DialogContent>
<RegisterFormModal
openLoginModal={() => setLoginIsOpen(true)}
close={() => setRegisterIsOpen(false)}
/>
</DialogContent>
</Dialog>
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
<DialogContent>
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
</DialogContent>
</Dialog>
</>
)}
</>
)
}