← back to drive-brand-growth__michigan-cdaio-program

Function bodies 11 total

All specs Real LLM only Function bodies
App function · javascript · L13-L127 (115 LOC)
src/App.jsx
function App() {
  const [selectedModule, setSelectedModule] = useState(0);
  const [activeTab, setActiveTab] = useState('overview');
  const [scenarioAnswers, setScenarioAnswers] = useState({});
  const [quizAnswers, setQuizAnswers] = useState({});
  const [quizSubmitted, setQuizSubmitted] = useState({});
  const { completedModules, markComplete, reset } = useProgress();

  const currentModule = modules[selectedModule];

  const handleModuleSelect = (idx) => {
    setSelectedModule(idx);
    setActiveTab('overview');
  };

  const handleReset = () => {
    if (window.confirm('Reset all progress? This cannot be undone.')) {
      reset();
      setScenarioAnswers({});
      setQuizAnswers({});
      setQuizSubmitted({});
    }
  };

  const handleScenarioAnswer = (scenarioId, optionIndex) => {
    if (optionIndex === undefined) {
      setScenarioAnswers((prev) => {
        const next = { ...prev };
        delete next[scenarioId];
        return next;
      });
    } else {
      setS
ModuleChart function · javascript · L17-L123 (107 LOC)
src/charts/ModuleChart.jsx
export default function ModuleChart({ data, type, label, moduleId }) {
  if (type === 'bar') {
    // Check if data has multiple numeric keys (grouped bar)
    const sampleItem = data[0] || {};
    const numericKeys = Object.keys(sampleItem).filter(
      (k) => k !== 'name' && typeof sampleItem[k] === 'number'
    );
    const isGrouped = numericKeys.length > 1;

    const colors = ['#ffcb05', '#60a5fa', '#4ade80', '#c084fc'];

    return (
      <ResponsiveContainer width="100%" height={280}>
        <BarChart data={data} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>
          <CartesianGrid strokeDasharray="3 3" stroke="#1e3a5f" />
          <XAxis
            dataKey="name"
            tick={{ fill: '#94a3b8', fontSize: 11 }}
            axisLine={{ stroke: '#1e3a5f' }}
            tickLine={{ stroke: '#1e3a5f' }}
          />
          <YAxis
            tick={{ fill: '#94a3b8', fontSize: 11 }}
            axisLine={{ stroke: '#1e3a5f' }}
            tickLine={{ stroke: '#1e
Header function · javascript · L12-L158 (147 LOC)
src/components/Header.jsx
export default function Header({ module, activeTab, onTabChange }) {
  const Icon = module.icon;

  return (
    <div style={{ borderBottom: '1px solid #1e3a5f' }}>
      {/* Title bar */}
      <div style={{
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'flex-start',
        padding: '20px 32px 12px',
      }}>
        <div style={{ display: 'flex', gap: 14, alignItems: 'flex-start' }}>
          <div style={{
            width: 40,
            height: 40,
            background: '#0f2744',
            borderRadius: 10,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}>
            <Icon size={20} color="#ffcb05" />
          </div>
          <div>
            <h1 style={{ fontSize: 20, fontWeight: 700, color: '#e2e8f0', margin: 0, lineHeight: 1.2 }}>
              {module.title}
            </h1>
            <p style={{ fontSize: 13, color: '#94a3b8', margin: '4px 0 0' }}>
        
Sidebar function · javascript · L5-L251 (247 LOC)
src/components/Sidebar.jsx
export default function Sidebar({ modules, selectedModule, onSelect, completedModules, onReset }) {
  const completedCount = completedModules.size;
  const progress = (completedCount / modules.length) * 100;

  const [collapsed, setCollapsed] = useState({});

  const togglePillar = (pillarId) => {
    setCollapsed((prev) => ({ ...prev, [pillarId]: !prev[pillarId] }));
  };

  // Group modules by pillar
  const grouped = {};
  modules.forEach((mod, idx) => {
    const key = mod.pillar || 'other';
    if (!grouped[key]) grouped[key] = [];
    grouped[key].push({ mod, idx });
  });

  // Order groups by pillars array
  const orderedGroups = pillars
    .filter((p) => grouped[p.id])
    .map((p) => ({ pillar: p, items: grouped[p.id] }));

  return (
    <div style={{
      width: 280,
      minWidth: 280,
      background: '#0a1628',
      borderRight: '1px solid #1e3a5f',
      display: 'flex',
      flexDirection: 'column',
      height: '100vh',
      overflow: 'hidden',
    }}>
      {
ChartTab function · javascript · L3-L24 (22 LOC)
src/components/tabs/ChartTab.jsx
export default function ChartTab({ module }) {
  return (
    <div style={{ maxWidth: 720 }}>
      <div style={{
        background: '#0a1628',
        border: '1px solid #1e3a5f',
        borderRadius: 12,
        padding: 24,
      }}>
        <h3 style={{ fontSize: 16, fontWeight: 700, color: '#e2e8f0', marginBottom: 20 }}>
          {module.chartLabel}
        </h3>
        <ModuleChart
          data={module.chartData}
          type={module.chartType}
          label={module.chartLabel}
          moduleId={module.id}
        />
      </div>
    </div>
  );
}
ConceptsTab function · javascript · L1-L30 (30 LOC)
src/components/tabs/ConceptsTab.jsx
export default function ConceptsTab({ module }) {
  return (
    <div style={{ maxWidth: 720 }}>
      <h3 style={{ fontSize: 16, fontWeight: 700, color: '#e2e8f0', marginBottom: 16 }}>
        Key Concepts
      </h3>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        {module.concepts.map((concept, idx) => (
          <div
            key={idx}
            style={{
              background: '#0a1628',
              border: '1px solid #1e3a5f',
              borderRadius: 12,
              padding: 20,
              borderLeft: '3px solid #ffcb05',
            }}
          >
            <h4 style={{ fontSize: 14, fontWeight: 700, color: '#e2e8f0', marginBottom: 6 }}>
              {concept.name}
            </h4>
            <p style={{ fontSize: 13, lineHeight: 1.6, color: '#94a3b8', margin: 0 }}>
              {concept.desc}
            </p>
          </div>
        ))}
      </div>
    </div>
  );
}
OverviewTab function · javascript · L3-L87 (85 LOC)
src/components/tabs/OverviewTab.jsx
export default function OverviewTab({ module }) {
  return (
    <div style={{ maxWidth: 720 }}>
      <div style={{
        background: '#0a1628',
        border: '1px solid #1e3a5f',
        borderRadius: 12,
        padding: 24,
        marginBottom: 20,
      }}>
        <h3 style={{ fontSize: 16, fontWeight: 700, color: '#e2e8f0', marginBottom: 12 }}>
          Module Overview
        </h3>
        <p style={{ fontSize: 14, lineHeight: 1.7, color: '#94a3b8' }}>
          {module.overview}
        </p>
      </div>

      {/* Learning Objectives */}
      {module.learningObjectives && module.learningObjectives.length > 0 && (
        <div style={{
          background: '#0a1628',
          border: '1px solid #1e3a5f',
          borderRadius: 12,
          padding: 24,
          marginBottom: 20,
        }}>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginBottom: 16 }}>
            <Target size={18} color="#60a5fa" />
            <h3 style={{ fontSize: 
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
QuizTab function · javascript · L3-L201 (199 LOC)
src/components/tabs/QuizTab.jsx
export default function QuizTab({ module, quizAnswers, quizSubmitted, onQuizAnswer, onQuizSubmit, onQuizRetake }) {
  const quiz = module.quiz;
  const moduleId = module.id;
  const isSubmitted = quizSubmitted[moduleId];
  const allAnswered = quiz.every((_, idx) => quizAnswers[`${moduleId}-${idx}`] !== undefined);
  const passingThreshold = 0.8;

  let score = 0;
  if (isSubmitted) {
    quiz.forEach((q, idx) => {
      if (quizAnswers[`${moduleId}-${idx}`] === q.answer) score++;
    });
  }

  const percentage = Math.round((score / quiz.length) * 100);
  const passed = percentage >= passingThreshold * 100;

  return (
    <div style={{ maxWidth: 720 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
        <div>
          <h3 style={{ fontSize: 16, fontWeight: 700, color: '#e2e8f0', margin: 0 }}>
            Knowledge Check
          </h3>
          <p style={{ fontSize: 12, color: '#64748b', margin: '4px 0 0' }}>
    
ScenariosTab function · javascript · L3-L118 (116 LOC)
src/components/tabs/ScenariosTab.jsx
export default function ScenariosTab({ module, scenarioAnswers, onAnswer }) {
  return (
    <div style={{ maxWidth: 720, display: 'flex', flexDirection: 'column', gap: 24 }}>
      {module.scenarios.map((scenario) => {
        const answered = scenarioAnswers[scenario.id] !== undefined;
        const selectedIdx = scenarioAnswers[scenario.id];
        const correctIdx = scenario.options.findIndex((o) => o.correct);

        return (
          <div
            key={scenario.id}
            style={{
              background: '#0a1628',
              border: '1px solid #1e3a5f',
              borderRadius: 12,
              padding: 24,
            }}
          >
            <div style={{
              fontSize: 10,
              fontWeight: 700,
              color: '#60a5fa',
              textTransform: 'uppercase',
              letterSpacing: '0.1em',
              marginBottom: 12,
            }}>
              Executive Scenario
            </div>
            <p style={{ fontSize:
VideoTab function · javascript · L1-L55 (55 LOC)
src/components/tabs/VideoTab.jsx
export default function VideoTab({ module }) {
  return (
    <div style={{ maxWidth: 800, display: 'flex', flexDirection: 'column', gap: 24 }}>
      {module.videos.map((video, idx) => (
        <div
          key={idx}
          style={{
            background: '#0a1628',
            border: '1px solid #1e3a5f',
            borderRadius: 12,
            padding: 20,
          }}
        >
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
            <h4 style={{ fontSize: 15, fontWeight: 700, color: '#e2e8f0', margin: 0, flex: 1 }}>
              {video.title}
            </h4>
            <span style={{
              fontSize: 10,
              padding: '3px 8px',
              borderRadius: 4,
              background: '#1e3a5f',
              color: '#60a5fa',
              fontWeight: 600,
              whiteSpace: 'nowrap',
            }}>
              {video.source}
            </span>
            <span style={{
              fontSize:
useProgress function · javascript · L3-L26 (24 LOC)
src/hooks/useProgress.js
export function useProgress() {
  const [completedModules, setCompletedModules] = useState(() => {
    try {
      const stored = localStorage.getItem('cdaio-completed');
      return stored ? new Set(JSON.parse(stored)) : new Set();
    } catch {
      return new Set();
    }
  });

  useEffect(() => {
    localStorage.setItem('cdaio-completed', JSON.stringify([...completedModules]));
  }, [completedModules]);

  const markComplete = (id) => {
    setCompletedModules((prev) => new Set([...prev, id]));
  };

  const reset = () => {
    setCompletedModules(new Set());
  };

  return { completedModules, markComplete, reset };
}