public games list functionality
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
import PublicGames from "@/components/home/PublicGames";
|
import PublicGames from "@/components/home/PublicGames/PublicGames";
|
||||||
import JoinGame from "@/components/home/JoinGame";
|
import JoinGame from "@/components/home/JoinGame";
|
||||||
import CreateGame from "@/components/home/CreateGame";
|
import CreateGame from "@/components/home/CreateGame";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="bg-base-200 flex w-full flex-wrap items-center justify-evenly gap-4 rounded-xl px-4 py-10 shadow-md lg:gap-0">
|
<div className="bg-base-200 flex w-full flex-wrap items-center justify-evenly gap-4 rounded-xl px-4 py-10 shadow-md lg:gap-0">
|
||||||
|
{/* @ts-expect-error Server Component */}
|
||||||
<PublicGames />
|
<PublicGames />
|
||||||
|
|
||||||
<div className="flex flex-col items-center gap-4">
|
<div className="flex flex-col items-center gap-4">
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import { IconRefresh } from "@tabler/icons-react";
|
|
||||||
|
|
||||||
export default function PublicGames() {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center">
|
|
||||||
<h2 className="mb-2 text-2xl font-bold leading-tight">
|
|
||||||
Public games{" "}
|
|
||||||
<div className="btn btn-sm btn-ghost">
|
|
||||||
<IconRefresh size={16} className="" />
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="bg-base-100 h-80 max-h-80 overflow-y-auto">
|
|
||||||
<table className="table-compact lg:table-normal table rounded-none">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="w-48">Host</th>
|
|
||||||
<th className="w-48">Opponent</th>
|
|
||||||
<th className="w-24"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>(empty)</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{/* <tr className="group">
|
|
||||||
<td>nize</td>
|
|
||||||
<td>nize</td>
|
|
||||||
<th>
|
|
||||||
<button className="btn btn-ghost btn-xs focus:opacity-100 lg:opacity-0 lg:group-hover:opacity-100">
|
|
||||||
Join
|
|
||||||
</button>
|
|
||||||
</th>
|
|
||||||
</tr> */}
|
|
||||||
{/* <tr className="group">
|
|
||||||
<td>WPlaceholder_Text</td>
|
|
||||||
<td>WPlaceholder_Text</td>
|
|
||||||
<th>
|
|
||||||
<button className="btn btn-ghost btn-xs focus:opacity-100 lg:opacity-0 lg:group-hover:opacity-100">
|
|
||||||
Join
|
|
||||||
</button>
|
|
||||||
</th>
|
|
||||||
</tr> */}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
27
client/src/components/home/PublicGames/JoinButton.tsx
Normal file
27
client/src/components/home/PublicGames/JoinButton.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useTransition } from "react";
|
||||||
|
|
||||||
|
export default function JoinButton({ code }: { code: string }) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, startTransition] = useTransition();
|
||||||
|
|
||||||
|
function handleJoin() {
|
||||||
|
startTransition(() => {
|
||||||
|
router.push(`/game/${code}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={
|
||||||
|
"btn btn-ghost btn-xs focus:opacity-100 lg:opacity-0 lg:group-hover:opacity-100" +
|
||||||
|
(isLoading ? " btn-disabled" : "")
|
||||||
|
}
|
||||||
|
onClick={handleJoin}
|
||||||
|
>
|
||||||
|
Join
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
client/src/components/home/PublicGames/PublicGames.tsx
Normal file
48
client/src/components/home/PublicGames/PublicGames.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { getPublicGames } from "@/lib/game";
|
||||||
|
import JoinButton from "./JoinButton";
|
||||||
|
import RefreshButton from "./RefreshButton";
|
||||||
|
|
||||||
|
export default async function PublicGames() {
|
||||||
|
const games = await getPublicGames();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<h2 className="mb-2 text-2xl font-bold leading-tight">
|
||||||
|
Public games <RefreshButton />
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className="bg-base-100 h-80 max-h-80 overflow-y-auto">
|
||||||
|
<table className="table-compact lg:table-normal table rounded-none">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="w-48">Host</th>
|
||||||
|
<th className="w-48">Opponent</th>
|
||||||
|
<th className="w-24"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{games && games.length > 0 ? (
|
||||||
|
games.map((game) => (
|
||||||
|
<tr key={game.code} className="group">
|
||||||
|
<td>{game.host?.name}</td>
|
||||||
|
<td>
|
||||||
|
{(game.host?.id === game.white?.id ? game.black?.name : game.white?.name) || ""}
|
||||||
|
</td>
|
||||||
|
<th>
|
||||||
|
<JoinButton code={game.code as string} />
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td>(empty)</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
client/src/components/home/PublicGames/RefreshButton.tsx
Normal file
25
client/src/components/home/PublicGames/RefreshButton.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { IconRefresh } from "@tabler/icons-react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useTransition } from "react";
|
||||||
|
|
||||||
|
export default function RefreshButton() {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, startTransition] = useTransition();
|
||||||
|
|
||||||
|
function handleRefresh() {
|
||||||
|
startTransition(() => {
|
||||||
|
router.refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={"btn btn-sm btn-ghost" + (isLoading ? " loading" : "")}
|
||||||
|
onClick={handleRefresh}
|
||||||
|
>
|
||||||
|
<IconRefresh size={16} />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -34,3 +34,16 @@ export const getGame = async (code: string) => {
|
|||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getPublicGames = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_URL}/v1/games`, { cache: "no-store" });
|
||||||
|
|
||||||
|
if (res && res.status === 200) {
|
||||||
|
const games: Game[] = await res.json();
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user