Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class AssistanceApplicationsController {

@Get(':id/document')
findOneDocument(@Param('id') id: string) {
return this.assistanceApplicationsService.findOne(id, true);
return this.assistanceApplicationsService.findOneDocument(id);
}

@Patch(':id')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ export class AssistanceApplicationsService {
return results;
}

async findOne(id: string, withDocument: boolean = false) {
async findOne(id: string) {
const application = await this.assistanceApplicationRepository.findOne({
where: { id },
relations: {
graduatedAssistance: {
professor: true,
},
student: true,
document: withDocument,
document: true,
},
});
if (!application) {
Expand All @@ -88,6 +88,37 @@ export class AssistanceApplicationsService {
return application;
}

async findOneDocument(id: string) {
const application = await this.findOne(id);
const graduatedAssistanceId = application.graduatedAssistance.id;

const applications = await this.assistanceApplicationRepository
.createQueryBuilder('app')
.select(['app.id'])
.where('app.graduatedAssistanceId = :graduatedAssistanceId', {
graduatedAssistanceId,
})
.orderBy('app.createdAt', 'ASC')
.addOrderBy('app.id', 'ASC')
.getMany();

const applicationIds = applications.map((app) => app.id);
const currentIndex = applicationIds.indexOf(application.id);

const previousId =
currentIndex > 0 ? applicationIds[currentIndex - 1] : null;
const nextId =
currentIndex < applicationIds.length - 1
? applicationIds[currentIndex + 1]
: null;

return {
application,
previousId,
nextId,
};
}

async update(
id: string,
updateAssistanceApplicationDto: UpdateAssistanceApplicationDto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export class AssistanceApplication extends Base {
@ManyToOne(() => Student, (student) => student.assistanceApplications)
student: Student;

@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;

@ManyToOne(
() => GraduatedAssistance,
(graduatedAssistance) => graduatedAssistance.assistanceApplications,
Expand Down
12 changes: 5 additions & 7 deletions apps/api/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,11 @@ export class UsersService {

getUserRoles(user: User) {
const roles: string[] = [];
if (user.administrator && user.administrator.isActive)
roles.push('administrador');
if (user.coordinator && user.coordinator.isActive)
roles.push('coordinador');
if (user.professor && user.professor.isActive) roles.push('profesor');
if (user.student && user.student.isActive) {
if (user.administrator && user.administrator.isActive) {
if (user.administrator?.isActive) roles.push('administrador');
if (user.coordinator?.isActive) roles.push('coordinador');
if (user.professor?.isActive) roles.push('profesor');
if (user.student?.isActive) {
if (user.administrator?.isActive) {
roles.push('estudiante');
roles.push('estudiante_maestria');
} else if (user.student.isUndergraduate) {
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/app/inicio/administrador/incidencia/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ const columns: ColumnDef<Incidence>[] = [
sortingFn: (rowA, rowB, columnId) => {
const a = rowA.getValue<boolean>(columnId);
const b = rowB.getValue<boolean>(columnId);
return a === b ? 0 : a ? 1 : -1;
if (a === b) return 0;
return a ? 1 : -1;
}
},
{
Expand Down Expand Up @@ -107,9 +108,10 @@ function ActionCell({ incidence }: { readonly incidence: Incidence }) {
const completed = incidence.isClosed? true: isClosing;

const handleClose = async () => {
if (!incidence.id) return;
setIsClosing(true);
try {
await closeIncidence(incidence.id!);
await closeIncidence(incidence.id);
await queryClient.invalidateQueries({ queryKey: ['incidences'] });
} catch (error) {
console.error("Error al cerrar la incidencia:", error);
Expand Down
104 changes: 53 additions & 51 deletions apps/web/src/app/inicio/administrador/lider/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useQuery, useQueryClient } from "@tanstack/react-query";
import { DataTable } from "@/components/data-table";
import { ColumnDef } from "@tanstack/react-table";
import { ColumnDef, Row } from "@tanstack/react-table";
import SpinnerPage from "@/components/shared/spinner-page";
import ErrorPage from "@/components/shared/error-page";
import { Button } from "@/components/ui/button";
Expand All @@ -20,59 +20,38 @@ import {
import { LeaderPerCourse } from "@/app/types/leader-per-course.type";
import { User } from "@/app/types/entities/user.type";

const columns: ColumnDef<LeaderPerCourse>[] = [
{
accessorKey: "code",
header: "Código",
},
{
accessorKey: "courseName",
header: "Nombre curso",
},
{
accessorKey: "professorName",
header: "Nombre profesor",
},
{
accessorKey: "email",
header: "Email",
},
{
id: "assign",
header: "Asignar",
enableSorting: false,
cell: ({ row }: { row: Row<LeaderPerCourse> }) => <PopoverPerCourse row={row} />
},
];

export default function CourseList() {
const queryClient = useQueryClient();

const { data, isFetching, isError } = useQuery({
queryKey: ["courses-leaders"],
queryFn: () => findAllWithMainProfessor(),
});

const columns: ColumnDef<LeaderPerCourse>[] = [
{
accessorKey: "code",
header: "Código",
},
{
accessorKey: "courseName",
header: "Nombre curso",
},
{
accessorKey: "professorName",
header: "Nombre profesor",
},
{
accessorKey: "email",
header: "Email",
},
{
id: "assign",
header: "Asignar",
enableSorting: false,
cell: ({ row }) => (
<ProfessorListPopover
courseId={row.original.courseId}
onAssigned={(newProfessor) => {
queryClient.setQueryData<LeaderPerCourse[]>(
["courses-leaders"],
(oldData) =>
oldData?.map((course) =>
course.courseId === row.original.courseId
? {
...course,
professorId: newProfessor.id,
professorName: newProfessor.name,
email: newProfessor.email,
}
: course
) ?? []
);
}}
/>
),
},
];

if (isFetching) return <SpinnerPage />;
if (isError) return <ErrorPage />;
return (
Expand All @@ -87,6 +66,31 @@ export default function CourseList() {
);
}

function PopoverPerCourse({ row }: { readonly row: Row<LeaderPerCourse> }) {
const queryClient = useQueryClient();
return (
<ProfessorListPopover
courseId={row.original.courseId}
onAssigned={(newProfessor) => {
queryClient.setQueryData<LeaderPerCourse[]>(
["courses-leaders"],
(oldData) =>
oldData?.map((course) =>
course.courseId === row.original.courseId
? {
...course,
professorId: newProfessor.id,
professorName: newProfessor.name,
email: newProfessor.email,
}
: course
) ?? []
);
}}
/>
)
}

function ProfessorListPopover({
courseId,
onAssigned,
Expand All @@ -96,7 +100,6 @@ function ProfessorListPopover({
}) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const [selected, setSelected] = useState<User | null>(null);

const { data } = useQuery({
queryKey: ["professors-by-course", courseId],
Expand All @@ -111,7 +114,6 @@ function ProfessorListPopover({
const handleAssign = async (professor: User) => {
try {
await assignProfessorAsCourseLeader(professor.id, courseId);
setSelected(professor);
setOpen(false);
onAssigned?.(professor);
} catch (error) {
Expand All @@ -123,7 +125,7 @@ function ProfessorListPopover({
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button className="w-full">
{selected?.name ?? "Asignar"}
Asignar
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px]">
Expand Down Expand Up @@ -155,4 +157,4 @@ function ProfessorListPopover({
</PopoverContent>
</Popover>
);
}
}
75 changes: 36 additions & 39 deletions apps/web/src/app/inicio/coordinador/cartelera/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,60 +69,57 @@ export default function UploadBillboard() {
handleUploadXlsm(file);
}
}}
dialogText={dialogText}
dialogText={dialogText}
>
<UploadedBillboard classesData={coursesData} loadError={loadError} />
</UploadFilePage >
<UploadedBillboard classesData={coursesData} loadError={loadError} />
</UploadFilePage >

<AlertDialogError open={loadError} onOpenChange={setLoadError} />
</>
);
}

const columns: ColumnDef<Course>[] = [
{
accessorKey: "name",
header: "Clase",
},
{
accessorKey: "code",
header: "Código",
},
{
accessorFn: (row) => row.sections.length,
header: "Secciones",
},
{
accessorKey: "credits",
header: "Créditos",
},
{
id: "professors",
header: "Profesores",
cell: ({ row }) => {
const professors = row.original.sections.flatMap((section) =>
section.professors.map((p) => p.user.name)
);
return (
<span>
{professors.length > 0 ? professors.join(", ") : "No asignados"}
</span>
);
},
},
];

function UploadedBillboard({
classesData,
loadError,
}: {
readonly classesData: Course[];
readonly loadError: boolean;
}) {
const columns: ColumnDef<Course>[] = [
{
accessorKey: "name",
header: "Clase",
},
{
accessorKey: "code",
header: "Código",
},
{
accessorFn: (row) => row.sections.length,
header: "Secciones",
},
{
accessorKey: "credits",
header: "Créditos",
},
{
id: "professors",
header: "Profesores",
cell: ({ row }) => {
const professors = row.original.sections.flatMap((section) =>
section.professors.map((p) => p.user.name)
);
return (
<span>
{professors.length > 0 ? professors.join(", ") : "No asignados"}
</span>
);
},
},
];

if (loadError) return <BillboardNotFound />;



return (
<div className="min-h-full min-w-full">
<div className="bg-card rounded-lg shadow-lg p-6 space-y-6">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const getProgramColumns = (handleDetail: (id: string) => void): ColumnDef
header: "Profesor",
cell: ({ row }) => (
<span className="text-primary">
{row.original.mainProfessor?.user?.name || "No professor assigned"}
{row.original.mainProfessor?.user?.name || "Profesor no asignado"}
</span>
),
},
Expand Down
Loading