Integrate LiveKit SFU and harden booking workflow
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, type FormEvent } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { TextField, FormError } from "@/components/FormField";
|
||||
import { fieldClass, TextField, FormError } from "@/components/FormField";
|
||||
|
||||
export const MEETING_SESSION_KEY = "anouma-meeting-session";
|
||||
const MEETING_CLIENT_ID_KEY = "anouma-meeting-client-id";
|
||||
@@ -28,18 +28,20 @@ function getOrCreateClientId(): string {
|
||||
|
||||
export type StoredMeetingSession = {
|
||||
token: string;
|
||||
participantToken?: string;
|
||||
serverUrl?: string;
|
||||
participantId: string;
|
||||
role: "host" | "participant";
|
||||
name: string;
|
||||
eventTitle: string;
|
||||
eventSlug: string;
|
||||
iceServers: RTCIceServer[];
|
||||
};
|
||||
|
||||
export function JoinForm({ slug }: { slug: string }) {
|
||||
const router = useRouter();
|
||||
const [name, setName] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -63,12 +65,13 @@ export function JoinForm({ slug }: { slug: string }) {
|
||||
|
||||
const session: StoredMeetingSession = {
|
||||
token: data.token,
|
||||
participantToken: data.participantToken,
|
||||
serverUrl: data.serverUrl,
|
||||
participantId: data.participantId,
|
||||
role: data.role,
|
||||
name,
|
||||
eventTitle: data.eventTitle,
|
||||
eventSlug: slug,
|
||||
iceServers: data.iceServers,
|
||||
};
|
||||
sessionStorage.setItem(MEETING_SESSION_KEY, JSON.stringify(session));
|
||||
router.push(`/termine/${slug}/call`);
|
||||
@@ -90,16 +93,31 @@ export function JoinForm({ slug }: { slug: string }) {
|
||||
placeholder="Name eingeben"
|
||||
autoComplete="name"
|
||||
/>
|
||||
<TextField
|
||||
label="Meeting-Passwort"
|
||||
id="password"
|
||||
type="text"
|
||||
required
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Passwort eingeben"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<label htmlFor="password" className="block text-sm font-medium text-anouma-plum">
|
||||
Meeting-Passwort
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
className="text-xs font-medium text-anouma-mauve-dark underline-offset-2 hover:underline"
|
||||
onClick={() => setShowPassword((visible) => !visible)}
|
||||
aria-pressed={showPassword}
|
||||
>
|
||||
{showPassword ? "Verbergen" : "Anzeigen"}
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
id="password"
|
||||
className={fieldClass}
|
||||
type={showPassword ? "text" : "password"}
|
||||
required
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Passwort eingeben"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
{error && <FormError>{error}</FormError>}
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
Reference in New Issue
Block a user