Files
Sistema-Educativo-Laravel/resources/views/tarea/mis_tareas.blade.php

337 lines
21 KiB
PHP

@extends('layouts.landing')
@section('title', 'Mis Tareas')
@section('content')
<div class="container-fluid">
{{-- Alertas de sesión --}}
@if (session('info'))
<div class="alert alert-success alert-dismissible fade show">
<strong>{{ session('info') }}</strong>
<button type="button" class="close" data-dismiss="alert"><span>&times;</span></button>
</div>
@endif
@if (session('error'))
<div class="alert alert-danger alert-dismissible fade show">
<strong>{{ session('error') }}</strong>
<button type="button" class="close" data-dismiss="alert"><span>&times;</span></button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-warning alert-dismissible fade show">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert"><span>&times;</span></button>
</div>
@endif
{{-- Sin ciclo activo --}}
@if (!$cicloActual)
<div class="alert alert-info">
<i class="fas fa-info-circle"></i>
No hay un ciclo escolar activo en este momento. Contacta a tu coordinador.
</div>
@else
{{-- ══════════════════════════════════════════════════
SECCIÓN 1: TAREAS POR ENTREGAR (ciclo actual)
══════════════════════════════════════════════════ --}}
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-tasks mr-1"></i> Tareas por Entregar
</h6>
<span class="badge badge-primary badge-pill">{{ $cicloActual->name }}</span>
</div>
<div class="card-body">
@if ($tareasPendientes->isEmpty())
<div class="alert alert-success mb-0">
<i class="fas fa-check-circle"></i> ¡Estás al corriente! No tienes tareas pendientes de entrega.
</div>
@else
@php $pendientesAgrupadas = $tareasPendientes->groupBy('material_id'); @endphp
@foreach ($pendientesAgrupadas as $materialId => $grupoTareas)
@php
$material = $grupoTareas->first()->material;
$grupo = $grupoTareas->first()->grupo;
$vencidas = $grupoTareas->filter(fn($t) =>
$t->fecha_entrega && \Carbon\Carbon::parse($t->fecha_entrega)->isPast()
)->count();
@endphp
<div class="card border mb-3 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center"
data-toggle="collapse"
data-target="#pend-mat-{{ $materialId }}"
aria-expanded="true"
style="cursor:pointer; user-select:none;">
<div class="d-flex align-items-center">
<i class="fas fa-book-open mr-2 text-primary"></i>
<div>
<h6 class="mb-0 font-weight-bold">{{ $material->name }}</h6>
<small class="text-muted">Grupo: {{ $grupo->clave }}</small>
</div>
</div>
<div class="d-flex align-items-center">
@if ($vencidas > 0)
<span class="badge badge-danger badge-pill mr-1"
title="{{ $vencidas }} tarea(s) vencida(s)">
{{ $vencidas }} vencida(s)
</span>
@endif
<span class="badge badge-warning badge-pill mr-2">
{{ $grupoTareas->count() }} por entregar
</span>
<i class="fas fa-chevron-down text-muted accordion-icon"></i>
</div>
</div>
<div id="pend-mat-{{ $materialId }}" class="collapse show">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0">
<thead class="thead-light">
<tr>
<th>Tarea</th>
<th style="width:130px">Fecha límite</th>
<th>Entregar</th>
</tr>
</thead>
<tbody>
@foreach ($grupoTareas as $tarea)
<tr>
<td class="align-middle">
<strong>{{ $tarea->titulo }}</strong>
@if ($tarea->descripcion)
<p class="text-muted small mb-0">
{{ Str::limit($tarea->descripcion, 100) }}
</p>
@endif
</td>
<td class="align-middle">
@if ($tarea->fecha_entrega)
{{ \Carbon\Carbon::parse($tarea->fecha_entrega)->format('d/m/Y') }}
@if (\Carbon\Carbon::parse($tarea->fecha_entrega)->isPast())
<br><span class="badge badge-danger">Vencida</span>
@else
<br><span class="badge badge-success">Activa</span>
@endif
@else
<span class="text-muted">Sin fecha</span>
@endif
</td>
<td>
<form action="{{ route('tarea.entregar', $tarea) }}"
method="POST"
enctype="multipart/form-data">
@csrf
<div class="form-group mb-1">
<textarea name="texto"
class="form-control form-control-sm"
rows="3"
placeholder="Escribe tu respuesta aquí (opcional)..."></textarea>
</div>
<div class="form-group mb-1">
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="archivo_{{ $tarea->id }}"
name="archivo">
<label class="custom-file-label small"
for="archivo_{{ $tarea->id }}">
Adjuntar archivo (opcional)
</label>
</div>
</div>
<button type="submit"
class="btn btn-primary btn-sm btn-block mt-1">
<i class="fas fa-upload fa-sm"></i> Entregar
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
{{-- ══════════════════════════════════════════════════
SECCIÓN 2: TAREAS YA ENTREGADAS
══════════════════════════════════════════════════ --}}
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-check-double mr-1"></i> Tareas Entregadas
</h6>
<span class="badge badge-success badge-pill">{{ $tareasEntregadas->count() }}</span>
</div>
<div class="card-body">
@if ($tareasEntregadas->isEmpty())
<div class="alert alert-info mb-0">
Aún no has entregado ninguna tarea en este ciclo.
</div>
@else
@php $entregadasAgrupadas = $tareasEntregadas->groupBy('material_id'); @endphp
@foreach ($entregadasAgrupadas as $materialId => $grupoTareas)
@php
$material = $grupoTareas->first()->material;
$grupo = $grupoTareas->first()->grupo;
$calificadas = $grupoTareas->filter(
fn($t) => ($entregasMap[$t->id]->status ?? '') === 'calificada'
)->count();
$pendientes = $grupoTareas->count() - $calificadas;
@endphp
<div class="card border mb-3 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center"
data-toggle="collapse"
data-target="#entr-mat-{{ $materialId }}"
aria-expanded="true"
style="cursor:pointer; user-select:none;">
<div class="d-flex align-items-center">
<i class="fas fa-book-open mr-2 text-success"></i>
<div>
<h6 class="mb-0 font-weight-bold">{{ $material->name }}</h6>
<small class="text-muted">Grupo: {{ $grupo->clave }}</small>
</div>
</div>
<div class="d-flex align-items-center">
@if ($pendientes > 0)
<span class="badge badge-warning badge-pill mr-1"
title="{{ $pendientes }} esperando calificación">
{{ $pendientes }} por calificar
</span>
@endif
@if ($calificadas > 0)
<span class="badge badge-success badge-pill mr-1">
{{ $calificadas }} calificada(s)
</span>
@endif
<span class="badge badge-secondary badge-pill mr-2">
{{ $grupoTareas->count() }} total
</span>
<i class="fas fa-chevron-down text-muted accordion-icon"></i>
</div>
</div>
<div id="entr-mat-{{ $materialId }}" class="collapse show">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0">
<thead class="thead-light">
<tr>
<th>Tarea</th>
<th style="width:110px">Status</th>
<th style="width:90px">Calificación</th>
<th>Lo que entregaste</th>
</tr>
</thead>
<tbody>
@foreach ($grupoTareas as $tarea)
@php
$entrega = $entregasMap[$tarea->id] ?? null;
$status = $entrega?->status ?? 'sin_subir';
@endphp
<tr>
<td class="align-middle">
<strong>{{ $tarea->titulo }}</strong>
@if ($tarea->descripcion)
<p class="text-muted small mb-0">
{{ Str::limit($tarea->descripcion, 80) }}
</p>
@endif
</td>
<td class="align-middle">
@if ($status === 'pendiente')
<span class="badge badge-warning">
<i class="fas fa-clock"></i> Pendiente
</span>
@else
<span class="badge badge-success">
<i class="fas fa-check"></i> Calificada
</span>
@endif
</td>
<td class="align-middle text-center">
@if ($status === 'calificada' && $entrega)
<strong class="text-success h5 mb-0">
{{ number_format($entrega->calificacion, 1) }}
</strong>
@if ($entrega->comentario)
<br><small class="text-muted">{{ $entrega->comentario }}</small>
@endif
@else
<span class="text-muted small">Esperando...</span>
@endif
</td>
<td class="align-middle">
@if ($entrega?->texto)
<div class="border rounded p-2 bg-light"
style="max-height:100px;overflow-y:auto;font-size:.85rem;">
{{ $entrega->texto }}
</div>
@endif
@if ($entrega?->archivo)
<a href="{{ route('files.serve', $entrega->archivo) }}"
target="_blank"
class="btn btn-sm btn-outline-info mt-1">
<i class="fas fa-eye fa-sm"></i> Ver archivo
</a>
@endif
@if (!$entrega?->texto && !$entrega?->archivo)
<span class="text-muted small">Sin contenido registrado</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
@endif {{-- fin @if $cicloActual --}}
</div>
@endsection
@section('scripts')
<script>
document.querySelectorAll('.custom-file-input').forEach(input => {
input.addEventListener('change', function () {
const fileName = this.files[0]?.name || 'Adjuntar archivo (opcional)';
this.nextElementSibling.textContent = fileName;
});
});
document.querySelectorAll('[data-toggle="collapse"]').forEach(header => {
const target = document.querySelector(header.dataset.target);
if (!target) return;
const icon = header.querySelector('.accordion-icon');
if (target.classList.contains('show') && icon) {
icon.classList.add('fa-rotate-180');
}
target.addEventListener('show.bs.collapse', () => icon?.classList.add('fa-rotate-180'));
target.addEventListener('hide.bs.collapse', () => icon?.classList.remove('fa-rotate-180'));
});
</script>
@endsection