--Added new pages Dashboard, Nodes, Cluster
This commit is contained in:
george committed 2026-09-08 15:10:34 +05:30
1 parent 50e424bc22
commit e9178bc340
2 files changed
+166 -12

No files matched your search

+56
View File
@@ -257,6 +257,13 @@
margin: 0;
}
.page-actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: flex-end;
}
.primary-button,
.secondary-button {
display: inline-flex;
@@ -284,6 +291,12 @@
background: var(--accent-border);
}
.primary-button:disabled,
.secondary-button:disabled {
cursor: not-allowed;
opacity: 0.65;
}
.secondary-button {
border: 1px solid var(--border);
background: var(--bg);
@@ -295,6 +308,11 @@
background: var(--accent-bg);
}
.secondary-button:disabled:hover {
border-color: var(--border);
background: var(--bg);
}
.primary-button:focus-visible,
.secondary-button:focus-visible,
.register-form input:focus-visible {
@@ -302,6 +320,40 @@
outline-offset: 2px;
}
.status-message {
width: fit-content;
margin-bottom: 18px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 14px;
font-weight: 600;
padding: 8px 12px;
}
.status-message.success {
border-color: #86efac;
background: #f0fdf4;
color: #166534;
}
.status-message.error {
border-color: #fecaca;
background: #fef2f2;
color: #991b1b;
}
.theme-dark .status-message.success {
border-color: #166534;
background: rgba(22, 101, 52, 0.18);
color: #bbf7d0;
}
.theme-dark .status-message.error {
border-color: #991b1b;
background: rgba(153, 27, 27, 0.18);
color: #fecaca;
}
.register-form {
border: 1px solid var(--border);
border-radius: 8px;
@@ -379,6 +431,10 @@
flex-direction: column;
}
.page-actions {
justify-content: flex-start;
}
.form-grid {
grid-template-columns: 1fr;
}
+110 -12
View File
@@ -4,9 +4,12 @@ import './App.css'
const navItems = [
{ id: 'dashboard', label: 'Dashboard' },
{ id: 'nodes', label: 'Nodes' },
]
{ id: 'clusters', label: 'Clusters' },
] as const
type PageId = (typeof navItems)[number]['id']
type Theme = 'light' | 'dark'
type TokenStatus = 'idle' | 'loading' | 'success' | 'error'
const getSavedTheme = (): Theme => {
try {
@@ -24,13 +27,67 @@ const saveTheme = (theme: Theme) => {
}
}
const getSavedPage = (): PageId => {
try {
const savedPage = localStorage.getItem('activePage')
return navItems.some((item) => item.id === savedPage)
? (savedPage as PageId)
: 'dashboard'
} catch {
return 'dashboard'
}
}
const savePage = (page: PageId) => {
try {
localStorage.setItem('activePage', page)
} catch {
return
}
}
const getSessionToken = async () => {
const response = await fetch('http://127.0.0.1:8000/get-token', {
method: 'POST',
})
if (!response.ok) {
throw new Error('Failed to get token')
}
const data = (await response.json()) as {
access_token: string
token_type: string
}
localStorage.setItem('access_token', data.access_token)
const storedToken = localStorage.getItem('access_token')
if (!storedToken) {
throw new Error('Token was not stored')
}
console.log('Token successfully stored:', storedToken)
return storedToken
}
function App() {
const [isCollapsed, setIsCollapsed] = useState(false)
const [activePage, setActivePage] = useState('dashboard')
const [activePage, setActivePage] = useState<PageId>(getSavedPage)
const [theme, setTheme] = useState<Theme>(getSavedTheme)
const [isRegisterFormOpen, setIsRegisterFormOpen] = useState(false)
const [tokenStatus, setTokenStatus] = useState<TokenStatus>('idle')
const [tokenError, setTokenError] = useState('')
const nextTheme = theme === 'light' ? 'dark' : 'light'
const selectPage = (page: PageId) => {
setActivePage(page)
savePage(page)
}
const toggleTheme = () => {
setTheme((currentTheme) => {
const updatedTheme = currentTheme === 'light' ? 'dark' : 'light'
@@ -41,6 +98,21 @@ function App() {
})
}
const handleTempButtonClick = async () => {
setTokenStatus('loading')
setTokenError('')
try {
await getSessionToken()
setTokenStatus('success')
} catch (error) {
setTokenStatus('error')
setTokenError(
error instanceof Error ? error.message : 'Failed to get token',
)
}
}
return (
<div
className={`app-shell theme-${theme} ${isCollapsed ? 'nav-collapsed' : ''}`}
@@ -66,7 +138,7 @@ function App() {
type="button"
className={`nav-link ${activePage === item.id ? 'active' : ''}`}
title={isCollapsed ? item.label : undefined}
onClick={() => setActivePage(item.id)}
onClick={() => selectPage(item.id)}
aria-current={activePage === item.id ? 'page' : undefined}
>
<span className="nav-icon" aria-hidden="true">
@@ -94,7 +166,7 @@ function App() {
</aside>
<main className="main-content">
{activePage === 'dashboard' ? (
{activePage === 'dashboard' && (
<section className="content-panel" id="dashboard">
<p className="eyebrow">Dashboard</p>
<h1>Welcome back</h1>
@@ -104,19 +176,39 @@ function App() {
grows.
</p>
</section>
) : (
)}
{activePage === 'nodes' && (
<section className="content-panel nodes-page" id="nodes">
<div className="page-header">
<h1>Nodes</h1>
<button
type="button"
className="primary-button"
onClick={() => setIsRegisterFormOpen(true)}
>
Register Nodes
</button>
<div className="page-actions">
<button
type="button"
className="primary-button"
onClick={() => setIsRegisterFormOpen(true)}
>
Register Nodes
</button>
<button
type="button"
className="secondary-button"
onClick={handleTempButtonClick}
disabled={tokenStatus === 'loading'}
>
{tokenStatus === 'loading' ? 'Getting Token' : 'Temp Button'}
</button>
</div>
</div>
{tokenStatus === 'success' && (
<p className="status-message success">Token successfully stored.</p>
)}
{tokenStatus === 'error' && (
<p className="status-message error">{tokenError}</p>
)}
{isRegisterFormOpen ? (
<form className="register-form">
<div className="form-grid">
@@ -174,6 +266,12 @@ function App() {
) : null}
</section>
)}
{activePage === 'clusters' && (
<section className="content-panel" id="clusters">
<h1>Clusters</h1>
</section>
)}
</main>
</div>
)