feat: Implement CRUD API endpoints for core modules
Adds Express.js routes and Prisma-based handlers for common database operations (Create, Read, Update, Delete) for the following modules: - Empleados (subset of Cliente model) - Asistencias - Tareas (TareaRealizada model) - Planillas Each module's routes are separated into their own files within `api/routes/`. The new routes are registered in `api/server.js`. Basic error handling, including try-catch blocks and checks for common Prisma errors (e.g., P2025 for record not found, P2003 for foreign key violations), has been implemented in each endpoint.
This commit is contained in:
0
api/routes/asistencias/.gitkeep
Normal file
0
api/routes/asistencias/.gitkeep
Normal file
129
api/routes/asistencias/asistencias.js
Normal file
129
api/routes/asistencias/asistencias.js
Normal file
@@ -0,0 +1,129 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import { PrismaClient } from '../../prisma/generated/client/index.js';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// GET all asistencias
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const asistencias = await prisma.asistencia.findMany();
|
||||
res.json(asistencias);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener asistencias.' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET asistencia by ID
|
||||
router.get('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const asistencia = await prisma.asistencia.findUnique({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
if (asistencia) {
|
||||
res.json(asistencia);
|
||||
} else {
|
||||
res.status(404).json({ error: 'Asistencia no encontrada.' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener asistencia.' });
|
||||
}
|
||||
});
|
||||
|
||||
// POST create new asistencia
|
||||
router.post('/', async (req, res) => {
|
||||
const { empleado_id, entrada, salida, historial, observacion, estado, fecha_anulado, creador_id, modificado_id, anulador_id } = req.body;
|
||||
try {
|
||||
// Basic validation: empleado_id is required
|
||||
if (!empleado_id) {
|
||||
return res.status(400).json({ error: 'El campo empleado_id es obligatorio.' });
|
||||
}
|
||||
|
||||
const nuevaAsistencia = await prisma.asistencia.create({
|
||||
data: {
|
||||
empleado_id: parseInt(empleado_id),
|
||||
entrada: entrada ? new Date(entrada) : null,
|
||||
salida: salida ? new Date(salida) : null,
|
||||
historial, // Assuming historial is already in JSON format or Prisma handles it
|
||||
observacion,
|
||||
estado,
|
||||
fecha_anulado: fecha_anulado ? new Date(fecha_anulado) : null,
|
||||
creador_id, // Should ideally be taken from authenticated user
|
||||
modificado_id, // Should ideally be taken from authenticated user
|
||||
anulador_id
|
||||
},
|
||||
});
|
||||
res.status(201).json(nuevaAsistencia);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al crear asistencia.' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT update asistencia by ID
|
||||
router.put('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const { empleado_id, entrada, salida, historial, observacion, estado, fecha_anulado, modificado_id, anulador_id } = req.body;
|
||||
|
||||
try {
|
||||
const updateData = {
|
||||
entrada: entrada ? new Date(entrada) : undefined,
|
||||
salida: salida ? new Date(salida) : undefined,
|
||||
historial,
|
||||
observacion,
|
||||
estado,
|
||||
fecha_anulado: fecha_anulado ? new Date(fecha_anulado) : undefined,
|
||||
modificado_id, // Should ideally be taken from authenticated user
|
||||
anulador_id
|
||||
};
|
||||
|
||||
// If empleado_id is provided, include it in updateData.
|
||||
// Be cautious: changing empleado_id might not be a typical operation for an existing attendance record.
|
||||
if (empleado_id !== undefined) {
|
||||
updateData.empleado_id = parseInt(empleado_id);
|
||||
}
|
||||
|
||||
const asistenciaActualizada = await prisma.asistencia.update({
|
||||
where: { id: parseInt(id) },
|
||||
data: updateData,
|
||||
});
|
||||
res.json(asistenciaActualizada);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to update not found
|
||||
return res.status(404).json({ error: 'Asistencia no encontrada para actualizar.' });
|
||||
}
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al actualizar asistencia.' });
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE asistencia by ID
|
||||
router.delete('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
await prisma.asistencia.delete({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
res.status(204).send(); // No content
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to delete not found
|
||||
return res.status(404).json({ error: 'Asistencia no encontrada para eliminar.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al eliminar asistencia.' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
0
api/routes/empleados/.gitkeep
Normal file
0
api/routes/empleados/.gitkeep
Normal file
142
api/routes/empleados/empleados.js
Normal file
142
api/routes/empleados/empleados.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import { PrismaClient } from '../../prisma/generated/client/index.js';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// GET all empleados
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const empleados = await prisma.cliente.findMany({
|
||||
where: { empleado: true },
|
||||
});
|
||||
res.json(empleados);
|
||||
} catch (error) {
|
||||
console.error(error); // Log the error for debugging
|
||||
res.status(500).json({ error: 'Error al obtener empleados.' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET empleado by ID
|
||||
router.get('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const empleado = await prisma.cliente.findFirst({
|
||||
where: {
|
||||
id: parseInt(id),
|
||||
empleado: true
|
||||
},
|
||||
});
|
||||
if (empleado) {
|
||||
res.json(empleado);
|
||||
} else {
|
||||
res.status(404).json({ error: 'Empleado no encontrado.' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error); // Log the error for debugging
|
||||
res.status(500).json({ error: 'Error al obtener empleado.' });
|
||||
}
|
||||
});
|
||||
|
||||
// POST create new empleado
|
||||
router.post('/', async (req, res) => {
|
||||
const { nombre, apellido, dni, telefono, direccion, email } = req.body;
|
||||
try {
|
||||
const nuevoEmpleado = await prisma.cliente.create({
|
||||
data: {
|
||||
nombre,
|
||||
apellido,
|
||||
dni,
|
||||
telefono,
|
||||
direccion,
|
||||
email,
|
||||
empleado: true, // Ensure empleado is set to true
|
||||
},
|
||||
});
|
||||
res.status(201).json(nuevoEmpleado);
|
||||
} catch (error) {
|
||||
console.error(error); // Log the error for debugging
|
||||
if (error.code === 'P2002' && error.meta?.target?.includes('dni')) {
|
||||
return res.status(400).json({ error: 'Ya existe un cliente con este DNI.' });
|
||||
}
|
||||
if (error.code === 'P2002' && error.meta?.target?.includes('email')) {
|
||||
return res.status(400).json({ error: 'Ya existe un cliente con este Email.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al crear empleado.' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT update empleado by ID
|
||||
router.put('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const { nombre, apellido, dni, telefono, direccion, email } = req.body;
|
||||
try {
|
||||
// First, check if the employee exists and is an employee
|
||||
const existingEmpleado = await prisma.cliente.findFirst({
|
||||
where: {
|
||||
id: parseInt(id),
|
||||
empleado: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingEmpleado) {
|
||||
return res.status(404).json({ error: 'Empleado no encontrado.' });
|
||||
}
|
||||
|
||||
const empleadoActualizado = await prisma.cliente.update({
|
||||
where: { id: parseInt(id) },
|
||||
data: {
|
||||
nombre,
|
||||
apellido,
|
||||
dni,
|
||||
telefono,
|
||||
direccion,
|
||||
email,
|
||||
// empleado: true, // Keep it as an employee, or allow changing this? For now, keep as true.
|
||||
},
|
||||
});
|
||||
res.json(empleadoActualizado);
|
||||
} catch (error) {
|
||||
console.error(error); // Log the error for debugging
|
||||
if (error.code === 'P2002' && error.meta?.target?.includes('dni')) {
|
||||
return res.status(400).json({ error: 'Ya existe un cliente con este DNI.' });
|
||||
}
|
||||
if (error.code === 'P2002' && error.meta?.target?.includes('email')) {
|
||||
return res.status(400).json({ error: 'Ya existe un cliente con este Email.' });
|
||||
}
|
||||
if (error.code === 'P2025') { // Record to update not found
|
||||
return res.status(404).json({ error: 'Empleado no encontrado para actualizar.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al actualizar empleado.' });
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE empleado by ID
|
||||
router.delete('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
// First, check if the employee exists and is an employee
|
||||
const existingEmpleado = await prisma.cliente.findFirst({
|
||||
where: {
|
||||
id: parseInt(id),
|
||||
empleado: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingEmpleado) {
|
||||
return res.status(404).json({ error: 'Empleado no encontrado para eliminar.' });
|
||||
}
|
||||
|
||||
await prisma.cliente.delete({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
res.status(204).send(); // No content
|
||||
} catch (error) {
|
||||
console.error(error); // Log the error for debugging
|
||||
if (error.code === 'P2025') { // Record to delete not found
|
||||
return res.status(404).json({ error: 'Empleado no encontrado para eliminar.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al eliminar empleado.' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
0
api/routes/planillas/.gitkeep
Normal file
0
api/routes/planillas/.gitkeep
Normal file
142
api/routes/planillas/planillas.js
Normal file
142
api/routes/planillas/planillas.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import { PrismaClient } from '../../prisma/generated/client/index.js';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// GET all planillas
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const planillas = await prisma.planilla.findMany();
|
||||
res.json(planillas);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener planillas.' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET planilla by ID
|
||||
router.get('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const planilla = await prisma.planilla.findUnique({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
if (planilla) {
|
||||
res.json(planilla);
|
||||
} else {
|
||||
res.status(404).json({ error: 'Planilla no encontrada.' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener planilla.' });
|
||||
}
|
||||
});
|
||||
|
||||
// POST create new planilla
|
||||
router.post('/', async (req, res) => {
|
||||
const {
|
||||
empleado_id,
|
||||
fecha_desde,
|
||||
fecha_hasta,
|
||||
titulo,
|
||||
total,
|
||||
estado,
|
||||
fecha_anulado,
|
||||
creador_id, // Should ideally be from authenticated user
|
||||
anulador_id,
|
||||
} = req.body;
|
||||
|
||||
try {
|
||||
// Basic validation
|
||||
if (!empleado_id || !fecha_desde || !fecha_hasta || !titulo) {
|
||||
return res.status(400).json({ error: 'Los campos empleado_id, fecha_desde, fecha_hasta y titulo son obligatorios.' });
|
||||
}
|
||||
|
||||
const nuevaPlanilla = await prisma.planilla.create({
|
||||
data: {
|
||||
empleado_id: parseInt(empleado_id),
|
||||
fecha_desde: new Date(fecha_desde),
|
||||
fecha_hasta: new Date(fecha_hasta),
|
||||
titulo,
|
||||
total: total ? parseFloat(total) : null, // Prisma expects Decimal to be passed as number or string
|
||||
estado: estado || 'pagado', // Default to 'pagado' if not provided
|
||||
fecha_anulado: fecha_anulado ? new Date(fecha_anulado) : null,
|
||||
creador_id,
|
||||
anulador_id,
|
||||
},
|
||||
});
|
||||
res.status(201).json(nuevaPlanilla);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al crear planilla.' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT update planilla by ID
|
||||
router.put('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
empleado_id,
|
||||
fecha_desde,
|
||||
fecha_hasta,
|
||||
titulo,
|
||||
total,
|
||||
estado,
|
||||
fecha_anulado,
|
||||
anulador_id,
|
||||
} = req.body;
|
||||
|
||||
try {
|
||||
const updateData = {};
|
||||
if (empleado_id !== undefined) updateData.empleado_id = parseInt(empleado_id);
|
||||
if (fecha_desde !== undefined) updateData.fecha_desde = new Date(fecha_desde);
|
||||
if (fecha_hasta !== undefined) updateData.fecha_hasta = new Date(fecha_hasta);
|
||||
if (titulo !== undefined) updateData.titulo = titulo;
|
||||
if (total !== undefined) updateData.total = total ? parseFloat(total) : null;
|
||||
if (estado !== undefined) updateData.estado = estado;
|
||||
if (fecha_anulado !== undefined) updateData.fecha_anulado = fecha_anulado ? new Date(fecha_anulado) : null;
|
||||
if (anulador_id !== undefined) updateData.anulador_id = anulador_id;
|
||||
// creador_id is typically not updated.
|
||||
|
||||
const planillaActualizada = await prisma.planilla.update({
|
||||
where: { id: parseInt(id) },
|
||||
data: updateData,
|
||||
});
|
||||
res.json(planillaActualizada);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to update not found
|
||||
return res.status(404).json({ error: 'Planilla no encontrada para actualizar.' });
|
||||
}
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al actualizar planilla.' });
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE planilla by ID
|
||||
router.delete('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
await prisma.planilla.delete({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
res.status(204).send(); // No content
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to delete not found
|
||||
return res.status(404).json({ error: 'Planilla no encontrada para eliminar.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al eliminar planilla.' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
0
api/routes/tareas/.gitkeep
Normal file
0
api/routes/tareas/.gitkeep
Normal file
156
api/routes/tareas/tareas.js
Normal file
156
api/routes/tareas/tareas.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import { PrismaClient } from '../../prisma/generated/client/index.js';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// GET all tareas
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const tareas = await prisma.tareaRealizada.findMany();
|
||||
res.json(tareas);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener tareas.' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET tarea by ID
|
||||
router.get('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const tarea = await prisma.tareaRealizada.findUnique({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
if (tarea) {
|
||||
res.json(tarea);
|
||||
} else {
|
||||
res.status(404).json({ error: 'Tarea no encontrada.' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Error al obtener tarea.' });
|
||||
}
|
||||
});
|
||||
|
||||
// POST create new tarea
|
||||
router.post('/', async (req, res) => {
|
||||
const {
|
||||
empleado_id,
|
||||
planilla_id,
|
||||
titulo,
|
||||
precio,
|
||||
estado,
|
||||
observacion,
|
||||
fecha,
|
||||
tipo,
|
||||
fecha_anulado,
|
||||
creador_id, // Should ideally be from authenticated user
|
||||
anulador_id,
|
||||
} = req.body;
|
||||
|
||||
try {
|
||||
// Basic validation
|
||||
if (!empleado_id || !titulo || !fecha) {
|
||||
return res.status(400).json({ error: 'Los campos empleado_id, titulo y fecha son obligatorios.' });
|
||||
}
|
||||
|
||||
const nuevaTarea = await prisma.tareaRealizada.create({
|
||||
data: {
|
||||
empleado_id: parseInt(empleado_id),
|
||||
planilla_id: planilla_id ? parseInt(planilla_id) : null,
|
||||
titulo,
|
||||
precio: precio ? parseFloat(precio) : null,
|
||||
estado: estado || 'pendiente', // Default to 'pendiente' if not provided
|
||||
observacion,
|
||||
fecha: new Date(fecha),
|
||||
tipo: tipo || '', // Default to empty string if not provided
|
||||
fecha_anulado: fecha_anulado ? new Date(fecha_anulado) : null,
|
||||
creador_id,
|
||||
anulador_id,
|
||||
},
|
||||
});
|
||||
res.status(201).json(nuevaTarea);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
if (error.meta?.field_name?.includes('planilla_id')) {
|
||||
return res.status(400).json({ error: 'El planilla_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al crear tarea.' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT update tarea by ID
|
||||
router.put('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
empleado_id,
|
||||
planilla_id,
|
||||
titulo,
|
||||
precio,
|
||||
estado,
|
||||
observacion,
|
||||
fecha,
|
||||
tipo,
|
||||
fecha_anulado,
|
||||
anulador_id,
|
||||
} = req.body;
|
||||
|
||||
try {
|
||||
const updateData = {};
|
||||
if (empleado_id !== undefined) updateData.empleado_id = parseInt(empleado_id);
|
||||
if (planilla_id !== undefined) updateData.planilla_id = planilla_id ? parseInt(planilla_id) : null;
|
||||
if (titulo !== undefined) updateData.titulo = titulo;
|
||||
if (precio !== undefined) updateData.precio = precio ? parseFloat(precio) : null;
|
||||
if (estado !== undefined) updateData.estado = estado;
|
||||
if (observacion !== undefined) updateData.observacion = observacion;
|
||||
if (fecha !== undefined) updateData.fecha = new Date(fecha);
|
||||
if (tipo !== undefined) updateData.tipo = tipo;
|
||||
if (fecha_anulado !== undefined) updateData.fecha_anulado = fecha_anulado ? new Date(fecha_anulado) : null;
|
||||
if (anulador_id !== undefined) updateData.anulador_id = anulador_id;
|
||||
// creador_id is typically not updated.
|
||||
|
||||
const tareaActualizada = await prisma.tareaRealizada.update({
|
||||
where: { id: parseInt(id) },
|
||||
data: updateData,
|
||||
});
|
||||
res.json(tareaActualizada);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to update not found
|
||||
return res.status(404).json({ error: 'Tarea no encontrada para actualizar.' });
|
||||
}
|
||||
if (error.code === 'P2003') { // Foreign key constraint failed
|
||||
if (error.meta?.field_name?.includes('empleado_id')) {
|
||||
return res.status(400).json({ error: 'El empleado_id proporcionado no existe.' });
|
||||
}
|
||||
if (error.meta?.field_name?.includes('planilla_id')) {
|
||||
return res.status(400).json({ error: 'El planilla_id proporcionado no existe.' });
|
||||
}
|
||||
}
|
||||
res.status(500).json({ error: 'Error al actualizar tarea.' });
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE tarea by ID
|
||||
router.delete('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
await prisma.tareaRealizada.delete({
|
||||
where: { id: parseInt(id) },
|
||||
});
|
||||
res.status(204).send(); // No content
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.code === 'P2025') { // Record to delete not found
|
||||
return res.status(404).json({ error: 'Tarea no encontrada para eliminar.' });
|
||||
}
|
||||
res.status(500).json({ error: 'Error al eliminar tarea.' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user