mejoras
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<<<<<<< HEAD
|
||||
<div x-data="{ isUploading: false }"
|
||||
<div x-data="{ isUploading: false,
|
||||
previewUrl: @entangle('imagePath').defer || ''}"
|
||||
x-on:livewire-upload-start="isUploading = true"
|
||||
x-on:livewire-upload-finish="isUploading = false"
|
||||
x-on:livewire-upload-error="isUploading = false">
|
||||
@@ -9,18 +9,25 @@
|
||||
|
||||
<!-- Zona de dropzone modificada -->
|
||||
<div wire:ignore
|
||||
x-on:drop.prevent="
|
||||
x-on:drop.prevent="
|
||||
const files = event.dataTransfer.files;
|
||||
if (files.length) {
|
||||
@this.upload('image', files[0]);
|
||||
updatePreview(files[0]);
|
||||
}
|
||||
$wire.toggleHover(false);
|
||||
event.stopPropagation(); // Evita propagación del evento
|
||||
"
|
||||
x-on:dragover.prevent="$wire.toggleHover(true)"
|
||||
x-on:dragleave.prevent="$wire.toggleHover(false)"
|
||||
class="dropzone {{ $hover ? 'dropzone-hover' : '' }} mb-3 p-4 border-2 border-dashed rounded text-center cursor-pointer">
|
||||
"
|
||||
x-on:dragover.prevent="$wire.toggleHover(true)"
|
||||
x-on:dragleave.prevent="$wire.toggleHover(false)"
|
||||
class="dropzone {{ $hover ? 'dropzone-hover' : '' }} mb-3 p-4 border-2 border-dashed rounded text-center cursor-pointer relative bg-cover bg-center"
|
||||
style="{{ $imagePath ? 'background-image: url(' . asset('storage/' . $imagePath) . ');' : '' }}"
|
||||
:style="previewUrl ? 'background-image: url(' + previewUrl + ')' : ''">
|
||||
|
||||
<!-- Overlay para mejor contraste -->
|
||||
<div class="absolute inset-0 bg-black/10 z-10"
|
||||
x-show="previewUrl || {{ $imagePath ? 'true' : 'false' }}"></div>
|
||||
|
||||
<!-- Contenido modificado -->
|
||||
<div wire:loading wire:target="image" class="text-center py-4">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
@@ -55,49 +62,4 @@
|
||||
<div class="alert alert-danger mt-2">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
=======
|
||||
<div>
|
||||
<!-- Preview de imagen -->
|
||||
<div class="relative mb-4">
|
||||
<img src="{{ $photo ? $photo->temporaryUrl() : ($currentImage ?? $placeholder) }}"
|
||||
alt="Preview"
|
||||
class="w-32 h-32 rounded-full object-cover border-2 border-gray-300">
|
||||
|
||||
@if($photo || $currentImage)
|
||||
<button type="button"
|
||||
wire:click="removePhoto"
|
||||
class="absolute top-0 right-0 bg-red-500 text-white rounded-full p-1 hover:bg-red-600 transition"
|
||||
title="Eliminar foto">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Input de archivo -->
|
||||
<label class="cursor-pointer bg-white px-4 py-2 rounded-md shadow-sm border border-gray-300 hover:bg-gray-50 inline-block">
|
||||
<span class="text-sm font-medium text-gray-700">
|
||||
{{ $photo || $currentImage ? 'Cambiar imagen' : 'Seleccionar imagen' }}
|
||||
</span>
|
||||
<input type="file"
|
||||
wire:model="photo"
|
||||
class="hidden"
|
||||
accept="image/*"
|
||||
name="{{ $fieldName }}_input"> <!-- Input oculto para Livewire -->
|
||||
|
||||
<!-- Input real para el formulario -->
|
||||
@if($photo)
|
||||
<input type="hidden" name="{{ $fieldName }}" value="{{ $photo->getFilename() }}">
|
||||
@elseif($currentImage)
|
||||
<input type="hidden" name="{{ $fieldName }}" value="current">
|
||||
@endif
|
||||
</label>
|
||||
|
||||
@error('photo')
|
||||
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
|
||||
<p class="mt-1 text-xs text-gray-500">PNG, JPG o JPEG (Max. 2MB)</p>
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
</div>
|
||||
74
resources/views/livewire/pdf-viewer.blade.php
Normal file
74
resources/views/livewire/pdf-viewer.blade.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<div class="h-screen bg-gray-100" wire:ignore>
|
||||
<!-- Toolbar -->
|
||||
<div class="fixed top-0 left-0 right-0 bg-white shadow-lg p-4 flex gap-4 z-50">
|
||||
<button @click="zoomIn">➕</button>
|
||||
<button @click="zoomOut">➖</button>
|
||||
<input type="number" v-model="currentPage" @change="goToPage">
|
||||
<span>@{{ currentPage }}/@{{ totalPages }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Visor PDF -->
|
||||
<div id="pdf-container" class="pt-16">
|
||||
<livewire-pdf
|
||||
:url="$pdfUrl"
|
||||
@page-loaded="totalPages = $event.total"
|
||||
@page-changed="currentPage = $event.current"
|
||||
:page="$currentPage"
|
||||
:zoom="$zoomLevel"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Canvas para Anotaciones -->
|
||||
<canvas id="annotation-layer" class="absolute top-0 left-0"></canvas>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const fabricCanvas = new fabric.Canvas('annotation-layer');
|
||||
|
||||
// Lógica de interacción con Fabric.js
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
Livewire.on('refreshAnnotations', () => {
|
||||
// Cargar anotaciones desde backend
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const container = document.getElementById('pdf-viewer');
|
||||
const pdfInstance = pdfjsLib.getDocument('{{ $pdfUrl }}');
|
||||
|
||||
pdfInstance.promise.then(pdf => {
|
||||
window.pdfDoc = pdf;
|
||||
Livewire.emit('totalPages', pdf.numPages);
|
||||
|
||||
// Función para renderizar página
|
||||
const renderPage = (num) => {
|
||||
pdf.getPage(num).then(page => {
|
||||
const viewport = page.getViewport({ scale: $wire.zoomLevel });
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
container.innerHTML = '';
|
||||
container.appendChild(canvas);
|
||||
|
||||
page.render({
|
||||
canvasContext: context,
|
||||
viewport: viewport
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Escuchar cambios desde Livewire
|
||||
Livewire.on('pageChanged', page => renderPage(page));
|
||||
Livewire.on('zoomChanged', zoom => renderPage($wire.currentPage));
|
||||
|
||||
// Renderizar primera página
|
||||
renderPage($wire.currentPage);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -18,8 +18,11 @@
|
||||
<h1 class="mt-2 text-2xl font-bold">{{ $project->name }}</h1>
|
||||
</div>
|
||||
<a href="{{ route('projects.edit', $project) }}"
|
||||
class="px-4 py-2 text-white bg-blue-600 rounded-lg hover:bg-blue-700">
|
||||
Editar Proyecto
|
||||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg flex items-center justify-center">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/>
|
||||
</svg>
|
||||
Editar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,8 +49,8 @@
|
||||
<button
|
||||
wire:click="openUploadModal"
|
||||
class="flex items-center p-2 text-gray-600 hover:bg-gray-100 rounded">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 16.5V9.75m0 0 3 3m-3-3-3 3M6.75 19.5a4.5 4.5 0 0 1-1.41-8.775 5.25 5.25 0 0 1 10.233-2.33 3 3 0 0 1 3.758 3.848A3.752 3.752 0 0 1 18 19.5H6.75Z" />
|
||||
</svg>
|
||||
<span class="text-sm">Subir archivos</span>
|
||||
</button>
|
||||
@@ -67,6 +70,7 @@
|
||||
:currentFolder="$currentFolder"
|
||||
:expandedFolders="$expandedFolders"
|
||||
wire:key="folder-{{ $folder->id }}"
|
||||
:itemsCount="$this->documents->count()"
|
||||
/>
|
||||
@endforeach
|
||||
</ul>
|
||||
@@ -79,7 +83,7 @@
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">Nombre</th>
|
||||
<th class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">Nombre - javi</th>
|
||||
<th class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">Versiones</th>
|
||||
<th class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">Última Actualización</th>
|
||||
<th class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">Estado</th>
|
||||
@@ -96,6 +100,7 @@
|
||||
@php
|
||||
$type = App\Helpers\FileHelper::getFileType($document->name);
|
||||
$iconComponent = $iconComponent = "icons." . $type;
|
||||
|
||||
$iconClass = [
|
||||
'pdf' => 'pdf text-red-500',
|
||||
'word' => 'word text-blue-500',
|
||||
@@ -280,4 +285,4 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
@@ -75,19 +75,13 @@
|
||||
<!-- Foto del usuario -->
|
||||
@if($user->profile_photo_path)
|
||||
<div class="mr-3 flex-shrink-0">
|
||||
<<<<<<< HEAD
|
||||
<img src="{{ asset('storage/' . $user->profile_photo_path) }}"
|
||||
=======
|
||||
<img src="{{ asset($user->profile_photo_path) }}"
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
alt="{{ $user->full_name }}"
|
||||
class="w-8 h-8 rounded-full object-cover transition-transform group-hover:scale-110">
|
||||
</div>
|
||||
@else
|
||||
<div class="w-8 h-8 rounded-full bg-gray-200 mr-3 flex items-center justify-center transition-colors group-hover:bg-blue-100">
|
||||
<svg class="w-4 h-4 text-gray-500 group-hover:text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
<div class="w-8 h-8 rounded-full bg-gray-100 mr-3 flex items-center justify-center transition-colors group-hover:bg-blue-100">
|
||||
<flux:icon.user variant="solid" class="size-4" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -169,19 +163,17 @@
|
||||
<a href="{{ route('users.edit', $user) }}"
|
||||
class="text-blue-600 hover:text-blue-900"
|
||||
title="Editar usuario">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/>
|
||||
</svg>
|
||||
<flux:icon.pencil class="size-5"/>
|
||||
</a>
|
||||
|
||||
<!-- Botón Eliminar -->
|
||||
<button wire:click="confirmDelete({{ $user->id }})"
|
||||
class="text-red-600 hover:text-red-900"
|
||||
title="Eliminar usuario">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
||||
</svg>
|
||||
<flux:icon.trash class="size-5"/>
|
||||
</button>
|
||||
|
||||
<flux:button size="sm" icon="trash" variant="ghost" inset />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user