diff --git a/apps/frontend/src/app/zone/layout.tsx b/apps/frontend/src/app/zone/layout.tsx
index 891681c..814ff1c 100644
--- a/apps/frontend/src/app/zone/layout.tsx
+++ b/apps/frontend/src/app/zone/layout.tsx
@@ -5,6 +5,7 @@ import ZoneSidebar from './_components/ZoneSidebar'
import { RealtimeProvider } from '../providers/realtime-provider'
import { redirect } from 'next/navigation'
import ZonesList from './_components/zones/ZonesList'
+import { MobileNav } from './_components/MobileNav'
export default async function ZoneLayout({
children,
@@ -16,21 +17,19 @@ export default async function ZoneLayout({
if (!user) {
redirect('/auth')
}
-
return (
-
-
+
+
-
-
- {children}
-
-
+
+
+
+ {children}
+
-
+
)
}
diff --git a/apps/frontend/src/app/zone/page.tsx b/apps/frontend/src/app/zone/page.tsx
index 08568d7..cb3a5e2 100644
--- a/apps/frontend/src/app/zone/page.tsx
+++ b/apps/frontend/src/app/zone/page.tsx
@@ -22,7 +22,7 @@ export default function ZoneHome() {
useEffect(() => {
let mounted = true
- api('/auth/me')
+ api(`/auth/me?t=${Date.now()}`)
.then(res => res.json())
.then(data => {
if (!mounted) return
diff --git a/apps/frontend/src/app/zone/zones/[zonePublicId]/channels/[channelPublicId]/page.tsx b/apps/frontend/src/app/zone/zones/[zonePublicId]/channels/[channelPublicId]/page.tsx
new file mode 100644
index 0000000..c914a86
--- /dev/null
+++ b/apps/frontend/src/app/zone/zones/[zonePublicId]/channels/[channelPublicId]/page.tsx
@@ -0,0 +1,363 @@
+'use client'
+
+import { useState, useEffect, useRef, useCallback } from "react"
+import { useParams } from "next/navigation"
+import { Avatar, AvatarFallback, AvatarImage, Button, Input } from "packages/ui"
+import { Info, Paperclip, Send, Hash, Plus } from "lucide-react"
+import { api, socket, getAvatarUrl, cn } from "@openchat/lib"
+import { useChatsStore } from "@/app/stores/chat-store"
+import { ChatHeader } from "../../../../_components/zones/ChatHeader"
+
+type Message = {
+ id: number
+ text: string | null
+ senderId: number
+ sender?: {
+ id: number
+ username: string
+ avatar?: string | null
+ }
+ fileUrl?: string
+ fileType?: string
+ isDeleted?: boolean
+}
+
+type Zone = {
+ publicId: string
+ name: string
+ avatar: string | null
+}
+
+type Member = {
+ id: number
+ username: string
+ avatar?: string | null
+ role: "OWNER" | "ADMIN" | "MEMBER"
+}
+
+type Channel = {
+ publicId: string
+ name: string
+ type: "TEXT" | "VOICE"
+}
+
+export default function ChannelPage() {
+ const { zonePublicId, channelPublicId } = useParams<{ zonePublicId: string; channelPublicId: string }>()
+ const [zone, setZone] = useState
(null)
+ const [channel, setChannel] = useState(null)
+ const [messages, setMessages] = useState([])
+ const [members, setMembers] = useState([])
+ const [user, setUser] = useState(null)
+ const [currentUserId, setCurrentUserId] = useState(null)
+ const [input, setInput] = useState("")
+ const [selectedFile, setSelectedFile] = useState(null)
+ const [previewUrl, setPreviewUrl] = useState(null)
+
+ const messagesRef = useRef(null)
+ const fileInputRef = useRef(null)
+ const userCache = useRef