Fixed room 404 issues

This commit is contained in:
Atridad Lahiji 2023-09-27 12:46:15 -06:00
parent 754e207d1e
commit 819cb03e9b
No known key found for this signature in database
2 changed files with 87 additions and 78 deletions

View file

@ -1,10 +1,18 @@
"use client";
import { EventTypes } from "@/_utils/types";
import Image from "next/image";
import { useEffect, useState } from "react";
import { EventTypes } from "@/_utils/types";
import LoadingIndicator from "@/_components/LoadingIndicator";
import type { PresenceItem, RoomResponse, VoteResponse } from "@/_utils/types";
import { useUser } from "@clerk/nextjs";
import { useChannel, usePresence } from "ably/react";
import { isAdmin, isVIP, jsonToCsv } from "app/_utils/helpers";
import { env } from "env.mjs";
import { useParams } from "next/navigation";
import { FaShieldAlt } from "react-icons/fa";
import { GiStarFormation } from "react-icons/gi";
import {
IoCheckmarkCircleOutline,
IoCopyOutline,
@ -15,15 +23,7 @@ import {
IoReloadOutline,
IoSaveOutline,
} from "react-icons/io5";
import { GiStarFormation } from "react-icons/gi";
import { FaShieldAlt } from "react-icons/fa";
import { RiVipCrownFill } from "react-icons/ri";
import { env } from "env.mjs";
import { isAdmin, isVIP, jsonToCsv } from "app/_utils/helpers";
import type { PresenceItem, RoomResponse, VoteResponse } from "@/_utils/types";
import LoadingIndicator from "@/_components/LoadingIndicator";
import { useUser } from "@clerk/nextjs";
import { useChannel, usePresence } from "ably/react";
import NoRoomUI from "./NoRoomUI";
const VoteUI = () => {
@ -40,12 +40,15 @@ const VoteUI = () => {
const [votesFromDb, setVotesFromDb] = useState<VoteResponse>(undefined);
const getRoomHandler = async () => {
const dbRoomResponse = await fetch(`/api/internal/room/${roomId}`, {
fetch(`/api/internal/room/${roomId}`, {
cache: "no-cache",
method: "GET",
}).then(async (response) => {
const dbRoom = (await response.json()) as RoomResponse;
setRoomFromDb(dbRoom);
}).catch(() => {
setRoomFromDb(null);
});
const dbRoom = (await dbRoomResponse.json()) as RoomResponse;
setRoomFromDb(dbRoom);
};
const getVotesHandler = async () => {
@ -196,7 +199,7 @@ const VoteUI = () => {
if (visible) {
if (!!matchedVote) {
return <div>{matchedVote.value}</div>;
return <div>{ matchedVote.value }</div>;
} else {
return <IoHourglassOutline className="text-xl text-error" />;
}
@ -216,30 +219,30 @@ const VoteUI = () => {
} else if (roomFromDb) {
return (
<div className="flex flex-col gap-4 text-center justify-center items-center">
<div className="text-2xl">{roomFromDb.roomName}</div>
<div className="text-2xl">{ roomFromDb.roomName }</div>
<div className="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-md">
<div>ID:</div>
<div>{roomFromDb.id}</div>
<div>{ roomFromDb.id }</div>
<button>
{copied ? (
{ copied ? (
<IoCheckmarkCircleOutline className="mx-1 text-success animate-bounce" />
) : (
<IoCopyOutline
className="mx-1 hover:text-primary"
onClick={copyRoomURLHandler}
onClick={ copyRoomURLHandler }
></IoCopyOutline>
)}
) }
</button>
</div>
{roomFromDb && (
{ roomFromDb && (
<div className="card card-compact bg-base-100 shadow-xl">
<div className="card-body">
<h2 className="card-title">Story: {roomFromDb.storyName}</h2>
<h2 className="card-title">Story: { roomFromDb.storyName }</h2>
<ul className="p-0 flex flex-row flex-wrap justify-center items-center text-ceter gap-4">
{presenceData &&
{ presenceData &&
presenceData
.filter(
(value, index, self) =>
@ -252,81 +255,80 @@ const VoteUI = () => {
.map((presenceItem) => {
return (
<li
key={presenceItem.clientId}
key={ presenceItem.clientId }
className="flex flex-row items-center justify-center gap-2"
>
<div className="w-10 rounded-full avatar">
<Image
src={presenceItem.data.image}
alt={`${presenceItem.data.name}'s Profile Picture`}
height={32}
width={32}
src={ presenceItem.data.image }
alt={ `${presenceItem.data.name}'s Profile Picture` }
height={ 32 }
width={ 32 }
/>
</div>
<p className="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-md">
{presenceItem.data.name}{" "}
{presenceItem.data.isAdmin && (
{ presenceItem.data.name }{ " " }
{ presenceItem.data.isAdmin && (
<span
className="tooltip tooltip-primary"
data-tip="Admin"
>
<FaShieldAlt className="inline-block text-primary" />
</span>
)}{" "}
{presenceItem.data.isVIP && (
) }{ " " }
{ presenceItem.data.isVIP && (
<span
className="tooltip tooltip-secondary"
data-tip="VIP"
>
<GiStarFormation className="inline-block text-secondary" />
</span>
)}{" "}
{presenceItem.clientId === roomFromDb.userId && (
) }{ " " }
{ presenceItem.clientId === roomFromDb.userId && (
<span
className="tooltip tooltip-warning"
data-tip="Room Owner"
>
<RiVipCrownFill className="inline-block text-yellow-500" />
</span>
)}
{" : "}
) }
{ " : " }
</p>
{roomFromDb &&
{ roomFromDb &&
votesFromDb &&
voteString(
roomFromDb.visible,
votesFromDb,
presenceItem.data
)}
) }
</li>
);
})}
}) }
</ul>
<div className="join md:btn-group-horizontal">
{roomFromDb.scale?.split(",").map((scaleItem, index) => {
{ roomFromDb.scale?.split(",").map((scaleItem, index) => {
return (
<button
key={index}
className={`join-item ${
getVoteForCurrentUser()?.value === scaleItem
? "btn btn-active btn-primary"
: "btn"
}`}
onClick={() => void setVoteHandler(scaleItem)}
key={ index }
className={ `join-item ${getVoteForCurrentUser()?.value === scaleItem
? "btn btn-active btn-primary"
: "btn"
}` }
onClick={ () => void setVoteHandler(scaleItem) }
>
{scaleItem}
{ scaleItem }
</button>
);
})}
}) }
</div>
</div>
</div>
)}
) }
{!!roomFromDb &&
{ !!roomFromDb &&
(roomFromDb.userId === user?.id || isAdmin(user?.publicMetadata)) && (
<>
<div className="card card-compact bg-base-100 shadow-xl">
@ -334,40 +336,40 @@ const VoteUI = () => {
<h2 className="card-title">Room Settings</h2>
<label className="label">
{"Vote Scale (Comma Separated):"}{" "}
{ "Vote Scale (Comma Separated):" }{ " " }
</label>
<input
type="text"
placeholder="Scale (Comma Separated)"
className="input input-bordered"
value={roomScale}
onChange={(event) => {
value={ roomScale }
onChange={ (event) => {
setRoomScale(event.target.value);
}}
} }
/>
<label className="label">{"Story Name:"} </label>
<label className="label">{ "Story Name:" } </label>
<input
type="text"
placeholder="Story Name"
className="input input-bordered"
value={storyNameText}
onChange={(event) => {
value={ storyNameText }
onChange={ (event) => {
setStoryNameText(event.target.value);
}}
} }
/>
<div className="flex flex-row flex-wrap text-center items-center justify-center gap-2">
<div>
<button
onClick={() =>
onClick={ () =>
void setRoomHandler(!roomFromDb.visible, false)
}
className="btn btn-primary inline-flex"
>
{roomFromDb.visible ? (
{ roomFromDb.visible ? (
<>
<IoEyeOffOutline className="text-xl mr-1" />
Hide
@ -377,13 +379,13 @@ const VoteUI = () => {
<IoEyeOutline className="text-xl mr-1" />
Show
</>
)}
) }
</button>
</div>
<div>
<button
onClick={() =>
onClick={ () =>
void setRoomHandler(
false,
true,
@ -400,8 +402,8 @@ const VoteUI = () => {
).length <= 1
}
>
{roomFromDb.storyName === storyNameText ||
votesFromDb?.length === 0 ? (
{ roomFromDb.storyName === storyNameText ||
votesFromDb?.length === 0 ? (
<>
<IoReloadOutline className="text-xl mr-1" /> Reset
</>
@ -409,16 +411,16 @@ const VoteUI = () => {
<>
<IoSaveOutline className="text-xl mr-1" /> Save
</>
)}
) }
</button>
</div>
{votesFromDb &&
{ votesFromDb &&
(roomFromDb.logs.length > 0 ||
votesFromDb.length > 0) && (
<div>
<button
onClick={() => downloadLogs()}
onClick={ () => downloadLogs() }
className="btn btn-primary inline-flex hover:animate-pulse"
>
<>
@ -426,12 +428,12 @@ const VoteUI = () => {
</>
</button>
</div>
)}
) }
</div>
</div>
</div>
</>
)}
) }
</div>
);
// Room does not exist

View file

@ -1,13 +1,13 @@
import { type NextRequest, NextResponse } from "next/server";
import { NextResponse, type NextRequest } from "next/server";
import { db } from "@/_lib/db";
import { logs, rooms, votes } from "@/_lib/schema";
import { eq } from "drizzle-orm";
import { publishToChannel } from "@/_lib/ably";
import { EventTypes } from "@/_utils/types";
import { db } from "@/_lib/db";
import { invalidateCache } from "@/_lib/redis";
import { createId } from "@paralleldrive/cuid2";
import { logs, rooms, votes } from "@/_lib/schema";
import { EventTypes } from "@/_utils/types";
import { getAuth } from "@clerk/nextjs/server";
import { createId } from "@paralleldrive/cuid2";
import { eq } from "drizzle-orm";
export const runtime = "edge";
export const preferredRegion = ["pdx1"];
@ -30,10 +30,17 @@ export async function GET(
},
});
return NextResponse.json(roomFromDb, {
status: 200,
statusText: "SUCCESS",
});
if (roomFromDb) {
return NextResponse.json(roomFromDb, {
status: 200,
statusText: "SUCCESS",
});
} else {
return new NextResponse("ROOM NOT FOUND", {
status: 404,
statusText: "ROOM NOT FOUND",
});
}
}
export async function DELETE(