From 11da66aacbad84ff61e8d58aec9945564d1f197c Mon Sep 17 00:00:00 2001 From: Muneerat Date: Sun, 21 Jul 2024 17:54:12 +0100 Subject: [PATCH 1/2] Fix : view modal --- app/components/modal/addUserModal.tsx | 127 ++++++++++++++++++++++++++ app/components/modal/deleteUser.tsx | 13 +++ app/components/modal/modal.tsx | 79 ++++++++++++++++ app/routes/_index.tsx | 21 +++++ 4 files changed, 240 insertions(+) create mode 100644 app/components/modal/addUserModal.tsx create mode 100644 app/components/modal/deleteUser.tsx create mode 100644 app/components/modal/modal.tsx diff --git a/app/components/modal/addUserModal.tsx b/app/components/modal/addUserModal.tsx new file mode 100644 index 00000000..0623f71c --- /dev/null +++ b/app/components/modal/addUserModal.tsx @@ -0,0 +1,127 @@ +import { useState, ChangeEvent, FormEvent } from "react"; + +interface AddUserContentProps { + toggleShow: (show: boolean) => void; +} + +const AddUserContent: React.FC = ({ toggleShow }) => { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [phoneNumber, setPhoneNumber] = useState(""); + const [errors, setErrors] = useState({ + name: "", + email: "", + phoneNumber: "" + }); + + const handleChange = (e: ChangeEvent) => { + const { id, value } = e.target; + if (id === "name") setName(value); + if (id === "email") setEmail(value); + if (id === "phoneNumber") setPhoneNumber(value); + }; + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + const newErrors = { + name: "", + email: "", + phoneNumber: "" + }; + + if (!name.trim()) { + newErrors.name = "Name is required"; + } + if (!email.trim()) { + newErrors.email = "Email is required"; + } else if (!/\S+@\S+\.\S+/.test(email)) { + newErrors.email = "Email address is invalid"; + } + if (!phoneNumber.trim()) { + newErrors.phoneNumber = "Phone number is required"; + } + if (newErrors.name || newErrors.email || newErrors.phoneNumber) { + setErrors(newErrors); + } else { + setName(""); + setEmail(""); + setPhoneNumber(""); + setErrors({ + name: "", + email: "", + phoneNumber: "" + }); + toggleShow(false); + } + }; + + return ( +
+

Add new user

+

Create a new user

+
+
+ +
+
+

Upload Picture

+
+

Click to upload

+ +
+
+
+
+
+ + + {errors.name &&

{errors.name}

} +
+
+ + + {errors.email &&

{errors.email}

} +
+
+ + + {errors.phoneNumber &&

{errors.phoneNumber}

} +
+
+
+ +
+
+ ); +}; + +export default AddUserContent; + + \ No newline at end of file diff --git a/app/components/modal/deleteUser.tsx b/app/components/modal/deleteUser.tsx new file mode 100644 index 00000000..543c1ab0 --- /dev/null +++ b/app/components/modal/deleteUser.tsx @@ -0,0 +1,13 @@ +const DeleteUserContent = () => { + return ( +
+

Are you sure you want to delete?

+

This action cannot be undone. This will permanently delete this user from the database.

+
+ + ); +}; + +export default DeleteUserContent; + + \ No newline at end of file diff --git a/app/components/modal/modal.tsx b/app/components/modal/modal.tsx new file mode 100644 index 00000000..af6b5792 --- /dev/null +++ b/app/components/modal/modal.tsx @@ -0,0 +1,79 @@ +import React, { useEffect, useRef, ReactNode } from 'react'; +import { Card } from '../ui/card'; + +interface ModalProps { + className?: string; + show: boolean; + toggleShow: (show: boolean) => void; + children: ReactNode; +} + +const Modal: React.FC = ({ className, show, toggleShow, children }) => { + const modal = useRef(null); + + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (modal.current && !modal.current.contains(e.target as Node)) { + toggleShow(false); + } + }; + + document.addEventListener('click', handleClickOutside); + return () => { + document.removeEventListener('click', handleClickOutside); + }; + }, [toggleShow]); + + return ( + + {show && ( +
+
+ {/* */} +
{children}
+
+
+ )} +
+ ); +}; + +export default Modal; +// context/ModalContext.tsx +// import { createContext, useContext, useState, ReactNode } from "react"; + +// interface ModalContextProps { +// showModal: boolean; +// toggleModal: (show: boolean) => void; +// } + +// const ModalContext = createContext(undefined); + +// export const useModal = () => { +// const context = useContext(ModalContext); +// if (!context) { +// throw new Error("useModal must be used within a ModalProvider"); +// } +// return context; +// }; + +// export const ModalProvider = ({ children }: { children: ReactNode }) => { +// const [showModal, setShowModal] = useState(false); + +// const toggleModal = (show: boolean) => setShowModal(show); + +// return ( +// +// {children} +// +// ); +// }; diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx index 1eeb5b2f..22331026 100644 --- a/app/routes/_index.tsx +++ b/app/routes/_index.tsx @@ -1,8 +1,14 @@ import type { MetaFunction } from "@remix-run/node"; +import { useState } from "react"; import { Button } from "~/components/ui/button"; import CardPlatform from "~/components/ui/card/card-platform"; +import Modal from "~/components/modal/modal"; +import AddUserContent from "~/components/modal/addUserModal"; +import DeleteUserContent from "~/components/modal/deleteUser"; export const meta: MetaFunction = () => { + + return [ { title: "New Remix App" }, { name: "description", content: "Welcome to Remix!" }, @@ -10,6 +16,11 @@ export const meta: MetaFunction = () => { }; export default function Index() { + const [show, setShow] = useState(false); + + const toggleShow = (show: boolean) => { + setShow(show); + }; return (

Welcome to Remix

@@ -54,6 +65,16 @@ export default function Index() { + + + {/* */} + +
); } From ed34b0bdf53a8d59be8e66f84718ec452440034d Mon Sep 17 00:00:00 2001 From: Muneerat Date: Mon, 22 Jul 2024 13:05:05 +0100 Subject: [PATCH 2/2] Fix: lint error --- app/components/modal/addUserModal.tsx | 16 ++++++++-------- app/components/modal/deleteUser.tsx | 2 +- app/components/modal/modal.tsx | 17 +++++++++-------- app/routes/_index.tsx | 10 +--------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/app/components/modal/addUserModal.tsx b/app/components/modal/addUserModal.tsx index 82d2ebe4..6a7835e1 100644 --- a/app/components/modal/addUserModal.tsx +++ b/app/components/modal/addUserModal.tsx @@ -1,4 +1,4 @@ -import {ChangeEvent, FormEvent, useState } from "react" +import { ChangeEvent, FormEvent, useState } from "react"; interface AddUserContentProperties { toggleShow: (show: boolean) => void; @@ -26,7 +26,7 @@ const AddUserContent: React.FC = ({ toggleShow }) => { const newErrors = { name: "", email: "", - phoneNumber: "" + phoneNumber: "", }; if (!name.trim()) { @@ -60,7 +60,7 @@ const AddUserContent: React.FC = ({ toggleShow }) => {

Add new user

Create a new user

-
+
= ({ toggleShow }) => {

Upload Picture

Click to upload

- +
@@ -110,9 +110,9 @@ const AddUserContent: React.FC = ({ toggleShow }) => { placeholder="e.g 08123456789" className="my-2 rounded-lg border-2 p-2 outline-[#CBD5E1] focus:border-none" /> - { - errors.phoneNumber &&

{errors.phoneNumber}

- } + {errors.phoneNumber && ( +

{errors.phoneNumber}

+ )}
@@ -124,4 +124,4 @@ const AddUserContent: React.FC = ({ toggleShow }) => { ); }; -export default AddUserContent; \ No newline at end of file +export default AddUserContent; diff --git a/app/components/modal/deleteUser.tsx b/app/components/modal/deleteUser.tsx index ff37cdbe..ccd34046 100644 --- a/app/components/modal/deleteUser.tsx +++ b/app/components/modal/deleteUser.tsx @@ -26,7 +26,7 @@ const DeleteUserContent: React.FC = ({ Cancel