added delete board delete column fuctionality and so on

This commit is contained in:
Juthatip McDevitt 2024-03-27 14:42:00 -05:00
parent 69b5b0376a
commit 1619a7ff7b
8 changed files with 163 additions and 15 deletions

View file

@ -36,3 +36,21 @@ export async function addEmailtoBoard(boardId: string, email: string){
await liveblocksClient.updateRoom(boardId, {usersAccesses});
return true;
}
export async function updateBoard(boardId:string, updateData:any){
const result = await liveblocksClient.updateRoom(boardId, updateData);
return true;
}
export async function removeEmailFromBoard(boardId:string, email:string){
const room = await liveblocksClient.getRoom(boardId);
const usersAccesses:any = room.usersAccesses;
usersAccesses[email] = null
await liveblocksClient.updateRoom(boardId, {usersAccesses});
return true;
}
export async function deleteBoard(boardId:string){
await liveblocksClient.deleteRoom(boardId)
return true
}

View file

@ -28,7 +28,7 @@ const BoardPage = async (props: PageProps) => {
return (
<div>
<Board name={boardInfo.metadata.boardName} id={boardId}/>
<Board name={boardInfo.metadata.boardName.toString()} id={boardId}/>
</div>
)
}

View file

@ -1,4 +1,6 @@
"use server"
import BoardDelete from "@/components/BoardDelete";
import EmailAccessList from "@/components/EmailAccessList";
import NewUserAccess from "@/components/forms/NewUserAccess";
import { liveblocksClient } from "@/lib/liveblocksClient";
import { getUserEmail } from "@/lib/userClient";
@ -23,14 +25,13 @@ const page = async ({params}: PageProps) => {
return (
<div>
<div className="flex justify-between">
<Link href={`/boards/${boardId}`} className="flex items-center gap-1 text-[#164863] font-semibold hover:text-[#427D9D] hover:duration-300"><ImBackward2/>Go back</Link>
<h1 className="text-2xl">Access to {boardInfo.metadata.boardName}:</h1>
<div className="mb-6">
{Object.keys(boardInfo.usersAccesses).map(email => (
<div>
{email}
<BoardDelete boardId={boardId}/>
</div>
))}
<h1 className="text-2xl mb-2">Access to {boardInfo.metadata.boardName}:</h1>
<div className="mb-6">
<EmailAccessList boardId={boardId} usersAccesses={boardInfo.usersAccesses}/>
</div>
<NewUserAccess boardId = {boardId}/>
</div>

View file

@ -5,9 +5,29 @@ import { ClientSideSuspense } from '@liveblocks/react';
import Columns from './Columns';
import Link from 'next/link';
import { IoMdSettings } from "react-icons/io";
import { FormEvent, useState } from 'react';
import { updateBoard } from '@/app/actions/boardActions';
import { useRouter } from 'next/navigation';
const Board = ({id, name}: {id:string, name:string}) => {
const [renameBoard, setRenameBoard] = useState(false);
const router = useRouter();
async function handleRenameSubmit(ev:FormEvent){
ev.preventDefault();
const input = (ev.target as HTMLFormElement).querySelector('input');
if(input){
const newBoardName = input?.value;
await updateBoard(id, {metadata: {boardName: newBoardName}});
input.value = '';
setRenameBoard(false);
router.refresh();
}
}
const Board = ({id, name}: {id: string, name: string}) => {
return (
<RoomProvider id={id} initialPresence={{}} initialStorage={
@ -19,7 +39,14 @@ const Board = ({id, name}: {id: string, name: string}) => {
<>
<div className='flex justify-between gap-2 items-center mb-4'>
<div>
<h1 className='text-2xl'>Board: {name}</h1>
{!renameBoard && (
<h1 onClick={() => setRenameBoard(true)} className='text-2xl'>Board: {name}</h1>
)}
{renameBoard && (
<form onSubmit={handleRenameSubmit}>
<input type="text" defaultValue={name} className='border p-2'/>
</form>
)}
</div>
<Link href={`/boards/${id}/settings`} className='flex items-center gap-1 bg-[#427D9D] p-2 rounded-full'>
<IoMdSettings className='text-white text-[18px]'/>

View file

@ -0,0 +1,23 @@
"use client"
import { deleteBoard } from "@/app/actions/boardActions"
import { useRouter } from "next/navigation";
const BoardDelete = ({boardId}:{boardId:string}) => {
const router = useRouter();
async function handleDeleteBoard(){
await deleteBoard(boardId);
router.push('/');
}
return (
<div>
<button onClick={() => handleDeleteBoard()} className="bg-[tomato] p-2 text-white rounded-md font-semibold hover:opacity-90">Delete board</button>
</div>
)
}
export default BoardDelete

View file

@ -2,6 +2,8 @@ import { Card, useMutation, useStorage } from '@/app/liveblocks.config';
import { shallow } from '@liveblocks/client';
import { ReactSortable } from 'react-sortablejs';
import NewCardForm from './forms/NewCardForm';
import { FormEvent, useState } from 'react';
import { BsThreeDots } from "react-icons/bs";
type ColumnProps = {
@ -35,13 +37,48 @@ const Column = ({id, name}: ColumnProps) => {
})
})
},[])
}, []);
const updateColumn = useMutation(({storage}, id, newName) => {
const columns = storage.get('columns');
columns.find(c => c.toObject().id === id)?.set('name', newName)
}, []);
const [renameColumn, setRenameColumn] = useState(false);
function handleRenameColumn(ev: FormEvent){
ev.preventDefault();
const input = (ev.target as HTMLFormElement).querySelector('input')
if(input){
const newColumnName = input.value;
updateColumn(id, newColumnName)
setRenameColumn(false);
}
}
return (
<div className='w-50 shadow-md rounded-md p-2 bg-gray-100'>
{!renameColumn && (
<div className='flex justify-between'>
<h3>{name}</h3>
{columnCards && (
<button onClick={() => setRenameColumn(true)}><BsThreeDots className='text-[#164863]'/></button>
</div>
)}
{renameColumn && (
<div className='mb-8'>
Edit name:
<form onSubmit={handleRenameColumn} className='mb-2'>
<input type="text" defaultValue={name} className='border p-2 w-full'/>
<button type="submit" className='w-full mt-2'>Save</button>
</form>
<button className='w-full p-2 bg-[tomato] text-white rounded-md font-semibold text-sm'> Delete column</button>
<button onClick={() => setRenameColumn(false)} className='w-full mt-4 text-xs uppercase font-bold text-gray-500 tracking-wider'>Cancel</button>
</div>
)}
{!renameColumn && columnCards && (
<>
<ReactSortable list={columnCards} setList={items => setTasksOrderForColumn(items, id)} group="cards" ghostClass='opacity-40' className='min-h-12'>
{columnCards.map(card => (
@ -52,7 +89,10 @@ const Column = ({id, name}: ColumnProps) => {
</ReactSortable>
</>
)}
{!renameColumn && (
<NewCardForm columnId={id}/>
)}
</div>
)

View file

@ -0,0 +1,33 @@
"use client"
import { deleteBoard, removeEmailFromBoard } from "@/app/actions/boardActions";
import { RoomAccesses } from "@liveblocks/node";
import { useRouter } from "next/navigation";
import { IoTrashOutline } from "react-icons/io5";
const EmailAccessList = ({boardId, usersAccesses} : {boardId:string ,usersAccesses:RoomAccesses}) => {
const router = useRouter();
async function handleDelete(emailToDelete: string){
await removeEmailFromBoard(boardId, emailToDelete)
router.refresh();
}
return (
<div className="max-w-xs">
{Object.keys(usersAccesses).map(email => (
<div key={email} className="flex gap-2 my-2 items-center max-w-xs justify-between border pl-2">
{email}
<button onClick={() => handleDelete(email)} className="p-2 bg-gray-100">
<IoTrashOutline className="text-[tomato] text-lg"/>
</button>
</div>
))}
</div>
)
}
export default EmailAccessList

View file

@ -3,3 +3,9 @@ import { Liveblocks } from "@liveblocks/node";
export const liveblocksClient = new Liveblocks({
secret: process.env.LIVEBLOCKS_SECRET_KEY || '',
});
export function getLiveblocksClient(){
return new Liveblocks({
secret: process.env.LIVEBLOCKS_SECRET_KEY || '',
});
}