pollo/src/app/_components/RoomList.tsx

166 lines
4.8 KiB
TypeScript
Raw Normal View History

2023-08-27 23:57:17 -06:00
"use client";
2023-04-20 04:20:00 -06:00
import Link from "next/link";
import { configureAbly, useChannel } from "@ably-labs/react-hooks";
2023-09-09 19:25:23 -06:00
import { useEffect, useState } from "react";
2023-07-11 17:22:54 -06:00
import { IoEnterOutline, IoTrashBinOutline } from "react-icons/io5";
2023-08-31 00:14:20 -06:00
import { env } from "@/env.mjs";
2023-09-06 13:00:00 -06:00
import LoadingIndicator from "./LoadingIndicator";
2023-09-06 12:53:48 -06:00
import { useUser } from "@clerk/nextjs";
2023-09-09 19:25:23 -06:00
import { createRoom, deleteRoom, getRooms } from "@/server/actions/room";
2023-09-06 12:53:48 -06:00
2023-09-06 12:57:13 -06:00
export const dynamic = "force-dynamic";
export const revalidate = 0;
export const fetchCache = "force-no-store";
2023-09-06 12:53:48 -06:00
const RoomList = () => {
2023-09-06 12:58:08 -06:00
const { user } = useUser();
2023-04-20 04:20:00 -06:00
configureAbly({
key: env.NEXT_PUBLIC_ABLY_PUBLIC_KEY,
2023-09-06 12:53:48 -06:00
clientId: user?.id,
2023-04-20 04:20:00 -06:00
recover: (_, cb) => {
cb(true);
},
});
2023-09-01 19:43:15 -06:00
useChannel(
2023-09-06 12:53:48 -06:00
`${env.NEXT_PUBLIC_APP_ENV}-${user?.id}`,
2023-09-09 19:25:23 -06:00
() => void getRoomsHandler()
2023-04-20 04:20:00 -06:00
);
const [roomName, setRoomName] = useState<string>("");
2023-09-09 19:25:23 -06:00
const [roomsFromDb, setRoomsFromDb] = useState<
| {
id: string;
createdAt: Date;
roomName: string;
}[]
| {
id: string;
created_at: Date | null;
userId: string;
roomName: string | null;
storyName: string | null;
visible: boolean;
scale: string;
}[]
| undefined
| null
>(undefined);
const createRoomHandler = async () => {
await createRoom(roomName);
2023-04-20 04:20:00 -06:00
setRoomName("");
(document.querySelector("#roomNameInput") as HTMLInputElement).value = "";
(document.querySelector("#new-room-modal") as HTMLInputElement).checked =
false;
};
2023-09-09 19:25:23 -06:00
const getRoomsHandler = async () => {
const dbRooms = await getRooms();
setRoomsFromDb(dbRooms);
};
2023-04-20 04:20:00 -06:00
2023-09-09 19:25:23 -06:00
const deleteRoomHandler = async (roomId: string) => {
await deleteRoom(roomId);
2023-04-20 04:20:00 -06:00
};
2023-09-09 19:25:23 -06:00
useEffect(() => {
void getRoomsHandler();
}, []);
2023-04-20 04:20:00 -06:00
return (
2023-06-05 16:56:28 -06:00
<div className="flex flex-col items-center justify-center gap-8">
2023-08-08 22:36:43 -06:00
{/* Modal for Adding Rooms */}
2023-04-20 04:20:00 -06:00
<input type="checkbox" id="new-room-modal" className="modal-toggle" />
<div className="modal modal-bottom sm:modal-middle">
<div className="modal-box flex-col flex text-center justify-center items-center">
<label
htmlFor="new-room-modal"
className="btn btn-sm btn-circle absolute right-2 top-2"
>
</label>
<h3 className="font-bold text-lg">Create a new room!</h3>
<div className="form-control w-full max-w-xs">
<label className="label">
<span className="label-text">Room Name</span>
</label>
<input
id="roomNameInput"
type="text"
placeholder="Type here"
className="input input-bordered w-full max-w-xs"
2023-08-08 22:36:43 -06:00
onChange={(event) => {
2023-04-20 04:20:00 -06:00
setRoomName(event.target.value);
2023-08-08 22:36:43 -06:00
}}
2023-04-20 04:20:00 -06:00
/>
</div>
<div className="modal-action">
2023-08-08 22:36:43 -06:00
{roomName.length > 0 && (
2023-04-20 04:20:00 -06:00
<label
htmlFor="new-room-modal"
className="btn btn-primary"
2023-09-09 19:25:23 -06:00
onClick={() => void createRoomHandler()}
2023-04-20 04:20:00 -06:00
>
Submit
</label>
2023-08-08 22:36:43 -06:00
)}
2023-04-20 04:20:00 -06:00
</div>
</div>
</div>
2023-08-08 22:36:43 -06:00
{roomsFromDb && roomsFromDb.length > 0 && (
2023-04-20 04:20:00 -06:00
<div className="overflow-x-auto">
<table className="table text-center">
2023-09-01 19:43:15 -06:00
{/* head */}
2023-04-20 04:20:00 -06:00
<thead>
<tr className="border-white">
2023-04-20 04:20:00 -06:00
<th>Room Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody className="">
2023-08-08 22:36:43 -06:00
{roomsFromDb?.map((room) => {
2023-04-20 04:20:00 -06:00
return (
2023-08-08 22:36:43 -06:00
<tr key={room.id} className="hover border-white">
2023-04-20 04:20:00 -06:00
<td className="break-all max-w-[200px] md:max-w-[400px]">
2023-08-08 22:36:43 -06:00
{room.roomName}
2023-04-20 04:20:00 -06:00
</td>
<td>
<Link
className="m-2 no-underline"
2023-08-08 22:36:43 -06:00
href={`/room/${room.id}`}
2023-04-20 04:20:00 -06:00
>
2023-09-01 19:43:15 -06:00
<IoEnterOutline className="text-xl inline-block hover:text-primary" />
2023-04-20 04:20:00 -06:00
</Link>
<button
className="m-2"
2023-09-09 19:25:23 -06:00
onClick={() => void deleteRoomHandler(room.id)}
2023-04-20 04:20:00 -06:00
>
<IoTrashBinOutline className="text-xl inline-block hover:text-error" />
</button>
</td>
</tr>
);
2023-08-08 22:36:43 -06:00
})}
2023-04-20 04:20:00 -06:00
</tbody>
</table>
</div>
2023-08-08 22:36:43 -06:00
)}
2023-09-01 19:43:15 -06:00
<label htmlFor="new-room-modal" className="btn btn-primary">
2023-04-20 04:20:00 -06:00
New Room
</label>
2023-09-06 13:00:00 -06:00
{roomsFromDb === undefined && <LoadingIndicator />}
2023-04-20 04:20:00 -06:00
</div>
);
};
2023-04-20 04:20:00 -06:00
export default RoomList;