harshapitla/github-actions-analytics
0
1import React, { Suspense, lazy, useState } from "react";2import ErrorBoundary from "./components/boundaries/ErrorBoundary";3import "./App.css";4 5import LoadingState from "./components/common/LoadingState";6import StatusBanner from "./components/common/StatusBanner";7import AppHeader from "./components/layout/AppHeader";8import DatasetMetaPanel from "./components/layout/DatasetMetaPanel";9 10import { useMarketplaceDataset } from "./hooks/useMarketplaceDataset";11import { DATASET_PATH } from "./config/appConfig";12 13/* ================= KPI OVERVIEW ================= */14const KpiOverview = lazy(() => import("./components/overview/KpiOverview"));15 16/* ================= SNAPSHOT ================= */17const InsightsSnapshot = lazy(() => import("./charts/InsightsSnapshot"));18 19/* ================= TRUST & ADOPTION ================= */20const VerifiedActionsChart = lazy(() =>21 import("./charts/VerifiedActionsChart")22);23const VerifiedActionsVsStarsChart = lazy(() =>24 import("./charts/VerifiedActionsVsStarsChart")25);26 27/* ================= ECOSYSTEM ================= */28const MostCommonTagsChart = lazy(() => import("./charts/MostCommonTagsChart"));29const VerificationByTagChart = lazy(() =>30 import("./charts/VerificationByTagChart")31);32 33/* ================= MAINTENANCE HEALTH ================= */34const PopularityVsMaintenanceLoadChart = lazy(() =>35 import("./charts/PopularityVsUnresolvedPainChart")36);37const VerificationImpactChart = lazy(() =>38 import("./charts/VerificationImpactChart")39);40 41const IssueBacklogRatioChart = lazy(() =>42 import("./charts/IssueBacklogRatioChart")43);44 45/* ================= MAINTAINER LOAD ================= */46const MaintainerStressIndexChart = lazy(() =>47 import("./charts/MaintainerStressIndexChart")48);49const MaintenanceLoadByTagChart = lazy(() =>50 import("./charts/MaintenanceLoadByTagChart")51);52const ContributorAdequacyChart = lazy(() =>53 import("./charts/ContributorAdequacyChart")54);55 56/* ================= CATEGORY INSIGHTS ================= */57const TagPopularityVsDifficultyChart = lazy(() =>58 import("./charts/TagPopularityVsDifficultyChart")59);60 61export default function App() {62 const [showFields, setShowFields] = useState(false);63 64 const { rows, metadata, status, error, hasData, refresh } =65 useMarketplaceDataset(DATASET_PATH);66 67 /* ================= INITIAL STATES ================= */68 if (status === "loading" && !hasData) {69 return (70 <LoadingState71 label="Loading dataset"72 description="Fetching GitHub Actions marketplace data…"73 />74 );75 }76 77 if (status === "error" && !hasData) {78 return (79 <StatusBanner80 variant="error"81 title="Dataset load failed"82 message={error ? String(error) : "Unknown error"}83 actionLabel="Retry"84 onAction={refresh}85 />86 );87 }88 89 /* ================= MAIN APP ================= */90 return (91 <div className="app-container">92 {/* ================= HEADER ================= */}93 <AppHeader94 metadata={metadata}95 showColumns={showFields}96 onToggleColumns={() => setShowFields((p) => !p)}97 isLoadingMetadata={status === "loading"}98 onRefresh={refresh}99 isRefreshing={status === "loading"}100 />101 102 {/* ================= DATASET META ================= */}103 <DatasetMetaPanel metadata={metadata} visible={showFields} />104 105 {/* ================= WARNING ================= */}106 {error && hasData && (107 <StatusBanner108 variant="warning"109 title="Showing cached data"110 message="Latest refresh failed. Using last successful dataset."111 actionLabel="Retry"112 onAction={refresh}113 />114 )}115 116 {/* ================= CONTENT ================= */}117 <ErrorBoundary>118 <Suspense119 fallback={120 <LoadingState121 label="Building dashboard"122 description="Preparing insights and charts…"123 />124 }125 >126 {/* ================= SNAPSHOT ================= */}127 128 {/* ================= KPI OVERVIEW ================= */}129 <div className="row">130 <KpiOverview rows={rows} />131 </div>132 133 {/* ================= TRUST & ADOPTION ================= */}134 <h2 className="section-heading">Trust & Adoption</h2>135 <div className="row card">136 <VerifiedActionsChart rows={rows} />137 </div>138 <div className="row card">139 <VerifiedActionsVsStarsChart rows={rows} />140 </div>141 142 {/* ================= ECOSYSTEM COMPOSITION ================= */}143 <h2 className="section-heading">Ecosystem Overview</h2>144 <div className="row card">145 <MostCommonTagsChart rows={rows} />146 </div>147 <div className="row card">148 <VerificationByTagChart rows={rows} />149 </div>150 151 {/* ================= MAINTENANCE HEALTH ================= */}152 <h2 className="section-heading">Maintenance Health</h2>153 <div className="row card">154 <PopularityVsMaintenanceLoadChart rows={rows} />155 </div>156 <div className="row card">157 <VerificationImpactChart rows={rows} />158 </div>159 <div className="row card">160 <IssueBacklogRatioChart rows={rows} />161 </div>162 163 {/* ================= MAINTAINER LOAD ================= */}164 <h2 className="section-heading">Maintainer Load & Risk</h2>165 <div className="row card">166 <MaintainerStressIndexChart rows={rows} />167 </div>168 <div className="row card">169 <MaintenanceLoadByTagChart rows={rows} />170 </div>171 <div className="row card">172 <ContributorAdequacyChart rows={rows} />173 </div>174 175 {/* ================= CATEGORY DIFFICULTY ================= */}176 <h2 className="section-heading">Popularity vs Difficulty</h2>177 <div className="row card">178 <TagPopularityVsDifficultyChart rows={rows} />179 </div>180 </Suspense>181 </ErrorBoundary>182 </div>183 );184}185 