From 1aab0d1df118ea8547991dc58675e241316118bf Mon Sep 17 00:00:00 2001 From: MythEclipse Date: Mon, 1 Jun 2026 15:51:28 +0700 Subject: [PATCH] docs: frontend major refactor design document Design for feature-sliced architecture, 8 bug fixes, and glass-morphism UI redesign. Co-Authored-By: Claude Opus 4.8 --- ...26-06-01-frontend-major-refactor-design.md | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/specs/2026-06-01-frontend-major-refactor-design.md diff --git a/docs/specs/2026-06-01-frontend-major-refactor-design.md b/docs/specs/2026-06-01-frontend-major-refactor-design.md new file mode 100644 index 0000000..dd5025f --- /dev/null +++ b/docs/specs/2026-06-01-frontend-major-refactor-design.md @@ -0,0 +1,201 @@ +# Frontend Major Refactor — Design Document + +**Date:** 2026-06-01 +**Scope:** `/mnt/code/bete/frontend/` — React + Vite + Tailwind +**Stack:** React 18, Vite, TailwindCSS, TanStack Query, lucide-react + +## Problem Statement + +1. `package.json` hilang — project tidak bisa `pnpm install` +2. `App.tsx` 285 baris monolithic (audio, socket, state, layout semua satu file) +3. `useMemo` dipakai untuk side effect (LivePanel:47) — anti-pattern React +4. Shared `ArrayBuffer` bug saat kirim PCM ke WebSocket (App:166) +5. `ws/client.ts` duplikat socket logic dengan `hooks/useDashboardSocket.ts` +6. Async handler tanpa await (MessageCard:88) +7. UI terlihat "jelek" — flat dark theme tanpa depth/visual interest +8. Mobile UX buruk — tab bar di atas, tidak ada sidebar drawer + +## Section 1: Arsitektur — Feature-Sliced Directory + +``` +frontend/ +├── index.html +├── package.json # [NEW] Lengkap dengan semua deps +├── vite.config.ts +├── tailwind.config.js +├── postcss.config.js +├── tsconfig.json +└── src/ + ├── main.tsx # React entry + QueryClient + ├── styles.css # Tailwind + design tokens + ├── App.tsx # Thin shell (~60 baris) + │ + ├── entities/ # Domain types + │ ├── message/types.ts + │ ├── guild/types.ts + │ ├── voice/types.ts + │ ├── media/types.ts + │ └── ui/types.ts + │ + ├── shared/ # Cross-cutting utilities + │ ├── api/client.ts # HTTP client + typed endpoints + │ ├── ws/socket.ts # WebSocket connection manager + │ ├── ws/events.ts # Typed event map + dispatcher + │ ├── hooks/useAudioPlayback.ts + │ ├── hooks/useAudioTransmit.ts + │ ├── hooks/useLocalStorage.ts + │ └── ui/ # UI primitives + │ ├── button.tsx + │ ├── card.tsx + │ ├── badge.tsx + │ ├── input.tsx + │ ├── select.tsx + │ ├── tabs.tsx + │ └── scroll-area.tsx + │ + ├── features/ # Feature-specific logic + presentation + │ ├── live/ + │ │ ├── hooks/useVoiceControl.ts + │ │ ├── hooks/useMediaControl.ts + │ │ ├── index.tsx # LivePanel + │ │ ├── components/VoiceConnectionCard.tsx + │ │ ├── components/AudioVisualizer.tsx + │ │ ├── components/ActiveSpeakers.tsx + │ │ ├── components/NowPlaying.tsx + │ │ ├── components/MusicSubPanel.tsx + │ │ ├── components/ScreenSubPanel.tsx + │ │ └── components/RecordingsSubPanel.tsx + │ ├── messages/ + │ │ ├── hooks/useMessages.ts + │ │ ├── index.tsx # MessagesPanel + │ │ ├── components/MessageFeed.tsx + │ │ ├── components/MessageCard.tsx + │ │ └── components/ImageGrid.tsx + │ ├── analytics/ + │ │ ├── hooks/useAnalytics.ts + │ │ ├── index.tsx # AnalyticsPanel + │ │ └── components/ # (charts, tables kept as-is) + │ └── auth/ + │ └── index.tsx # AuthOverlay + │ + └── widgets/ # Composite layouts + ├── DashboardLayout.tsx + ├── Header.tsx + └── Sidebar.tsx +``` + +### Key Architectural Decisions + +- **`App.tsx`** = hanya layout shell + providers. Semua hooks pindah ke `features/`. +- **Socket** = satu instance di `shared/ws/socket.ts`. Features subscribe via typed event bus. +- **Entities** = pure types, zero logic. +- **Features** = self-contained (hooks + components). Tidak cross-import antar feature. +- **Widgets** = layout compositions (sidebar, header, dashboard shell). + +## Section 2: Bug Fixes + +| # | Bug | Location | Fix | +|---|-----|----------|-----| +| 1 | `useMemo` untuk async fetch (anti-pattern) | `LivePanel.tsx:47` | Ganti ke `useEffect` + `useCallback` | +| 2 | Shared `ArrayBuffer` dikirim ke WS | `App.tsx:166` | `.slice()` sebelum send | +| 3 | Missing useEffect deps | `App.tsx:187` | Add proper dependency arrays | +| 4 | Unstable keys (`i` sebagai fallback) | `LivePanel.tsx:246` | Gunakan `s.userId ?? 'unknown-${i}'` | +| 5 | Async handler tanpa await | `MessageCard.tsx:88` | `onReanalyze` → `Promise`, di-await | +| 6 | `monitorGuild` recompute tiap render | `App.tsx:65` | Pakai `useMemo` | +| 7 | Socket localStorage tanpa validasi | `useUIState.ts:9` | Schema validation sebelum parse | +| 8 | Duplikat socket (`ws/client.ts` vs `hooks/useDashboardSocket.ts`) | Global | Hapus `ws/client.ts`, satu socket di `shared/ws/socket.ts` | + +## Section 3: UI Redesign — Glass-morphism Modern + +### Color Tokens + +```css +--background: 222 47% 8%; /* slightly darker */ +--foreground: 210 40% 98%; +--card: 222 47% 12% / 0.7; /* semi-transparent */ +--card-border: 222 47% 25% / 0.4;/* translucent border */ +--primary: 199 89% 52%; /* brighter cyan-blue */ +--accent: 217 33% 20%; +--muted: 217 33% 20%; +--radius: 0.85rem; +``` + +### Visual Changes + +- **Background**: Gradient mesh (dark → dark-purple → dark) dengan subtle noise overlay +- **Cards**: `backdrop-blur-xl` + semi-transparent bg + subtle glow border +- **Sidebar**: Expandable — icon-only (w-16) ↔ full (w-64) dengan smooth transition +- **Mobile**: Bottom tab bar (bukan top tabs), slide-in sidebar +- **Typography**: Inter tetap, heading scale lebih besar, weight lebih variatif +- **Micro-interactions**: `transition-all duration-200`, hover scale `1.01`, focus rings +- **Audio Visualizer**: CSS animated bars (bukan static levels map) +- **Message cards**: Rounded-xl, subtle shadow, AI badge dengan color coding yang lebih jelas +- **Charts**: Recharts-based (existing), tapi dengan color scheme yang matching theme + +### Responsive Breakpoints + +| Breakpoint | Layout | +|------------|--------| +| `< 768px` | Bottom tab bar, no sidebar, full-width content | +| `768px–1024px` | Collapsed sidebar (icon-only), full content | +| `> 1024px` | Full sidebar (w-64), spaced content | + +## Section 4: Error Handling + +- **Error Boundaries**: Setiap feature punya error boundary (existing `AnalyticsErrorBoundary` pattern) +- **API Errors**: Global error toast via `shared/ui/Toast` component +- **Socket Errors**: Auto-reconnect dengan exponential backoff (existing pattern, diperbaiki) +- **Loading States**: Skeleton loaders (bukan text "Loading...") untuk semua data panels + +## Section 5: Data Flow + +``` +Browser → shared/ws/socket.ts → shared/ws/events.ts (dispatch) + ↓ + features/* subscribe via typed handlers + ↓ + features/*/hooks/ (React Query / useState) + ↓ + features/*/components (render) + ↓ + widgets/ (layout shell) +``` + +- **REST API**: React Query hooks di `features/*/hooks/` +- **WebSocket Events**: Event bus di `shared/ws/events.ts`, hooks subscribe ke events +- **UI State**: `localStorage` + `shared/ws/socket.ts` sync (existing pattern, dengan validasi) + +## Section 6: Testing Strategy + +- **Unit**: Hooks testing dengan `@testing-library/react` — socket mocking +- **Integration**: Component render tests untuk panels +- **E2E**: Tidak termasuk scope initial refactor (future enhancement) + +## Section 7: Migration Plan + +### Phase 1: Foundation +1. `package.json` lengkap +2. `tsconfig.json` + `vite.config.ts` verified +3. `shared/` structure + UI primitives +4. `entities/` types extracted + +### Phase 2: Bug Fixes + Hooks Extraction +5. Extract hooks dari `App.tsx` → `features/*/hooks/` +6. Fix semua 8 bugs yang teridentifikasi +7. Single socket instance di `shared/ws/socket.ts` +8. `App.tsx` thin shell + +### Phase 3: UI Polish +9. Design tokens baru (glass-morphism) +10. Sidebar redesign (expandable + mobile drawer) +11. Audio visualizer animated +12. Message card redesign +13. Loading skeletons +14. Error boundaries + toast + +### Phase 4: Verification +15. `pnpm run typecheck` — zero errors +16. `pnpm run lint` — zero warnings +17. App runs + all 3 tabs functional +18. WebSocket connects + events work +19. Mobile responsive verified