Files
zyrarbot/frontend
lgooseandClaude Bot 105f3e6c6a chore(frontend): ESLint dla Vue i TypeScriptu
Konfiguracja we flat configu: zalecane zestawy js, typescript-eslint oraz
eslint-plugin-vue. Bloki <script setup lang="ts"> obsługuje vue-eslint-parser
przekazujący zawartość do parsera TypeScriptu.

Odstępstwa od domyślnych reguł:

- vue/multi-word-component-names wyłączone - kafelki panelu mają nazwy
  własne i nie każda jest dwuczłonowa
- no-unused-vars przepuszcza nazwy z prefiksem podkreślenia
- no-console wyłączone dla testu dymnego, który raportuje wynik na stdout

Szablony przepuszczone przez eslint --fix, co ujednoliciło łamanie
atrybutów i domykanie znaczników. Po zmianach kontrola typów, build
i test dymny nadal przechodzą.

Dochodzą skrypty npm: lint (z --max-warnings 0) oraz lint:fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:34:55 +02:00
..

Panel webowy ŻyrarBOT

Frontend napisany w Vue 3 + TypeScript, budowany przez Vite.

Panel jest samodzielną aplikacją we własnym kontenerze. Backend wystawia wyłącznie API i steruje botem - nie serwuje żadnych plików statycznych.

Praca lokalna

npm install
npm run dev      # http://localhost:5173, proxy /api i /ws na backend :8000

Backend uruchamiamy równolegle (python main.py). Serwer deweloperski Vite przejmuje wtedy rolę nginxa i przekierowuje REST oraz WebSocket. Inny adres backendu wskazuje zmienna VITE_BACKEND_URL:

VITE_BACKEND_URL=http://192.168.1.10:8000 npm run dev

Budowanie

npm run build    # typecheck + bundle do dist/
npm run smoke    # test dymny zbudowanego artefaktu

Kontener

Dockerfile buduje panel w etapie node:22-alpine, a wynik serwuje nginx:1.27-alpine. Konfiguracja z nginx.conf przekazuje /api i /ws do usługi discord-bot, dzięki czemu przeglądarka widzi jedno źródło i nie potrzeba CORS-u.

docker compose up --build    # panel na :80, API na :8000

Aby panel łączył się z backendem pod innym adresem, wystarczy podmienić set $backend w nginx.conf - obraz nie wymaga przebudowania frontendu.

Struktura

src/
├── main.ts               montowanie aplikacji
├── App.vue               układ pulpitu i przełączanie okien modalnych
├── api/client.ts         typowane wywołania REST - jedyne miejsce z adresami
├── types/status.ts       kontrakt danych z /api/status i WebSocketu
├── composables/
│   ├── useBotStatus.ts    jedno połączenie WebSocket na aplikację
│   ├── useToasts.ts       kolejka powiadomień + helper run()
│   ├── useTrackProgress.ts płynny pasek postępu między pakietami z serwera
│   └── useUploads.ts      serwerowa baza plików
├── utils/plural.ts       polska odmiana liczebników
├── assets/style.css      system stylów (zachowany wygląd sprzed przepisania)
└── components/
    ├── AppHeader.vue          nagłówek ze statusem połączenia
    ├── VoiceChannelPanel.vue  wybór kanału głosowego
    ├── PlayerPanel.vue        odtwarzacz, postęp, głośność, zapętlanie
    ├── AddTrackPanel.vue      dodawanie po linku lub frazie
    ├── UploadsPanel.vue       10 ostatnio używanych plików + wysyłanie
    ├── UploadedFileRow.vue    wiersz pliku (współdzielony z oknem modalnym)
    ├── QueuePanel.vue         kolejka z przeciąganiem i zmianą kolejności
    ├── QueueItem.vue          pozycja kolejki wraz z limitem odtworzeń
    ├── HistoryPanel.vue       historia z ponownym dodaniem do kolejki
    ├── ModalShell.vue         wspólna ramka okien modalnych
    ├── SettingsModal.vue      ustawienia bota i kanałów logów
    ├── UploadsLibraryModal.vue pełna lista plików na serwerze
    └── ToastHost.vue          powiadomienia

Zasady

  • Stan płynie z serwera. Nie duplikujemy stanu bota lokalnie - komponenty czytają status z WebSocketu i wywołują API. Wyjątkiem są pola formularzy podczas edycji oraz suwak głośności w trakcie przeciągania.
  • Zero innerHTML. Poprzednia wersja składała wiersze kolejki ze stringów, przez co tytuły utworów trafiały do DOM bez escapowania. Teraz wszystko idzie przez szablony Vue.
  • Ikony jako komponenty (lucide-vue-next) zamiast skryptu z CDN.