Skip to content

Commit

Permalink
add delete modal and delete board context for deleting a board with c…
Browse files Browse the repository at this point in the history
…onfrimation
  • Loading branch information
Alforoan committed Jun 26, 2024
1 parent 7af6b94 commit 8d4f0fc
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 17 deletions.
53 changes: 52 additions & 1 deletion client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"axios": "^1.7.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.16.1",
"react-router-dom": "^6.23.1",
"uuid": "^10.0.0"
},
Expand Down
12 changes: 12 additions & 0 deletions client/src/assets/deleteBoard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 35 additions & 11 deletions client/src/components/BoardPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import React, {useContext} from "react";
import { Board } from "../types";
import {DeleteBoardContext} from "../context/DeleteBoardContext";

interface BoardPreviewProps {
board: Board;
Expand All @@ -11,17 +12,40 @@ const BoardPreview: React.FC<BoardPreviewProps> = ({
handleSelectBoard,
}) => {
// should show progress bar on this preview

const {deleteBoardModal, setModalOpen} = useContext(DeleteBoardContext);


const handleClick = (e: React.MouseEvent) => {
e.stopPropagation();
setModalOpen(true);
deleteBoardModal(board.uuid);
}
return (
<div
onClick={() => handleSelectBoard(board)}
className="bg-secondaryElements border border-secondaryElements-200 p-4 shadow-sm w-40 h-40 flex-col items-center justify-center rounded"
>
<h1 className="text-center text-primaryText text-lg font-medium pb-8">
{board.name}
</h1>
<p>Total cards: {board.cards!.length - 1}</p>
</div>
);
<div
onClick={() => handleSelectBoard(board)}
className='bg-secondaryElements border border-secondaryElements-200 p-4 shadow-sm w-40 h-40 flex-col items-center justify-center rounded relative'
>
<h1 className='text-center text-primaryText text-lg font-medium pb-8'>
{board.name}
</h1>
<div onClick={handleClick} className="absolute top-0 right-0 p-1">
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="w-6 h-6 text-gray-600 hover:text-gray-800 cursor-pointer"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</div>
<p>Total cards: {board.cards!.length - 1}</p>
</div>
);
};

export default BoardPreview;
65 changes: 65 additions & 0 deletions client/src/components/DeleteModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, {useContext} from 'react';
import { DeleteBoardContext } from '../context/DeleteBoardContext';

interface ModalProps {
isOpen: boolean;
onClose: () => void;
onDelete: (uuid: string) => void;
}

const Modal: React.FC<ModalProps> = ({ isOpen, onClose }) => {
const {setModalOpen, handleDeleteBoard} = useContext(DeleteBoardContext)


if (!isOpen) return null;

return (
<div className='fixed inset-0 z-50 flex items-center justify-center overflow-x-hidden overflow-y-auto outline-none'>
<div className='relative w-auto max-w-sm mx-auto my-6 bg-white rounded-lg shadow-lg'>
<div className='flex items-start justify-between p-5 border-b border-gray-200 rounded-t'>
<h3 className='text-lg font-semibold'>Confirm Delete</h3>
<button
onClick={onClose}
className='text-gray-400 hover:text-gray-600'
>
<svg
className='w-6 h-6'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
>
<line x1='18' y1='6' x2='6' y2='18' />
<line x1='6' y1='6' x2='18' y2='18' />
</svg>
</button>
</div>
<div className='p-5'>
<p className='text-sm text-gray-700'>
Are you sure you want to delete this board?
</p>
</div>
<div className='flex items-center justify-end px-5 py-4 bg-gray-100 border-t border-gray-200 rounded-b'>
<button
className='px-4 py-2 mr-2 text-white bg-red-500 rounded hover:bg-red-600 focus:outline-none'
onClick={() => {
handleDeleteBoard();
}}
>
Delete
</button>
<button
onClick={() => setModalOpen(false)}
className='px-4 py-2 text-gray-600 bg-gray-200 rounded hover:bg-gray-300 focus:outline-none'
>
Cancel
</button>
</div>
</div>
</div>
);
};

export default Modal;
67 changes: 67 additions & 0 deletions client/src/context/DeleteBoardContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { createContext, useState } from 'react';
import Modal from '../components/DeleteModal';
import useDeleteBoard from '../hooks/useDeleteBoard';
import useGetUserBoards from '../hooks/useGetUserBoards';
import { Board } from '../types';

interface DeleteBoardContextType {
deleteBoardModal: (id: string) => void;
setModalOpen: (isOpen: boolean) => void;
handleDeleteBoard: () => void;
currentBoards: Board[];
setCurrentBoards: (boards: Board[]) => void;
currentBoardId: string;
}

const defaultSetCurrentBoards: (boards: Board[]) => void = () => {};

export const DeleteBoardContext = createContext<DeleteBoardContextType>({
deleteBoardModal: () => {},
setModalOpen: () => {},
handleDeleteBoard: () => {},
currentBoards: [],
setCurrentBoards: defaultSetCurrentBoards,
currentBoardId: "",
});

export const DeleteBoardProvider = ({ children }) => {
const [isModalOpen, setModalOpen] = useState(false);
const [currentBoardId, setCurrentBoardId] = useState<string>('');
const [currentBoards, setCurrentBoards] = useState<Board[]>([]);
const { getUserBoards } = useGetUserBoards();
const {deleteBoard} = useDeleteBoard();
const requestDeleteBoard = (id: string) => {
setCurrentBoardId(id);
setModalOpen(true);
};



const handleDeleteBoard = async () => {
await deleteBoard(currentBoardId);
const newBoards = await getUserBoards();
setModalOpen(false);
setCurrentBoards(newBoards);
console.log({newBoards});

};

const cancelDeleteBoard = () => {
setModalOpen(false);
};

return (
<DeleteBoardContext.Provider value={{ deleteBoardModal: requestDeleteBoard, setModalOpen, handleDeleteBoard, currentBoards, setCurrentBoards, currentBoardId }}>
{children}
{isModalOpen && (
<Modal
isOpen={isModalOpen}
onClose={cancelDeleteBoard}
onDelete={handleDeleteBoard}
/>
)}
</DeleteBoardContext.Provider>
);
};


33 changes: 33 additions & 0 deletions client/src/hooks/useDeleteBoard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import axios from 'axios';
import { useState } from 'react';

const useDeleteBoard = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const [successMsg, setSuccessMsg] = useState<string>('');

const deleteBoard = async (boardId: string) => {
setIsLoading(true);
setError(null);

try {
const response = await axios.delete(
`http://127.0.0.1:5000/api/boards/${boardId}`
);
setIsLoading(false);
if (response.status === 200) {
setSuccessMsg(response?.data?.message);
}

} catch (err) {
if (err instanceof Error) {
setError(err);
}
setIsLoading(false);
}
};

return { deleteBoard, isLoading, error, successMsg, setSuccessMsg };
};

export default useDeleteBoard;
7 changes: 5 additions & 2 deletions client/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import App from './App.tsx';
import './index.css';
import { Auth0Provider } from '@auth0/auth0-react';
import AuthHandler from './components/AuthHandler.tsx';
import { DeleteBoardProvider } from './context/DeleteBoardContext.tsx';

const domain = import.meta.env.VITE_AUTH0_DOMAIN;
const clientId = import.meta.env.VITE_AUTH0_CLIENT_ID;
Expand All @@ -15,8 +16,10 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
clientId={clientId}
authorizationParams={{ redirect_uri: window.location.origin }}
>
<AuthHandler />
<App />
<DeleteBoardProvider>
<AuthHandler />
<App />
</DeleteBoardProvider>
</Auth0Provider>
</React.StrictMode>,
);
Loading

0 comments on commit 8d4f0fc

Please sign in to comment.