feat: enhance SuccessModal and News context for improved modal management and subscription flow
This commit is contained in:
parent
fe9b8bc97a
commit
6b2ba85642
@ -11,45 +11,34 @@ import { LeftArrow } from '~/components/icons/left-arrow'
|
|||||||
import { Button } from '~/components/ui/button'
|
import { Button } from '~/components/ui/button'
|
||||||
import { APP } from '~/data/meta'
|
import { APP } from '~/data/meta'
|
||||||
|
|
||||||
type ModalProperties = {
|
export type ModalProperties = {
|
||||||
isOpen: boolean
|
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
type:
|
isOpen?: 'error' | 'warning' | 'resetPassword' | 'register' | 'payment'
|
||||||
| 'success'
|
|
||||||
| 'error'
|
|
||||||
| 'warning'
|
|
||||||
| 'success-reset-password'
|
|
||||||
| 'success-register'
|
|
||||||
| 'success-payment'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DescriptionMap = {
|
type DescriptionMap = {
|
||||||
[key in ModalProperties['type']]: string
|
[key in Exclude<ModalProperties['isOpen'], undefined>]: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const DESCRIPTIONS: DescriptionMap = {
|
const DESCRIPTIONS: DescriptionMap = {
|
||||||
'success-reset-password':
|
resetPassword: 'Link Reset Password telah dikirimkan ke email anda',
|
||||||
'Link Reset Password telah dikirimkan ke email anda',
|
register: 'Selamat! Pendaftaran anda berhasil!',
|
||||||
'success-register': 'Selamat! pendaftaran anda berhasil!',
|
payment: 'Selamat! Pembayaran anda berhasil!',
|
||||||
'success-payment': 'Selamat! Pembayaran anda berhasil!',
|
|
||||||
warning:
|
warning:
|
||||||
'Mohon maaf fitur berikut hanya untuk anggota yang sudah tersubscribe',
|
'Mohon maaf fitur berikut hanya untuk anggota yang sudah tersubscribe',
|
||||||
error: 'Terjadi kesalahan. Silakan coba lagi.',
|
error: 'Terjadi kesalahan. Silakan coba lagi.',
|
||||||
success: '',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SuccessModal = ({
|
export const SuccessModal = ({ isOpen, onClose }: ModalProperties) => {
|
||||||
isOpen,
|
|
||||||
onClose,
|
|
||||||
type = 'success-register',
|
|
||||||
}: ModalProperties) => {
|
|
||||||
if (!isOpen) return
|
if (!isOpen) return
|
||||||
|
|
||||||
const message = DESCRIPTIONS[type] || 'Terjadi kesalahan. Silakan coba lagi.'
|
const message =
|
||||||
|
DESCRIPTIONS[isOpen] || 'Terjadi kesalahan. Silakan coba lagi.'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={!!isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
className="relative z-50"
|
className="relative z-50"
|
||||||
transition
|
transition
|
||||||
@ -84,11 +73,7 @@ export const SuccessModal = ({
|
|||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="relative flex flex-col items-center justify-center">
|
<div className="relative flex flex-col items-center justify-center">
|
||||||
<div className="mb-4 p-4 text-center">
|
<div className="mb-4 p-4 text-center">
|
||||||
{[
|
{['resetPassword', 'register', 'payment'].includes(isOpen) && (
|
||||||
'success-reset-password',
|
|
||||||
'success-register',
|
|
||||||
'success-payment',
|
|
||||||
].includes(type) && (
|
|
||||||
<div className="justify-center">
|
<div className="justify-center">
|
||||||
<img
|
<img
|
||||||
src={'/images/back-to-home.svg'}
|
src={'/images/back-to-home.svg'}
|
||||||
@ -104,7 +89,7 @@ export const SuccessModal = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{type === 'warning' && (
|
{isOpen === 'warning' && (
|
||||||
<div className="justify-center">
|
<div className="justify-center">
|
||||||
<img
|
<img
|
||||||
src={'/images/warning.svg'}
|
src={'/images/warning.svg'}
|
||||||
|
|||||||
@ -7,15 +7,21 @@ import {
|
|||||||
type SetStateAction,
|
type SetStateAction,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
|
||||||
type NewsContextProperties = {
|
import type { ModalProperties } from '~/components/popup/success-modal'
|
||||||
|
|
||||||
|
export type NewsContextProperties = {
|
||||||
isLoginOpen: boolean
|
isLoginOpen: boolean
|
||||||
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
|
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
|
||||||
isRegisterOpen: boolean
|
isRegisterOpen: boolean
|
||||||
setIsRegisterOpen: Dispatch<SetStateAction<boolean>>
|
setIsRegisterOpen: Dispatch<SetStateAction<boolean>>
|
||||||
isForgetOpen: boolean
|
isForgetOpen: boolean
|
||||||
setForgetOpen: Dispatch<SetStateAction<boolean>>
|
setForgetOpen: Dispatch<SetStateAction<boolean>>
|
||||||
isSuccessModalOpen: boolean
|
isSuccessModalOpen?: ModalProperties['isOpen']
|
||||||
setIsSuccessModalOpen: Dispatch<SetStateAction<boolean>>
|
setIsSuccessModalOpen?: Dispatch<
|
||||||
|
SetStateAction<ModalProperties['isOpen'] | undefined>
|
||||||
|
>
|
||||||
|
isInitSubscribeOpen: boolean
|
||||||
|
setIsInitSubscribeOpen: Dispatch<SetStateAction<boolean>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewsContext = createContext<NewsContextProperties | undefined>(undefined)
|
const NewsContext = createContext<NewsContextProperties | undefined>(undefined)
|
||||||
@ -24,7 +30,9 @@ export const NewsProvider = ({ children }: PropsWithChildren) => {
|
|||||||
const [isLoginOpen, setIsLoginOpen] = useState(false)
|
const [isLoginOpen, setIsLoginOpen] = useState(false)
|
||||||
const [isRegisterOpen, setIsRegisterOpen] = useState(false)
|
const [isRegisterOpen, setIsRegisterOpen] = useState(false)
|
||||||
const [isForgetOpen, setForgetOpen] = useState(false)
|
const [isForgetOpen, setForgetOpen] = useState(false)
|
||||||
const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false)
|
const [isSuccessModalOpen, setIsSuccessModalOpen] =
|
||||||
|
useState<ModalProperties['isOpen']>()
|
||||||
|
const [isInitSubscribeOpen, setIsInitSubscribeOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NewsContext.Provider
|
<NewsContext.Provider
|
||||||
@ -37,6 +45,8 @@ export const NewsProvider = ({ children }: PropsWithChildren) => {
|
|||||||
setForgetOpen,
|
setForgetOpen,
|
||||||
isSuccessModalOpen,
|
isSuccessModalOpen,
|
||||||
setIsSuccessModalOpen,
|
setIsSuccessModalOpen,
|
||||||
|
isInitSubscribeOpen,
|
||||||
|
setIsInitSubscribeOpen,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { FormRegister } from '~/layouts/news/form-register'
|
|||||||
|
|
||||||
import { FooterLinks } from './footer-links'
|
import { FooterLinks } from './footer-links'
|
||||||
import { FooterNewsletter } from './footer-newsletter'
|
import { FooterNewsletter } from './footer-newsletter'
|
||||||
|
import FormSubscription from './form-subscription'
|
||||||
import { HeaderMenu } from './header-menu'
|
import { HeaderMenu } from './header-menu'
|
||||||
import { HeaderTop } from './header-top'
|
import { HeaderTop } from './header-top'
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
|
|||||||
setForgetOpen,
|
setForgetOpen,
|
||||||
isSuccessModalOpen,
|
isSuccessModalOpen,
|
||||||
setIsSuccessModalOpen,
|
setIsSuccessModalOpen,
|
||||||
|
isInitSubscribeOpen,
|
||||||
|
setIsInitSubscribeOpen,
|
||||||
} = useNewsContext()
|
} = useNewsContext()
|
||||||
return (
|
return (
|
||||||
<main className="relative min-h-dvh bg-[#ECECEC]">
|
<main className="relative min-h-dvh bg-[#ECECEC]">
|
||||||
@ -50,7 +53,7 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
|
|||||||
setIsRegisterOpen={setIsRegisterOpen}
|
setIsRegisterOpen={setIsRegisterOpen}
|
||||||
setIsLoginOpen={setIsLoginOpen}
|
setIsLoginOpen={setIsLoginOpen}
|
||||||
setIsForgetOpen={setForgetOpen}
|
setIsForgetOpen={setForgetOpen}
|
||||||
setIsSuccessModalOpen={setIsSuccessModalOpen}
|
setIsInitSubscribeOpen={setIsInitSubscribeOpen}
|
||||||
/>
|
/>
|
||||||
</PopupModal>
|
</PopupModal>
|
||||||
|
|
||||||
@ -70,12 +73,21 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
|
|||||||
<FormForgotPassword />
|
<FormForgotPassword />
|
||||||
</PopupModal>
|
</PopupModal>
|
||||||
|
|
||||||
|
<PopupModal
|
||||||
|
isOpen={isInitSubscribeOpen}
|
||||||
|
onClose={() => setIsInitSubscribeOpen(false)}
|
||||||
|
description="Selamat Datang, silakan Pilih Subscription Anda untuk melanjutkan!"
|
||||||
|
>
|
||||||
|
<FormSubscription />
|
||||||
|
</PopupModal>
|
||||||
|
|
||||||
<SuccessModal
|
<SuccessModal
|
||||||
isOpen={isSuccessModalOpen}
|
isOpen={isSuccessModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setIsSuccessModalOpen(false)
|
if (setIsSuccessModalOpen) {
|
||||||
|
setIsSuccessModalOpen(undefined)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
type="warning"
|
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
// import { EyeIcon, EyeOffIcon } from 'lucide-react'
|
// import { EyeIcon, EyeOffIcon } from 'lucide-react'
|
||||||
import { zodResolver } from '@hookform/resolvers/zod'
|
import { zodResolver } from '@hookform/resolvers/zod'
|
||||||
import { type Dispatch, type SetStateAction } from 'react'
|
|
||||||
import { FormProvider, useForm } from 'react-hook-form'
|
import { FormProvider, useForm } from 'react-hook-form'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
import { Button } from '~/components/ui/button'
|
import { Button } from '~/components/ui/button'
|
||||||
import { Input } from '~/components/ui/input'
|
import { Input } from '~/components/ui/input'
|
||||||
|
import type { NewsContextProperties } from '~/contexts/news'
|
||||||
|
|
||||||
const loginSchema = z.object({
|
const loginSchema = z.object({
|
||||||
email: z.string().email('Email tidak valid'),
|
email: z.string().email('Email tidak valid'),
|
||||||
@ -15,10 +15,10 @@ const loginSchema = z.object({
|
|||||||
type TLoginSchema = z.infer<typeof loginSchema>
|
type TLoginSchema = z.infer<typeof loginSchema>
|
||||||
|
|
||||||
type TProperties = {
|
type TProperties = {
|
||||||
setIsRegisterOpen: Dispatch<SetStateAction<boolean>>
|
setIsRegisterOpen: NewsContextProperties['setIsRegisterOpen']
|
||||||
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
|
setIsLoginOpen: NewsContextProperties['setIsLoginOpen']
|
||||||
setIsForgetOpen: Dispatch<SetStateAction<boolean>>
|
setIsForgetOpen: NewsContextProperties['setForgetOpen']
|
||||||
setIsSuccessModalOpen: Dispatch<SetStateAction<boolean>>
|
setIsInitSubscribeOpen: NewsContextProperties['setIsInitSubscribeOpen']
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FormLogin = (properties: TProperties) => {
|
export const FormLogin = (properties: TProperties) => {
|
||||||
@ -26,7 +26,7 @@ export const FormLogin = (properties: TProperties) => {
|
|||||||
setIsRegisterOpen,
|
setIsRegisterOpen,
|
||||||
setIsLoginOpen,
|
setIsLoginOpen,
|
||||||
setIsForgetOpen,
|
setIsForgetOpen,
|
||||||
setIsSuccessModalOpen,
|
setIsInitSubscribeOpen,
|
||||||
} = properties
|
} = properties
|
||||||
|
|
||||||
const formMethods = useForm<TLoginSchema>({
|
const formMethods = useForm<TLoginSchema>({
|
||||||
@ -37,7 +37,7 @@ export const FormLogin = (properties: TProperties) => {
|
|||||||
|
|
||||||
const onSubmit = handleSubmit((data) => {
|
const onSubmit = handleSubmit((data) => {
|
||||||
console.log('data', data) // eslint-disable-line no-console
|
console.log('data', data) // eslint-disable-line no-console
|
||||||
setIsSuccessModalOpen(true)
|
setIsInitSubscribeOpen(true)
|
||||||
setIsLoginOpen(false)
|
setIsLoginOpen(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user