@@ -3,13 +3,11 @@ import { AdminsSettings } from "./AdminsSettings";
33import { getMe , logout } from "./api" ;
44import { Credentials } from "./Credentials" ;
55import { BrandLogo } from "./Logo" ;
6- import { EventsPanel } from "./EventsPanel" ;
76import { OverviewPanel } from "./OverviewPanel" ;
87import { PaymentsPage } from "./PaymentsPage" ;
98import { useIsAdmin , useIsOwner } from "./role" ;
109import { navigate , useRoute } from "./router" ;
1110import { SettingsPanel } from "./SettingsPanel" ;
12- import { StatsPanel } from "./StatsPanel" ;
1311import {
1412 cn ,
1513 Drawer ,
@@ -21,19 +19,14 @@ import {
2119 IconChevron ,
2220 IconGithub ,
2321} from "./ui" ;
24- import { UsersPanel } from "./UsersPanel " ;
22+ import { UsersPage } from "./UsersPage " ;
2523
2624// "admins" is a page without a nav tab: the roster is reached from the account menu
2725// (it's about who runs the panel, not about how the VPN is configured), so it never
2826// appears in NAV — only in the route.
29- type Tab =
30- | "overview"
31- | "users"
32- | "stats"
33- | "payments"
34- | "events"
35- | "settings"
36- | "admins" ;
27+ // Statistics and the journal aren't tabs either: they're sub-tabs of "users"
28+ // (see UsersPage), because both only ever describe end users.
29+ type Tab = "overview" | "users" | "payments" | "settings" | "admins" ;
3730
3831export function Dashboard ( {
3932 username,
@@ -74,16 +67,15 @@ export function Dashboard({
7467 return ( ) => window . removeEventListener ( "rospanel:billing-changed" , h ) ;
7568 } , [ ] ) ;
7669
77- // An operator gets the tabs whose routes they can actually call: end users, stats
78- // and the journal. Settings and the payments desk are admin-and-up, so they're not
79- // rendered — and if an operator navigates to /settings by hand, `tab` falls back
80- // to the dashboard rather than showing a page whose every request would 403.
70+ // An operator gets the tabs whose routes they can actually call: the dashboard and
71+ // the users section (list, stats, journal). Settings and the payments desk are
72+ // admin-and-up, so they're not rendered — and if an operator navigates to /settings
73+ // by hand, `tab` falls back to the dashboard rather than showing a page whose every
74+ // request would 403.
8175 const NAV : { value : Tab ; label : string } [ ] = [
8276 { value : "overview" , label : "Дашборд" } ,
8377 { value : "users" , label : "Пользователи" } ,
84- { value : "stats" , label : "Статистика" } ,
8578 ...( billing && isAdmin ? [ { value : "payments" as Tab , label : "Оплата" } ] : [ ] ) ,
86- { value : "events" , label : "Журнал" } ,
8779 ...( isAdmin ? [ { value : "settings" as Tab , label : "Настройки" } ] : [ ] ) ,
8880 ] ;
8981 // The roster isn't in NAV, so resolve it separately — and only for the owner, so
@@ -232,10 +224,8 @@ export function Dashboard({
232224 < main className = "mx-auto w-full max-w-6xl flex-1 px-3 py-6 sm:px-4" >
233225 < div key = { tab } className = "animate-fade-in" >
234226 { tab === "overview" && < OverviewPanel /> }
235- { tab === "users" && < UsersPanel /> }
236- { tab === "stats" && < StatsPanel /> }
227+ { tab === "users" && < UsersPage /> }
237228 { tab === "payments" && < PaymentsPage /> }
238- { tab === "events" && < EventsPanel /> }
239229 { tab === "settings" && < SettingsPanel /> }
240230 { tab === "admins" && < AdminsSettings /> }
241231 </ div >
0 commit comments