import { FormEvent, KeyboardEvent, useEffect, useMemo, useState } from 'react'; import './app.css'; import { fallbackDashboardSnapshot, panelAuth } from './data/mockDashboard'; import { buildProxyLink, formatBytes, formatQuotaState, formatTrafficShare, getServiceTone, isQuotaExceeded, } from './lib/3proxy'; import type { CreateUserInput, DashboardSnapshot, ProxyServiceRecord, ProxyUserRecord, } from './shared/contracts'; type TabId = 'dashboard' | 'users' | 'system'; const tabs: Array<{ id: TabId; label: string }> = [ { id: 'dashboard', label: 'Dashboard' }, { id: 'users', label: 'Users' }, { id: 'system', label: 'System' }, ]; function LoginGate({ onUnlock }: { onUnlock: () => void }) { const [login, setLogin] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const handleSubmit = (event: FormEvent) => { event.preventDefault(); if (login === panelAuth.login && password === panelAuth.password) { setError(''); onUnlock(); return; } setError('Wrong panel credentials. Check the hardcoded startup values.'); }; return (

3proxy UI

Sign in to the control panel.

{error ?

{error}

: null}
); } function AddUserModal({ host, services, onClose, onCreate, }: { host: string; services: ProxyServiceRecord[]; onClose: () => void; onCreate: (input: CreateUserInput) => Promise; }) { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [serviceId, setServiceId] = useState(services[0]?.id ?? ''); const [quotaMb, setQuotaMb] = useState(''); const [error, setError] = useState(''); useEffect(() => { const handleKeyDown = (event: globalThis.KeyboardEvent) => { if (event.key === 'Escape') { onClose(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); const stopPropagation = (event: KeyboardEvent) => { event.stopPropagation(); }; const selectedService = services.find((service) => service.id === serviceId); const handleSubmit = async (event: FormEvent) => { event.preventDefault(); try { await onCreate({ username, password, serviceId, quotaMb: quotaMb.trim() ? Number(quotaMb) : null, }); onClose(); } catch (submitError) { setError(submitError instanceof Error ? submitError.message : 'Unable to create user.'); } }; return (

Add user

Endpoint {selectedService ? `${host}:${selectedService.port}` : 'Unavailable'}
Protocol {selectedService ? selectedService.protocol : 'Unavailable'}
{error ?

{error}

: null}
); } function ConfirmDeleteModal({ username, onClose, onConfirm, }: { username: string; onClose: () => void; onConfirm: () => Promise; }) { useEffect(() => { const handleKeyDown = (event: globalThis.KeyboardEvent) => { if (event.key === 'Escape') { onClose(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); const stopPropagation = (event: KeyboardEvent) => { event.stopPropagation(); }; return (

Delete user

Remove profile {username}? This action will delete the user entry from the current panel state.

); } function DashboardTab({ snapshot, onRuntimeAction, }: { snapshot: DashboardSnapshot; onRuntimeAction: (action: 'start' | 'restart') => Promise; }) { const serviceTone = getServiceTone(snapshot.service.status); return (

Service

{snapshot.service.status}
Process
{snapshot.service.pidLabel}
Version
{snapshot.service.versionLabel}
Uptime
{snapshot.service.uptimeLabel}
Last event
{snapshot.service.lastEvent}

Traffic

Total {formatBytes(snapshot.traffic.totalBytes)}
Connections {snapshot.traffic.liveConnections}
Active users {snapshot.traffic.activeUsers}

Daily usage

{snapshot.traffic.daily.map((bucket) => (
{bucket.day}
{formatBytes(bucket.bytes)}
))}

Attention

{snapshot.attention.map((item) => (
{item.title}

{item.message}

))}
); } function UsersTab({ snapshot, onCreateUser, onTogglePause, onDeleteUser, }: { snapshot: DashboardSnapshot; onCreateUser: (input: CreateUserInput) => Promise; onTogglePause: (userId: string) => Promise; onDeleteUser: (userId: string) => Promise; }) { const [copiedId, setCopiedId] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [deleteTargetId, setDeleteTargetId] = useState(null); const servicesById = useMemo( () => new Map(snapshot.system.services.map((service) => [service.id, service] as const)), [snapshot.system.services], ); const assignableServices = snapshot.system.services.filter((service) => service.enabled && service.assignable); const deleteTarget = snapshot.userRecords.find((user) => user.id === deleteTargetId) ?? null; const handleCopy = async (userId: string, proxyLink: string) => { await navigator.clipboard.writeText(proxyLink); setCopiedId(userId); window.setTimeout(() => setCopiedId((value) => (value === userId ? null : value)), 1200); }; return ( <>

Users

{snapshot.userRecords.length} accounts in current profile

{snapshot.users.live} live {snapshot.users.nearQuota} near quota {snapshot.users.exceeded} exceeded
{snapshot.userRecords.map((user) => { const service = servicesById.get(user.serviceId); const endpoint = service ? `${snapshot.system.publicHost}:${service.port}` : 'service missing'; const proxyLink = service ? buildProxyLink( user.username, user.password, snapshot.system.publicHost, service.port, service.protocol, ) : ''; const exhausted = isQuotaExceeded(user.usedBytes, user.quotaBytes); const displayStatus = user.paused ? 'paused' : user.status; return ( ); })}
User Endpoint Status Used Remaining Share Proxy Actions
{user.username}
{service?.name ?? 'Unknown service'} {endpoint}
{displayStatus} {formatBytes(user.usedBytes)} {formatQuotaState(user.usedBytes, user.quotaBytes)} {formatTrafficShare(user.usedBytes, snapshot.traffic.totalBytes)}
{isModalOpen ? ( setIsModalOpen(false)} onCreate={onCreateUser} /> ) : null} {deleteTarget ? ( setDeleteTargetId(null)} onConfirm={async () => { await onDeleteUser(deleteTarget.id); setDeleteTargetId(null); }} /> ) : null} ); } function SystemTab({ snapshot }: { snapshot: DashboardSnapshot }) { return (

Runtime

Config mode
{snapshot.system.configMode}
Reload
{snapshot.system.reloadMode}
Storage
{snapshot.system.storageMode}

Services

{snapshot.system.services.map((service) => (
{service.name}

{service.description}

{service.port} {service.enabled ? 'enabled' : 'disabled'}
))}

Generated config

{snapshot.system.previewConfig}
); } export default function App() { const [isAuthed, setIsAuthed] = useState(false); const [activeTab, setActiveTab] = useState('dashboard'); const [snapshot, setSnapshot] = useState(fallbackDashboardSnapshot); useEffect(() => { let cancelled = false; void fetch('/api/state') .then((response) => (response.ok ? response.json() : Promise.reject(new Error('API unavailable')))) .then((payload: DashboardSnapshot) => { if (!cancelled) { setSnapshot(payload); } }) .catch(() => { // Keep fallback snapshot for local UI and tests when backend is not running. }); return () => { cancelled = true; }; }, []); if (!isAuthed) { return setIsAuthed(true)} />; } const mutateSnapshot = async ( request: () => Promise, fallback: (current: DashboardSnapshot) => DashboardSnapshot, ) => { try { const response = await request(); if (response.ok) { const payload = (await response.json()) as DashboardSnapshot; setSnapshot(payload); return; } } catch { // Fall back to local optimistic state when the API is unavailable. } setSnapshot((current) => fallback(current)); }; const handleRuntimeAction = async (action: 'start' | 'restart') => { await mutateSnapshot( () => fetch(`/api/runtime/${action}`, { method: 'POST' }), (current) => withDerivedSnapshot({ ...current, service: { ...current.service, status: 'live', lastEvent: action === 'restart' ? 'Runtime restarted from panel' : 'Runtime start requested from panel', }, }), ); }; const handleCreateUser = async (input: CreateUserInput) => { await mutateSnapshot( () => fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(input), }), (current) => { const nextUser: ProxyUserRecord = { id: `u-${Math.random().toString(36).slice(2, 10)}`, username: input.username.trim(), password: input.password.trim(), serviceId: input.serviceId, status: 'idle', paused: false, usedBytes: 0, quotaBytes: input.quotaMb === null ? null : input.quotaMb * 1024 * 1024, }; return withDerivedSnapshot({ ...current, service: { ...current.service, lastEvent: `User ${nextUser.username} created from panel`, }, userRecords: [...current.userRecords, nextUser], }); }, ); }; const handleTogglePause = async (userId: string) => { await mutateSnapshot( () => fetch(`/api/users/${userId}/pause`, { method: 'POST' }), (current) => withDerivedSnapshot({ ...current, userRecords: current.userRecords.map((user) => user.id === userId ? { ...user, paused: !user.paused } : user, ), }), ); }; const handleDeleteUser = async (userId: string) => { await mutateSnapshot( () => fetch(`/api/users/${userId}`, { method: 'DELETE' }), (current) => withDerivedSnapshot({ ...current, userRecords: current.userRecords.filter((user) => user.id !== userId), }), ); }; return (

3proxy UI

{snapshot.system.publicHost}

Status {snapshot.service.status}
Version {snapshot.service.versionLabel}
Users {snapshot.users.total}
{activeTab === 'dashboard' ? : null} {activeTab === 'users' ? ( ) : null} {activeTab === 'system' ? : null}
); } function withDerivedSnapshot(snapshot: DashboardSnapshot): DashboardSnapshot { const live = snapshot.userRecords.filter((user) => !user.paused && user.status === 'live').length; const exceeded = snapshot.userRecords.filter( (user) => user.quotaBytes !== null && user.usedBytes >= user.quotaBytes, ).length; const nearQuota = snapshot.userRecords.filter((user) => { if (user.paused || user.quotaBytes === null || user.usedBytes >= user.quotaBytes) { return false; } return user.usedBytes / user.quotaBytes >= 0.8; }).length; return { ...snapshot, traffic: { ...snapshot.traffic, activeUsers: snapshot.userRecords.filter((user) => !user.paused).length, }, users: { total: snapshot.userRecords.length, live, nearQuota, exceeded, }, }; }