Files
ladill-meet/resources/views/meet/room/show.blade.php
T
isaaccladandCursor eed5853c2f
Deploy Ladill Meet / deploy (push) Successful in 1m16s
Add share meeting link control to the live room UI.
Expose join URL and passcode in the room shell with header and toolbar share buttons, native share on supported devices, and a copy-link popover.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 08:00:22 +00:00

243 lines
22 KiB
PHP

<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ $room->title }} · Ladill Meet</title>
@include('partials.favicon')
@vite(['resources/css/app.css', 'resources/js/meet-room.js'])
</head>
<body class="h-full overflow-hidden bg-slate-950 font-sans text-white" x-data="meetRoom()" x-init="init()">
<div id="meet-config"
data-token="{{ $mediaToken }}"
data-url="{{ $mediaUrl }}"
data-configured="{{ $mediaConfigured ? '1' : '0' }}"
data-participant="{{ $participant->uuid }}"
data-display-name="{{ $participant->display_name }}"
data-is-host="{{ $participant->isHost() ? '1' : '0' }}"
data-poll-url="{{ route('meet.room.poll', $session) }}"
data-chat-url="{{ route('meet.room.chat', $session) }}"
data-reaction-url="{{ route('meet.room.reaction', $session) }}"
data-raise-hand-url="{{ route('meet.room.raise-hand', $session) }}"
data-leave-url="{{ route('meet.room.leave', $session) }}"
data-end-url="{{ route('meet.room.end', $session) }}"
data-recording-start-url="{{ route('meet.room.recording.start', $session) }}"
data-recording-stop-url="{{ route('meet.room.recording.stop', $session) }}"
data-lock-url="{{ route('meet.room.lock', $session) }}"
data-unlock-url="{{ route('meet.room.unlock', $session) }}"
data-caption-url="{{ route('meet.room.caption', $session) }}"
data-live-captions="{{ $room->setting('live_captions') ? '1' : '0' }}"
data-watermark="{{ $watermark ? '1' : '0' }}"
data-locked="{{ $session->is_locked ? '1' : '0' }}"
data-recording-active="{{ $activeRecording ? '1' : '0' }}"
data-is-webinar="{{ ($isWebinar ?? false) ? '1' : '0' }}"
data-can-publish="{{ ($canPublish ?? true) ? '1' : '0' }}"
data-qa-url="{{ route('meet.room.qa.submit', $session) }}"
data-polls-create-url="{{ route('meet.room.polls.create', $session) }}"
data-breakouts-create-url="{{ route('meet.room.breakouts.create', $session) }}"
data-breakouts-close-url="{{ route('meet.room.breakouts.close', $session) }}"
data-breakouts-broadcast-url="{{ route('meet.room.breakouts.broadcast', $session) }}"
data-files-upload-url="{{ route('meet.room.files.upload', $session) }}"
data-whiteboard-url="{{ route('meet.room.whiteboard.show', $session) }}"
data-whiteboard-save-url="{{ route('meet.room.whiteboard.save', $session) }}"
data-join-url="{{ $room->joinUrl() }}"
data-room-title="{{ $room->title }}"
data-passcode="{{ $room->passcode ?? '' }}"
data-csrf="{{ csrf_token() }}"
hidden></div>
@if (! $mediaConfigured)
<div class="absolute inset-x-0 top-0 z-50 bg-amber-500 px-4 py-2 text-center text-sm font-medium text-amber-950">
LiveKit is not configured. Set LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET in .env for video.
</div>
@endif
<div class="relative flex h-full flex-col">
<header class="flex shrink-0 items-center justify-between border-b border-slate-800 px-4 py-3">
<div>
<h1 class="text-sm font-semibold">{{ $room->title }}</h1>
<p class="text-xs text-slate-400" x-text="connectionStatus"></p>
</div>
<div class="flex items-center gap-2 text-xs text-slate-400">
<button @click="openShare()" type="button"
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-900 px-2.5 py-1.5 text-xs font-medium text-slate-200 transition-colors hover:bg-slate-800"
title="Share meeting link">
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.935-2.186 2.25 2.25 0 0 0-3.935 2.186Z"/></svg>
Share
</button>
<span x-show="isRecording" class="rounded bg-red-600 px-2 py-0.5 font-medium text-white">REC</span>
<span x-show="isLocked" class="rounded bg-amber-600 px-2 py-0.5 font-medium text-white">Locked</span>
<span x-text="participants.length + ' participants'"></span>
</div>
</header>
<div x-show="shareOpen" x-cloak @click.outside="shareOpen = false"
class="absolute right-4 top-14 z-50 w-80 rounded-xl border border-slate-700 bg-slate-900 p-4 shadow-xl">
<div class="flex items-start justify-between gap-2">
<div>
<p class="text-sm font-medium text-white">Invite others</p>
<p class="mt-0.5 text-xs text-slate-400">Share this link so people can join the meeting.</p>
</div>
<button @click="shareOpen = false" type="button" class="rounded p-1 text-slate-400 hover:bg-slate-800 hover:text-white" title="Close">
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
</button>
</div>
<div class="mt-3 flex gap-2">
<input type="text" readonly :value="joinUrl"
class="min-w-0 flex-1 rounded-lg border-slate-700 bg-slate-950 px-3 py-2 text-xs text-slate-200">
<button @click="copyJoinLink()" type="button"
class="shrink-0 rounded-lg bg-indigo-600 px-3 py-2 text-xs font-medium text-white hover:bg-indigo-500"
x-text="shareCopied ? 'Copied' : 'Copy'"></button>
</div>
<p x-show="passcode" class="mt-3 text-xs text-slate-400">
Passcode: <span class="font-mono font-medium text-slate-200" x-text="passcode"></span>
</p>
</div>
<div class="flex min-h-0 flex-1">
<main class="relative min-w-0 flex-1 p-4">
<div id="video-grid" class="grid h-full gap-2 sm:grid-cols-2 lg:grid-cols-3"></div>
<div id="screen-share" class="absolute inset-4 hidden rounded-xl bg-black"></div>
<div x-show="watermark" class="pointer-events-none absolute right-6 top-6 rounded bg-black/40 px-3 py-1 text-xs text-white/80" x-text="displayName"></div>
<div x-show="liveCaptions && captionText" class="pointer-events-none absolute inset-x-0 bottom-20 flex justify-center px-4">
<p class="max-w-2xl rounded-lg bg-black/70 px-4 py-2 text-center text-sm text-white" x-text="captionText"></p>
</div>
<div class="pointer-events-none absolute inset-x-0 bottom-4 flex justify-center gap-2">
<template x-for="reaction in floatingReactions" :key="reaction.id">
<span class="flex h-10 w-10 animate-bounce items-center justify-center rounded-full bg-slate-800/90 text-sky-300 ring-1 ring-white/20">
<svg x-show="reaction.kind === 'thumbs'" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6.633 10.25c.806 0 1.533-.278 2.118-.764.585-.486.96-1.15 1.05-1.875.09-.725-.03-1.46-.34-2.115-.31-.655-.8-1.2-1.41-1.56-.61-.36-1.31-.52-2.02-.46-.71.06-1.38.36-1.92.86-.54.5-.92 1.18-1.08 1.92h-.01A4.5 4.5 0 0 0 2.25 12c0 1.59.83 2.99 2.08 3.79.63.4 1.35.61 2.08.61h8.34c.98 0 1.93-.32 2.71-.91.78-.59 1.32-1.42 1.52-2.34l1.14-5.7c.1-.5-.02-1.02-.33-1.42-.31-.4-.78-.63-1.28-.63H9.75"/></svg>
<svg x-show="reaction.kind === 'heart'" class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"><path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z"/></svg>
</span>
</template>
</div>
</main>
<aside class="hidden w-80 shrink-0 flex-col border-l border-slate-800 lg:flex" :class="{ '!flex': chatOpen }">
<div class="border-b border-slate-800 px-4 py-3 text-sm font-medium">Chat</div>
<div class="flex-1 space-y-3 overflow-y-auto p-4" id="chat-messages">
@foreach ($messages as $message)
<div class="text-sm">
<span class="font-medium text-sky-400">{{ $message->sender_name }}</span>
<span class="text-slate-400">{{ $message->created_at->format('g:i A') }}</span>
<p class="mt-0.5 text-slate-200">{{ $message->body }}</p>
</div>
@endforeach
</div>
<form @submit.prevent="sendChat" class="border-t border-slate-800 p-3">
<div class="flex gap-2">
<input type="text" x-model="chatInput" placeholder="Message everyone…"
class="flex-1 rounded-lg border-slate-700 bg-slate-900 px-3 py-2 text-sm text-white">
<button type="submit" class="rounded-lg bg-indigo-600 px-3 py-2 text-sm font-medium hover:bg-indigo-500">Send</button>
</div>
</form>
</aside>
</div>
<footer class="shrink-0 border-t border-slate-800 px-4 py-4">
<div class="mx-auto flex max-w-4xl flex-wrap items-center justify-center gap-2 sm:gap-3">
<button @click="toggleMute()" type="button"
class="rounded-full p-3 transition-colors"
:class="isMuted ? 'bg-red-600 hover:bg-red-500' : 'bg-slate-700 hover:bg-slate-600'"
:title="isMuted ? 'Unmute' : 'Mute'">
<svg x-show="!isMuted" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 0 1 6 0v8.25a3 3 0 0 1-3 3Z"/></svg>
<svg x-show="isMuted" x-cloak class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 0 1 6 0v8.25a3 3 0 0 1-3 3Z"/><path stroke-linecap="round" stroke-linejoin="round" d="m3 3 18 18"/></svg>
</button>
<button @click="toggleVideo()" type="button"
class="rounded-full p-3 transition-colors"
:class="isVideoOff ? 'bg-red-600 hover:bg-red-500' : 'bg-slate-700 hover:bg-slate-600'"
:title="isVideoOff ? 'Turn camera on' : 'Turn camera off'">
<svg x-show="!isVideoOff" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z"/></svg>
<svg x-show="isVideoOff" x-cloak class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z"/><path stroke-linecap="round" stroke-linejoin="round" d="m3 3 18 18"/></svg>
</button>
<button @click="toggleScreenShare()" type="button"
class="rounded-full p-3 transition-colors"
:class="isScreenSharing ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
title="Share screen">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 0 1-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0 1 15 18.257V17.25m6-12V15a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 15V5.25m18 0A2.25 2.25 0 0 0 18.75 3H5.25A2.25 2.25 0 0 0 3 5.25m18 0V12a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 12V5.25"/></svg>
</button>
<button @click="openShare()" type="button"
class="rounded-full bg-slate-700 p-3 hover:bg-slate-600"
title="Share meeting link">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.935-2.186 2.25 2.25 0 0 0-3.935 2.186Z"/></svg>
</button>
<button @click="raiseHand()" type="button" class="rounded-full bg-slate-700 p-3 hover:bg-slate-600" title="Raise hand">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M10.05 4.575a1.575 1.575 0 1 0-3.15 0v3m3.15-3v-1.5a1.575 1.575 0 0 1 3.15 0v1.5m-3.15 3v6.75a1.575 1.575 0 0 0 3.15 0V10.5m-6.3 0H4.875A1.125 1.125 0 0 0 3.75 11.625v4.125c0 .621.504 1.125 1.125 1.125h2.25m8.25-9.75V6.75a1.575 1.575 0 0 1 3.15 0v2.25m-3.15 3v6.75a1.575 1.575 0 0 0 3.15 0V10.5"/></svg>
</button>
<button @click="sendReaction('thumbs')" type="button" class="rounded-full bg-slate-700 p-3 hover:bg-slate-600" title="Applause">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6.633 10.25c.806 0 1.533-.278 2.118-.764.585-.486.96-1.15 1.05-1.875.09-.725-.03-1.46-.34-2.115-.31-.655-.8-1.2-1.41-1.56-.61-.36-1.31-.52-2.02-.46-.71.06-1.38.36-1.92.86-.54.5-.92 1.18-1.08 1.92h-.01A4.5 4.5 0 0 0 2.25 12c0 1.59.83 2.99 2.08 3.79.63.4 1.35.61 2.08.61h8.34c.98 0 1.93-.32 2.71-.91.78-.59 1.32-1.42 1.52-2.34l1.14-5.7c.1-.5-.02-1.02-.33-1.42-.31-.4-.78-.63-1.28-.63H9.75"/></svg>
</button>
<button @click="sendReaction('heart')" type="button" class="rounded-full bg-slate-700 p-3 hover:bg-slate-600" title="React">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"/></svg>
</button>
<button @click="chatOpen = !chatOpen" type="button" class="rounded-full bg-slate-700 p-3 hover:bg-slate-600 lg:hidden" title="Chat">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm3.75 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm3.75 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm-8.25 3.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm3.75 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm3.75 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332 48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"/></svg>
</button>
<button @click="featuresOpen = !featuresOpen" type="button"
class="rounded-full bg-slate-700 px-3 py-3 text-xs font-medium hover:bg-slate-600"
:class="featuresOpen ? 'ring-2 ring-indigo-400' : ''"
title="More options">More</button>
<input type="file" id="meet-file-input" class="hidden" @change="uploadFile">
<button @click="document.getElementById('meet-file-input').click()" type="button" class="rounded-full bg-slate-700 p-3 hover:bg-slate-600" title="Upload file">
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.114-8.962a1.875 1.875 0 1 1-2.652 2.652L8.552 18.32"/></svg>
</button>
@if ($participant->isHost())
<button @click="toggleRecording()" type="button"
class="rounded-full p-3 transition-colors"
:class="isRecording ? 'bg-red-600 hover:bg-red-500' : 'bg-slate-700 hover:bg-slate-600'"
:title="isRecording ? 'Stop recording' : 'Start recording'">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/></svg>
</button>
<button @click="toggleLock()" type="button"
class="rounded-full p-3 transition-colors"
:class="isLocked ? 'bg-amber-600 hover:bg-amber-500' : 'bg-slate-700 hover:bg-slate-600'"
:title="isLocked ? 'Unlock meeting' : 'Lock meeting'">
<svg x-show="!isLocked" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 0 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"/></svg>
<svg x-show="isLocked" x-cloak class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75M3.75 21h16.5A2.25 2.25 0 0 0 22.5 18.75v-6.75A2.25 2.25 0 0 0 20.25 9.75H3.75A2.25 2.25 0 0 0 1.5 12.75v6.75A2.25 2.25 0 0 0 3.75 21Z"/></svg>
</button>
@endif
<form method="POST" action="{{ route('meet.room.leave', $session) }}" class="inline">
@csrf
<button type="submit" class="rounded-full bg-red-600 px-5 py-3 text-sm font-medium hover:bg-red-500">Leave</button>
</form>
@if ($participant->isHost())
<form method="POST" action="{{ route('meet.room.end', $session) }}" class="inline" onsubmit="return confirm('End meeting for everyone?')">
@csrf
<button type="submit" class="rounded-full border border-red-500 px-4 py-3 text-sm text-red-400 hover:bg-red-950">End</button>
</form>
@endif
</div>
</footer>
<div x-show="featuresOpen" x-cloak class="absolute inset-x-4 bottom-24 z-40 rounded-xl border border-slate-700 bg-slate-900/95 p-4 shadow-xl">
<div class="flex gap-4">
@if ($isWebinar ?? false)
<div class="flex-1">
<p class="text-xs font-medium text-slate-400">Q&A</p>
<ul class="mt-2 max-h-32 space-y-1 overflow-y-auto text-sm">
<template x-for="item in qaItems" :key="item.uuid">
<li><span class="text-sky-400" x-text="item.asker_name"></span>: <span x-text="item.question"></span></li>
</template>
</ul>
<form @submit.prevent="submitQuestion" class="mt-2 flex gap-2">
<input type="text" x-model="qaInput" placeholder="Ask a question…" class="flex-1 rounded border-slate-700 bg-slate-800 px-2 py-1 text-sm">
<button type="submit" class="rounded bg-indigo-600 px-2 py-1 text-xs">Send</button>
</form>
</div>
@endif
@if ($participant->isHost())
<div class="space-y-2 text-sm">
<button @click="createBreakouts()" type="button" class="block w-full rounded bg-slate-700 px-3 py-2 hover:bg-slate-600">Start breakouts</button>
<button @click="closeBreakouts()" type="button" class="block w-full rounded bg-slate-700 px-3 py-2 hover:bg-slate-600">Close breakouts</button>
</div>
@endif
</div>
<p x-show="breakoutBroadcast" class="mt-3 rounded bg-amber-900/50 px-3 py-2 text-sm text-amber-100" x-text="breakoutBroadcast"></p>
</div>
</div>
</body>
</html>