Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
b66d6cd
cambios isaac
aizac17 Feb 20, 2026
2dafb56
cambios jose en home
SIN98 Feb 20, 2026
ff80da1
Cambios en Clock UI - Emilio
Emirami Feb 20, 2026
3e4a671
cambios reports alejandro
Ale87w Feb 20, 2026
4d29120
cambios en sidebar-Chiquil
Chiquil1 Feb 20, 2026
60735a7
cambios hechos en el sideba-Chiquil
Chiquil1 Feb 20, 2026
84e4c9e
Cambios en Clock UI - alejandro
Ale87w Feb 23, 2026
88a6642
Modificación de Teachers-Isaac
aizac17 Feb 26, 2026
f5c6446
Modificacion Dashboard
Emirami Feb 26, 2026
5072a77
Cambios en sidebar y app
Chiquil1 Feb 27, 2026
e5cfb31
jose reloj2
SIN98 Feb 27, 2026
b4b2465
Merge pull request #3 from arlinchc/feature-jose
arlinchc Feb 27, 2026
71f05e4
cambios en Systemconfig
Ale87w Feb 27, 2026
97d0992
Merge branch 'desarrollo' into feature-emilio
arlinchc Feb 27, 2026
4007351
Merge pull request #4 from arlinchc/feature-emilio
arlinchc Feb 27, 2026
7dfb7d8
Merge pull request #2 from arlinchc/feature-isaac
arlinchc Feb 27, 2026
b05db1e
cambios en Systemconfig
Ale87w Feb 27, 2026
bb879f8
Merge branch 'desarrollo' into feature-Chiquil
arlinchc Feb 27, 2026
e9b0250
Merge pull request #6 from arlinchc/feature-Chiquil
arlinchc Feb 27, 2026
5fef3e5
cambios en Systemconfig
Ale87w Feb 27, 2026
65f5d7b
sistem config
Chiquil1 Feb 27, 2026
950597d
cambios en Systemconfig
Ale87w Feb 27, 2026
fa75692
cambios en Systemconfig
Ale87w Feb 27, 2026
0c5eb8c
Merge branch 'desarrollo' into palikhov-daniil
arlinchc Feb 27, 2026
12b0179
Merge pull request #7 from arlinchc/palikhov-daniil
arlinchc Feb 27, 2026
136eaa6
Merge pull request #8 from arlinchc/feature-sky
arlinchc Feb 27, 2026
9ed3df9
Merge branch 'desarrollo' into feature-alejandro
arlinchc Feb 27, 2026
e6d2db7
Merge pull request #9 from arlinchc/feature-alejandro
arlinchc Feb 27, 2026
cd577c5
cambios sidebar
Chiquil1 Feb 27, 2026
57cf8cc
Delete src/components/Sidebar.jsx
arlinchc Feb 27, 2026
18dfc7a
Add files via upload
arlinchc Feb 27, 2026
4efc8dc
Delete src/components/Sidebar.jsx
arlinchc Feb 27, 2026
b131c19
Delete src/components/Sidebar.jsx
arlinchc Feb 27, 2026
d4b40ae
nuevo sidebar
Chiquil1 Feb 27, 2026
0111686
resolver conflicto
Chiquil1 Feb 27, 2026
61a2e3d
Add files via upload
arlinchc Feb 27, 2026
f0ee0c0
Rename Sidebar (1).jsx to Sidebar.jsx
arlinchc Feb 27, 2026
829f0d8
Add .env file
dpalik500 Mar 6, 2026
04cc212
Correcciones en Sidebar
iarlinchc Mar 6, 2026
134d186
Actualizar desarrollo
iarlinchc Mar 6, 2026
3539887
Merge branch 'desarrollo' into feature-sky
arlinchc Mar 6, 2026
7660391
Merge pull request #12 from arlinchc/feature-sky
arlinchc Mar 6, 2026
b6005b4
Actualiza dependencias y modulo Reports
iarlinchc Mar 6, 2026
13b3e7b
Fix: Normalize SystemConfigRoutes filename
Mar 27, 2026
87203c7
Integración API teachers con frontend y correcciones
iarlinchc Mar 27, 2026
7d3be1e
Add schedules module with backend API and frontend integration
dpalik500 Mar 27, 2026
271e5a0
Cambios en config
Mar 27, 2026
8c9d69d
Cambios en config del sistema
Mar 27, 2026
7685748
reloj y reportes conectados a la base de datos en las tablas teachers…
SIN98 Mar 28, 2026
37e1b76
Cambios en Teachers.jsx - Isaac
aizac17 Mar 30, 2026
1b2a1c2
Cambios en Teachers.jsx - Isaac
aizac17 Mar 30, 2026
47f196a
Agrego backend inicial con server.js y configuración
aizac17 Mar 30, 2026
e55ae9f
Corrección de Sidebar y Creacion de la base de datos de system_Config
Chiquil1 Apr 1, 2026
8f7570b
Add schedules module with backend API and frontend integration
dpalik500 Apr 10, 2026
260a120
Merge feature-jose resuelto
iarlinchc Apr 17, 2026
b90de54
Merge feature-jose correctamente integrado
iarlinchc Apr 17, 2026
75f21ef
Cambios antes de merge con palikhov-daniil
iarlinchc Apr 17, 2026
6776eff
Merge feature-isaac integrando CRUD completo de teachers
iarlinchc Apr 17, 2026
718bb11
Fix merge feature-isaac and clean Teachers module
iarlinchc Apr 17, 2026
1b516b2
Merge feature-Chiquil sin romper Teachers + configuración integrada
iarlinchc Apr 17, 2026
82affe3
Fix duplicate Package.json casing issue
iarlinchc Apr 17, 2026
6df84b1
Restore backend package.json
iarlinchc Apr 17, 2026
40105e6
Fix corrupted package.json
iarlinchc Apr 17, 2026
93bc916
Remove lingering submodule reference ontimeClock
iarlinchc Apr 17, 2026
231cb9e
Use DATABASE_URL for Render
iarlinchc Apr 17, 2026
734e948
Connect frontend to Render backend (production API)
iarlinchc Apr 17, 2026
3383f6c
Fix Teachers full UI (Render compatibility + crash fix)
iarlinchc Apr 17, 2026
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
5 changes: 5 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DB_HOST="72.56.71.92"
DB_PORT="5433"
DB_USER="student"
DB_PASSWORD="qL8jZQlj6YSLV4zpXaVw"
DB_NAME="unid"
Binary file modified .gitignore
Binary file not shown.
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"2guys1account.quackrack-cursor"
]
}
Empty file added backend/.env.example
Empty file.
11 changes: 11 additions & 0 deletions backend/config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require("dotenv").config();
const { Pool } = require("pg");

const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false,
},
});

module.exports = pool;
90 changes: 90 additions & 0 deletions backend/controllers/SystemConfigController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const {
getAllConfigs,
getConfigById,
createConfig,
updateConfig,
deleteConfig,
getworkdays,
updateworkday,
createworkday // ✅ CORREGIDO: faltaba esta importación
} = require('../models/SystemConfigModel');

// Manejador para obtener todas las configuraciones
exports.getConfigs = async (req, res) => {
try {
const configs = await getAllConfigs();
res.json(configs);
} catch (error) {
res.status(500).json({ error: error.message });
}
};

// Manejador para obtener una configuración por ID
exports.getConfig = async (req, res) => {
try {
const { id } = req.params;
const config = await getConfigById(id);
if (!config) return res.status(404).json({ message: 'Configuración no encontrada' });
res.json(config);
} catch (error) {
res.status(500).json({ error: error.message });
}
};

exports.createConfig = async (req, res) => {
try {
const newConfig = await createConfig(req.body);
res.status(201).json(newConfig);
} catch (error) {
res.status(500).json({ error: error.message });
}
};

exports.updateConfig = async (req, res) => {
try {
const { id } = req.params;
const updated = await updateConfig(id, req.body);
res.json(updated);
} catch (error) {
res.status(500).json({ error: error.message });
}
};

exports.deleteConfig = async (req, res) => {
try {
const { id } = req.params;
const result = await deleteConfig(id);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
};

// Manejadores para los días laborales (Work_Days)
exports.getworkdays = async (req, res) => {
try {
const days = await getworkdays();
res.json(days);
} catch (error) {
res.status(500).json({ error: 'Error al obtener días laborales' });
}
};

exports.createworkday = async (req, res) => {
try {
const newDay = await createworkday(req.body);
res.status(201).json(newDay);
} catch (error) {
res.status(500).json({ error: 'Error al crear día laboral' });
}
};

exports.updateworkday = async (req, res) => {
try {
const { id } = req.params;
const updated = await updateworkday(id, req.body);
res.json(updated);
} catch (error) {
res.status(500).json({ error: 'Error al actualizar día laboral' });
}
};
45 changes: 45 additions & 0 deletions backend/controllers/recordsControllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//controlador para registros de asistencia
const recordsModel = require('../modelos/recordsModel');

exports.createRecord = async (req, res) => {
try {
const record = await recordsModel.createRecord(req.body);
res.status(201).json(record);
} catch (error) {
console.error('Error al crear registro:', error.message);

if (error.message.includes('No existe')) {
res.status(404).json({ error: error.message });
} else if (
error.message.includes('Ya registraste') ||
error.message.includes('Primero debes registrar') ||
error.message.includes('obligatoria') ||
error.message.includes('tipo de registro')
) {
res.status(400).json({ error: error.message });
} else {
res.status(500).json({ error: 'Error al registrar asistencia' });
}
}
}

exports.getRecords = async (req, res) => {
try {
const records = await recordsModel.getRecords();
res.json(records);
} catch (error) {
console.error('Error al obtener registros:', error);
res.status(500).json({ error: 'Error al obtener registros' });
}
}

exports.getRecordsByMatricula = async (req, res) => {
try {
const { matricula } = req.params;
const records = await recordsModel.getRecordsByMatricula(matricula);
res.json(records);
} catch (error) {
console.error('Error al obtener registros:', error);
res.status(500).json({ error: 'Error al obtener registros' });
}
}
50 changes: 50 additions & 0 deletions backend/controllers/reportsControllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const reportsModel = require('../modelos/reportsModel');

exports.getSummaryReport = async (req, res) => {
try {
const { startDate, endDate } = req.query;

if (!startDate || !endDate) {
return res.status(400).json({ error: 'startDate y endDate son obligatorios' });
}

const data = await reportsModel.getSummaryReport(startDate, endDate);
res.json(data);
} catch (error) {
console.error('Error al generar reporte:', error.message);

if (
error.message.includes('formato') ||
error.message.includes('inicio no puede ser mayor')
) {
return res.status(400).json({ error: error.message });
}

res.status(500).json({ error: 'Error al generar reporte' });
}
};

exports.getTeacherReportDetails = async (req, res) => {
try {
const { matricula } = req.params;
const { startDate, endDate } = req.query;

if (!startDate || !endDate) {
return res.status(400).json({ error: 'startDate y endDate son obligatorios' });
}

const data = await reportsModel.getTeacherReportDetails(matricula, startDate, endDate);
res.json(data);
} catch (error) {
console.error('Error al generar detalle del reporte:', error.message);

if (
error.message.includes('formato') ||
error.message.includes('inicio no puede ser mayor')
) {
return res.status(400).json({ error: error.message });
}

res.status(500).json({ error: 'Error al generar detalle del reporte' });
}
};
115 changes: 115 additions & 0 deletions backend/controllers/schedulesController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const schedulesModel = require('../models/schedulesModel');
const teachersModel = require('../models/teachesModel');

exports.getSchedules = async (req, res) => {
try {
const schedules = await schedulesModel.getAllSchedules();
res.json(schedules);
} catch (error) {
console.error('Error getting schedules:', error);
res.status(500).json({ error: 'Failed to fetch schedules' });
}
};

exports.getScheduleById = async (req, res) => {
try {
const { id } = req.params;
const schedule = await schedulesModel.getScheduleById(id);
if (!schedule) {
return res.status(404).json({ error: 'Schedule not found' });
}
res.json(schedule);
} catch (error) {
console.error('Error getting schedule:', error);
res.status(500).json({ error: 'Failed to fetch schedule' });
}
};

exports.getSchedulesByTeacher = async (req, res) => {
try {
const { teacherId } = req.params;
const schedules = await schedulesModel.getSchedulesByTeacher(teacherId);
res.json(schedules);
} catch (error) {
console.error('Error getting schedules by teacher:', error);
res.status(500).json({ error: 'Failed to fetch schedules by teacher' });
}
};

exports.createSchedule = async (req, res) => {
try {
const { teacher_id, subject, day, start_time, end_time, room, group_name } = req.body;

// Validate required fields
if (!teacher_id || !subject || !day || !start_time || !end_time || !room || !group_name) {
return res.status(400).json({
error: 'Missing required fields: teacher_id, subject, day, start_time, end_time, room, group_name'
});
}

// Verify teacher exists
const teacher = await teachersModel.getTeacherById(teacher_id);
if (!teacher) {
return res.status(404).json({ error: 'Teacher not found' });
}

const schedule = await schedulesModel.createSchedule({
teacher_id,
subject,
day,
start_time,
end_time,
room,
group_name
});

res.status(201).json(schedule);
} catch (error) {
console.error('Error creating schedule:', error);
res.status(500).json({ error: 'Failed to create schedule' });
}
};

exports.updateSchedule = async (req, res) => {
try {
const { id } = req.params;
const { teacher_id, subject, day, start_time, end_time, room, group_name } = req.body;

const schedule = await schedulesModel.updateSchedule(id, {
teacher_id,
subject,
day,
start_time,
end_time,
room,
group_name
});

res.json(schedule);
} catch (error) {
console.error('Error updating schedule:', error);
res.status(500).json({ error: 'Failed to update schedule' });
}
};

exports.deleteSchedule = async (req, res) => {
try {
const { id } = req.params;
await schedulesModel.deleteSchedule(id);
res.status(204).end();
} catch (error) {
console.error('Error deleting schedule:', error);
res.status(500).json({ error: 'Failed to delete schedule' });
}
};

exports.getTeachers = async (req, res) => {
try {
const teachers = await teachersModel.getAllTeachers();
res.json(teachers);
} catch (error) {
console.error('Error getting teachers:', error);
res.status(500).json({ error: 'Failed to fetch teachers' });
}
};

38 changes: 38 additions & 0 deletions backend/controllers/teachersController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const teacherModel = require('../models/teachesModel');


exports.getTeachers = async (req, res) => {
const teachers = await teacherModel.getAllTeachers();
res.json(teachers);
}

exports.newTeacher = async (req, res) => {
const { name, email, phone, mat } = req.body;
const newTeacher = await teacherModel.newTeacheradd({ name, email, phone, mat });
res.status(201).json(newTeacher);
}

exports.getTeacherById = async (req, res) => {
const { id } = req.params;
const teacher = await teacherModel.getTeacherById(id);
res.json(teacher);
}

exports.createTeacher = async (req, res) => {
const { name, subject, email, phone, degree, status, avatar } = req.body;
const newTeacher = await teacherModel.createTeacher({ name, subject, email, phone, degree, status, avatar });
res.status(201).json(newTeacher);
}

exports.updateTeacher = async (req, res) => {
const { id } = req.params;
const { name, subject, email, phone, degree, status, avatar } = req.body;
const updatedTeacher = await teacherModel.updateTeacher(id, { name, subject, email, phone, degree, status, avatar });
res.json(updatedTeacher);
}

exports.deleteTeacher = async (req, res) => {
const { id } = req.params;
await teacherModel.deleteTeacher(id);
res.status(204).end();
}
Loading