Skip to content

Commit

Permalink
Feature: Modal Component (#3)
Browse files Browse the repository at this point in the history
# Story Title
Feature: Modal Component

## Changes made

- Create Modal Component, on Atom/Modal
- Create Jotai Reducer to handle Modal Component
- Add Modal Component to jotai-sample page

## How does the solution address the problem

This PR will create a reusable modal component that can be accessed anywhere in the app, and can display any content that is passed to it.
  • Loading branch information
edwardlayaodev committed Jun 25, 2024
1 parent 7d0db68 commit 4bc21a9
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 8 deletions.
28 changes: 28 additions & 0 deletions app/_components/atoms/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client";
import { Modal as AntModal, ModalProps } from "antd";
import { useAtom } from "jotai";
import { modalReducerAtom } from "@/app/_data/modalState";

interface IModalProps extends ModalProps {}

const Modal: React.FunctionComponent<IModalProps> = ({}) => {
// reducer sample for jotai uses dispatch instead of setModal
const [modal, dispatch] = useAtom(modalReducerAtom);

const handleCancel = () => {
dispatch({ type: "close" });
};

return (
<AntModal
open={modal?.open}
onCancel={handleCancel}
// hide the default ok & cancel buttons
footer={null}
>
{modal?.content}
</AntModal>
);
};

export default Modal;
4 changes: 3 additions & 1 deletion app/_components/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import Card from "./Card";
import Logo from "./Logo";
import Button from "./Button";
import GitHub from "./GitHub";
import Modal from "./Modal";

const Atom = {
Visibility,
Card,
Logo,
Button,
GitHub,
}
Modal,
};

export default Atom;
12 changes: 5 additions & 7 deletions app/_components/templates/Default.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import Head from 'next/head';
import Head from "next/head";
import Organism from "@organism";
import "../../_styles/globals.css";
import Atom from "@atom";

const Default = ({
children,
}: {
children: React.ReactNode
}) => {
const Default = ({ children }: { children: React.ReactNode }) => {
return (
<html lang="en" className="h-full">
<Head>
Expand All @@ -18,12 +15,13 @@ const Default = ({
<body className="flex flex-col h-full">
<Organism.Wrapper>
<Organism.Header />
<Atom.Modal />
<div className="container mx-auto flex-1">{children}</div>
<Organism.Footer />
</Organism.Wrapper>
</body>
</html>
);
}
};

export default Default;
31 changes: 31 additions & 0 deletions app/_data/modalState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";
import { ReactNode } from "react";

import { atomWithReducer } from "jotai/utils";

interface IModalState {
open: boolean;
content: ReactNode | null;
}

const modalState: IModalState = {
open: false,
content: null,
};

const modalReducer = (prev: any, action: any) => {
// content is the content of the modal, for ex, a login form
// this will be passed on reducer action.payload
if (action.type == "open")
return {
open: true,
content: action.payload,
};
if (action.type == "close")
return {
open: false,
content: null,
};
};

export const modalReducerAtom = atomWithReducer(modalState, modalReducer);
9 changes: 9 additions & 0 deletions app/jotai-example/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@
import { useAtom } from "jotai";
import { msgAtom } from "../_data/atoms";
import { useState } from "react";
import { modalReducerAtom } from "../_data/modalState";
import Atom from "@atom";

export default function JotaiExamplePage() {
const [msg, setMsg] = useAtom(msgAtom);
const [input, setInput] = useState("");
const [modal, dispatch] = useAtom(modalReducerAtom);

const open = () => {
// open a modal, payload will be the content of the modal
dispatch({ type: "open", payload: <h1>TEST: This is a Modal</h1> });
};

return (
<div>
Expand All @@ -25,6 +33,7 @@ export default function JotaiExamplePage() {
/>
<button type="submit">submit</button>
</form>
<Atom.Button onClick={open}>Test Open Modal</Atom.Button>
</div>
);
}

0 comments on commit 4bc21a9

Please sign in to comment.