stack / src /App.js
harshapitla's picture
Initial commit for new Hugging Face Space
8f3ae5d
Raw
History Blame Contribute Delete
8.7 kB
import React, { Suspense, lazy, useState } from "react";
import ErrorBoundary from "./components/boundaries/ErrorBoundary";
import "./App.css";
import LoadingState from "./components/common/LoadingState";
import StatusBanner from "./components/common/StatusBanner";
import AppHeader from "./components/layout/AppHeader";
import DatasetMetaPanel from "./components/layout/DatasetMetaPanel";
import KpiOverview from "./components/overview/KpiOverview";
import StackOverflowKpiOverview from "./components/overview/StackOverflowKpiOverview";
import { useMarketplaceDataset } from "./hooks/useMarketplaceDataset";
import { useProductHuntDataset } from "./hooks/useProductHuntDataset";
import { DATASET_PATH } from "./config/appConfig";
/* ================= CHART IMPORTS ================= */
// Demographics
const DevelopersByCountryBar = lazy(() =>
import("./charts/DevelopersByCountryBar")
);
const AgeDistributionHistogram = lazy(() =>
import("./charts/AgeDistributionHistogram")
);
const GenderDistributionDonut = lazy(() =>
import("./charts/GenderDistributionDonut")
);
// Experience & Career
const CodingExperienceHistogram = lazy(() =>
import("./charts/CodingExperienceHistogram")
);
const DeveloperRolesChart = lazy(() => import("./charts/DeveloperRolesChart"));
const SalaryByRoleChart = lazy(() => import("./charts/SalaryByRoleChart"));
const RemoteWorkVsSalaryBoxPlot = lazy(() =>
import("./charts/RemoteWorkVsSalaryBoxPlot")
);
// Education & Work Style
const EducationLevelBarChart = lazy(() =>
import("./charts/EducationLevelBarChart")
);
const RemoteWorkPreferencePieChart = lazy(() =>
import("./charts/RemoteWorkPreferencePieChart")
);
const OrgSizeVsRemoteWorkChart = lazy(() =>
import("./charts/OrgSizeVsRemoteWorkChart")
);
// Technology Usage
const MostUsedLanguagesChart = lazy(() =>
import("./charts/MostUsedLanguagesChart")
);
const LanguagesUsedVsAdmiredChart = lazy(() =>
import("./charts/LanguagesUsedVsAdmiredChart")
);
const MostUsedDatabasesChart = lazy(() =>
import("./charts/MostUsedDatabasesChart")
);
const DatabasesHaveVsWantChart = lazy(() =>
import("./charts/DatabasesHaveVsWantChart")
);
const PlatformsDevelopersWorkWithChart = lazy(() =>
import("./charts/PlatformsDevelopersWorkWithChart")
);
const PlatformsHaveVsWantChart = lazy(() =>
import("./charts/PlatformsHaveVsWantChart")
);
// AI & Community
const ExperienceVsAIUsageChart = lazy(() =>
import("./charts/ExperienceVsAIUsageChart")
);
const StackOverflowChart = lazy(() => import("./charts/StackOverflowChart"));
export default function App() {
const [showFields, setShowFields] = useState(false);
const { metadata, status, error, hasData, refresh } =
useMarketplaceDataset(DATASET_PATH);
const productHuntData = useProductHuntDataset(DATASET_PATH);
const initialLoading = status === "loading" && !hasData;
const initialError = status === "error" && !hasData;
return (
<div className="app-container">
{/* ================= HEADER ================= */}
<AppHeader
metadata={metadata}
showColumns={showFields}
onToggleColumns={() => setShowFields((p) => !p)}
isLoadingMetadata={status === "loading"}
onRefresh={refresh}
isRefreshing={status === "loading"}
/>
{/* ================= DATASET META ================= */}
<DatasetMetaPanel metadata={metadata} visible={showFields} />
{/* ================= WARNING ================= */}
{error && hasData && (
<StatusBanner
variant="warning"
title="Showing cached data"
message="Latest refresh failed. Using last successful dataset."
actionLabel="Retry"
onAction={refresh}
/>
)}
{/* ================= INITIAL LOADING / ERROR ================= */}
{initialLoading && (
<LoadingState
label="Loading dataset"
description="Fetching Stack Overflow survey data…"
/>
)}
{initialError && (
<StatusBanner
variant="error"
title="Dataset load failed"
message={error ? String(error) : "Unknown error"}
actionLabel="Retry"
onAction={refresh}
/>
)}
{/* ================= CONTENT ================= */}
<ErrorBoundary>
{/* ================= STACK OVERFLOW KPI OVERVIEW ================= */}
<div className="row card">
<Suspense
fallback={<LoadingState label="Loading Stack Overflow KPI…" />}
>
<StackOverflowKpiOverview rows={productHuntData.rows} />
</Suspense>
</div>
{/* <h2 className="section-heading">Developer Demographics</h2>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<DevelopersByCountryBar rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<AgeDistributionHistogram rows={productHuntData.rows} />
</Suspense>
</div>
<h2 className="section-heading">Experience & Career Insights</h2>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<CodingExperienceHistogram rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<DeveloperRolesChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<SalaryByRoleChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<RemoteWorkVsSalaryBoxPlot rows={productHuntData.rows} />
</Suspense>
</div>
<h2 className="section-heading">Education & Work Style</h2>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<EducationLevelBarChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<RemoteWorkPreferencePieChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<OrgSizeVsRemoteWorkChart rows={productHuntData.rows} />
</Suspense>
</div>
<h2 className="section-heading">Technology Trends</h2>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<MostUsedLanguagesChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<LanguagesUsedVsAdmiredChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<MostUsedDatabasesChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<DatabasesHaveVsWantChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<PlatformsDevelopersWorkWithChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<PlatformsHaveVsWantChart rows={productHuntData.rows} />
</Suspense>
</div>
<h2 className="section-heading">AI & Community Usage</h2>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<ExperienceVsAIUsageChart rows={productHuntData.rows} />
</Suspense>
</div>
<div className="row card">
<Suspense fallback={<LoadingState label="Loading chart…" />}>
<StackOverflowChart rows={productHuntData.rows} />
</Suspense>
</div> */}
</ErrorBoundary>
</div>
);
}