workspace/projects/gamilit/docs/01-fase-alcance-inicial/EAI-005-admin-base/historias-usuario/US-ADM-003-dashboard-maestro.md
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

10 KiB

US-ADM-003: Dashboard de Maestro

Épica: EAI-005 (Plataforma de Maestro Básica) Sprint: Mes 1, Semana 2 Story Points: 8 SP Presupuesto: $3,200 MXN Prioridad: Alta (Alcance Inicial) Estado: Completada (Mes 1)


Descripción

Como profesor, quiero tener un dashboard general que me muestre un resumen de todas mis aulas para tener una vista panorámica de mi trabajo y acceder rápidamente a cada aula.

Contexto del Alcance Inicial:

Este es el dashboard principal del profesor al iniciar sesión. Muestra un resumen de todas sus aulas con estadísticas básicas y acceso rápido a analytics. NO incluye gráficas avanzadas, comparativas entre aulas, ni métricas de engagement (eso va a EXT-001 Portal de Maestros Completo).


Criterios de Aceptación

CA-01: Vista General de Aulas

  • Grid/cards con todas las aulas del profesor
  • Para cada aula muestra:
    • Nombre y nivel/grado
    • total de estudiantes

    • Progreso promedio (%)
    • de módulos asignados

    • Acceso rápido a dashboard del aula (US-ANA-001)
    • Acceso a lista de estudiantes (US-ADM-002)

CA-02: Resumen Global

  • Cards con métricas totales:
    • Total de aulas
    • Total de estudiantes (suma de todas las aulas)
    • Promedio general de progreso
  • Destacar aula con mejor/peor progreso

CA-03: Actividad Reciente Global

  • Feed de las últimas 10 actividades de TODAS las aulas
  • Cada actividad muestra: estudiante, aula, actividad, timestamp
  • Link rápido a perfil del estudiante

CA-04: Acciones Rápidas

  • Botón "Crear Nueva Aula" (US-ADM-001)
  • Selector de aula en header (dropdown para cambiar de contexto)

CA-05: Navegación

  • Breadcrumb: Dashboard
  • Sidebar con:
    • Dashboard (esta vista)
    • Mis Aulas (lista completa)
    • Configuración (placeholder)

Especificaciones Técnicas

Backend

Endpoint Principal:

GET /api/teacher/dashboard

Response:

{
  "summary": {
    "totalClassrooms": 3,
    "totalStudents": 75,
    "averageProgress": 62.5
  },
  "classrooms": [
    {
      "id": "uuid",
      "name": "Matemáticas 6A",
      "level": "primaria",
      "grade": 6,
      "studentCount": 25,
      "averageProgress": 65.5,
      "moduleCount": 5,
      "lastActivity": "2025-11-02T10:00:00Z"
    }
  ],
  "recentActivities": [
    {
      "id": "activity-uuid",
      "studentName": "Juan Pérez",
      "classroomName": "Matemáticas 6A",
      "activityName": "Suma de fracciones",
      "timestamp": "2025-11-02T10:30:00Z"
    }
  ],
  "insights": {
    "bestPerformingClassroom": {
      "id": "uuid",
      "name": "Matemáticas 6A",
      "progress": 75.5
    },
    "needsAttentionClassroom": {
      "id": "uuid",
      "name": "Ciencias 5B",
      "progress": 45.2
    }
  }
}

Controller:

@Get('teacher/dashboard')
async getTeacherDashboard(@CurrentUser() teacher: User) {
  return this.teacherService.getDashboard(teacher.id);
}

Service:

async getDashboard(teacherId: string) {
  const classrooms = await this.getClassroomsSummary(teacherId);
  const recentActivities = await this.getRecentActivitiesAcrossClassrooms(teacherId, 10);

  const summary = {
    totalClassrooms: classrooms.length,
    totalStudents: classrooms.reduce((sum, c) => sum + c.studentCount, 0),
    averageProgress: classrooms.length > 0
      ? classrooms.reduce((sum, c) => sum + c.averageProgress, 0) / classrooms.length
      : 0
  };

  const sortedByProgress = [...classrooms].sort((a, b) => b.averageProgress - a.averageProgress);

  return {
    summary,
    classrooms,
    recentActivities,
    insights: {
      bestPerformingClassroom: sortedByProgress[0] || null,
      needsAttentionClassroom: sortedByProgress[sortedByProgress.length - 1] || null
    }
  };
}

Frontend

Ruta:

/teacher/dashboard

Componente Principal:

// TeacherDashboard.tsx
export const TeacherDashboard = () => {
  const { dashboardData, isLoading } = useTeacherDashboard();
  const navigate = useNavigate();

  if (isLoading) return <DashboardSkeleton />;

  return (
    <div className="teacher-dashboard">
      <PageHeader
        title="Dashboard"
        subtitle={`Bienvenido, ${dashboardData.teacherName}`}
        action={
          <Button
            onClick={() => navigate('/teacher/classrooms/new')}
            leftIcon={<PlusIcon />}
          >
            Crear Aula
          </Button>
        }
      />

      <SummaryCards summary={dashboardData.summary} />

      <InsightsSection insights={dashboardData.insights} />

      <ClassroomGrid
        classrooms={dashboardData.classrooms}
        onViewClassroom={(id) => navigate(`/teacher/classroom/${id}/dashboard`)}
      />

      <RecentActivityFeed activities={dashboardData.recentActivities} />
    </div>
  );
};

Componente de Cards de Resumen:

// SummaryCards.tsx
export const SummaryCards = ({ summary }) => {
  return (
    <div className="summary-cards">
      <SummaryCard
        icon={<ClassroomIcon />}
        label="Aulas"
        value={summary.totalClassrooms}
      />
      <SummaryCard
        icon={<UsersIcon />}
        label="Estudiantes"
        value={summary.totalStudents}
      />
      <SummaryCard
        icon={<ProgressIcon />}
        label="Progreso Promedio"
        value={`${summary.averageProgress.toFixed(1)}%`}
      />
    </div>
  );
};

Componente de Insights:

// InsightsSection.tsx
export const InsightsSection = ({ insights }) => {
  if (!insights.bestPerformingClassroom) return null;

  return (
    <div className="insights-section">
      <InsightCard
        type="success"
        icon={<TrophyIcon />}
        title="Mejor Desempeño"
        classroom={insights.bestPerformingClassroom}
      />
      {insights.needsAttentionClassroom && (
        <InsightCard
          type="warning"
          icon={<AlertIcon />}
          title="Requiere Atención"
          classroom={insights.needsAttentionClassroom}
        />
      )}
    </div>
  );
};

Componente de Grid de Aulas:

// ClassroomGrid.tsx
export const ClassroomGrid = ({ classrooms, onViewClassroom }) => {
  if (classrooms.length === 0) {
    return (
      <EmptyState
        icon={<ClassroomIcon />}
        title="No tienes aulas creadas"
        description="Crea tu primera aula para comenzar"
      />
    );
  }

  return (
    <div className="classroom-grid">
      {classrooms.map(classroom => (
        <ClassroomDashboardCard
          key={classroom.id}
          classroom={classroom}
          onClick={() => onViewClassroom(classroom.id)}
        />
      ))}
    </div>
  );
};

const ClassroomDashboardCard = ({ classroom, onClick }) => {
  return (
    <Card className="classroom-dashboard-card" onClick={onClick}>
      <CardHeader>
        <h3>{classroom.name}</h3>
        <Badge>{getLevelLabel(classroom.level)} {classroom.grade}°</Badge>
      </CardHeader>
      <CardBody>
        <div className="stats">
          <Stat
            icon={<UsersIcon />}
            label="Estudiantes"
            value={classroom.studentCount}
          />
          <Stat
            icon={<ProgressIcon />}
            label="Progreso"
            value={`${classroom.averageProgress.toFixed(1)}%`}
          />
          <Stat
            icon={<ModulesIcon />}
            label="Módulos"
            value={classroom.moduleCount}
          />
        </div>
        <ProgressBar percentage={classroom.averageProgress} />
      </CardBody>
      <CardFooter>
        <Button variant="primary" size="sm" fullWidth>
          Ver Dashboard
        </Button>
      </CardFooter>
    </Card>
  );
};

Diseño UI/UX

Layout Desktop

+-------------------------------------------------------------------+
|  Dashboard                                      [+ Crear Aula]   |
|  Bienvenido, Prof. García                                        |
+-------------------------------------------------------------------+
|  [3 Aulas]       [75 Estudiantes]       [62.5% Progreso]        |
+-------------------------------------------------------------------+
|  🏆 Mejor Desempeño: Matemáticas 6A (75.5%)                      |
|  ⚠️ Requiere Atención: Ciencias 5B (45.2%)                       |
+-------------------------------------------------------------------+
|  MIS AULAS                                                        |
|  +------------------+  +------------------+  +------------------+ |
|  | Matemáticas 6A   |  | Español 5B       |  | Ciencias 6A      | |
|  | Primaria - 6°    |  | Primaria - 5°    |  | Primaria - 6°    | |
|  | 👥 25 | 📊 65.5% |  | 👥 30 | 📊 58%   |  | 👥 20 | 📊 64%   | |
|  | [████████░] 65%  |  | [███████░░] 58%  |  | [████████░] 64%  | |
|  | [Ver Dashboard]  |  | [Ver Dashboard]  |  | [Ver Dashboard]  | |
|  +------------------+  +------------------+  +------------------+ |
+-------------------------------------------------------------------+
|  ACTIVIDAD RECIENTE                                              |
|  • Juan Pérez (Mat 6A) completó "Suma de fracciones" - 5 min    |
|  • Ana López (Esp 5B) completó "Comprensión lectora" - 10 min   |
+-------------------------------------------------------------------+

Alcance Básico vs Extensiones

EAI-005 (Este alcance - Admin Base):

  • Dashboard simple con resumen de aulas
  • Métricas básicas (# estudiantes, progreso promedio)
  • Grid de aulas con stats básicas
  • Actividad reciente (últimas 10)
  • Insights simples (mejor/peor aula)

EXT-001 (Extensión futura - Portal Maestros Completo):

  • Gráficas de tendencia de progreso
  • Comparativas entre aulas
  • Métricas de engagement
  • Dashboard personalizable (widgets)
  • Filtros por fecha
  • Exportación de reportes

Dependencias

Dependencias de User Stories:

  • US-ADM-001 (aulas)
  • US-ANA-001 (para navegación a dashboard de aula)

Estimación de Esfuerzo

Backend: 3 SP Frontend: 4 SP Testing: 1 SP

Total: 8 SP = $3,200 MXN