Files
GMW/services/frontend
asepharyana e3dd6a3427 fix(messages): Discord-style order (oldest top, newest bottom)
Backend returns messages DESC (newest first); the view previously rendered
that directly, so the feed was inverted vs Discord (old at bottom, new at top)
while the load-older control sat at the top — contradictory.

- Reverse the display list so it reads oldest→newest top→bottom, like DC.
- Load-older (cursor to lower created_at) prepends at the top; scroll position
  is preserved by offsetting scrollTop by the height added above.
- Open at the bottom (newest visible) on first load / scope change.
- New live messages append at the bottom and auto-scroll only when the user is
  already near the bottom (nearBottomRef), so reading history isn't disrupted.
- Scroll container now tracked via ref; onScroll updates nearBottom + triggers
  load-older when scrolled to the top.

tsc, biome, next build all clean.
2026-08-16 17:56:39 +07:00
..
2026-08-02 16:46:22 +07:00

Bete Frontend

Next.js 16 (React 19) dashboard untuk Discord Moderation Watcher.

Stack: Next.js 16 (App Router, static export), React 19, TypeScript strict, Tailwind v4, shadcn/ui, base-ui, lucide-react.

Dev

bun run dev        # next dev — port 3000 (lokal; prod via nginx 4009)
bun run build      # next build — static export ke out/
bun run lint       # Biome check

Architecture

src/
├── app/                  # Pages
│   ├── page.tsx          # Redirect ke /dashboard
│   └── dashboard/        # Dashboard layout + tabs
│       ├── layout.tsx    # Sidebar, header, WS provider, chatbot
│       └── page.tsx      # Tab routing (messages/live/dashboard)
├── features/
│   ├── messages/         # Message feed, search, review, detail modal
│   ├── live/             # Voice connection, music player, recordings
│   ├── dashboard/        # Stats, users, channels overview
│   └── chatbot/          # AI chatbot
├── lib/
│   ├── api/              # Fetch-based API client (all BE endpoints)
│   ├── ws/               # WebSocket client + React context
│   └── hooks/            # Shared hooks (config, auth)
└── components/
    └── layout/           # Sidebar, header, mobile tab bar

API

Backend berjalan di port 4001. Frontend mengakses API via window.location (same-origin atau proxy).

WebSocket terhubung otomatis ke /ws di host yang sama.