Skip to content

Commit

Permalink
[frontend] add room page (#40)
Browse files Browse the repository at this point in the history
Enabled to hit api related to room from frontend.
  • Loading branch information
lim396 authored Nov 12, 2023
1 parent 190db5f commit 824befd
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 0 deletions.
25 changes: 25 additions & 0 deletions frontend/app/lib/client-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,28 @@ export async function createUser(formData: FormData) {
redirect("/user", RedirectType.push);
}
}

export async function createRoom(formData: FormData) {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/room`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: formData.get("name"),
}),
});
const data = await res.json();
if (!res.ok) {
toast({
title: res.status + " " + res.statusText,
description: data.message,
});
} else {
toast({
title: "Success",
description: "Room created successfully.",
});
redirect(`/room/${data.id}`, RedirectType.push);
}
}
26 changes: 26 additions & 0 deletions frontend/app/room/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
async function getRoom(id: number) {
const res = await fetch(`${process.env.API_URL}/room/${id}`, {
cache: "no-cache",
});
const room = await res.json();
return room;
}

export default async function getRoomInfo({
params: { id },
}: {
params: { id: number };
}) {
const room = await getRoom(id);
return (
<div>
<h1>
<b>Room info</b>
</h1>
<p>
room ID: {room.id} <br />
room name: {room.name}
</p>
</div>
);
}
23 changes: 23 additions & 0 deletions frontend/app/room/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// components
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import Form from "@/app/ui/room/create-room";

export default function CreateChatRoom() {
return (
<Card className="w-[300px]">
<CardHeader>
<CardTitle>Create Account</CardTitle>
</CardHeader>
<CardContent>
<Form />
</CardContent>
</Card>
);
}
22 changes: 22 additions & 0 deletions frontend/app/room/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import RoomCard from "@/components/RoomCard";

export type Room = { id: number; name?: string };

async function getRooms(): Promise<Room[]> {
const res = await fetch(`${process.env.API_URL}/room`, {
cache: "no-cache",
});
const rooms = await res.json();
return rooms;
}

export default async function RoomListPage() {
const rooms = await getRooms();
return (
<div className="flex flex-wrap gap-8">
{rooms.map((room, index) => (
<RoomCard room={room} key={index} />
))}
</div>
);
}
1 change: 1 addition & 0 deletions frontend/app/ui/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default function Nav() {
<li className="flex gap-8 items-center">
<Link href="/">Home</Link>
<Link href="/user">User List</Link>
<Link href="/room">ChatRoom List</Link>
<Link href="/user/signup">Sign Up</Link>
<Link href="/playground/pong.html" target="_blank">
Pong
Expand Down
27 changes: 27 additions & 0 deletions frontend/app/ui/room/create-room.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use client";

import { createRoom } from "@/app/lib/client-actions";

// components
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";

export default function RoomCreateForm() {
return (
<form action={createRoom}>
<div className="grid w-full items-center gap-8">
<div className="flex flex-col space-y-1.5">
<Label htmlFor="name">Room Name</Label>
<Input
id="name"
type="text"
name="name"
placeholder="e.g. temporary room"
/>
</div>
<Button type="submit">Create</Button>
</div>
</form>
);
}
115 changes: 115 additions & 0 deletions frontend/components/RoomCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"use client";

import { useRouter } from "next/navigation";

// components
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";
import Link from "next/link";

export type Room = { id: number; name?: string };

export default function RoomCard({ room }: { room: Room }) {
const router = useRouter();
const { toast } = useToast();
async function updateRoom(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
const { id, ...updateData } = Object.fromEntries(
new FormData(event.currentTarget),
);
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/room/${room.id}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(updateData),
},
);
const data = await res.json();
if (!res.ok) {
toast({
title: res.status + " " + res.statusText,
description: data.message,
});
} else {
toast({
title: "Success",
description: "room updated successfully.",
});
router.push("/room");
router.refresh();
}
}
async function deleteRoom(event: React.SyntheticEvent) {
event.preventDefault();
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/room/${room.id}`,
{
method: "DELETE",
},
);
const data = await res.json();
if (!res.ok) {
toast({
title: res.status + " " + res.statusText,
description: data.message,
});
} else {
toast({
title: "Success",
description: "room deleted successfully.",
});
router.push("/room");
router.refresh();
}
}
return (
<>
<Card className="w-[300px]">
<CardHeader>Room ID: {room.id}</CardHeader>
<CardContent>
<form onSubmit={updateRoom} id={"UpdateRoomForm." + room.id}>
<div className="grid w-full items-center gap-4">
<div className="flex flex-col space-y-1.5">
<Label htmlFor="name">Name</Label>
<Input
id="name"
type="text"
name="name"
defaultValue={room.name}
/>
</div>
</div>
</form>
</CardContent>
<CardFooter className="flex justify-between">
<Button asChild>
<Link href={`/room/${room.id}`}>Join</Link>
</Button>
<Button type="button" onClick={deleteRoom}>
Delete
</Button>
<Button
variant="outline"
type="submit"
form={"UpdateRoomForm." + room.id}
>
Update
</Button>
</CardFooter>
</Card>
</>
);
}

0 comments on commit 824befd

Please sign in to comment.