Skip to content

Commit

Permalink
Add Modals
Browse files Browse the repository at this point in the history
  • Loading branch information
Abolfazl-ghodrati-k committed Mar 25, 2024
1 parent bc27e88 commit ea28953
Show file tree
Hide file tree
Showing 33 changed files with 629 additions and 419 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
MONGODB_URI="mongodb://localhost:27017"
MONGODB_URI="mongodb://localhost:27017/abolfazlNote"
JWT_SECRET=degrjgniuwreghnrwg%^&%#&^%*#%^645756%^&
5 changes: 5 additions & 0 deletions components/ModalsManager/components/CloseButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";

export default function IconButton() {
return <span>x</span>;
}
72 changes: 72 additions & 0 deletions components/ModalsManager/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useCallback, useRef } from 'react';
// @ts-ignore
import { Modal as ModalWrapper } from 'react-dialog-polyfill';
// import { useOnClickOutside } from '@avtkit/hooks/useOnClickOutside';
import { ModalProps } from '../types';
import DefaultCloseButton from './CloseButton';
import { useModal } from '../useModal';
import { useOnClickOutside } from '../../../hooks/useOnClickOutside';

const Modal: React.FC<ModalProps> = (props: ModalProps) => {
const {
index,
children,
closeButton: CloseButton = DefaultCloseButton,
renderOnOpen = false,
clickOverlayClose = true,
escClose = true,
showExitButton = true
} = props;

const { activeModal, closeModal } = useModal();
const isActive = activeModal.id === index;

const wrapperRef = useRef<HTMLDivElement | null>();

const closeHandler = useCallback(() => {
if (isActive) {
closeModal(activeModal.id);
}
}, [isActive, activeModal.id, closeModal]);

useOnClickOutside(wrapperRef, () => {
if (clickOverlayClose && showExitButton) {
closeHandler();
}
});

return (
<ModalWrapper
className="modal-wrapper"
open={isActive}
onCancel={() => {
if (escClose) {
closeHandler();
}
}}
>
<div
className='modal-buttons-container'
ref={(ref) => {
if (ref) {
wrapperRef.current = ref;
}
}}
>
<div className="ms-modal-buttons-container">
{!!CloseButton && showExitButton && (
// @ts-ignore
<CloseButton onClick={() => closeHandler()} />
)}
</div>
{(renderOnOpen || isActive) && children}
</div>
</ModalWrapper>
);
};

Modal.defaultProps = {
clickOverlayClose: true,
};

export default Modal
16 changes: 16 additions & 0 deletions components/ModalsManager/components/ModalContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

export type ModalContextType<T> = {
modalsStack: ModalStack<T>[];
setModalsStack: React.Dispatch<React.SetStateAction<ModalStack<T>[]>>;
};

export type ModalStack<T> = {
id: string;
options?: T;
};

export default React.createContext<ModalContextType<{}>>({
modalsStack: [],
setModalsStack: () => {},
});
11 changes: 11 additions & 0 deletions components/ModalsManager/components/ModalsProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { useState } from 'react';
import { ModalProviderProps } from '../types';
import ModalContext, { ModalStack } from './ModalContext';

const ModalsManager = ({ children }: ModalProviderProps) => {
const [modalsStack, setModalsStack] = useState<ModalStack<{}>[]>([]);

return <ModalContext.Provider value={{ modalsStack, setModalsStack }}>{children}</ModalContext.Provider>;
};

export default ModalsManager;
3 changes: 3 additions & 0 deletions components/ModalsManager/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as ModalsProvider } from './components/ModalsProvider';
export { default as Modal } from './components/Modal';
export { default as ModalContext } from './components/ModalContext';
19 changes: 19 additions & 0 deletions components/ModalsManager/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ModalStack } from "./components/ModalContext";

export type ModalProviderProps = {
defaultStack?: ModalStack<any>[];
children: React.ReactNode
};

export type ModalProps = {
children: React.ReactNode
index: string;
renderOnOpen?: boolean;
closeButton?: React.ReactNode | false;
extraButtons?: { id: string; button: React.FC<any> }[];
clickOverlayClose?: boolean;
escClose?: boolean;
buttonsPosition?: { x: string; y: string };
backgroundColor?: string;
showExitButton?: boolean
};
48 changes: 48 additions & 0 deletions components/ModalsManager/useModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useCallback, useContext, useEffect, useState } from 'react';
import ModalContext, { ModalStack, ModalContextType } from './components/ModalContext';
import { uniqBy, isEqual } from 'lodash';

export const useModal = <T>() => {
const { modalsStack, setModalsStack } = useContext<ModalContextType<T>>(
ModalContext as unknown as React.Context<ModalContextType<T>>
);
const [activeModal, setActiveModal] = useState<ModalStack<T>>(modalsStack[0] || { id: '' });

useEffect(() => {
const newStack = modalsStack[0] || { id: '' };

if (!isEqual(newStack, activeModal)) {
setActiveModal(newStack);
}
}, [modalsStack, activeModal]);

const closeModal = useCallback(
(id: string) => {
setModalsStack((previousStacks) => {
const clone = [...previousStacks];
const index = clone.findIndex((m) => m.id === id);
if (index >= 0) {
clone.splice(index, 1);
}

return clone;
});
},
[setModalsStack]
);

const addToModalsStack = useCallback(
(newStacks: ModalStack<T>[], removeDuplicates: boolean = true) => {
setModalsStack((previousStacks) =>
removeDuplicates ? uniqBy([...previousStacks, ...newStacks], 'id') : [...previousStacks, ...newStacks]
);
},
[setModalsStack]
);

return {
activeModal,
closeModal,
addToModalsStack,
};
};
12 changes: 5 additions & 7 deletions components/Notes/Notes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import NotesTitle from "./NotesTitle";
import NotesButton from "./NotesButton";
import NoteLoadingIndicator from "./NoteLoadingIndicator";
import NoteNavLoadingIndicator from "./NoteNavLoadingIndicator";
import dynamic from "next/dynamic";

const NoteCard = lazy(() => import("./NoteCard"));
const NotesNav = lazy(() => import("./NotesNav"));
const NoteCard = dynamic(() => import("./NoteCard"));
const NotesNav = dynamic(() => import("./NotesNav"));

type Props = {
Notes: Note[] | [];
Expand Down Expand Up @@ -50,15 +51,13 @@ function NotesContainer({ Notes, title, setNotes }: Props) {
ShowNote(note?.id);
} else {
const is_selected = isSelected(note?.id);
console.log(is_selected);
if (is_selected) {
const filteredNotes = selectedNotes?.filter(
(selectednote) => selectednote?.id != note?.id
);
console.log(`filterednotes ${filteredNotes}`);
setselectedNotes([...filteredNotes]);
} else {
console.log(`how you dare`);
setselectedNotes([...selectedNotes, { ...note }]);
}
}
Expand All @@ -67,7 +66,6 @@ function NotesContainer({ Notes, title, setNotes }: Props) {
function removeJunkNote() {
localStorage.removeItem("CURRENTID");
if (Notes) {
console.log(Notes);
const updatedNotes = Notes?.filter((n) => {
if (n?.text || n?.title) {
return n;
Expand All @@ -93,9 +91,9 @@ function NotesContainer({ Notes, title, setNotes }: Props) {
: `${styles.note_app_container}`
}
>
{showSidebar && (
{/* {showSidebar && (
<SideBar showSidebar={showSidebarCopy} setNotes={setNotes} />
)}
)} */}
<div className={styles.note_app}>
{/* Title */}
<NotesTitle
Expand Down
Loading

0 comments on commit ea28953

Please sign in to comment.