Selaa lähdekoodia

Add TareasComponent and routing for task management in Profesor module

EmilianoChavarria 1 kuukausi sitten
vanhempi
commit
6b400ac949

+ 1 - 1
Front/src/app/modules/Profesor/pages/main/main.component.ts

@@ -37,7 +37,7 @@ export class MainComponent {
   public cardsMain = [
     { img: "assets/img/libro.png", texto: "Asistencia", pendiente: true, url: "asistencia" },
     { img: "assets/img/colegiatura.png", texto: "Centro de Recursos", pendiente: true, url: "centroRecursos" },
-    { img: "assets/img/uniforme.png", texto: "Asignar Tareas", pendiente: false, url: "main" },
+    { img: "assets/img/uniforme.png", texto: "Asignar Tareas", pendiente: false, url: "tareas" },
     { img: "assets/img/facturas.png", texto: "Registrar en Bitácora", pendiente: false, url: "registroBitacora" },
     { img: "assets/img/hijos.png", texto: "Registro de Calificaciones", pendiente: true, url: "registroCalificaciones" },
   ]

+ 236 - 0
Front/src/app/modules/Profesor/pages/tareas/ModalTarea.component.html

@@ -0,0 +1,236 @@
+<div class="close ">
+  <button class="cerrar-b cursor-pointer" mat-dialog-close><mat-icon>close</mat-icon></button>
+</div>
+
+<span class="center">Asignar Tarea</span>
+<!-- --------------------------------------------------------------------------------- -->
+<!-- form -->
+
+<mat-dialog-content class="mat-typography space mt-40" [autofocus]="['none']">
+
+  <form (ngSubmit)="crearTarea()" [formGroup]="form">
+
+    <div class="form-container">
+
+      <!-- Materia -->
+      <mat-form-field class="item">
+        <mat-label>Materia</mat-label>
+        <mat-select name="idMateriaTarea" formControlName="idMateriaTarea">
+          <mat-option *ngFor="let option of materias" [value]="option.idMateria">
+            {{ option.nombreMateria + ' - ' + (option.nombreGrado ? option.nombreGrado : option.nombreGrupo) }}
+          </mat-option>
+        </mat-select>
+        <mat-hint *ngIf="isValidField('idMateriaTarea', 'required')" style="color: red;">El campo es obligatorio</mat-hint>
+      </mat-form-field>
+
+
+      <!-- Tipo de tarea -->
+      <mat-form-field class="item">
+        <mat-label>Tipo de tarea</mat-label>
+        <mat-select name="idTipoTarea" formControlName="idTipoTarea">
+          <mat-option *ngFor="let option of tipoTareas" [value]="option.idTareasTipos">
+            {{option.nombreTareasTipos}}
+          </mat-option>
+        </mat-select>
+        <mat-hint *ngIf="isValidField('idTipoTarea', 'required')" style="color: red;">El campo es obligatorio</mat-hint>
+      </mat-form-field>
+
+      <!-- Titulo -->
+      <mat-form-field class="item">
+        <mat-label>Titulo</mat-label>
+        <input matInput name="tituloTarea" formControlName="tituloTarea" placeholder="Titulo">
+        <mat-icon [class.is-invalid-icon]="campoVacio('tituloTarea')" matSuffix>badge</mat-icon>
+        <!-- <mat-hint *ngIf="campoVacio('titulo')" class="is-invalid">El campo es obligatorio</mat-hint> -->
+        <mat-hint *ngIf="isValidField('tituloTarea', 'required')" style="color: red;">El campo es obligatorio</mat-hint>
+      </mat-form-field>
+
+      <!-- _________________________________________________________________________ -->
+
+      <!-- Campo Fecha inicio -->
+
+      <div class="item">
+        <div class="responsive">
+          <div class="flex-col">
+            <label for="fechaInicio">Fecha Inicio</label>
+            <div style="display: flex;">
+              <mat-form-field class="w-responsive">
+                <mat-label>Desde</mat-label>
+                <input matInput [matDatepicker]="pickerStart" [min]="todayDate" name="fechaPublicacion" id="fechaPublicacion"
+                  formControlName="fechaPublicacion" readonly>
+                <!-- <mat-hint>MM/DD/YYYY</mat-hint> -->
+                <mat-datepicker-toggle matIconSuffix [for]="pickerStart"></mat-datepicker-toggle>
+                <mat-datepicker #pickerStart></mat-datepicker>
+                <mat-hint *ngIf="isValidField('fechaPublicacion', 'required')"
+                  style="color: red; width: 200px; position: absolute;">El campo es obligatorio</mat-hint>
+                <mat-hint
+                  *ngIf="isValidField('fechaInicio', 'fechaInvalida') && !isValidField('fechaInicio', 'required')"
+                  style="color: red; width: 380px; position: absolute;">La fecha de inicio debe ser mayor o igual a la
+                  fecha actual</mat-hint>
+              </mat-form-field>
+
+              <mat-form-field class="ml-10 w-responsive">
+                <mat-label>Hora</mat-label>
+                <mat-select matNativeControl name="horaPublicacion" formControlName="horaPublicacion">
+                  <mat-option *ngFor="let hora of horasDelDia" [value]="hora.hora24">{{hora.hora12}}
+                  </mat-option>
+                </mat-select>
+                <mat-hint *ngIf="isValidField('horaPublicacion', 'required')"
+                  style="color: red; width: 200px; position: absolute;">El campo es obligatorio</mat-hint>
+              </mat-form-field>
+            </div>
+          </div>
+
+        </div>
+
+      </div>
+
+      <!-- Campo Fecha fin -->
+      <div class="item">
+        <div class="responsive">
+          <div class="flex-col ml-20">
+            <label for="fechaInicio">Fecha Final</label>
+            <div style="display: flex;">
+              <mat-form-field class="w-responsive">
+                <mat-label>Desde</mat-label>
+                <input matInput [matDatepicker]="pickerStart1" [min]="todayDate" name="fechaEntrega"
+                  id="fechaEntrega" formControlName="fechaEntrega" readonly>
+                <!-- <mat-hint>MM/DD/YYYY</mat-hint> -->
+                <mat-datepicker-toggle matIconSuffix [for]="pickerStart1"></mat-datepicker-toggle>
+                <mat-datepicker #pickerStart1></mat-datepicker>
+                <mat-hint *ngIf="isValidField('fechaEntrega', 'required')"
+                  style="color: red; width: 200px; position: absolute;">El campo es obligatorio</mat-hint>
+                <mat-hint
+                  *ngIf="isValidField('fechaEntrega', 'fechaInvalida') && !isValidField('fechaEntrega', 'required')"
+                  style="color: red; width: 380px; position: absolute;">La fecha de caducidad debe ser mayor o igual a
+                  la fecha de inicio</mat-hint>
+              </mat-form-field>
+
+              <mat-form-field class="ml-10 w-responsive">
+                <mat-label>Hora</mat-label>
+                <mat-select matNativeControl name="horaEntrega" formControlName="horaEntrega">
+                  <mat-option *ngFor="let hora of horasDelDia" [value]="hora.hora24">{{hora.hora12}}
+                  </mat-option>
+                </mat-select>
+                <mat-hint *ngIf="isValidField('horaEntrega', 'required')"
+                  style="color: red; width: 200px; position: absolute;">El campo es obligatorio</mat-hint>
+              </mat-form-field>
+            </div>
+
+          </div>
+        </div>
+      </div>
+
+
+      <!-- Sección de file uploader -->
+
+      <div class="item flex-col two-columns">
+
+        <input type="file" class="file-input" (change)="onFilesSelected($event)" #fileUpload multiple>
+
+
+        <div class="file-upload">
+
+          {{archivosData.length>0? '':"Ningún archivo seleccionado"}}
+
+          <button mat-mini-fab color="primary" class="upload-btn" type="button" (click)="fileUpload.click()">
+            <mat-icon>attach_file</mat-icon>
+          </button>
+        </div>
+        <div *ngIf="archivosData.length > 0"
+          style="border: 1px solid #ccc; padding: 20px 12px; margin-top: 10px; max-height: 150px; border-radius: 10px; overflow-y: auto;">
+          <ul style="margin: 0; padding: 0; list-style: none; ">
+            <span style="margin-bottom: 10px;">Listado de archivos:</span>
+            <li *ngFor="let archivo of archivosData; let i = index"
+              style="border: 1px solid #ccc; padding: 10px 15px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; border-radius: 8px;">
+              <span>
+                {{ archivo.nombre }} ({{ archivo.tamanio }} kb)
+              </span>
+              <button class="btnDelete" type="button" (click)="deleteIndex(i)">
+                <mat-icon>close</mat-icon>
+              </button>
+            </li>
+          </ul>
+        </div>
+
+
+        <div class="progress">
+
+          <!-- <mat-progress-bar class="progress-bar" mode="determinate"
+                              [value]="uploadProgress" *ngIf="uploadProgress">
+          
+            </mat-progress-bar> -->
+
+          <!-- <mat-icon class="cancel-upload" (click)="cancelUpload()" 
+                      *ngIf="uploadProgress">delete_forever</mat-icon> -->
+
+        </div>
+      </div>
+
+      <!-- Sección de urls -->
+
+      <div class="item two-columns"
+        style="display: flex; flex-direction: column; justify-content: space-between; align-items: center;">
+        <!-- Input y botón en la misma fila -->
+        <div style="display: flex; align-items: center; width: 100%; gap: 10px; padding: 0 20px;">
+          <mat-form-field style="flex: 1;">
+            <mat-label>Vinculo</mat-label>
+            <input matInput name="vinculoTarea" formControlName="vinculoTarea" placeholder="URL">
+            <mat-icon matSuffix>link</mat-icon>
+          </mat-form-field>
+
+          <button (click)="addUrl()" type="button"
+            style="background-color: #3f51b5; border-radius: 50%; border: none; color: white; font-size: 24px; height: 40px; width: 40px; cursor: pointer; display: flex; align-items: center; justify-content: center;">
+            +
+          </button>
+        </div>
+
+        <!-- Listado de urls -->
+        <div *ngIf="urls.length > 0"
+          style="margin-top: 10px; padding-top: 10px; width: 100%; padding-left: 20px; max-height: 150px; overflow-y: auto; border: 1px solid #ccc; border-radius: 8px; padding-right: 10px;">
+          <span style="margin-bottom: 10px;">Listado de archivos:</span>
+          <ul style="margin: 0; padding: 0;">
+            <li *ngFor="let url of urls; let i = index"
+              style="margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center;">
+              <a [href]="url" target="_blank" style="word-break: break-word; flex: 1;">{{ url }}</a>
+              <button class="btnDelete" type="button" (click)="deleteUrl(i)">
+                <mat-icon>close</mat-icon>
+              </button>
+            </li>
+          </ul>
+        </div>
+
+
+      </div>
+
+
+
+
+
+    </div>
+    <div class="NgxEditor__Wrapper" style="min-height: 200px; height: auto;">
+      <ngx-editor-menu [editor]="editor" [toolbar]="toolbar" [colorPresets]="colorPresets"> </ngx-editor-menu>
+      <ngx-editor placeholder="Escriba aquí..." [editor]="editor" formControlName="descripcionTarea"> </ngx-editor>
+    </div>
+  </form>
+
+
+
+
+</mat-dialog-content>
+<div class="align flex-row mt-20 pb-10">
+  <div class="align-items">
+    <button type="button" (click)="crearTarea()" class="yellow">Ingresar<mat-icon class="icon"
+        matSuffix>description</mat-icon></button>
+  </div>
+  <div class="align-items">
+    <button class="orange" (click)="limpiar()">Limpiar <mat-icon class="icon" matSuffix>delete</mat-icon></button>
+  </div>
+  <div class="align-items">
+    <button class="red" mat-dialog-close>Cerrar <mat-icon class="icon" matSuffix>cancel</mat-icon></button>
+  </div>
+
+
+</div>
+
+
+<!-- -------------------------------------- -->

+ 350 - 0
Front/src/app/modules/Profesor/pages/tareas/tareas.component.css

@@ -0,0 +1,350 @@
+.centrar {
+    margin-top: 4%;
+    line-height: auto;
+    text-align: center;
+}
+
+.cerrar-b {
+  background-color: #fff;
+  border: none;
+}
+
+.fondo {
+    border-radius: 10px;
+    line-height: 1;
+    display: inline-block;
+    vertical-align: middle;
+}
+
+.content {
+    margin-bottom: 0;
+    margin-top: 0;
+    padding-top: 10px;
+    padding-bottom: 10px;
+    padding-left: 70px;
+    padding-right: 70px;
+    font-weight: 500;
+    font-size: 32px;
+    color: white;
+    font-family: "Serenity Medium";
+}
+
+.form-container {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr); /* 4 columnas iguales */
+  gap: 10px; /* espacio entre columnas y filas */
+}
+
+.item {
+  box-sizing: border-box;
+  padding: 10px;
+}
+
+.item.two-columns {
+  grid-column: span 2;
+}
+
+.w-responsive {
+    width: 160px;
+}
+
+.input {
+    width: 500px;
+    color: rgb(0, 140, 255);
+}
+
+.file-input {
+  display: none;
+}
+
+.btnDelete {
+  display: flex;              
+  align-items: center;        
+  justify-content: center;
+  cursor: pointer;
+  border: none;
+  background-color: transparent;
+  height: 30px;
+  width: 30px;
+  color: #ccc;
+  border-radius: 5px;
+  padding: 0;
+}
+
+
+.btnDelete:hover {
+  color: #dd131a;
+  background-color: #f7e3e4;
+}
+
+.container-col {
+    display: flex;
+    flex-direction: column;
+    padding-top: 100px;
+    padding-left: 30px;
+    padding-right: 65px;
+    width: 100%;
+    box-sizing: border-box;
+}
+
+.yellow {
+    border: none;
+    border-radius: 5px;
+    padding: 5px 15px;
+    font-size: 1rem;
+    color: white;
+    margin-left: 10px;
+    background-color: #ebac3f;
+}
+
+.yellow:hover {
+    background-color: #be8b32;
+
+}
+
+.orange {
+    border: none;
+    border-radius: 5px;
+    padding: 5px 15px;
+    font-size: 1rem;
+    color: white;
+    margin-left: 10px;
+    background-color: #f56227;
+
+}
+
+.orange:hover {
+    background-color: #d15321;
+
+}
+
+.red {
+    border: none;
+    border-radius: 5px;
+    padding: 5px 15px;
+    font-size: 1rem;
+    color: white;
+    margin-left: 10px;
+    background-color: red;
+
+}
+
+.red:hover {
+    background-color: rgb(177, 0, 0);
+
+}
+
+.action-edit {
+    margin-left: 5px;
+    background-color: #1d156e;
+    color: white;
+    height: 30px;
+    width: 30px;
+}
+
+.action-delete {
+    margin-left: 5px;
+    background-color: #e43b3d;
+    color: white;
+    height: 30px;
+    width: 30px;
+}
+
+.inline {
+    display: flex;
+    align-items: center;
+    color: red;
+    cursor: pointer;
+}
+
+.icon {
+    transform: scale(0.8);
+    vertical-align: middle;
+}
+
+.green {
+    background-color: #2a6c42;
+    border: none;
+    color: white !important;
+    cursor: pointer;
+    border-radius: 6px;
+    height: 35px;
+}
+
+.green:hover {
+    background-color: #205232;
+}
+
+.buttons {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    width: 100%;
+    margin-bottom: 15px;
+    padding-left: 20px;
+}
+
+.badge-active {
+    color: #026AA2;
+    font-weight: 500;
+    padding: 3px 7px;
+    background-color: #E0F2FE;
+    border-radius: 15px;
+}
+
+.badge-inactive {
+    color: #AC2722;
+    font-weight: 500;
+    padding: 3px 7px;
+    background-color: #FEE4E2;
+    border-radius: 15px;
+}
+
+/* --------------- Table and responsive styles ---------------- */
+.table-container {
+    width: 100%;
+    overflow: auto;
+}
+
+.table-responsive {
+
+    overflow: auto;
+}
+
+/* --------------- Special button styles for Circulares ---------------- */
+.btn-grande {
+    display: inline-flex;
+    align-items: center;
+    background-color: rgb(184, 221, 247);
+    border-radius: 4px;
+    padding: 0 12px;
+    height: 36px;
+}
+
+.btn-movil {
+    display: none;
+    background: none;
+    border: none;
+    padding: 0;
+    margin: 0;
+}
+
+/* --------------- Modal and form styles ---------------- */
+.close {
+    padding-top: 20px;
+    padding-right: 20px;
+    display: flex;
+    justify-content: end;
+}
+
+.center {
+    text-align: center;
+    font-size: 32px;
+    font-weight: 600;
+}
+
+.responsive {
+    display: flex;
+    flex-direction: row;
+}
+
+.align {
+    margin-top: 30px;
+    display: flex;
+    justify-content: center;
+}
+
+/* --------------- Media Queries ---------------- */
+@media only screen and (max-width: 600px) {
+    .centrar {
+        margin-top: 8%;
+    }
+
+    .fondo {
+        width: 90%;
+    }
+
+    .content {
+        font-size: 24px;
+        padding: 10px 20px;
+    }
+
+    .container-col {
+        padding-top: 50px;
+        padding-left: 15px;
+        padding-right: 15px;
+    }
+
+    .input {
+        width: 100%;
+    }
+
+    .container-search {
+        flex-direction: column;
+    }
+
+    .buttons {
+        flex-direction: column;
+        align-items: stretch;
+        gap: 10px;
+        padding-left: 0;
+    }
+
+    .table-container {
+        width: 100%;
+    }
+
+    /* Special mobile styles for Circulares buttons */
+    .btn-grande {
+        display: none;
+    }
+
+    .btn-movil {
+        display: inline-flex;
+    }
+
+    .btn-movil img {
+        width: 24px;
+        height: 24px;
+    }
+
+    /* Adjust action buttons container */
+    .flex-row.items-center {
+        justify-content: center;
+    }
+}
+
+@media (max-width: 768px) {
+    .w-responsive {
+        width: 100%;
+    }
+
+    .content {
+        font-size: 22px;
+        padding: 10px 15px;
+    }
+
+    .item {
+        flex: 1 0 100%;
+    }
+
+    .table-responsive {
+
+        overflow-x: auto;
+    }
+
+    /* Ensure table cells have proper spacing */
+    .mat-cell,
+    .mat-header-cell {
+        padding: 4px 8px;
+    }
+
+    /* Adjust column widths for mobile */
+    .mat-column-acciones {
+        min-width: 80px;
+    }
+
+    .mat-column-adjuntos {
+        min-width: 100px;
+    }
+}

+ 232 - 443
Front/src/app/modules/Profesor/pages/tareas/tareas.component.ts

@@ -14,13 +14,13 @@ import { NivelEducativo } from '../../../Administrador/interfaces/NivelEducativo
 import { GradosEducativosService } from '../../../Administrador/services/grados-educativos.service';
 import { GruposService } from '../../../Administrador/services/grupos.service';
 import { MateriaService } from '../../../Administrador/services/materia.service';
-import { Editor } from 'ngx-editor';
-import Toolbar from 'quill/modules/toolbar';
+import { Editor, Toolbar } from 'ngx-editor';
 import { forkJoin, tap } from 'rxjs';
 import moment from 'moment';
 
 import { v4 as uuidv4 } from 'uuid';
 import { MAT_DATE_LOCALE, provideNativeDateAdapter } from '@angular/material/core';
+import { TareasService } from '../../services/tareas.service';
 
 
 @Component({
@@ -95,162 +95,162 @@ export class TareasComponent {
 
 
   }
-  
+
 
 
   public allInfo: any;
   public files: any;
-//Traer la información y mostrarla en la tabla
-getCirculares() {
-  this.circularService.getAllCirculares().subscribe((response: any) => {
-    this.isLoading = false;
+  //Traer la información y mostrarla en la tabla
+  getCirculares() {
+    this.circularService.getAllCirculares().subscribe((response: any) => {
+      this.isLoading = false;
 
-    this.allInfo = response.map((circular: any) => {
+      this.allInfo = response.map((circular: any) => {
 
-      if (circular.jsonAdjuntos) {
-        circular.jsonAdjuntos = JSON.parse(circular.jsonAdjuntos);
+        if (circular.jsonAdjuntos) {
+          circular.jsonAdjuntos = JSON.parse(circular.jsonAdjuntos);
 
-      } else {
-        circular.jsonAdjuntos = [];
-      }
-      return circular;
-    });
+        } else {
+          circular.jsonAdjuntos = [];
+        }
+        return circular;
+      });
 
-    this.dataSource = new MatTableDataSource<any>(this.allInfo.filter((filtro: any) => filtro.estado === 'Activo'));
-    this.dataSource.paginator = this.paginator;
-  });
-}
+      this.dataSource = new MatTableDataSource<any>(this.allInfo.filter((filtro: any) => filtro.estado === 'Activo'));
+      this.dataSource.paginator = this.paginator;
+    });
+  }
 
-buscarArchivo(ruta: string) {
-  window.open(ruta, '_blank');
-}
+  buscarArchivo(ruta: string) {
+    window.open(ruta, '_blank');
+  }
 
 
 
-deleteCircular(id: string) {
+  deleteCircular(id: string) {
 
-  Swal.fire({
-    icon: 'question',
-    title: '¿Desea cambiar el estado de la circular?',
-    showCancelButton: true,
-    allowOutsideClick: false,
-    allowEscapeKey: false,
-    confirmButtonColor: '#3085d6',
-    cancelButtonColor: '#d33',
-    confirmButtonText: "Eliminar",
-  }).then((result: any) => {
-    /* Read more about isConfirmed, isDenied below */
-    if (result.isConfirmed) {
-      this.circularService.eliminarCircular(id).subscribe((response: any) => {
-        Swal.fire({
-          icon: 'success',
-          title: `${response.mensaje}`,
-          confirmButtonColor: 'rgb(237,46,56)',
-          confirmButtonText: 'Ok',
-        }).then((result: any) => {
-
-          if (result.isConfirmed) {
-            this._enviarInfo.notifyCambioTabla();
-            Swal.close();
-          }
-        })
-      }, (err: any) => {
-        Swal.fire({
-          icon: 'error',
-          title: 'Error al eliminar',
-          text: `${err.error.mensaje}`,
-        })
+    Swal.fire({
+      icon: 'question',
+      title: '¿Desea cambiar el estado de la circular?',
+      showCancelButton: true,
+      allowOutsideClick: false,
+      allowEscapeKey: false,
+      confirmButtonColor: '#3085d6',
+      cancelButtonColor: '#d33',
+      confirmButtonText: "Eliminar",
+    }).then((result: any) => {
+      /* Read more about isConfirmed, isDenied below */
+      if (result.isConfirmed) {
+        this.circularService.eliminarCircular(id).subscribe((response: any) => {
+          Swal.fire({
+            icon: 'success',
+            title: `${response.mensaje}`,
+            confirmButtonColor: 'rgb(237,46,56)',
+            confirmButtonText: 'Ok',
+          }).then((result: any) => {
+
+            if (result.isConfirmed) {
+              this._enviarInfo.notifyCambioTabla();
+              Swal.close();
+            }
+          })
+        }, (err: any) => {
+          Swal.fire({
+            icon: 'error',
+            title: 'Error al eliminar',
+            text: `${err.error.mensaje}`,
+          })
+          this._enviarInfo.notifyCambioTabla();
+        }
+        )
+      } else if (result.dismiss == 'cancel') {
         this._enviarInfo.notifyCambioTabla();
       }
-      )
-    } else if (result.dismiss == 'cancel') {
-      this._enviarInfo.notifyCambioTabla();
-    }
-  });
+    });
 
-}
+  }
 
-enableCircular(id: string) {
-  Swal.fire({
-    icon: 'question',
-    title: '¿Desea habilitar la circular?',
-    showCancelButton: true,
-    allowOutsideClick: false,
-    allowEscapeKey: false,
-    confirmButtonColor: '#3085d6',
-    cancelButtonColor: '#d33',
-    confirmButtonText: "Habilitar",
-  }).then((result: any) => {
-
-    if (result.value) {
-      this.circularService.habilitarCircular(id).subscribe((response: any) => {
-        Swal.fire({
-          icon: 'success',
-          title: `${response.mensaje}`,
-          confirmButtonColor: 'rgb(237,46,56)',
-          confirmButtonText: 'Ok',
-        }).then((result: any) => {
-          if (result.isConfirmed) {
-            Swal.close();
-            this._enviarInfo.notifyCambioTabla();
-          }
-        })
-      }, (err: any) => {
-        Swal.fire({
-          icon: 'error',
-          title: 'Error al habilitar',
-          text: `${err.error.message}`,
-        })
+  enableCircular(id: string) {
+    Swal.fire({
+      icon: 'question',
+      title: '¿Desea habilitar la circular?',
+      showCancelButton: true,
+      allowOutsideClick: false,
+      allowEscapeKey: false,
+      confirmButtonColor: '#3085d6',
+      cancelButtonColor: '#d33',
+      confirmButtonText: "Habilitar",
+    }).then((result: any) => {
+
+      if (result.value) {
+        this.circularService.habilitarCircular(id).subscribe((response: any) => {
+          Swal.fire({
+            icon: 'success',
+            title: `${response.mensaje}`,
+            confirmButtonColor: 'rgb(237,46,56)',
+            confirmButtonText: 'Ok',
+          }).then((result: any) => {
+            if (result.isConfirmed) {
+              Swal.close();
+              this._enviarInfo.notifyCambioTabla();
+            }
+          })
+        }, (err: any) => {
+          Swal.fire({
+            icon: 'error',
+            title: 'Error al habilitar',
+            text: `${err.error.message}`,
+          })
+        }
+        )
+      } else if (result.dismiss == 'cancel') {
+        this._enviarInfo.notifyCambioTabla();
       }
-      )
-    } else if (result.dismiss == 'cancel') {
-      this._enviarInfo.notifyCambioTabla();
-    }
-  });
-}
+    });
+  }
 
-option(event: string) {
-  this.isLoading = true;
-  let filteredData: any;
+  option(event: string) {
+    this.isLoading = true;
+    let filteredData: any;
 
-  if (event === 'Activos') {
-    filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Activo');
-  } else if (event === 'Eliminados') {
-    filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Eliminado');
-  }
+    if (event === 'Activos') {
+      filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Activo');
+    } else if (event === 'Eliminados') {
+      filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Eliminado');
+    }
 
-  this.dataSource = new MatTableDataSource<any>(filteredData);
-  this.dataSource.paginator = this.paginator;
-  this.isLoading = false;
-}
+    this.dataSource = new MatTableDataSource<any>(filteredData);
+    this.dataSource.paginator = this.paginator;
+    this.isLoading = false;
+  }
 
 
-//filtro de búsqueda
-applyFilter(event: Event) {
-  const filterValue = (event.target as HTMLInputElement).value;
-  this.dataSource.filter = filterValue.trim().toLowerCase();
-}
+  //filtro de búsqueda
+  applyFilter(event: Event) {
+    const filterValue = (event.target as HTMLInputElement).value;
+    this.dataSource.filter = filterValue.trim().toLowerCase();
+  }
 
 
 
 
-//exportar búsqueda a excel
-exportAsExcel() {
-  const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement);
-  const wb: XLSX.WorkBook = XLSX.utils.book_new();
-  XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaCirculares');
-  XLSX.writeFile(wb, 'Circulares.xlsx');
+  //exportar búsqueda a excel
+  exportAsExcel() {
+    const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement);
+    const wb: XLSX.WorkBook = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaCirculares');
+    XLSX.writeFile(wb, 'Circulares.xlsx');
 
-}
-//exportar toda la data a excel
-exportAll() {
-  const dataSource = this.dataSource.data;
-  const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(dataSource);
-  const wb: XLSX.WorkBook = XLSX.utils.book_new();
-
-  XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaCirculares');
-  XLSX.writeFile(wb, 'Circulares.xlsx');
-}
+  }
+  //exportar toda la data a excel
+  exportAll() {
+    const dataSource = this.dataSource.data;
+    const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(dataSource);
+    const wb: XLSX.WorkBook = XLSX.utils.book_new();
+
+    XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaCirculares');
+    XLSX.writeFile(wb, 'Circulares.xlsx');
+  }
 
 
   // openDialog(id: string) {
@@ -290,7 +290,7 @@ exportAll() {
 
   // }
 
-  
+
 
 
 }
@@ -312,26 +312,29 @@ export class ModalTarea {
     private gradoService: GradosEducativosService,
     private grupoService: GruposService,
     private materiaService: MateriaService,
+    private tareaService: TareasService
   ) {
     // this.lista()
+    this.getTipoTareas();
+    this.getMaterias();
   }
 
   public todayDate: Date = new Date();
-  valoresCombinados: any = {};
 
   public info: any;
   private userData = JSON.parse(localStorage.getItem('userData') || '');
+  private userDataS = JSON.parse(localStorage.getItem('userDataS') || '');
   editor!: Editor;
-  // toolbar: Toolbar = [
-  //   ['bold', 'italic'],
-  //   ['underline', 'strike'],
-  //   ['blockquote'],
-  //   ['ordered_list', 'bullet_list'],
-  //   [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }],
-  //   ['link', 'image'],
-  //   ['text_color', 'background_color'],
-  //   ['align_left', 'align_center', 'align_right', 'align_justify'],
-  // ];
+  toolbar: Toolbar = [
+    ['bold', 'italic'],
+    ['underline', 'strike'],
+    ['blockquote'],
+    ['ordered_list', 'bullet_list'],
+    [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }],
+    ['link', 'image'],
+    ['text_color', 'background_color'],
+    ['align_left', 'align_center', 'align_right', 'align_justify'],
+  ];
   colorPresets = [
     "#000000", // Negro
     "#FF0000", // Rojo
@@ -355,9 +358,6 @@ export class ModalTarea {
 
   ngOnInit(): void {
     this.editor = new Editor();
-    this.lista().subscribe(() => {
-      this.originales = [...this.opciones]; // Guarda las opciones originales
-    });
   }
 
   ngOnDestroy(): void {
@@ -365,165 +365,38 @@ export class ModalTarea {
   }
 
 
-  audiencia = [
-    { value: 'AL', audiencia: 'Alumnos' },
-    { value: 'PF', audiencia: 'Padre de Familia' },
-    { value: 'AD', audiencia: 'Administradores' },
-    { value: 'PR', audiencia: 'Profesores' },
-    { value: 'TD', audiencia: 'Todos los usuarios' },
-  ]
-
-  importancia = [
-    { value: 'Alta', importancia: 'Alta' },
-    { value: 'Normal', importancia: 'Normal' },
-    { value: 'Baja', importancia: 'Baja' },
-  ]
-  public opciones: any;
-  public roles = ['Administradores', 'Padres'];
-  public originales: any;
-
-  public selectedAudiencia: string[] = [];
-
-  onAudienciaChange(value: string[]) {
-    // Si selecciona TD → bloquear todo excepto TD
-    if (value.includes('TD')) {
-      this.form.get('audiencia')?.setValue(['TD']);
-      this.selectedAudiencia = ['TD'];
-    } else {
-      // Si lo deselecciona, volver a habilitar todas
-      this.selectedAudiencia = value;
-    }
-
-    // 🔹 Siempre resetear destinos al cambiar audiencia
-    this.form.get('destinos')?.setValue([]);
-    this.selectedDestino = [];
-
-    console.log('Audiencia seleccionada:', this.selectedAudiencia);
-
-    // 🔹 Tu lógica de opciones según audiencia
-    let extra = {};
-    switch (this.selectedAudiencia[0]) {
-      case 'AL':
-        extra = { name: 'Alumnos', grupo: [{ value: 'AL', Destino: 'todos', viewValue: 'Todos los Alumnos' }] };
-        this.opciones = [extra, ...this.originales];
-        break;
-      case 'PF':
-        extra = { name: 'Padres de Familia', grupo: [{ value: 'PF', Destino: 'todos', viewValue: 'Todos los Padres de Familia' }] };
-        this.opciones = [extra, ...this.originales];
-        break;
-      case 'AD':
-        extra = { name: 'Administradores', grupo: [{ value: 'AD', Destino: 'todos', viewValue: 'Todos los Administradores' }] };
-        this.opciones = [extra];
-        break;
-      case 'PR':
-        extra = { name: 'Profesores', grupo: [{ value: 'PR', Destino: 'todos', viewValue: 'Todos los Profesores' }] };
-        this.opciones = [extra, ...this.originales];
-        break;
-      case 'TD':
-        extra = { name: 'Todos', grupo: [{ value: 'TD', Destino: 'todos', viewValue: 'Todos los usuarios' }] };
-        this.opciones = [extra];
-        this.form.get('destinos')?.setValue(['TD']);
-        break;
-      default:
-        this.opciones = [...this.originales];
-        break;
-    }
+  public tipoTareas: any = [];
+  public materias: any = [];
+  getMaterias() {
+    this.materiaService.getHabilitados().subscribe((response: any) => {
+      this.materias = response.filter((materia: any) => materia.estado === 'Activo');
+      console.log("🚀 ~ ModalTarea ~ getMaterias ~ response:", response)
+    });
   }
 
+  getTipoTareas() {
+    this.tareaService.getTipoTareas().subscribe((response: any) => {
+      this.tipoTareas = response.filter((tarea: any) => tarea.estado === 'Activo');
+      console.log("🚀 ~ ModalTarea ~ getTipoTareas ~ this.tipoTareas:", this.tipoTareas)
+    });
+  }
 
 
-  lista() {
-    return forkJoin({
-      niveles: this.nivelService.getHabilitados(),
-      grados: this.gradoService.getHabilitados(),
-      grupos: this.grupoService.getHabilitados(),
-      materias: this.materiaService.getHabilitados(),
-    }).pipe(
-      tap(({ niveles, grados, grupos, materias }: any) => {
-        this.opciones = [
-          {
-            name: 'Nivel Educativo',
-            grupo: niveles.map((nivel: any) => ({
-              value: nivel.idNivel,
-              Destino: 'NivelEducativo',
-              viewValue: nivel.nombreNivel,
-            })),
-          },
-          {
-            name: 'Grados',
-            grupo: grados.map((grado: any) => ({
-              value: grado.nombreGrado,
-              Destino: 'Grado',
-              viewValue: grado.nombreGrado,
-            })),
-          },
-          {
-            name: 'Grupos',
-            grupo: grupos.map((grupo: any) => ({
-              value: grupo.idGrupo,
-              Destino: 'Grupo',
-              viewValue: grupo.nombreGrupo,
-            })),
-          },
-          {
-            name: 'Materia',
-            grupo: materias.map((materia: any) => ({
-              value: materia.idMateria,
-              Destino: 'Materias',
-              viewValue: materia.nombreMateria,
-            })),
-          },
-        ];
-      })
-    );
-  }
+  public opciones: any;
+  public originales: any;
 
   public form = new FormGroup({
-    titulo: new FormControl<string>('', Validators.required),
-    audiencia: new FormControl<string[]>([''], Validators.required),
-    destinos: new FormControl<string[]>([''], Validators.required),
-    contenido: new FormControl<string>('', Validators.required),
-    importancia: new FormControl<string>('', Validators.required),
-    fechaInicio: new FormControl<any>(null, [Validators.required, this.validateFechaInicio.bind(this)]),
-    horaInicio: new FormControl<any>(null, Validators.required),
-    fechaCaducidad: new FormControl<any>(null, [Validators.required, this.validatefechaCaducidad.bind(this)]),
-    horaCaducidad: new FormControl<any>(null, Validators.required),
-    link: new FormControl<string>('')
+    tituloTarea: new FormControl<string>('', Validators.required),
+    idMateriaTarea: new FormControl<string[]>([''], Validators.required),
+    idTipoTarea: new FormControl<string[]>([''], Validators.required),
+    descripcionTarea: new FormControl<string>('', Validators.required),
+    fechaPublicacion: new FormControl<any>(null, [Validators.required]),
+    horaPublicacion: new FormControl<any>(null, Validators.required),
+    fechaEntrega: new FormControl<any>(null, [Validators.required]),
+    horaEntrega: new FormControl<any>(null, Validators.required),
+    vinculoTarea: new FormControl<string>('')
   });
 
-  validateFechaInicio(control: AbstractControl): ValidationErrors | null {
-    const fechaInicio = new Date(control.value);
-    const today = new Date();
-    today.setHours(0, 0, 0, 0);
-
-    if (fechaInicio >= today) {
-      this.form.get('fechaCaducidad')?.updateValueAndValidity();
-      return null;
-    } else {
-      return { fechaInvalida: true };
-    }
-  }
-
-  validatefechaCaducidad(control: AbstractControl): ValidationErrors | null {
-    if (!this.form) {
-      return null;
-    }
-    const fechaInicioValue = this.form.get('fechaInicio')?.value;
-    const fechaCaducidadValue = control.value;
-
-    if (!fechaInicioValue || !fechaCaducidadValue) {
-      return { fechaInvalida: true };
-    }
-
-    const fechaInicio = new Date(fechaInicioValue);
-    const fechaCaducidad = new Date(fechaCaducidadValue);
-
-    if (fechaCaducidad >= fechaInicio) {
-      return null;
-    } else {
-      return { fechaInvalida: true };
-    }
-  }
 
   isValidField(field: string, errorType: string) {
     const control = this.form.get(field);
@@ -533,93 +406,61 @@ export class ModalTarea {
   public urls: any = []
 
   addUrl() {
-    const link = this.form.get('link')?.value;
-    this.urls.push(link);
-    this.form.get('link')?.setValue('');
+    const vinculoTarea = this.form.get('vinculoTarea')?.value;
+    this.urls.push(vinculoTarea);
+    this.form.get('vinculoTarea')?.setValue('');
     console.log(this.urls);
   }
 
 
-  public selectedDestino: string[] = [];
 
-  Evaluar(event: any) {
-    const todosValores = ['AL', 'PF', 'AD', 'PR', 'TD'];
-    let destinosActuales: any[] = this.form.get('destinos')?.value || [];
-
-    if (todosValores.includes(event.value)) {
-      // Caso: selecciona "Todos"
-      if (destinosActuales.includes(event.value)) {
-        // Si ya estaba seleccionado, lo quitamos y reactivamos los demás
-        destinosActuales = destinosActuales.filter((d: any) => d !== event.value);
-        this.selectedDestino = destinosActuales;
-        this.form.get('destinos')?.setValue(destinosActuales);
-      } else {
-        // Si lo selecciona por primera vez → limpiar y dejar solo "Todos"
-        this.selectedDestino = [event.value];
-        this.form.get('destinos')?.setValue([event.value]);
-      }
-    } else {
-      // Caso: selecciona normales
-      this.selectedDestino = destinosActuales;
-    }
-
-    // Para tu combinación
-    this.valoresCombinados = {
-      Destino: event.Destino,
-      id: event.value,
-    };
-  }
 
 
 
   convertToDatetime() {
     // Obtener valores del formulario
-    const fechaInicio: any = this.form.get('fechaInicio')?.value;
-    const horaInicio: any = this.form.get('horaInicio')?.value;
-    const fechaCaducidad: any = this.form.get('fechaCaducidad')?.value;
-    const horaCaducidad: any = this.form.get('horaCaducidad')?.value;
+    const fechaPublicacion: any = this.form.get('fechaPublicacion')?.value;
+    const horaPublicacion: any = this.form.get('horaPublicacion')?.value;
+    const fechaEntrega: any = this.form.get('fechaEntrega')?.value;
+    const horaEntrega: any = this.form.get('horaEntrega')?.value;
 
-    let fechaHoraInicio: string | undefined;
-    let fechaHoraCaducidad: string | undefined;
+    let fechahoraPublicacion: string | undefined;
+    let fechahoraEntrega: string | undefined;
 
-    if (fechaInicio && horaInicio) {
+    if (fechaPublicacion && horaPublicacion) {
       // Formatear fecha en 'YYYY-MM-DD'
-      var formattedDate = moment(fechaInicio).format("YYYY-MM-DD");
-      fechaHoraInicio = `${formattedDate} ${horaInicio}`;
+      var formattedDate = moment(fechaPublicacion).format("YYYY-MM-DD");
+      fechahoraPublicacion = `${formattedDate} ${horaPublicacion}`;
 
     } else {
       console.error('Fecha de inicio o hora de inicio no válidas.');
     }
 
-    if (fechaCaducidad && horaCaducidad) {
+    if (fechaEntrega && horaEntrega) {
       // Formatear fecha en 'YYYY-MM-DD'
-      var formattedDate = moment(fechaCaducidad).format("YYYY-MM-DD");
-      fechaHoraCaducidad = `${formattedDate} ${horaCaducidad}`;
+      var formattedDate = moment(fechaEntrega).format("YYYY-MM-DD");
+      fechahoraEntrega = `${formattedDate} ${horaEntrega}`;
 
     } else {
       console.error('Fecha de caducidad o hora de caducidad no válidas.');
     }
 
     this.info = {
-      titulo: this.form.get('titulo')?.value,
-      audiencia: this.form.get('audiencia')?.value,
-      idReceptores: this.form.get('destinos')?.value,
-      contenido: this.form.get('contenido')?.value,
-      importancia: this.form.get('importancia')?.value,
-      jsonAdjuntos: this.archivosData,
+      tituloTarea: this.form.get('tituloTarea')?.value,
+      idMateriaTarea: this.form.get('idMateriaTarea')?.value,
+      idTipoTarea: this.form.get('idTipoTarea')?.value,
+      descripcionTarea: this.form.get('descripcionTarea')?.value,
+      adjuntoTarea: this.archivosData,
       bases64: this.bases64,
       fechaCreacion: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),
-      fechaPublicacion: fechaHoraInicio,
-      fechaCaducidad: fechaHoraCaducidad,
-      idUsuario: this.userData[0],
-      urls: this.urls.join('||')
+      fechaPublicacion: fechahoraPublicacion,
+      fechaEntrega: fechahoraEntrega,
+      idUsuario: this.userDataS[0] ? this.userDataS[0] : this.userData[0],
+      vinculoTarea: this.urls.join('||')
     };
 
 
-    this.valoresCombinados = {
-      Audiencia: this.form.get('audiencia')?.value,
-      ...this.valoresCombinados
-    }
+
   }
 
 
@@ -719,118 +560,66 @@ export class ModalTarea {
 
 
   valoresCombinados2: any[] = [];
-  
+
 
   arregloCombinaciones: any[] = [];
   idCircular: any;
 
-  async crearCircular() {
-    if (this.form.invalid) {
-      return Object.values(this.form.controls).forEach(control => {
-        control.markAllAsTouched();
-        Swal.fire({
-          icon: 'error',
-          title: `Por favor, llene todos los campos obligatorios.`
-        })
-      });
-    }
-
-    const audiencias = this.form.get('audiencia')?.value || [];
-    const destinos = this.form.get('destinos')?.value || [];
-
-    // Genera el arreglo de combinaciones
-    this.arregloCombinaciones = [];
-    audiencias.forEach((audiencia: string) => {
-      destinos.forEach((destino: any) => {
-        this.arregloCombinaciones.push({
-          Audiencia: audiencia,
-          Destino: destino.Destino,
-          id: destino.value
-        });
-      });
-    });
+  public alumnos:any = [];
 
+  crearTarea() {
     this.convertToDatetime();
-    this.info.audiencia = JSON.stringify(audiencias);
-    this.info.idReceptores = JSON.stringify(destinos.map((d: any) => d.value));
-    console.log('Combinaciones:', this.arregloCombinaciones);
-    console.log('Info:', this.info);
+    console.log(this.info);
 
-    // Loading
-    Swal.fire({
-      title: 'Cargando...',
-      allowOutsideClick: false,
-      didOpen: () => {
-        Swal.showLoading();
+    this.tareaService.getAlumnos(this.info.idMateriaTarea).subscribe(
+      (response: any) => {
+        this.alumnos = response.map((alumno: any) => alumno.idUsuario);
+        console.log("🚀 ~ ModalTarea ~ crearTarea ~ alumnos:", this.alumnos)
+      },
+      (err) => {
+        console.error('Error al obtener los alumnos:', err);
+        
       }
-    });
-
-    // 1️⃣ Primero creamos la circular
-    this.circularService.crearCircular(this.info).subscribe(
-      async (response: any) => {
-        console.log('Circular creada:', response);
-        this.idCircular = response.idCircular;
-
-        // 2️⃣ Obtener destinatarios únicos
-        const destinatariosUnicos: Set<string> = new Set();
-
-        for (const combinacion of this.arregloCombinaciones) {
-          console.log('Obteniendo destinatarios para:', combinacion);
-          await new Promise<void>((resolve) => {
-            this.circularService.obtenerDestinatarios(combinacion).subscribe(
-              (resp: any) => {
-                if (resp.idUsuario && Array.isArray(resp.idUsuario)) {
-                  resp.idUsuario.forEach((id: string) => destinatariosUnicos.add(id));
-                }
-                resolve();
-              },
-              (err) => {
-                console.error('Error al obtener destinatarios:', err);
-                resolve();
-              }
-            );
-          });
-        }
-
-        console.log('Destinatarios únicos:', Array.from(destinatariosUnicos));
-
-        // 3️⃣ Enviar circular a cada destinatario
-        const valoresCombinados2: any[] = [];
-        Array.from(destinatariosUnicos).forEach((idUsuario: string) => {
-          valoresCombinados2.push({
-            idUsuario,
-            idCircular: this.idCircular
-          });
-        });
+    );
 
-        for (let i = 0; i < valoresCombinados2.length; i++) {
-          this.circularService.enviarCircular(valoresCombinados2[i]).subscribe(
-            (resp: any) => console.log('Envío OK:', resp),
-            (err) => console.error('Error en envío:', err)
+    this.tareaService.crearTarea(this.info).subscribe(
+      (response: any) => {
+        console.log('Tarea creada:', response);
+        // Swal.fire({
+        //   icon: 'success',
+        //   title: `${response.mensaje}`
+        // });
+
+        this.alumnos.forEach((alumno:any) => {
+          this.tareaService.asignarTarea({
+            idTarea: response.idTarea,
+            idUsuario: alumno
+          }).subscribe(
+            (res) => {
+              console.log('Tarea asignada al alumno:', res);
+            },
+            (err) => {
+              console.error('Error al asignar la tarea al alumno:', err);
+            }
           );
-        }
-
-        Swal.close();
-        Swal.fire({
-          icon: 'success',
-          title: `${response.mensaje}`
         });
 
         this.dialog.closeAll();
         this._enviarInfoService.notifyCambioTabla();
       },
       (err) => {
-        Swal.close();
-        Swal.fire({
-          icon: 'error',
-          title: `${err.mensaje}`
-        });
+        console.error('Error al crear la tarea:', err);
+        // Swal.fire({
+        //   icon: 'error',
+        //   title: `Error al crear la tarea: ${err.error.mensaje || err.message || 'Error desconocido'}`
+        // });
       }
     );
   }
 
 
 
+
   public horasDelDia: any = this.generarHorasDelDia();
   generarHorasDelDia(): { hora24: string, hora12: string }[] {
     const horas: { hora24: string, hora12: string }[] = [];

+ 2 - 0
Front/src/app/modules/Profesor/profesor-routing.module.ts

@@ -8,6 +8,7 @@ import { CentroRecursosComponent } from "./pages/centro-recursos/centro-recursos
 import { CursoMateriaComponent } from "./pages/curso-materia/curso-materia.component";
 import { AsistenciaComponent } from "./pages/asistencia/asistencia.component";
 import { RegistroCalificacionesComponent } from "./pages/registroCalificaciones/registro-calificaciones.component";
+import { TareasComponent } from "./pages/tareas/tareas.component";
 
 
 
@@ -18,6 +19,7 @@ const routes: Routes = [
         path: '', component: LayoutPageComponent, children: [
             { path: 'main', component: MainComponent },
             { path: 'asistencia', component: AsistenciaComponent },
+            { path: 'tareas', component: TareasComponent },
             { path: 'registroBitacora', component: RegistroBitacoraComponent },
             { path: 'centroRecursos', component: CentroRecursosComponent },
             { path: 'cursoMateria/:id', component: CursoMateriaComponent },

+ 55 - 3
Front/src/app/modules/Profesor/profesor.module.ts

@@ -11,7 +11,14 @@ import { CentroRecursosComponent } from './pages/centro-recursos/centro-recursos
 import { CursoMateriaComponent, ModalAnuncio } from './pages/curso-materia/curso-materia.component';
 import { AsistenciaComponent, ModalAsistenciaEdit, ModalLista } from './pages/asistencia/asistencia.component';
 import { RegistroCalificacionesComponent } from './pages/registroCalificaciones/registro-calificaciones.component';
-import { TareasComponent } from './pages/tareas/tareas.component';
+import { ModalTarea, TareasComponent } from './pages/tareas/tareas.component';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatButtonModule } from '@angular/material/button';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+import { MatTabsModule } from '@angular/material/tabs';
+import { NgxEditorModule } from 'ngx-editor';
 
 
 
@@ -28,13 +35,58 @@ import { TareasComponent } from './pages/tareas/tareas.component';
     ModalAsistenciaEdit,
     ModalLista,
     RegistroCalificacionesComponent,
-    TareasComponent
+    TareasComponent,
+    ModalTarea
   ],
   imports: [
     MaterialModule,
     SharedModule,
     CommonModule,
-    ProfesorRoutingModule
+    ProfesorRoutingModule,
+    SharedModule,
+    MatFormFieldModule,
+    MatInputModule,
+    FormsModule,
+    ReactiveFormsModule,
+    MatButtonModule,
+    MatCheckboxModule,
+    MatTabsModule,
+    NgxEditorModule.forRoot({
+      locals: {
+        // menu
+        bold: 'Bold',
+        italic: 'Italic',
+        code: 'Code',
+        blockquote: 'Blockquote',
+        underline: 'Underline',
+        strike: 'Strike',
+        bullet_list: 'Bullet List',
+        ordered_list: 'Ordered List',
+        heading: 'Heading',
+        h1: 'Header 1',
+        h2: 'Header 2',
+        h3: 'Header 3',
+        h4: 'Header 4',
+        h5: 'Header 5',
+        h6: 'Header 6',
+        align_left: 'Left Align',
+        align_center: 'Center Align',
+        align_right: 'Right Align',
+        align_justify: 'Justify',
+        text_color: 'Text Color',
+        background_color: 'Background Color',
+
+        // popups, forms, others...
+        url: 'URL',
+        text: 'Text',
+        openInNewTab: 'Open in new tab',
+        insert: 'Insert',
+        altText: 'Alt Text',
+        title: 'Title',
+        remove: 'Remove',
+        enterValidUrl: 'Please enter a valid URL',
+      },
+    }),
   ]
 })
 export class ProfesorModule { }

+ 37 - 0
Front/src/app/modules/Profesor/services/tareas.service.ts

@@ -0,0 +1,37 @@
+import { Injectable } from '@angular/core';
+import { environments } from '../../../../environments/environments';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TareasService {
+  private URL: string = environments.baseUrl;
+
+  constructor(private http: HttpClient) { }
+
+  private getHeaders(): HttpHeaders {
+    const token = localStorage.getItem('token') || '';
+    return new HttpHeaders({
+      'Content-Type': 'application/json',
+      'Authorization': `Bearer ${token}`
+    });
+  }
+
+  getTipoTareas(){
+    return this.http.get(`${this.URL}/tipoTarea`, {headers: this.getHeaders()});
+  }
+
+  crearTarea(tarea: any){
+    return this.http.post(`${this.URL}/crearTarea`, tarea, {headers: this.getHeaders()});
+  }
+
+  getAlumnos(idMateria: string){
+    return this.http.get(`${this.URL}/materias/${idMateria}/alumnos`, {headers: this.getHeaders()});
+  }
+
+  asignarTarea(usuarioTarea: any){
+    return this.http.post(`${this.URL}/tareas-usuarios`, usuarioTarea, {headers: this.getHeaders()});
+  }
+
+}