diff --git a/ui/README.md b/ui/README.md index 1511959..779c0be 100644 --- a/ui/README.md +++ b/ui/README.md @@ -3,3 +3,97 @@ This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` +``` +The specific prop name matches the module (e.g., `asistencia` for `cardAsistencia`, `employee` for `cardEmpleado`, `planilla` for `cardPlanilla`, `tarea` for `cardTarea`). diff --git a/ui/postcss.config.js b/ui/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/ui/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/ui/src/components/asistencias/cardAsistencia.vue b/ui/src/components/asistencias/cardAsistencia.vue index b7426a4..5a2c389 100644 --- a/ui/src/components/asistencias/cardAsistencia.vue +++ b/ui/src/components/asistencias/cardAsistencia.vue @@ -1,24 +1,32 @@ @@ -26,6 +34,7 @@ diff --git a/ui/src/components/empleados/cardEmpleado.vue b/ui/src/components/empleados/cardEmpleado.vue index d25fede..1abb0cf 100644 --- a/ui/src/components/empleados/cardEmpleado.vue +++ b/ui/src/components/empleados/cardEmpleado.vue @@ -1,41 +1,45 @@ @@ -44,18 +48,15 @@ import { PropType } from 'vue' import { useRouter } from 'vue-router' -// Define the structure of the employee object based on the Prisma schema interface Employee { - id: string | number // Changed from BigInt to string | number for easier handling in frontend + id: string | number name: string - cedula: number // Changed from BigInt + cedula: number avatar_url?: string telefono?: string ubicacion: string idciat?: string grupo_estudio?: string - // created_at and updated_at are usually not displayed directly in a summary card - // empleado: boolean // This is implicit as it's an employee card } const props = defineProps({ @@ -68,65 +69,29 @@ const props = defineProps({ const router = useRouter() const handleEdit = () => { - // Ensure employee.id is available and correctly typed for URL - router.push(`/empleados/edit/${props.employee.id}`) + // The router pushes to `/empleados/:id` as per current router config, + // which maps to `EmpleadoForm.vue`. This form serves for both editing and viewing details. + router.push(`/empleados/${props.employee.id}`) } -const handleViewDetails = () => { - // This could navigate to a more detailed employee page if one exists - // For now, it can also navigate to an edit page or a specific detail view - // Depending on the application's routing structure, this might be the same as edit or a different view - router.push(`/empleados/view/${props.employee.id}`) // Assuming a dedicated view route exists or will be created -} +// handleViewDetails method removed for consistency + +const buttonHover = (event: MouseEvent, isHovering: boolean) => { + const target = event.target as HTMLElement; + if (isHovering) { + target.style.filter = 'brightness(90%)'; + } else { + target.style.filter = 'brightness(100%)'; + } +}; diff --git a/ui/src/components/planillas/cardPlanilla.vue b/ui/src/components/planillas/cardPlanilla.vue index 40bcda9..92f7fe0 100644 --- a/ui/src/components/planillas/cardPlanilla.vue +++ b/ui/src/components/planillas/cardPlanilla.vue @@ -1,15 +1,31 @@ @@ -36,9 +52,7 @@ const formatDate = (dateString) => { }; const formatCurrency = (value) => { - if (value == null) return 'N/A'; // Handle null or undefined totals - // Assuming the value is a number or can be converted to one. - // Adjust 'es-PY' and currency 'PYG' (Paraguayan Guarani) as needed. + if (value == null) return 'N/A'; return Number(value).toLocaleString('es-PY', { style: 'currency', currency: 'PYG' @@ -50,8 +64,7 @@ const editPlanilla = () => { }; const confirmDeletePlanilla = () => { - // In a real app, you'd use a confirmation dialog here - if (confirm(`¿Está seguro de que desea eliminar la planilla "${props.planilla.titulo}"?`)) { + if (confirm(`¿Está seguro de que desea eliminar la planilla "${props.planilla.titulo}" (ID: ${props.planilla.id})?`)) { deletePlanilla(); } }; @@ -59,85 +72,35 @@ const confirmDeletePlanilla = () => { const deletePlanilla = async () => { try { await planillasStore.deletePlanilla(props.planilla.id); - // Optionally, emit an event or show a notification upon successful deletion - // For example: emit('deleted', props.planilla.id); } catch (error) { console.error('Error deleting planilla:', error); - // Handle error (e.g., show a notification to the user) + alert('Ocurrió un error al eliminar la planilla.'); } }; + +const getStatusClass = (status) => { + if (!status) return 'bg-gray-400'; + const statusNormalized = status.toLowerCase().replace(/\s+/g, '-'); + switch (statusNormalized) { + case 'pagado': return 'bg-green-500'; + case 'pendiente': return 'bg-yellow-500 text-gray-800'; + case 'anulado': return 'bg-red-500'; + case 'borrador': return 'bg-gray-500'; + default: return 'bg-gray-400'; + } +}; + +const buttonHover = (event, isHovering) => { + if (isHovering) { + event.target.style.filter = 'brightness(90%)'; + } else { + event.target.style.filter = 'brightness(100%)'; + } +}; + diff --git a/ui/src/components/tareas/cardTarea.vue b/ui/src/components/tareas/cardTarea.vue index bac3921..3e15c10 100644 --- a/ui/src/components/tareas/cardTarea.vue +++ b/ui/src/components/tareas/cardTarea.vue @@ -1,17 +1,34 @@ @@ -39,7 +56,7 @@ const formatDate = (dateString) => { const formatCurrency = (value) => { if (value == null) return ''; - return Number(value).toLocaleString('es-PY', { // Paraguayan Guarani + return Number(value).toLocaleString('es-PY', { style: 'currency', currency: 'PYG', }); @@ -50,7 +67,7 @@ const editTarea = () => { }; const confirmDeleteTarea = () => { - if (confirm(`¿Está seguro de que desea eliminar la tarea "${props.tarea.titulo}"?`)) { + if (confirm(`¿Está seguro de que desea eliminar la tarea "${props.tarea.titulo}" (ID: ${props.tarea.id})?`)) { deleteTareaInternal(); } }; @@ -58,99 +75,42 @@ const confirmDeleteTarea = () => { const deleteTareaInternal = async () => { try { await tareasStore.deleteTarea(props.tarea.id); - // Optionally, emit a 'deleted' event: emit('deleted', props.tarea.id); - // Or show a success notification. } catch (error) { console.error('Error deleting tarea:', error); alert('Ocurrió un error al eliminar la tarea. Por favor, intente de nuevo.'); - // Potentially show a more user-friendly notification. } }; + +const getStatusClass = (status) => { + if (!status) return 'bg-gray-400'; + const statusNormalized = status.toLowerCase().replace(/\s+/g, '-'); + switch (statusNormalized) { + case 'pendiente': return 'bg-yellow-500 text-gray-800'; + case 'realizada': + case 'completada': + case 'hecho': return 'bg-green-500'; + case 'en-progreso': return 'bg-blue-500'; + case 'anulada': + case 'cancelada': return 'bg-red-500'; + case 'archivada': return 'bg-gray-500'; + default: return 'bg-gray-400'; + } +}; + +const buttonHover = (event, isHovering) => { + if (isHovering) { + event.target.style.filter = 'brightness(90%)'; + } else { + event.target.style.filter = 'brightness(100%)'; + } +}; + diff --git a/ui/src/style.css b/ui/src/style.css index 7e95078..c0b0f78 100644 --- a/ui/src/style.css +++ b/ui/src/style.css @@ -4,20 +4,22 @@ @tailwind utilities; :root { - --primary-color: #1976D2; - --secondary-color: #424242; - --warning-color: #FFC107; - --background-color: #FFFFFF; - --font-family: 'Roboto', sans-serif; - --font-size: 16px; - /* Add other variables as needed, e.g., text colors for themes */ - --text-color: #212121; /* Default text color for light theme */ - - /* Module-specific accent colors - Default Fallbacks */ - --accent-color-empleados: #2196F3; - --accent-color-tareas: #4CAF50; - --accent-color-planillas: #FF9800; - --accent-color-asistencias: #E91E63; + --accent-color-asistencias: #4CAF50; /* Example Green */ + --accent-color-empleados: #2196F3; /* Example Blue */ + --accent-color-planillas: #FF9800; /* Example Orange */ + --accent-color-tareas: #9C27B0; /* Example Purple */ + --warning-color: #dc3545; /* Example Red for delete buttons */ + --background-color: #ffffff; + --text-color: #333333; + --muted-text-color: #555555; + --border-color: #e0e0e0; + --card-shadow: 0 2px 5px rgba(0,0,0,0.05); + --card-hover-shadow: 0 4px 10px rgba(0,0,0,0.1); + /* Retaining existing theme variables that don't conflict */ + --primary-color: #1976D2; /* Kept from original */ + --secondary-color: #424242; /* Kept from original */ + --font-family: 'Roboto', sans-serif; /* Kept from original */ + --font-size: 16px; /* Kept from original */ } html.theme-dark { diff --git a/ui/tailwind.config.js b/ui/tailwind.config.js new file mode 100644 index 0000000..bd3eb14 --- /dev/null +++ b/ui/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{vue,js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}