Skip to content

Commit 7cb0e3e

Browse files
committed
state: add zustand for state management
1 parent 342a382 commit 7cb0e3e

9 files changed

Lines changed: 93 additions & 18 deletions

File tree

package-lock.json

Lines changed: 33 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"next": "16.0.8",
2525
"react": "19.2.1",
2626
"react-dom": "19.2.1",
27-
"zod": "^4.1.13"
27+
"zod": "^4.1.13",
28+
"zustand": "^5.0.9"
2829
},
2930
"devDependencies": {
3031
"@tailwindcss/postcss": "^4",

src/app/room/[roomId]/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { useRoomStore } from "@/app/store/roomStore";
34
import { RoomHeader } from "@/components/room/roomHeader";
45
import { RoomInput } from "@/components/room/roomInput";
56
import { RoomMessages } from "@/components/room/roomMessages";
@@ -8,10 +9,12 @@ import { useParams } from "next/navigation";
89
const Page = () => {
910
const params = useParams();
1011
const roomId = params.roomId as string;
12+
const setRoomId = useRoomStore((state) => state.setRoomId);
1113

14+
setRoomId(roomId);
1215
return (
1316
<main className="flex h-screen max-h-screen flex-col overflow-hidden">
14-
<RoomHeader roomId={roomId} />
17+
<RoomHeader />
1518
<RoomMessages />
1619
<RoomInput />
1720
</main>

src/app/store/roomStore.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { create } from "zustand";
2+
import { persist } from "zustand/middleware";
3+
4+
interface RoomStore {
5+
roomId: string;
6+
setRoomId: (roomId: string) => void;
7+
}
8+
9+
export const useRoomStore = create<RoomStore>()(
10+
persist(
11+
(set) => ({
12+
roomId: "",
13+
setRoomId: (roomId: string) => set({ roomId }),
14+
}),
15+
{ name: "room-store" },
16+
),
17+
);

src/components/createRoom.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"use client";
22

33
import { useCreateRoom } from "@/hooks/useCreateRoom";
4-
import { useUsername } from "@/hooks/useGetUsername";
4+
import { useGetUsername } from "@/hooks/useGetUsername";
55
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
66

77
export const CreateRoom = ({ router }: { router: AppRouterInstance }) => {
8-
const { username } = useUsername();
8+
const { username } = useGetUsername();
99
const { createRoom } = useCreateRoom(router);
1010

1111
return (

src/components/room/roomHeader.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1+
import { useRoomStore } from "@/app/store/roomStore";
12
import { useState } from "react";
23

3-
interface RoomHeaderProps {
4-
roomId: string;
5-
}
6-
74
const formatTimeRemaining = (seconds: number) => {
85
const mins = Math.floor(seconds / 60);
96
const secs = seconds % 60;
107
return `${mins}:${secs.toString().padStart(2, "0")}`;
118
};
129

13-
export const RoomHeader = ({ roomId }: RoomHeaderProps) => {
10+
export const RoomHeader = () => {
1411
const [timeRemaining, setTimeRemaining] = useState<number>(23);
1512
const [copyStatus, setCopyStatus] = useState<"copy" | "copied">("copy");
13+
const roomId = useRoomStore((state) => state.roomId);
1614

1715
const copyLink = () => {
1816
navigator.clipboard.writeText(`${window.location.origin}/room/${roomId}`);

src/components/room/roomInput.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { useRef, useState } from "react";
2+
import { useSendMessage } from "@/hooks/useSendMessage";
3+
import { useRoomStore } from "@/app/store/roomStore";
4+
import { useGetUsername } from "@/hooks/useGetUsername";
25

36
export const RoomInput = () => {
7+
const { sendMessage, isPending } = useSendMessage();
48
const [input, setInput] = useState("");
59
const inputRef = useRef<HTMLInputElement>(null);
10+
const roomId = useRoomStore((state) => state.roomId);
11+
const { username } = useGetUsername();
612

7-
const sendMessage = (message: { text: string }) => {
8-
// TODO: Implement send message
9-
};
1013
return (
1114
<div className="border-t border-zinc-800 bg-zinc-900/30 p-4">
1215
<div className="flex gap-4">
@@ -20,7 +23,7 @@ export const RoomInput = () => {
2023
value={input}
2124
onKeyDown={(e) => {
2225
if (e.key === "Enter" && input.trim()) {
23-
sendMessage({ text: input });
26+
sendMessage({ text: input, roomId, username });
2427
inputRef.current?.focus();
2528
}
2629
}}
@@ -32,7 +35,7 @@ export const RoomInput = () => {
3235

3336
<button
3437
onClick={() => {
35-
sendMessage({ text: input });
38+
sendMessage({ text: input, roomId, username });
3639
inputRef.current?.focus();
3740
}}
3841
disabled={!input.trim()}

src/hooks/useGetUsername.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const generateUsername = () => {
6060
return `anonymous-${animal}-${id}`;
6161
};
6262

63-
export const useUsername = () => {
63+
export const useGetUsername = () => {
6464
const [username, setUsername] = useState("");
6565

6666
useEffect(() => {

src/hooks/useSendMessage.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { client } from "@/lib/client";
2+
import { useMutation } from "@tanstack/react-query";
3+
4+
export const useSendMessage = () => {
5+
const { mutate: sendMessage, isPending } = useMutation({
6+
mutationFn: async ({
7+
text,
8+
roomId,
9+
username,
10+
}: {
11+
text: string;
12+
roomId: string;
13+
username: string;
14+
}) => {
15+
await client.messages.post(
16+
{ sender: username, text },
17+
{ query: { roomId } },
18+
);
19+
},
20+
});
21+
22+
return { sendMessage, isPending };
23+
};

0 commit comments

Comments
 (0)