Merge branch 'main' into feat/chat-color-customization

This commit is contained in:
josedario87
2025-05-31 03:45:26 -06:00
committed by GitHub
8 changed files with 207 additions and 93 deletions

View File

@@ -68,6 +68,7 @@ watch(() => chat.items.length, scrollBottom)
fontFamily: 'var(--chat-font-family)',
fontSize: 'var(--chat-font-size)'
}">
{{ m.text }}
</div>
</div>
@@ -84,6 +85,7 @@ watch(() => chat.items.length, scrollBottom)
@keydown="handleKey"
rows="1"
placeholder="Escribí un mensaje… (Enter para enviar, Shift+Enter salto)"
class="flex-1 resize-none rounded-lg border p-3 focus:outline-none focus:ring-2 custom-scroll"
:style="{
backgroundColor: 'var(--chat-input-box-color)',
@@ -102,6 +104,18 @@ watch(() => chat.items.length, scrollBottom)
</template>
<style scoped>
.canvas-chat-root {
background-color: var(--background-color-chat, #F0F0F0); /* Fallback to store default */
}
/* Default accent color for chat if not provided by CSS variable */
:root {
--accent-color-chat-fallback: #0D9488; /* Teal-700 as a fallback */
--accent-color-chat-alpha-35-fallback: rgba(13, 148, 136, 0.35);
--accent-color-chat-alpha-70-fallback: rgba(13, 148, 136, 0.7);
--accent-color-chat-alpha-60-fallback: rgba(13, 148, 136, 0.6);
}
.custom-scroll::-webkit-scrollbar { width: 8px; }
.custom-scroll::-webkit-scrollbar-track { background: transparent; } /* Consider if track needs to adapt to --chat-background-color */
.custom-scroll::-webkit-scrollbar-thumb { background-color: var(--chat-accent-color); opacity: 0.35; border-radius: 4px; }

View File

@@ -39,48 +39,54 @@
@mouseleave="buttonHover($event, false)"
:class="`focus:ring-[var(--accent-color-empleados)]`"
>Editar</button>
<!-- "View Details" button removed for consistency as other modules use the edit view for details -->
<button
@click="confirmDeleteEmpleado"
class="px-3 py-1 md:px-4 md:py-2 text-xs md:text-sm font-medium rounded-md transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 bg-red-600 hover:bg-red-700 text-white focus:ring-red-500"
>Eliminar</button>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useRouter } from 'vue-router'
import { useUi } from '../../stores/useUi.js';
const ui = useUi();
interface Employee {
id: string | number
name: string
cedula: number
avatar_url?: string
telefono?: string
ubicacion: string
idciat?: string
grupo_estudio?: string
}
const emit = defineEmits(['edit']);
const empleadosStore = useEmpleadosStore();
const props = defineProps({
employee: {
type: Object as PropType<Employee>,
type: Object,
required: true,
},
})
const router = useRouter()
});
const handleEdit = () => {
// 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}`)
}
emit('edit', props.employee.id);
};
// handleViewDetails method removed for consistency
const confirmDeleteEmpleado = () => {
if (confirm(`¿Está seguro de que desea eliminar al empleado "${props.employee.name}" (ID: ${props.employee.id})?`)) {
deleteEmpleado();
}
};
const buttonHover = (event: MouseEvent, isHovering: boolean) => {
const target = event.target as HTMLElement;
const deleteEmpleado = async () => {
try {
await empleadosStore.deleteEmpleado(props.employee.id);
// Optionally, show a success notification or emit an event if needed,
// though typically the list will update reactively from the store.
} catch (error) {
console.error('Error deleting employee:', error);
alert('Ocurrió un error al eliminar el empleado.');
}
};
const buttonHover = (event, isHovering) => {
const target = event.target;
if (isHovering) {
target.style.filter = 'brightness(90%)';
} else {

View File

@@ -63,8 +63,8 @@
<button @click="handleEdit(employee.id)" class="p-1.5 sm:p-2 rounded-md transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 hover:bg-blue-100 dark:hover:bg-blue-600/20 focus:ring-blue-500 dark:focus:ring-blue-400" title="Editar Empleado">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" /></svg>
</button>
<button @click="handleViewDetails(employee.id)" class="p-1.5 sm:p-2 rounded-md transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 text-green-600 dark:text-green-400 hover:text-green-800 dark:hover:text-green-300 hover:bg-green-100 dark:hover:bg-green-600/20 focus:ring-green-500 dark:focus:ring-green-400" title="Ver Detalles">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" /></svg>
<button @click="confirmDeleteEmpleado(employee)" class="p-1.5 sm:p-2 rounded-md transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300 hover:bg-red-100 dark:hover:bg-red-600/20 focus:ring-red-500 dark:focus:ring-red-400" title="Eliminar">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12.56 0c1.153 0 2.24.03 3.22.077m3.22-.077L10.879 3.28a2.25 2.25 0 012.244-2.077h.093c.956 0 1.853.543 2.244 2.077L14.74 5.79m-4.858 0l-2.828-2.828A1.875 1.875 0 016.188 2.188l2.828 2.828m6.912 0l2.828-2.828a1.875 1.875 0 00-2.652-2.652L12 5.79M9.26 9h5.48L9.26 9z" /></svg>
</button>
</div>
</td>
@@ -74,43 +74,39 @@
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useRouter } from 'vue-router'
<script setup>
import { useUi } from '../../stores/useUi.js';
import { useEmpleadosStore } from '../../stores/useEmpleados';
const ui = useUi();
// Interface for Employee object structure, aligning with prisma model (excluding sensitive or large fields for table view)
interface Employee {
id: string | number; // Primary key for navigation and :key
name: string;
cedula: number; // Assuming cedula is a number; adjust if it's a string
avatar_url?: string;
telefono?: string;
ubicacion: string; // As per schema, this has a default and likely always present
idciat?: string;
grupo_estudio?: string;
// Omitting created_at, updated_at, empleado boolean for brevity in table
}
const emit = defineEmits(['edit']);
const empleadosStore = useEmpleadosStore();
const props = defineProps({
employees: {
type: Array as PropType<Employee[]>,
type: Array,
required: true,
default: () => [], // Provides a default empty array if no prop is passed
default: () => [],
},
});
const router = useRouter();
const handleEdit = (employeeId: string | number) => {
router.push(`/empleados/edit/${employeeId}`);
const handleEdit = (employeeId) => {
emit('edit', employeeId);
};
const handleViewDetails = (employeeId: string | number) => {
// This could navigate to a dedicated detail view or the edit view itself
router.push(`/empleados/view/${employeeId}`); // Adjust route as per application structure
const confirmDeleteEmpleado = (employee) => {
if (confirm(`¿Está seguro de que desea eliminar al empleado "${employee.name}" (ID: ${employee.id})?`)) {
deleteEmpleadoInternal(employee.id);
}
};
const deleteEmpleadoInternal = async (id) => {
try {
await empleadosStore.deleteEmpleado(id);
} catch (error) {
console.error(`Error deleting employee with id ${id}:`, error);
// Optional: Show error notification
}
};
</script>