Files
akademiawodociagowca/frontend/src/pages/settings/VideoSettingsPage.tsx
T
2026-09-02 08:21:27 +02:00

126 lines
5.5 KiB
TypeScript

import { SettingsPane } from './SettingsPane'
import { SettingsSection } from './SettingsSection'
/**
* Ustawienia wideo instancji.
*
* TO JEST MIEJSCE DLA TECHNIKA, NIE DLA OSOBY ZAKLADAJACEJ WEBINAR.
* ---------------------------------------------------------------------------
* Klucze dostawcow (LiveKit, Zoom, Jitsi) i sekret webhooka ustawia sie tutaj
* RAZ, przy wdrozeniu instancji u klienta. Osoba tworzaca webinar nigdy tego
* nie dotyka: w formularzu webinaru wybiera tylko gotowego dostawce z listy
* i klika "Utworz pokoj". Dlatego instrukcja techniczna jest tutaj, a nie
* przy webinarze.
*
* Wczesniej tych kluczy NIE DALO SIE ustawic przez panel (byly wylacznie
* w bazie/zmiennych srodowiskowych), a instrukcja "?" przy webinarze mylila,
* bo odsylala do nieistniejacej sekcji Wideo. Ta strona domyka te luke.
*/
const KEYS = [
'VIDEO_PROVIDER',
'VIDEO_WEBHOOK_SECRET',
'VIDEO_DELETE_AFTER_DOWNLOAD',
// LiveKit
'LIVEKIT_URL',
'LIVEKIT_API_KEY',
'LIVEKIT_API_SECRET',
// Jitsi
'JITSI_DOMAIN',
'JITSI_JWT_ENABLED',
'JITSI_APP_ID',
'JITSI_APP_SECRET',
// Zoom
'ZOOM_ACCOUNT_ID',
'ZOOM_CLIENT_ID',
'ZOOM_CLIENT_SECRET',
'ZOOM_SDK_KEY',
'ZOOM_SDK_SECRET',
]
export function VideoSettingsPage() {
return (
<SettingsPane>
{({ settings, onSave, saving }) => (
<SettingsSection
title="Wideo (konfiguracja instancji)"
description="Dostawca wideo i jego klucze. Ustawia się raz, przy wdrożeniu. Osoba zakładająca webinar tego nie dotyka - wybiera tylko gotowego dostawcę z listy."
settings={settings}
keys={KEYS}
onSave={onSave}
saving={saving}
intro={<VideoInstructions />}
/>
)}
</SettingsPane>
)
}
/**
* Instrukcja techniczna, ktora WCZESNIEJ byla w oknie "?" przy webinarze.
* Jej miejsce jest tu: to jednorazowa konfiguracja infrastruktury.
*/
function VideoInstructions() {
return (
<details className="rounded-md border border-slate-200 bg-slate-25 p-4 text-sm">
<summary className="cursor-pointer font-semibold text-slate-800">
Jak skonfigurować dostawcę wideo (instrukcja dla administratora)
</summary>
<div className="mt-3 space-y-4 text-slate-600">
<p>
Wybierz jednego dostawcę w polu <strong>VIDEO_PROVIDER</strong> i uzupełnij jego klucze.
Pozostali dostawcy mogą zostać puści. Po zapisaniu konfiguracji osoba zakładająca
webinar wybiera dostawcę z gotowej listy i klika „Utwórz pokój" - bez żadnych kroków
technicznych.
</p>
<div>
<p className="font-semibold text-slate-800">LiveKit (zalecany)</p>
<p>
Serwer wideo uruchamiany na własnej infrastrukturze. Uprawnienia egzekwuje serwer na
podstawie podpisanego tokenu, nagrywanie działa automatycznie.
</p>
<ol className="mt-1 list-decimal space-y-1 pl-5">
<li>Uruchom serwer: profil Docker Compose „livekit" (<code>docker compose --profile livekit up -d</code>). Nagrywanie wymaga usług Redis i Egress z tego profilu.</li>
<li>Wpisz parę klucz-sekret w <strong>LIVEKIT_API_KEY</strong> i <strong>LIVEKIT_API_SECRET</strong>.</li>
<li>Podaj adres WebSocket serwera w <strong>LIVEKIT_URL</strong> (np. <code>wss://twoj-serwer</code>; lokalnie <code>ws://localhost:7880</code>).</li>
</ol>
</div>
<div>
<p className="font-semibold text-slate-800">Zoom</p>
<p>Obraz osadzony w oknie webinaru. Wymaga płatnego konta Zoom (min. Pro) i dwóch aplikacji na koncie dewelopera.</p>
<ol className="mt-1 list-decimal space-y-1 pl-5">
<li>Na marketplace.zoom.us utwórz aplikację <strong>Server-to-Server OAuth</strong> - da Account ID, Client ID, Client Secret. Dodaj zakresy: meeting:write, meeting:read, recording:read, recording:write.</li>
<li>Wpisz je w <strong>ZOOM_ACCOUNT_ID</strong>, <strong>ZOOM_CLIENT_ID</strong>, <strong>ZOOM_CLIENT_SECRET</strong>.</li>
<li>Utwórz drugą aplikację <strong>Meeting SDK</strong> - da SDK Key i SDK Secret. Wpisz w <strong>ZOOM_SDK_KEY</strong> i <strong>ZOOM_SDK_SECRET</strong>.</li>
<li>W Event Subscriptions dodaj adres <code>/api/webhooks/video/zoom</code> i zdarzenia: Recording Completed, Participant joined/left. Zoom poda Secret Token - wpisz go w <strong>VIDEO_WEBHOOK_SECRET</strong>.</li>
</ol>
<p className="mt-1">
Uwaga: Zoom nie egzekwuje uprawnień do obrazu i dźwięku per uczestnik - steruje nimi na
poziomie całego spotkania (jak Jitsi, nie jak LiveKit).
</p>
</div>
<div>
<p className="font-semibold text-slate-800">Jitsi Meet</p>
<p>
Publiczny <code>meet.jit.si</code> działa bez konta (<strong>JITSI_DOMAIN</strong>), ale pokój jest wtedy
otwarty dla każdego, kto zna adres. Własny serwer z modułem JWT pozwala włączyć
<strong> JITSI_JWT_ENABLED</strong> i wpisać <strong>JITSI_APP_ID</strong> oraz <strong>JITSI_APP_SECRET</strong>.
</p>
</div>
<div>
<p className="font-semibold text-slate-800">Bez wbudowanego wideo (NONE)</p>
<p>
Ustaw <strong>VIDEO_PROVIDER</strong> na NONE. Obraz idzie zewnętrznym narzędziem - link
wkleja się w formularzu każdego webinaru. Czat, pytania i zapytania ofertowe zostają
na tej platformie.
</p>
</div>
</div>
</details>
)
}