From e9178bc340d4d262b34b247fdeea9a6afeb96ef8 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 8 Sep 2026 15:10:34 +0530 Subject: [PATCH] feat: --Added new pages Dashboard, Nodes, Cluster --- src/App.css | 56 ++++++++++++++++++++++++ src/App.tsx | 122 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 166 insertions(+), 12 deletions(-) diff --git a/src/App.css b/src/App.css index 08461f4..dacf55e 100644 --- a/src/App.css +++ b/src/App.css @@ -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; } diff --git a/src/App.tsx b/src/App.tsx index 2992ae1..936ecb6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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(getSavedPage) const [theme, setTheme] = useState(getSavedTheme) const [isRegisterFormOpen, setIsRegisterFormOpen] = useState(false) + const [tokenStatus, setTokenStatus] = useState('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 (
setActivePage(item.id)} + onClick={() => selectPage(item.id)} aria-current={activePage === item.id ? 'page' : undefined} >
)