feat: enhance SuccessModal and News context for improved modal management and subscription flow

This commit is contained in:
Ardeman 2025-02-25 05:18:40 +08:00
parent fe9b8bc97a
commit 6b2ba85642
4 changed files with 49 additions and 42 deletions

View File

@ -11,45 +11,34 @@ import { LeftArrow } from '~/components/icons/left-arrow'
import { Button } from '~/components/ui/button'
import { APP } from '~/data/meta'
type ModalProperties = {
isOpen: boolean
export type ModalProperties = {
onClose: () => void
children?: ReactNode
type:
| 'success'
| 'error'
| 'warning'
| 'success-reset-password'
| 'success-register'
| 'success-payment'
isOpen?: 'error' | 'warning' | 'resetPassword' | 'register' | 'payment'
}
type DescriptionMap = {
[key in ModalProperties['type']]: string
[key in Exclude<ModalProperties['isOpen'], undefined>]: string
}
const DESCRIPTIONS: DescriptionMap = {
'success-reset-password':
'Link Reset Password telah dikirimkan ke email anda',
'success-register': 'Selamat! pendaftaran anda berhasil!',
'success-payment': 'Selamat! Pembayaran anda berhasil!',
resetPassword: 'Link Reset Password telah dikirimkan ke email anda',
register: 'Selamat! Pendaftaran anda berhasil!',
payment: 'Selamat! Pembayaran anda berhasil!',
warning:
'Mohon maaf fitur berikut hanya untuk anggota yang sudah tersubscribe',
error: 'Terjadi kesalahan. Silakan coba lagi.',
success: '',
}
export const SuccessModal = ({
isOpen,
onClose,
type = 'success-register',
}: ModalProperties) => {
export const SuccessModal = ({ isOpen, onClose }: ModalProperties) => {
if (!isOpen) return
const message = DESCRIPTIONS[type] || 'Terjadi kesalahan. Silakan coba lagi.'
const message =
DESCRIPTIONS[isOpen] || 'Terjadi kesalahan. Silakan coba lagi.'
return (
<Dialog
open={isOpen}
open={!!isOpen}
onClose={onClose}
className="relative z-50"
transition
@ -84,11 +73,7 @@ export const SuccessModal = ({
<div className="relative">
<div className="relative flex flex-col items-center justify-center">
<div className="mb-4 p-4 text-center">
{[
'success-reset-password',
'success-register',
'success-payment',
].includes(type) && (
{['resetPassword', 'register', 'payment'].includes(isOpen) && (
<div className="justify-center">
<img
src={'/images/back-to-home.svg'}
@ -104,7 +89,7 @@ export const SuccessModal = ({
</Button>
</div>
)}
{type === 'warning' && (
{isOpen === 'warning' && (
<div className="justify-center">
<img
src={'/images/warning.svg'}

View File

@ -7,15 +7,21 @@ import {
type SetStateAction,
} from 'react'
type NewsContextProperties = {
import type { ModalProperties } from '~/components/popup/success-modal'
export type NewsContextProperties = {
isLoginOpen: boolean
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
isRegisterOpen: boolean
setIsRegisterOpen: Dispatch<SetStateAction<boolean>>
isForgetOpen: boolean
setForgetOpen: Dispatch<SetStateAction<boolean>>
isSuccessModalOpen: boolean
setIsSuccessModalOpen: Dispatch<SetStateAction<boolean>>
isSuccessModalOpen?: ModalProperties['isOpen']
setIsSuccessModalOpen?: Dispatch<
SetStateAction<ModalProperties['isOpen'] | undefined>
>
isInitSubscribeOpen: boolean
setIsInitSubscribeOpen: Dispatch<SetStateAction<boolean>>
}
const NewsContext = createContext<NewsContextProperties | undefined>(undefined)
@ -24,7 +30,9 @@ export const NewsProvider = ({ children }: PropsWithChildren) => {
const [isLoginOpen, setIsLoginOpen] = useState(false)
const [isRegisterOpen, setIsRegisterOpen] = useState(false)
const [isForgetOpen, setForgetOpen] = useState(false)
const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false)
const [isSuccessModalOpen, setIsSuccessModalOpen] =
useState<ModalProperties['isOpen']>()
const [isInitSubscribeOpen, setIsInitSubscribeOpen] = useState(false)
return (
<NewsContext.Provider
@ -37,6 +45,8 @@ export const NewsProvider = ({ children }: PropsWithChildren) => {
setForgetOpen,
isSuccessModalOpen,
setIsSuccessModalOpen,
isInitSubscribeOpen,
setIsInitSubscribeOpen,
}}
>
{children}

View File

@ -10,6 +10,7 @@ import { FormRegister } from '~/layouts/news/form-register'
import { FooterLinks } from './footer-links'
import { FooterNewsletter } from './footer-newsletter'
import FormSubscription from './form-subscription'
import { HeaderMenu } from './header-menu'
import { HeaderTop } from './header-top'
@ -24,6 +25,8 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
setForgetOpen,
isSuccessModalOpen,
setIsSuccessModalOpen,
isInitSubscribeOpen,
setIsInitSubscribeOpen,
} = useNewsContext()
return (
<main className="relative min-h-dvh bg-[#ECECEC]">
@ -50,7 +53,7 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
setIsRegisterOpen={setIsRegisterOpen}
setIsLoginOpen={setIsLoginOpen}
setIsForgetOpen={setForgetOpen}
setIsSuccessModalOpen={setIsSuccessModalOpen}
setIsInitSubscribeOpen={setIsInitSubscribeOpen}
/>
</PopupModal>
@ -70,12 +73,21 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => {
<FormForgotPassword />
</PopupModal>
<PopupModal
isOpen={isInitSubscribeOpen}
onClose={() => setIsInitSubscribeOpen(false)}
description="Selamat Datang, silakan Pilih Subscription Anda untuk melanjutkan!"
>
<FormSubscription />
</PopupModal>
<SuccessModal
isOpen={isSuccessModalOpen}
onClose={() => {
setIsSuccessModalOpen(false)
if (setIsSuccessModalOpen) {
setIsSuccessModalOpen(undefined)
}
}}
type="warning"
/>
</main>
)

View File

@ -1,11 +1,11 @@
// import { EyeIcon, EyeOffIcon } from 'lucide-react'
import { zodResolver } from '@hookform/resolvers/zod'
import { type Dispatch, type SetStateAction } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { z } from 'zod'
import { Button } from '~/components/ui/button'
import { Input } from '~/components/ui/input'
import type { NewsContextProperties } from '~/contexts/news'
const loginSchema = z.object({
email: z.string().email('Email tidak valid'),
@ -15,10 +15,10 @@ const loginSchema = z.object({
type TLoginSchema = z.infer<typeof loginSchema>
type TProperties = {
setIsRegisterOpen: Dispatch<SetStateAction<boolean>>
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
setIsForgetOpen: Dispatch<SetStateAction<boolean>>
setIsSuccessModalOpen: Dispatch<SetStateAction<boolean>>
setIsRegisterOpen: NewsContextProperties['setIsRegisterOpen']
setIsLoginOpen: NewsContextProperties['setIsLoginOpen']
setIsForgetOpen: NewsContextProperties['setForgetOpen']
setIsInitSubscribeOpen: NewsContextProperties['setIsInitSubscribeOpen']
}
export const FormLogin = (properties: TProperties) => {
@ -26,7 +26,7 @@ export const FormLogin = (properties: TProperties) => {
setIsRegisterOpen,
setIsLoginOpen,
setIsForgetOpen,
setIsSuccessModalOpen,
setIsInitSubscribeOpen,
} = properties
const formMethods = useForm<TLoginSchema>({
@ -37,7 +37,7 @@ export const FormLogin = (properties: TProperties) => {
const onSubmit = handleSubmit((data) => {
console.log('data', data) // eslint-disable-line no-console
setIsSuccessModalOpen(true)
setIsInitSubscribeOpen(true)
setIsLoginOpen(false)
})