Internal Operations · React 18.3 · CRA + CRACO

Admin Dashboard
Bảng Điều Khiển Nội Bộ

Nền tảng vận hành nội bộ cho đội ngũ KioskGaming — quản lý người dùng, duyệt rút tiền, xử lý ticket hỗ trợ và giám sát toàn bộ giao dịch nền tảng theo thời gian thực.

30+
Routes chức năng
5
Admin roles
3
Bước duyệt rút tiền
:3000
Dev port (CRA)
TS 4.9
TypeScript
🎯
Section 01
Mục đích nghiệp vụ
ℹ️
Admin Dashboard là trung tâm vận hành nội bộ — nơi đội ngũ tài chính, vận hành và quản trị theo dõi, kiểm soát toàn bộ hoạt động của nền tảng KioskGaming. Không phải sản phẩm hướng đến người chơi, đây là công cụ nghiệp vụ để business vận hành kiosk gaming hàng ngày.
💼 Vấn đề được giải quyết
  • Duyệt rút tiền thủ công: Finance team xem xét, approve và xác nhận hoàn tất chuyển khoản bank / crypto
  • Kiểm soát người dùng: Ban tài khoản vi phạm, thay đổi trạng thái, xem toàn bộ lịch sử ví
  • Xử lý yêu cầu hỗ trợ: Phản hồi ticket, cập nhật trạng thái, đóng ticket đã giải quyết
  • Giám sát giao dịch: Theo dõi tất cả giao dịch deposit/withdrawal qua mọi payment provider
  • Tổng quan điều hành: Dashboard stats — ban lãnh đạo nắm bắt tình hình tức thì
Stack kỹ thuật
React 18.3 CRA CRACO 7 TypeScript 4.9 React Router v6 React Query v3 Zustand 5 Radix UI + shadcn @kioskgaming/ui Axios Tailwind CSS 3 Playwright E2E Turnstile CAPTCHA
🏢 Ai vận hành hệ thống này?
  • Finance Team: Xử lý withdrawal requests hàng ngày, verify transfers
  • Operations Team: Quản lý user accounts, xử lý support tickets
  • Super Admin: Oversight toàn bộ, quản lý admin accounts
🗺️ Luồng điều hướng — React Router v6
Route Component Permission Guard Mô tả
/login LoginPage.tsx Public Đăng nhập admin (email + password + OTP)
/dashboard Dashboard.tsx Authenticated Tổng quan stats, quick actions
/users UsersManagement userManagement Danh sách + tìm kiếm + filter users
/users/:id UserDetailPage userManagement Chi tiết user, ví, lịch sử giao dịch, ban modal
/transactions TransactionsManagement transactionManagement Tất cả payment transactions nền tảng
/withdrawal-requests WithdrawalManagement withdrawalManagement Approve / Complete / Reject withdrawals (3-step)
/tickets TicketManagement ticketManagement Support ticket list + reply thread + status update
/flagged-withdrawals FlaggedWithdrawalsManagement withdrawalManagement Rút tiền bị flag fraud — review riêng
/manual-game-deposits ManualGameDepositsManagement manualGameDepositManagement Duyệt nạp game thủ công (manual deposit)
/usd-wallets UsdWalletsManagement transactionManagement USD wallet ledger & activity
/credit-wallets CreditWalletsManagement transactionManagement Credit wallet management
/cash-transactions CashTransactionsManagement transactionManagement Giao dịch tiền mặt tại shop/cashier
/agents · /shops · /cashiers Agent/Shop/Cashier Mgmt agentManagement Quản lý agent hierarchy + shops
/broadcasts · /in-app-popups Broadcast / Popup Mgmt super_admin only Thông báo toàn nền tảng + popup in-app
/integration-logs IntegrationLogsManagement super_admin only API integration logs
/vfx-config ScheduleManagement vfxConfigManagement Cấu hình VFX/background kiosk
/transaction-limits TransactionLimitsManagement transactionLimitsManagement Giới hạn giao dịch & fraud flags
/domains DomainsManagement domainManagement Quản lý domain kiosk
/wallets GameWalletsManagement walletManagement Game wallets (đã implement)
/admins AdminManagement adminManagement CRUD admin accounts (đã implement)
🔐
Section 02
Đối tượng & Phân quyền
🔑
Hệ thống phân quyền RBAC qua config/permissions.ts: roles system_admin, super_admin, platform_admin, finance_admin, support_admin. AuthProvider (React Context) bọc app; ProtectedRoute kiểm tra permission; permissions resolve từ API permissionObjects hoặc role map.
👑
Super Admin
role: admin
userManagement
walletManagement
transactionManagement
withdrawalManagement
ticketManagement
adminManagement
financeManagement
✦ Full access — không giới hạn
💰
Finance Admin
role: finance
userManagement
walletManagement
transactionManagement
withdrawalManagement
ticketManagement
adminManagement
financeManagement
✦ Tập trung tài chính: ví, giao dịch, rút tiền
🛠️
Operation Admin
role: planned
userManagement
walletManagement
transactionManagement
withdrawalManagement
ticketManagement
⚠ Chưa implement trong useAuth.ts
🔧
Platform Admin
role: planned
~ Quyền hạn chế
~ Tùy cấu hình
⚠ Chưa định nghĩa trong codebase
🔒 Cơ chế xác thực & Authorization
// useAuth.ts — hasPermission logic if (user.profile?.role === 'admin') { return true; // Full access mọi route } if (user.profile?.role === 'finance') { const financePerms = [ 'walletManagement', 'transactionManagement', 'withdrawalManagement', 'financeManagement', ]; return financePerms.includes(permission); } return false;
// ProtectedRoute.tsx — route guard if (!isAuthenticated) { return <Navigate to="/login" state={{ from: location }} />; } if (requiredPermission && !hasPermission(requiredPermission)) { return <Navigate to="/dashboard" />; } return <>{children}</>;
⚠️
Lưu ý quan trọng: Phân quyền hiện chỉ kiểm tra phía client. Mọi API call backend đều phải có JWT token và backend thực hiện authorization độc lập. Client-side guards chỉ để UX — không phải security layer duy nhất.
💸
Section 03
Module Rút Tiền (Withdrawal Approval)
🚨
Nghiệp vụ quan trọng nhất — Quy trình duyệt rút tiền 3 bước bảo vệ người dùng và đảm bảo finance team xác nhận chuyển khoản thực tế trước khi đánh dấu hoàn tất. Mỗi action được thực hiện qua modal riêng để tránh thao tác nhầm.
🔄 Luồng xử lý 3 bước — Withdrawal Workflow
Bước 1
Pending
Người dùng gửi yêu cầu rút tiền từ player app. Hệ thống tạo withdrawal request với trạng thái pending.
pending
Bước 2
Approve
Finance admin xem xét thông tin, kiểm tra số dư, mở ApproveWithdrawalModal và xác nhận với admin notes tùy chọn.
approved
Bước 3A
Complete
Sau khi chuyển khoản thực tế (bank / crypto), finance admin mở CompleteWithdrawalModal để đánh dấu hoàn tất.
completed
Bước 3B
Reject
Từ bất kỳ trạng thái nào, admin có thể mở RejectWithdrawalModal với lý do rõ ràng. Số tiền được hoàn vào ví người dùng.
rejected
Withdraw Types được hỗ trợ
🏦 Bank Transfer
Trường: bankCode, accountNumber, accountName, routingNumber. Finance team chuyển khoản ngân hàng thủ công.
₿ Bitcoin Transfer
Trường: bitcoinAddress, bitcoinNetwork. Finance team gửi crypto thủ công đến địa chỉ ví.
3 Modal Actions
  • ApproveWithdrawalModal: Xác nhận approve, có admin notes field (max 1000 chars). POST /admin/withdrawal/:id/approve
  • CompleteWithdrawalModal: Xác nhận đã chuyển khoản xong, có admin notes. POST /admin/withdrawal/:id/complete
  • RejectWithdrawalModal: Nhập lý do từ chối (bắt buộc). POST /admin/withdrawal/:id/reject
🖥️ Approve Withdrawal Modal — Preview Layout
📋 WithdrawalList — Filters & Columns
Bộ lọc có sẵn
  • status: pending / approved / completed / rejected
  • withdrawalType: bank_transfer / bitcoin_transfer
  • dateFrom / dateTo: Date range picker
  • sortBy: createdAt / amount / status
  • sortOrder: ASC / DESC
  • page / limit: Pagination (default 20/page)
Columns hiển thị
  • Transaction ID — unique identifier
  • User — firstName + lastName + email
  • Type — Bank / Bitcoin badge
  • Amount + Currency
  • Status badge — color-coded
  • Created At
  • Actions — View / Approve / Complete / Reject
👥
Section 04
Quản lý Người Dùng
📋 UserList — Danh sách người dùng
  • Search: Tìm theo email (debounced input)
  • Filter status: active / inactive / suspended
  • Filter banned: Hiện / ẩn tài khoản bị ban
  • Sort: created_at / email / status / banned
  • Pagination: 20 user/trang mặc định
  • Click row: Điều hướng đến /users/:id
active inactive suspended banned
👤 UserDetailPage — Chi tiết người dùng
  • Info section: ID, email, email_verified, last_login_at, created_at
  • Stats section: totalDeposits, totalWithdrawals, walletBalance, totalTransactions
  • WalletSection: Số dư ví, locked balance, credit/debit thủ công
  • WalletTransactionTable: Lịch sử giao dịch ví với filter & pagination
  • Action buttons: Ban User / Unban / Update Status
🚫 BanUserModal — Ban tài khoản
⚠ Hành động không thể hoàn tác ngay
  • reason field: Bắt buộc nhập lý do ban (ghi lại audit trail)
  • Ghi lại: banned_at, banned_by (admin ID), ban_reason
  • Unban: Modal riêng để confirm mở khóa tài khoản
// BanUserRequest type interface BanUserRequest { reason?: string; } // Response ghi lại đầy đủ audit data: { userId: string; banned: true; banned_at: string; // ISO timestamp ban_reason?: string; }
🔄 UpdateUserStatusModal
3 trạng thái có thể cập nhật:
active Tài khoản hoạt động bình thường
inactive Tài khoản không hoạt động / chưa verify
suspended Tạm đình chỉ (ít nghiêm trọng hơn ban)
💰 WalletSection Admin Actions
  • Credit Wallet: Thêm tiền thủ công (amount + reason + description)
  • Debit Wallet: Trừ tiền thủ công (amount + reason + description)
  • Xem: balance, lockedBalance, currency
🎫
Section 05
Hỗ trợ Khách Hàng — Ticket Management
🎫
Operations team xử lý support tickets từ người chơi qua hệ thống ticket. Mỗi ticket có thread replies đầy đủ, phân biệt giữa admin reply và user reply. Admin có thể mark internal notes chỉ đội nội bộ thấy.
🔄 Ticket Status Flow
pending in_progress resolved closed
done — Trạng thái đặc biệt: admin đánh dấu hoàn tất (có resolvedAt + resolvedBy)
📋 TicketList
  • Filter status: pending / in_progress / resolved / closed / done
  • Pagination: 20 tickets/trang
  • Hiển thị: ticketNumber, email, phoneNumber, category, status badge, createdAt
  • Click: Mở TicketDetails panel
SupportTicket fields11 fields
Category typesDynamic từ API
Reply typesadmin / user
💬 TicketDetails & Reply System
  • Thread view: Hiển thị toàn bộ conversation history theo thứ tự thời gian
  • Reply phân biệt: Admin replies có adminName, user replies có email
  • Internal notes: isInternal: true — chỉ admin thấy
  • ReplyTicketModal: Text area + checkbox internal note
  • UpdateTicketStatusModal: Dropdown chọn status mới + ghi notes
  • Mark as Done: Ghi resolvedAt + resolvedBy tự động
📊 Support Stats (Dashboard data)
total
Tổng tickets
open
Chờ xử lý
progress
Đang xử lý
today
Giải quyết hôm nay
💳
Section 06
Giám sát Giao Dịch
📋 TransactionList — Bộ lọc đầy đủ
  • search: Tìm theo transactionId / userId
  • type: deposit / withdrawal
  • status: pending / completed / failed / cancelled
  • paymentMethod: Filter theo payment provider
  • dateFrom / dateTo: Date range
  • sortBy: created_at / amount / status / type
  • Pagination: 20/page mặc định
🔍 TransactionDetails — Chi tiết giao dịch
  • Core fields: transactionId, userId, type, amount, currency, status
  • Payment info: paymentMethod, description, paymentResult (raw JSON)
  • Admin fields: adminNotes, approvedAt, approvedBy
  • Stats: processingTime, relatedTransactions, userTransactionCount
  • Raw data: linkMePayRequest payload (debug)
🔄 UpdateTransactionStatusModal & Transaction Stats
Status transitions cho phép:
pending → Đang chờ xử lý
completed → Hoàn tất thành công
failed → Giao dịch thất bại
cancelled → Đã hủy
Transaction Stats API response:
  • overview: totalTransactions, totalAmount, completed/pending/failed counts
  • byType: totalDeposits vs totalWithdrawals
  • byMethod: breakdown theo payment provider (deposits + withdrawals)
⚙️
Section 07
Kỹ thuật — Architecture & Patterns
🔄 React Query Data Fetching
// hooks/useApi.ts — Query patterns const { data, isLoading, error, refetch } = useWithdrawals(filters); // React Query v3 config const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 1, refetchOnWindowFocus: false, }, }, });
  • useWithdrawals(filters): Pagination + filter state → query key
  • useApproveWithdrawal(): Mutation → onSuccess gọi refetch()
  • useDashboardStats(): Single query cho tất cả stats
  • Cache invalidation: Sau mỗi mutation gọi refetch() parent query
🪟 Modal Architecture Pattern
// Withdrawal Management pattern const [showApproveModal, setShowApproveModal] = useState(false); const [selectedWithdrawal, setSelected...] = useState<WithdrawalRequest | null>(null); // Mở modal: set target + show flag const handleApprove = (w) => { setSelectedWithdrawal(w); setShowApproveModal(true); };
  • Modal isolation: Mỗi action (approve/reject/complete/ban) có modal riêng
  • Confirmation pattern: Ngăn thao tác nhầm trên dữ liệu nhạy cảm
  • Toast feedback: react-hot-toast sau mỗi action thành công/thất bại
  • Error parsing: Parse lỗi từ error.response.data.message
🛡️ Protected Routes & Auth Flow
  • JWT localStorage: Token + userData lưu local, khởi tạo từ useEffect
  • ProtectedRoute wrapper: Mọi route private đều qua component này
  • requiredPermission prop: Route-level permission check
  • Fallback logic: Not auth → /login, No perm → /dashboard
  • Loading state: isLoading: true trong khi restore auth từ localStorage
  • Logout: Clear localStorage + reset state
📊 Dashboard — Stats & Recharts
  • DashboardStats type: users, wallets, transactions, tickets sections
  • 6 stat cards: Total Users, Active Users, Wallet Balance, Total Transactions, Pending Withdrawals, Open Tickets
  • Quick Actions panel: Links tới Quản lý Users, Duyệt rút tiền, Xử lý Tickets
  • 4 summary cards: Hành động nhanh, Thống kê Users, Giao dịch hôm nay, Support Tickets
  • Recharts: Charts cho trends (deposit/withdrawal over time)
  • Lucide icons: Users, Wallet, CreditCard, ArrowUpRight, Activity, AlertCircle, MessageSquare
🎨 Layout & Navigation Architecture
Layout.tsx
Root layout wrapper. Compose Sidebar + Header + main content area. Applied via ProtectedRoute wrapping.
Sidebar.tsx
Left nav với active state detection via React Router useLocation. Menu items conditional dựa trên permissions.
Header.tsx
Top header với user info, role badge, logout button. Hiển thị tên admin đang đăng nhập.
🗂️
Section 08
Pages & Component Map
Auth
LoginPage.tsx
Email + password + OTP flow. 2-step: gửi code rồi verify
ProtectedRoute.tsx
Route guard — kiểm tra auth + permission trước render
useAuth.ts
Hook trung tâm: login, logout, hasPermission, hasRole, updateUser
Layout
Layout.tsx
Root layout wrapper: Sidebar + Header + content
Sidebar.tsx
Left nav với active state, permission-gated menu items
Header.tsx
Top bar: user info, role badge, logout
MenuContainer.tsx
Menu container wrapper
Dashboard
Dashboard.tsx
6 stat cards, 4 summary panels, quick actions. Recharts charts
Users
UserList.tsx
Table với filter, search, sort, pagination
UserDetailPage.tsx
Full user profile + stats + action buttons
WalletSection.tsx
Wallet balance, credit/debit manual actions
WalletTransactionTable.tsx
Wallet transaction history với filter & pagination
BanUserModal.tsx
Ban/unban với reason field. Ghi audit trail
UpdateUserStatusModal.tsx
Chuyển active / inactive / suspended
Withdrawal Requests
WithdrawalList.tsx
Table với status/type/date filters. Action buttons per row
WithdrawalDetails.tsx
Full withdrawal info: bankInfo / bitcoinInfo
ApproveWithdrawalModal.tsx
Step 2 — Approve với admin notes tùy chọn
CompleteWithdrawalModal.tsx
Step 3A — Confirm đã chuyển tiền xong
RejectWithdrawalModal.tsx
Step 3B — Từ chối với lý do bắt buộc
Support Tickets
TicketList.tsx
Ticket table với status filter + pagination
TicketDetails.tsx
Full conversation thread (admin + user replies)
ReplyTicketModal.tsx
Textarea + internal note checkbox để reply
UpdateTicketStatusModal.tsx
Dropdown status + notes + mark as done
Transactions
TransactionList.tsx
Full filter: type, status, method, date, sort
TransactionDetails.tsx
Chi tiết + raw payload + stats + admin notes
UpdateTransactionStatusModal.tsx
Update status + adminNotes cho transaction
Shared UI Components
Card.tsx
Card, CardHeader, CardTitle, CardContent
Badge.tsx
Color-coded status badges
Table.tsx
Table wrapper với consistent styling
Button.tsx
Button variants: default, outline, ghost, sizes: sm/md/lg
Input.tsx
Styled input với consistent form appearance
Loading.tsx
LoadingSpinner + LoadingPage components
Menu.tsx
Dropdown menu component
Services & Types
services/api.ts
Axios instance + interceptors + base URL config
hooks/useApi.ts
React Query hooks cho mọi API endpoint
types/index.ts
700+ lines TypeScript types cho mọi entity
utils/index.ts
formatCurrency, date helpers, misc utils
constants/index.ts
STORAGE_KEYS và app-level constants
Kiến trúc rõ ràng: Mọi entity (Withdrawal, User, Transaction, Ticket) đều có đầy đủ TypeScript interface cho request, response, filters và pagination. Separation of concerns tốt giữa UI components, hooks/queries và types.