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