Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useAuthBridge } from '@/components/auth';
import { initSupa, getSupa } from '@/lib/supa';
import {
Activity,
RefreshCw,
Expand Down Expand Up @@ -514,7 +514,10 @@ function ApplicationRow({
// ---------------------------------------------------------------------------

export default function ReactArgoDashboard() {
const { session, isLoading: authLoading } = useAuthBridge();
const [authState, setAuthState] = useState<
'loading' | 'authenticated' | 'unauthenticated'
>('loading');
const [accessToken, setAccessToken] = useState<string | null>(null);

const [applications, setApplications] = useState<ArgoApplication[]>([]);
const [loading, setLoading] = useState(true);
Expand All @@ -523,8 +526,6 @@ export default function ReactArgoDashboard() {
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const [expandedApp, setExpandedApp] = useState<string | null>(null);

const token = session?.access_token;

const fetchData = useCallback(async (tkn: string) => {
try {
setError(null);
Expand All @@ -543,9 +544,39 @@ export default function ReactArgoDashboard() {
}
}, []);

// Initial load + auto-refresh
// Auth init — same pattern as Grafana dashboard
useEffect(() => {
let cancelled = false;

(async () => {
try {
await initSupa();
const supa = getSupa();
const sessionResult = await supa.getSession().catch(() => null);
const session = sessionResult?.session ?? null;

if (cancelled) return;

if (!session?.access_token) {
setAuthState('unauthenticated');
return;
}

setAccessToken(session.access_token as string);
setAuthState('authenticated');
} catch {
if (!cancelled) setAuthState('unauthenticated');
}
})();

return () => {
cancelled = true;
};
}, []);

// Data load + auto-refresh
useEffect(() => {
if (!token) return;
if (!accessToken) return;

// Try cache first
const cached = loadCache();
Expand All @@ -555,20 +586,20 @@ export default function ReactArgoDashboard() {
setLoading(false);
}

fetchData(token);
fetchData(accessToken);

const interval = setInterval(
() => fetchData(token),
() => fetchData(accessToken),
REFRESH_INTERVAL_MS,
);
return () => clearInterval(interval);
}, [token, fetchData]);
}, [accessToken, fetchData]);

// -----------------------------------------------------------------------
// Auth states
// -----------------------------------------------------------------------

if (authLoading) {
if (authState === 'loading') {
return (
<div style={fullCenter}>
<Loader2
Expand All @@ -583,7 +614,7 @@ export default function ReactArgoDashboard() {
);
}

if (!session || !token) {
if (authState === 'unauthenticated' || !accessToken) {
return (
<div style={fullCenter}>
<LogIn
Expand Down Expand Up @@ -685,9 +716,9 @@ export default function ReactArgoDashboard() {
</div>
<button
onClick={() => {
if (token) {
if (accessToken) {
setLoading(true);
fetchData(token);
fetchData(accessToken);
}
}}
disabled={loading}
Expand Down Expand Up @@ -834,7 +865,7 @@ export default function ReactArgoDashboard() {
<ApplicationRow
key={app.metadata.name}
app={app}
token={token}
token={accessToken}
expanded={expandedApp === app.metadata.name}
onToggle={() =>
setExpandedApp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import React, {
useMemo,
Suspense,
} from 'react';
import { useAuthBridge } from '@/components/auth';
import { initSupa, getSupa } from '@/lib/supa';
import {
BarChart3,
GitBranch,
Zap,
Loader2,
LogIn,
ShieldOff,
ArrowRight,
Activity,
} from 'lucide-react';
Expand Down Expand Up @@ -351,23 +350,54 @@ function StatItem({
// ---------------------------------------------------------------------------

export default function ReactDashboardHome() {
const { session, isLoading: authLoading } = useAuthBridge();
const [authState, setAuthState] = useState<
'loading' | 'authenticated' | 'unauthenticated'
>('loading');
const [accessToken, setAccessToken] = useState<string | null>(null);
const [grafana, setGrafana] = useState<GrafanaSummary | null>(null);
const [argo, setArgo] = useState<ArgoSummary | null>(null);
const [edge, setEdge] = useState<EdgeSummary | null>(null);
const [loading, setLoading] = useState(true);
const containerRef = useRef<HTMLDivElement>(null);

const token = session?.access_token;
// Auth init — same pattern as Grafana dashboard
useEffect(() => {
let cancelled = false;

(async () => {
try {
await initSupa();
const supa = getSupa();
const sessionResult = await supa.getSession().catch(() => null);
const session = sessionResult?.session ?? null;

if (cancelled) return;

if (!session?.access_token) {
setAuthState('unauthenticated');
return;
}

setAccessToken(session.access_token as string);
setAuthState('authenticated');
} catch {
if (!cancelled) setAuthState('unauthenticated');
}
})();

return () => {
cancelled = true;
};
}, []);

const fetchAll = useCallback(async () => {
setLoading(true);
const edgePromise = fetchEdgeSummary();

if (token) {
if (accessToken) {
const [g, a, e] = await Promise.all([
fetchGrafanaSummary(token),
fetchArgoSummary(token),
fetchGrafanaSummary(accessToken),
fetchArgoSummary(accessToken),
edgePromise,
]);
setGrafana(g);
Expand All @@ -378,16 +408,16 @@ export default function ReactDashboardHome() {
setEdge(e);
}
setLoading(false);
}, [token]);
}, [accessToken]);

useEffect(() => {
if (!authLoading) fetchAll();
}, [authLoading, fetchAll]);
if (authState === 'authenticated') fetchAll();
}, [authState, fetchAll]);

// GSAP entrance animation
useGSAP(
() => {
if (authLoading || !containerRef.current) return;
if (authState !== 'authenticated' || !containerRef.current) return;

const header =
containerRef.current.querySelector('.dashboard-header');
Expand All @@ -414,14 +444,14 @@ export default function ReactDashboardHome() {
});
}
},
{ scope: containerRef, dependencies: [authLoading, loading] },
{ scope: containerRef, dependencies: [authState, loading] },
);

// -----------------------------------------------------------------------
// Auth states
// -----------------------------------------------------------------------

if (authLoading) {
if (authState === 'loading') {
return (
<div className="not-content" style={styles.centeredMessage}>
<Loader2
Expand All @@ -434,7 +464,7 @@ export default function ReactDashboardHome() {
);
}

if (!session) {
if (authState === 'unauthenticated') {
return (
<div className="not-content" style={styles.centeredMessage}>
<LogIn
Expand Down
2 changes: 1 addition & 1 deletion apps/kbve/axum-kbve/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "axum-kbve"
authors = ["kbve", "h0lybyte"]
version = "1.0.34"
version = "1.0.35"
edition = "2021"
publish = false

Expand Down
Loading