// [TSM.ID].[11031972] — All Rights Reserved. Proprietary & Confidential. "use client"; import { useSearchParams } from "next/navigation"; import { use, useEffect, useState } from "react"; import { XCURoom } from "../../../components/xcuRoom"; export default function RoomPage({ params, }: { params: Promise<{ roomName: string }>; }) { const resolvedParams = use(params); const roomName = resolvedParams.roomName; const searchParams = useSearchParams(); const isVoiceCall = searchParams.get("audioOnly") === "true"; const [token, setToken] = useState(""); const [serverUrl, setServerUrl] = useState(""); const [error, setError] = useState(""); const [isInitializing, setIsInitializing] = useState(true); const [username, setUsername] = useState(""); // Guest Lobby State const [showGuestLobby, setShowGuestLobby] = useState(false); const [guestName, setGuestName] = useState(""); const [guestLoading, setGuestLoading] = useState(false); const [guestError, setGuestError] = useState(""); useEffect(() => { (async () => { try { const authResp = await fetch(`/vc/api/auth/me?_cb=${Date.now()}`); const authData = await authResp.json(); if (authData.error) { // User tidak login → tampilkan Guest Lobby (seperti Zoom) setShowGuestLobby(true); setIsInitializing(false); return; } const userEmail = authData.email; setUsername(userEmail); const qResp = await fetch(`/api/auth/quantum_token?_cb=${Date.now()}`, { credentials: 'include' }); if (!qResp.ok) { throw new Error("Otorisasi JUMPA.ID Ditolak: Gagal memverifikasi Lisensi Tenant."); } const qData = await qResp.json(); if (qData.error || !qData.token) { throw new Error("Akses Ilegal Terdeteksi: Harap masuk melalui Dasbor JUMPA.ID terlebih dahulu."); } setToken(qData.token); setServerUrl(process.env.NEXT_PUBLIC_XCU_SERVER_URL || "/xcu-engine"); setIsInitializing(false); } catch (e: unknown) { // Auth failed but not critical → show guest lobby setShowGuestLobby(true); setIsInitializing(false); } })(); }, [roomName]); // Handle Guest Join const handleGuestJoin = async () => { if (!guestName.trim() || guestName.trim().length < 2) { setGuestError("Masukkan nama Anda (minimal 2 karakter)."); return; } setGuestLoading(true); setGuestError(""); try { const res = await fetch('/api/auth/guest-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ roomName, displayName: guestName.trim() }), }); const data = await res.json(); if (!res.ok || data.error) { setGuestError(data.error || "Gagal masuk sebagai tamu."); setGuestLoading(false); return; } // Guest token received — set state and enter room setToken(data.token); setUsername(data.displayName); setServerUrl(process.env.NEXT_PUBLIC_XCU_SERVER_URL || "/xcu-engine"); setShowGuestLobby(false); } catch (e) { setGuestError("Koneksi gagal. Periksa jaringan Anda."); setGuestLoading(false); } }; // ═══════════════════════════════════════ // GUEST LOBBY UI (Zoom-Like) // ═══════════════════════════════════════ if (showGuestLobby) { return (
{/* Background Animation */}
{/* Header */}

Gabung Rapat

Room: {decodeURIComponent(roomName)}

{/* Form */}
{ setGuestName(e.target.value); setGuestError(""); }} onKeyDown={(e) => e.key === 'Enter' && handleGuestJoin()} placeholder="Masukkan nama Anda..." maxLength={50} autoFocus className="w-full px-4 py-3.5 bg-white/5 border border-white/10 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-base" />
{guestError && (
{guestError}
)}

Sudah punya akun JUMPA.ID?

Masuk dengan Akun →
{/* Footer */}

Powered by JUMPA.ID • XCom ULTRA Engine • [TSM.ID].[11031972]

); } if (error) { return (

Akses Ditolak

{error}

); } if (isInitializing) { return (

Initializing JUMPA.ID Engine

ESTABLISHING SECURE CONNECTION FOR {username.toUpperCase()}...

); } // THE ABSOLUTE XCU CORE ENGINE // 100% XCU Ultra Node [TSM.ID].[11031972] return ( ); } // Custom Error Boundary to catch & display the EXACT crash reason import React from "react"; class ErrorBoundaryWrapper extends React.Component<{roomName: string, children: React.ReactNode}, {hasError: boolean, error: string}> { constructor(props: any) { super(props); this.state = { hasError: false, error: "" }; } static getDerivedStateFromError(error: Error) { return { hasError: true, error: `${error.name}: ${error.message}\n${error.stack}` }; } render() { if (this.state.hasError) { return (

XCU Engine Crash Report

{this.state.error}
); } return this.props.children; } }