-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: add loadable component package * feat: implement modal management system with context and dynamic loading
- Loading branch information
1 parent
a20fddc
commit 2d40e4f
Showing
13 changed files
with
178 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { useContext } from 'react'; | ||
import { ModalsDispatchContext, ModalsStateContext } from './index.context'; | ||
import loadable from '@loadable/component'; | ||
|
||
export interface ModalProps { | ||
[key: string]: unknown; | ||
} | ||
|
||
export const modals = { | ||
roleModal: loadable(() => import('@features/auth/SignUp/components/common/RoleModal')), | ||
}; | ||
|
||
export default function Modals() { | ||
const openedModals = useContext(ModalsStateContext); | ||
const { close } = useContext(ModalsDispatchContext); | ||
|
||
return openedModals.map((modal, index) => { | ||
const { Component, props } = modal; | ||
const { onSubmit, ...restProps } = props; | ||
|
||
const handleClose = () => close(Component); | ||
|
||
const handleSubmit = async () => { | ||
if (typeof onSubmit === 'function') await onSubmit(); | ||
handleClose(); | ||
}; | ||
|
||
return <Component {...restProps} key={index} onClose={handleClose} onSubmit={handleSubmit} />; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useContext } from 'react'; | ||
import { ModalsDispatchContext } from '../index.context'; | ||
|
||
export default function useModals() { | ||
const { open, close } = useContext(ModalsDispatchContext); | ||
|
||
const openModal = (Component: React.ComponentType<any>, props: any) => { | ||
open(Component, props); | ||
}; | ||
|
||
const closeModal = (Component: React.ComponentType<any>) => { | ||
close(Component); | ||
}; | ||
|
||
return { | ||
openModal, | ||
closeModal, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { createContext } from 'react'; | ||
|
||
interface ModalsDispatchContextProps { | ||
open: (Component: React.ComponentType<any>, props: any) => void; | ||
close: (Component: React.ComponentType<any>) => void; | ||
} | ||
|
||
export const ModalsDispatchContext = createContext<ModalsDispatchContextProps>({ | ||
open: () => {}, | ||
close: () => {}, | ||
}); | ||
|
||
interface ModalState { | ||
Component: React.ComponentType<any>; | ||
props: any; | ||
} | ||
|
||
export const ModalsStateContext = createContext<ModalState[]>([]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { ModalsDispatchContext, ModalsStateContext } from '../common/Modal/index.context'; | ||
import { PropsWithChildren, useState, useMemo } from 'react'; | ||
|
||
interface ModalState { | ||
Component: React.ComponentType<any>; | ||
props: any; | ||
} | ||
|
||
const ModalsProvider = ({ children }: PropsWithChildren<unknown>) => { | ||
const [openedModals, setOpenedModals] = useState<ModalState[]>([]); | ||
|
||
const open = (Component: React.ComponentType<any>, props: any) => { | ||
setOpenedModals((modals) => [...modals, { Component, props }]); | ||
}; | ||
|
||
const close = (Component: React.ComponentType<any>) => { | ||
setOpenedModals((modals) => modals.filter((modal) => modal.Component !== Component)); | ||
}; | ||
|
||
const dispatch = useMemo(() => ({ open, close }), []); | ||
|
||
return ( | ||
<ModalsStateContext.Provider value={openedModals}> | ||
<ModalsDispatchContext.Provider value={dispatch}>{children}</ModalsDispatchContext.Provider> | ||
</ModalsStateContext.Provider> | ||
); | ||
}; | ||
|
||
export default ModalsProvider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,15 @@ | ||
import { ReactNode } from 'react'; | ||
import GlobalStylesProvider from './GlobalStylesProvider/index.provider'; | ||
import ModalsProvider from './Modals.provider'; | ||
import Modals from '../common/Modal/Modals'; | ||
|
||
export default function AppProviders({ children }: { children: ReactNode }) { | ||
return <GlobalStylesProvider>{children}</GlobalStylesProvider>; | ||
return ( | ||
<GlobalStylesProvider> | ||
<ModalsProvider> | ||
{children} | ||
<Modals /> | ||
</ModalsProvider> | ||
</GlobalStylesProvider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,13 @@ | ||
import { Flex } from '@components/common'; | ||
import RoleSelector from './common/RoleSelector'; | ||
import { ReactNode } from 'react'; | ||
|
||
type Props = { | ||
onRoleSelect: (modalContent: ReactNode) => void; | ||
}; | ||
const FLEX_GAP_CONFIG = { x: '30px' }; | ||
|
||
export default function RoleSelection({ onRoleSelect }: Props) { | ||
export default function RoleSelection() { | ||
return ( | ||
<Flex justifyContent="center" alignItems="center" gap={{ x: '30px' }}> | ||
<RoleSelector role="employer" onClick={onRoleSelect} /> | ||
<RoleSelector role="worker" onClick={onRoleSelect} /> | ||
<Flex justifyContent="center" alignItems="center" gap={FLEX_GAP_CONFIG}> | ||
<RoleSelector role="employer" /> | ||
<RoleSelector role="worker" /> | ||
</Flex> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,20 @@ | ||
import { ReactNode, useState } from 'react'; | ||
import Layout from '@features/layout'; | ||
import { InnerContainer } from '@components/common'; | ||
import { responsiveStyle, responsiveSectionPadding } from '@utils/responsive'; | ||
import RoleSelection from '@/features/auth/SignUp/components/RoleSelection'; | ||
import RoleModal from '@/features/auth/SignUp/components/common/RoleModal'; | ||
import useToggle from '@hooks/useToggle'; | ||
import SignUpText from '@/features/auth/SignUp/components/SignUpText'; | ||
|
||
const sectionStyle = responsiveStyle(responsiveSectionPadding); | ||
|
||
export default function SignUp() { | ||
const [isToggle, toggle] = useToggle(); | ||
const [modalContent, setModalContent] = useState<ReactNode>(); | ||
|
||
const handleRoleSelect = (modalContent: ReactNode) => { | ||
toggle(); | ||
setModalContent(modalContent); | ||
}; | ||
|
||
return ( | ||
<Layout> | ||
<section css={sectionStyle}> | ||
<InnerContainer> | ||
<SignUpText /> | ||
<RoleSelection onRoleSelect={handleRoleSelect} /> | ||
<RoleSelection /> | ||
</InnerContainer> | ||
</section> | ||
{isToggle && <RoleModal content={modalContent} onClose={toggle} />} | ||
</Layout> | ||
); | ||
} |