= ({ modalFactory }) => {
+ const { modalOpened, closeModal } = useModalStore((state) => ({
+ modalOpened: state.modalOpened,
+ closeModal: state.actions.closeModal,
+ }))
+
+ if (!modalOpened) {
+ return null
+ }
+
+ const ModalRenderer = modalFactory.get(modalOpened)
+
+ return
+}
diff --git a/src/libs/modals/modal.store.ts b/src/libs/modals/modal.store.ts
new file mode 100644
index 00000000000..ba99ce8d71d
--- /dev/null
+++ b/src/libs/modals/modal.store.ts
@@ -0,0 +1,50 @@
+import { createStore } from 'libs/store/createStore'
+
+export type Modal = {
+ key: string
+ params: P
+}
+
+type State = {
+ modalOpened?: Modal
+ queue: Modal[]
+}
+
+const defaultStore: State = {
+ modalOpened: undefined,
+ queue: [],
+}
+
+const setActions = (set: (payload: (state: State) => State) => void) => ({
+ openModal: (modal: Modal) => {
+ set((state) => {
+ const hasModalOpened = state.modalOpened !== undefined
+
+ return {
+ ...state,
+ modalOpened: modal,
+ queue: hasModalOpened ? [...state.queue, modal] : state.queue,
+ }
+ })
+ },
+ closeModal: () => {
+ set((state) => {
+ const [nextModal] = state.queue
+
+ return {
+ ...state,
+ modalOpened: nextModal,
+ queue: state.queue.filter((queuedModal) => queuedModal !== nextModal),
+ }
+ })
+ },
+})
+
+export const modalStore = createStore>(
+ 'modals',
+ defaultStore,
+ setActions
+)
+
+export const useModalStore = modalStore
+export const useModalActions = () => modalStore((state) => state.actions)
diff --git a/src/libs/modals/modals.factory.native.spec.tsx b/src/libs/modals/modals.factory.native.spec.tsx
new file mode 100644
index 00000000000..bf3de858b5f
--- /dev/null
+++ b/src/libs/modals/modals.factory.native.spec.tsx
@@ -0,0 +1,35 @@
+import React from 'react'
+
+import { TypoDS } from 'ui/theme'
+
+import { createModal } from './modal.creator'
+import { createModalFactory } from './modals.factory'
+
+describe('Feature: Modals render factory', () => {
+ test('Modal is added', () => {
+ const modalFactory = createModalFactory()
+ const modal = createModal('modal-key')
+ const render = () => Modal
+ modalFactory.add(modal, render)
+
+ expect(modalFactory.get(modal(undefined))).toEqual(render)
+ })
+
+ test('Already exist error is thrown when modal already exist', () => {
+ const modalFactory = createModalFactory()
+ const modal = createModal('modal-key')
+ modalFactory.add(modal, () => Modal)
+
+ expect(() => modalFactory.add(modal, () => Modal)).toThrowError(
+ `Modal with key\u00a0: ${modal.key} Already exist`
+ )
+ })
+
+ test('Throw error when modal is not found', () => {
+ const modalFactory = createModalFactory()
+ const modal = createModal('modal-key')
+ expect(() => modalFactory.get(modal(undefined))).toThrowError(
+ `Modal with key\u00a0: ${modal.key} Not found`
+ )
+ })
+})
diff --git a/src/libs/modals/modals.factory.ts b/src/libs/modals/modals.factory.ts
new file mode 100644
index 00000000000..623a5002ebf
--- /dev/null
+++ b/src/libs/modals/modals.factory.ts
@@ -0,0 +1,29 @@
+import React from 'react'
+
+import { ModalCreator } from './modal.creator'
+import { Modal } from './modal.store'
+
+export type ModalFactory = ReturnType
+
+export const createModalFactory = () => {
+ const modals: Map void }>> = new Map()
+
+ return {
+ add: (
+ modalCreator: ModalCreator,
+ element: React.FC<{ params: T; close: () => void }>
+ ) => {
+ if (modals.has(modalCreator.key)) {
+ throw new Error(`Modal with key\u00a0: ${modalCreator.key} Already exist`)
+ }
+ modals.set(modalCreator.key, element as React.FC<{ params: unknown }>)
+ },
+ get: (modal: Modal) => {
+ const modalElement = modals.get(modal.key)
+ if (!modalElement) {
+ throw new Error(`Modal with key\u00a0: ${modal.key} Not found`)
+ }
+ return modalElement
+ },
+ }
+}
diff --git a/src/libs/modals/modals.ts b/src/libs/modals/modals.ts
new file mode 100644
index 00000000000..5b41cb9bc3c
--- /dev/null
+++ b/src/libs/modals/modals.ts
@@ -0,0 +1,20 @@
+import { AchievementEnum, BookingOfferResponse, OfferResponse, ReactionTypeEnum } from 'api/gen'
+import { ReactionChoiceModalBodyEnum, ReactionFromEnum } from 'features/reactions/enum'
+import { OfferImageBasicProps } from 'features/reactions/types'
+
+import { createModal } from './modal.creator'
+import { createModalFactory } from './modals.factory'
+
+export const achievementsModal = createModal<{ names: AchievementEnum[] }>('achievements')
+
+// reactionModal à réadapter
+export const reactionModal = createModal<{
+ offer: OfferResponse | BookingOfferResponse
+ dateUsed: string
+ defaultReaction?: ReactionTypeEnum | null
+ from: ReactionFromEnum
+ bodyType: ReactionChoiceModalBodyEnum
+ offerImages?: OfferImageBasicProps[]
+}>('reaction')
+
+export const modalFactory = createModalFactory()