Merge branch 'main' of https://homehud.duckdns.org/javier/Nexora
This commit is contained in:
@@ -57,8 +57,12 @@ class UserController extends Controller
|
||||
'end_date' => 'nullable|date|after_or_equal:start_date',
|
||||
'email' => 'required|email|unique:users',
|
||||
'phone' => 'nullable|string|max:20',
|
||||
<<<<<<< HEAD
|
||||
'address' => 'nullable|string|max:255',
|
||||
'profile_photo_path' => 'nullable|string' // Ruta de la imagen subida por Livewire
|
||||
=======
|
||||
'address' => 'nullable|string|max:255'
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
]);
|
||||
|
||||
// Creación del usuario
|
||||
@@ -73,12 +77,20 @@ class UserController extends Controller
|
||||
'address' => $validated['address'],
|
||||
'access_start' => $validated['start_date'],
|
||||
'access_end' => $validated['end_date'],
|
||||
<<<<<<< HEAD
|
||||
'is_active' => true,
|
||||
'profile_photo_path' => $validated['profile_photo_path'] ?? null
|
||||
]);
|
||||
|
||||
if ($request->hasFile('image_path')) {
|
||||
$path = $request->file('image_path')->store('public/photos');
|
||||
=======
|
||||
'is_active' => true
|
||||
]);
|
||||
|
||||
if ($request->hasFile('photo')) {
|
||||
$path = $request->file('photo')->store('public/photos');
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
$user->profile_photo_path = basename($path);
|
||||
$user->save();
|
||||
}
|
||||
@@ -130,11 +142,17 @@ class UserController extends Controller
|
||||
Rule::unique('users')->ignore($user->id)
|
||||
],
|
||||
'phone' => 'nullable|string|max:20',
|
||||
<<<<<<< HEAD
|
||||
'address' => 'nullable|string|max:255',
|
||||
'profile_photo_path' => 'nullable|string', // Añadido para la ruta de la imagen
|
||||
//'is_active' => 'nullable|boolean' // Añadido para el estado activo
|
||||
]);
|
||||
|
||||
=======
|
||||
'address' => 'nullable|string|max:255'
|
||||
]);
|
||||
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
// Preparar datos para actualización
|
||||
$updateData = [
|
||||
'title' => $validated['title'],
|
||||
@@ -146,14 +164,21 @@ class UserController extends Controller
|
||||
'address' => $validated['address'],
|
||||
'access_start' => $validated['start_date'],
|
||||
'access_end' => $validated['end_date'],
|
||||
<<<<<<< HEAD
|
||||
'is_active' => $validated['is_active'] ?? false,
|
||||
'profile_photo_path' => $validated['profile_photo_path'] ?? $user->profile_photo_path
|
||||
];
|
||||
|
||||
=======
|
||||
'is_active' => $request->has('is_active') // Si usas un checkbox
|
||||
];
|
||||
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
// Actualizar contraseña solo si se proporciona
|
||||
if (!empty($validated['password'])) {
|
||||
$updateData['password'] = Hash::make($validated['password']);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
// Eliminar imagen anterior si se está actualizando
|
||||
if (isset($validated['profile_photo_path']) && $user->profile_photo_path) {
|
||||
@@ -171,6 +196,32 @@ class UserController extends Controller
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
|
||||
} catch (QueryException $e) {
|
||||
=======
|
||||
|
||||
if ($request->hasFile('photo')) {
|
||||
// Eliminar foto anterior si existe
|
||||
if ($user->prfile_photo_path) {
|
||||
Storage::delete('public/photos/'.$user->profile_photo_path);
|
||||
}
|
||||
|
||||
$path = $request->file('photo')->store('public/photos');
|
||||
$user->update(['profile_photo_path' => basename($path)]);
|
||||
}
|
||||
|
||||
// Actualizar el usuario
|
||||
$user->update($updateData);
|
||||
|
||||
// Redireccionar con mensaje de éxito
|
||||
return redirect()->route('users.show', $user)
|
||||
->with('success', 'Usuario actualizado exitosamente');
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
// Redireccionar con errores de validación
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
|
||||
} catch (QueryException $e) {
|
||||
// Manejar errores de base de datos
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
$errorCode = $e->errorInfo[1];
|
||||
$errorMessage = 'Error al actualizar el usuario: ';
|
||||
|
||||
@@ -179,11 +230,20 @@ class UserController extends Controller
|
||||
} else {
|
||||
$errorMessage .= 'Error en la base de datos';
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
Log::error("Error actualizando usuario ID {$user->id}: " . $e->getMessage());
|
||||
return redirect()->back()->with('error', $errorMessage)->withInput();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
=======
|
||||
|
||||
Log::error("Error actualizando usuario ID {$user->id}: " . $e->getMessage());
|
||||
return redirect()->back()->with('error', $errorMessage)->withInput();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Manejar otros errores
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
Log::error("Error general actualizando usuario ID {$user->id}: " . $e->getMessage());
|
||||
return redirect()->back()->with('error', 'Ocurrió un error inesperado al actualizar el usuario')->withInput();
|
||||
}
|
||||
@@ -193,13 +253,20 @@ class UserController extends Controller
|
||||
{
|
||||
$previousUser = User::where('id', '<', $user->id)->latest('id')->first();
|
||||
$nextUser = User::where('id', '>', $user->id)->oldest('id')->first();
|
||||
<<<<<<< HEAD
|
||||
$permissionGroups = $this->getPermissionGroups($user);
|
||||
=======
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
|
||||
return view('users.show', [
|
||||
'user' => $user,
|
||||
'previousUser' => $previousUser,
|
||||
'nextUser' => $nextUser,
|
||||
<<<<<<< HEAD
|
||||
'permissionGroups' => $permissionGroups,
|
||||
=======
|
||||
'permissionGroups' => Permission::all()->groupBy('group')
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ class ImageUploader extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
<<<<<<< HEAD
|
||||
public $image;
|
||||
public $imagePath;
|
||||
public $fieldName; // Nombre del campo para el formulario
|
||||
@@ -46,10 +47,41 @@ class ImageUploader extends Component
|
||||
field: $this->fieldName,
|
||||
path: $this->imagePath
|
||||
);
|
||||
=======
|
||||
public $photo;
|
||||
public $currentImage;
|
||||
public $fieldName;
|
||||
public $placeholder;
|
||||
public $storagePath = 'tmp/uploads';
|
||||
|
||||
protected $rules = [
|
||||
'photo' => 'nullable|image|max:2048', // 2MB Max
|
||||
];
|
||||
|
||||
public function mount($fieldName = 'photo', $currentImage = null, $placeholder = null)
|
||||
{
|
||||
$this->fieldName = $fieldName;
|
||||
$this->currentImage = $currentImage;
|
||||
$this->placeholder = $placeholder ?? asset('images/default-avatar.png');
|
||||
}
|
||||
|
||||
public function updatedPhoto()
|
||||
{
|
||||
$this->validate([
|
||||
'photo' => 'image|max:2048', // 2MB Max
|
||||
]);
|
||||
}
|
||||
|
||||
public function removePhoto()
|
||||
{
|
||||
$this->photo = null;
|
||||
$this->currentImage = null;
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
$this->validate([
|
||||
'image' => 'required|image|max:2048',
|
||||
]);
|
||||
@@ -79,6 +111,38 @@ class ImageUploader extends Component
|
||||
$this->hover = $status;
|
||||
}
|
||||
|
||||
=======
|
||||
$this->validate();
|
||||
|
||||
if ($this->photo) {
|
||||
$path = $this->photo->store($this->storagePath);
|
||||
|
||||
if ($this->model) {
|
||||
// Eliminar imagen anterior si existe
|
||||
if ($this->model->{$this->fieldName}) {
|
||||
Storage::delete($this->model->{$this->fieldName});
|
||||
}
|
||||
|
||||
$this->model->{$this->fieldName} = $path;
|
||||
$this->model->save();
|
||||
}
|
||||
|
||||
$this->currentUrl = Storage::url($path);
|
||||
$this->showSavedMessage = true;
|
||||
$this->photo = null; // Limpiar el input de subida
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCurrentImageUrl()
|
||||
{
|
||||
if ($this->model && $this->model->{$this->fieldName}) {
|
||||
return Storage::url($this->model->{$this->fieldName});
|
||||
}
|
||||
|
||||
return $this->placeholder;
|
||||
}
|
||||
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.image-uploader');
|
||||
|
||||
@@ -240,6 +240,7 @@ class ProjectShow extends Component
|
||||
|
||||
public function render()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
return view('livewire.project.show')->layout('components.layouts.documents', [
|
||||
'title' => __('Project: :name', ['name' => $this->project->name]),
|
||||
'breadcrumbs' => [
|
||||
@@ -247,5 +248,8 @@ class ProjectShow extends Component
|
||||
['name' => $this->project->name, 'url' => route('projects.show', $this->project)],
|
||||
],
|
||||
]);
|
||||
=======
|
||||
return view('livewire.project-show');
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
<div x-data="{ isUploading: false }"
|
||||
x-on:livewire-upload-start="isUploading = true"
|
||||
x-on:livewire-upload-finish="isUploading = false"
|
||||
@@ -54,4 +55,49 @@
|
||||
<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>
|
||||
117
resources/views/livewire/project-show.blade.php
Normal file
117
resources/views/livewire/project-show.blade.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<div>
|
||||
<!-- Header y Breadcrumbs -->
|
||||
<div class="p-4 bg-white border-b">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<nav class="flex space-x-2 text-sm">
|
||||
<a wire:click="currentFolder = null" class="cursor-pointer text-gray-600 hover:text-blue-600">
|
||||
Inicio
|
||||
</a>
|
||||
@foreach($this->breadcrumbs as $folder)
|
||||
<span class="text-gray-400">/</span>
|
||||
<a wire:click="selectFolder({{ $folder->id }})"
|
||||
class="cursor-pointer text-gray-600 hover:text-blue-600">
|
||||
{{ $folder->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
<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
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Barra de Herramientas y Contenido -->
|
||||
<div class="grid grid-cols-1 gap-6 p-4 lg:grid-cols-4">
|
||||
<!-- Treeview de Carpetas -->
|
||||
<div class="col-span-1 bg-white rounded-lg shadow">
|
||||
<div class="p-4 border-b">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-medium">Carpetas</h3>
|
||||
<button wire:click="createFolder" class="p-1 text-gray-600 hover:bg-gray-100 rounded">
|
||||
<x-icons icon="plus" class="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<input type="text"
|
||||
wire:model.live="folderName"
|
||||
placeholder="Nueva carpeta"
|
||||
class="w-full p-2 mt-2 border rounded"
|
||||
@keyup.enter="createFolder">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<ul class="space-y-2">
|
||||
@foreach($project->rootFolders as $folder)
|
||||
<x-folder-item
|
||||
:folder="$folder"
|
||||
:currentFolder="$currentFolder"
|
||||
:expandedFolders="$expandedFolders"
|
||||
wire:key="folder-{{ $folder->id }}"
|
||||
/>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documentos y Subida de Archivos -->
|
||||
<div class="col-span-3">
|
||||
<div class="bg-white rounded-lg shadow">
|
||||
<div class="p-4 border-b">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-medium">Documentos</h3>
|
||||
<input type="file"
|
||||
wire:model="files"
|
||||
multiple
|
||||
class="hidden"
|
||||
id="file-upload">
|
||||
<label for="file-upload" class="px-4 py-2 text-sm text-white bg-green-600 rounded-lg cursor-pointer hover:bg-green-700">
|
||||
Subir Archivos
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<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">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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@forelse($this->documents as $document)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<x-icons icon="document" class="w-5 h-5 mr-2 text-gray-400" />
|
||||
{{ $document->name }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{{ $document->versions_count }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{{ $document->updated_at->diffForHumans() }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<x-status-badge :status="$document->status" />
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4" class="px-6 py-4 text-center text-gray-500">
|
||||
No se encontraron documentos
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -75,7 +75,11 @@
|
||||
<!-- 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>
|
||||
|
||||
@@ -197,9 +197,15 @@
|
||||
<div>
|
||||
<x-label for="longitude" :value="__('Longitud')" />
|
||||
<input type="number"
|
||||
<<<<<<< HEAD
|
||||
id="longitude"
|
||||
name="longitude"
|
||||
value="{{ old('longitude') }}"
|
||||
=======
|
||||
id="latitude"
|
||||
name="latitude"
|
||||
value="{{ old('latitude') }}"
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
step="any"
|
||||
class="border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
@@ -308,7 +314,11 @@
|
||||
|
||||
<template x-if="files.length === 0">
|
||||
<div>
|
||||
<<<<<<< HEAD
|
||||
<x-icons icon="upload" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
=======
|
||||
<x-icons.upload class="mx-auto h-12 w-12 text-gray-400" />
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
Arrastra archivos o haz clic para subir
|
||||
</p>
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
</div>
|
||||
|
||||
<!-- Barra de herramientas principal -->
|
||||
<<<<<<< HEAD
|
||||
javi
|
||||
=======
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
|
||||
|
||||
<!-- Componente principal Livewire -->
|
||||
|
||||
@@ -291,12 +291,21 @@
|
||||
</td>
|
||||
<td class="py-2">
|
||||
<div class="mb-6">
|
||||
<<<<<<< HEAD
|
||||
@livewire('image-uploader', [
|
||||
'fieldName' => 'image_path', // Nombre del campo en la BD
|
||||
'label' => 'Imagen principal' // Etiqueta personalizada
|
||||
])
|
||||
<!-- Campo oculto para la ruta de la imagen -->
|
||||
<input type="hidden" name="profile_photo_path" id="profilePhotoPathInput" value="{{ old('profile_photo_path', $user->profile_photo_path) }}">
|
||||
=======
|
||||
|
||||
@livewire('image-uploader', [
|
||||
'fieldName' => 'profile_photo_path',
|
||||
'currentImage' => $user->profile_photo_path ?? null,
|
||||
'placeholder' => asset('images/default-user.png')
|
||||
])
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
</div>
|
||||
</td>
|
||||
</tr>php
|
||||
@@ -317,6 +326,7 @@
|
||||
|
||||
|
||||
<script>
|
||||
<<<<<<< HEAD
|
||||
// Escuchar el evento de Livewire y actualizar el campo oculto
|
||||
document.addEventListener('imageUploaded', (event) => {
|
||||
document.getElementById('profilePhotoPathInput').value = event.detail.path;
|
||||
@@ -326,6 +336,8 @@
|
||||
document.getElementById('profilePhotoPathInput').value = '';
|
||||
});
|
||||
|
||||
=======
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
function generatePassword() {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()';
|
||||
let password = '';
|
||||
|
||||
@@ -6,8 +6,14 @@
|
||||
<!-- User Info Left -->
|
||||
<div class="flex items-center space-x-6">
|
||||
<!-- User Photo -->
|
||||
<<<<<<< HEAD
|
||||
<img src="{{ $user->profile_photo_path ? asset('storage/' . $user->profile_photo_path) : 'https://via.placeholder.com/150' }}"
|
||||
class="w-24 h-24 rounded-full object-cover border-2 border-blue-100">
|
||||
=======
|
||||
<img src="{{ $user->photo_url ?? 'https://via.placeholder.com/150' }}"
|
||||
class="w-24 h-24 rounded-full object-cover border-4 border-blue-100">
|
||||
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<!-- User Details -->
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-700">
|
||||
@@ -127,9 +133,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<<<<<<< HEAD
|
||||
<div class="mt-6 flex justify-end space-x-4">
|
||||
<a href="{{ route('users.edit', $user) }}"
|
||||
class="w-[150px] px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg flex items-center justify-center">
|
||||
=======
|
||||
<div class="mt-6 flex space-x-4">
|
||||
<a href="{{ route('users.edit', $user) }}"
|
||||
class="px-4 py-2 w-[150px] bg-blue-600 hover:bg-blue-700 text-white rounded-lg flex items-center">
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<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>
|
||||
@@ -141,7 +153,11 @@
|
||||
@csrf
|
||||
@method('PUT') <!-- Important! -->
|
||||
<button type="submit"
|
||||
<<<<<<< HEAD
|
||||
class="w-[150px] px-4 py-2 bg-yellow-500 hover:bg-yellow-600 text-white rounded-lg flex items-center justify-center">
|
||||
=======
|
||||
class="px-4 py-2 w-[150px] {{ $user->is_active ? 'bg-red-600 hover:bg-red-700' : 'bg-green-600 hover:bg-green-700' }} text-white rounded-lg flex items-center">
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<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="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/>
|
||||
</svg>
|
||||
@@ -155,7 +171,11 @@
|
||||
@method('DELETE') <!-- Important! -->
|
||||
<button type="submit"
|
||||
onclick="return confirm('¿Estás seguro de querer eliminar este usuario?')"
|
||||
<<<<<<< HEAD
|
||||
class="px-4 py-2 w-[150px] bg-red-600 hover:bg-red-700 text-white rounded-lg flex items-center justify-center">
|
||||
=======
|
||||
class="px-4 py-2 w-[150px] bg-red-600 hover:bg-red-700 text-white rounded-lg flex items-center">
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<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="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>
|
||||
@@ -166,6 +186,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Permissions Tab -->
|
||||
<<<<<<< HEAD
|
||||
<div class="space-y-4">
|
||||
@foreach($permissionGroups as $groupName => $group)
|
||||
<div class="border rounded-lg overflow-hidden">
|
||||
@@ -225,6 +246,22 @@
|
||||
wire:change="togglePermission('{{ $permission['name'] }}')"
|
||||
class="sr-only peer">
|
||||
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
||||
=======
|
||||
<div x-show="activeTab === 'permissions'" x-cloak>
|
||||
<div class="space-y-6">
|
||||
@foreach($permissionGroups as $group => $permissions)
|
||||
<div class="border rounded-lg p-4">
|
||||
<h3 class="text-lg font-semibold mb-4">{{ ucfirst($group) }}</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
@foreach($permissions as $permission)
|
||||
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
|
||||
<span class="text-sm">{{ $permission->name }}</span>
|
||||
<label class="switch">
|
||||
<input type="checkbox"
|
||||
@if($user->hasPermissionTo($permission)) checked @endif
|
||||
wire:change="togglePermission('{{ $permission->name }}')">
|
||||
<span class="slider round"></span>
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
@@ -234,7 +271,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<<<<<<< HEAD
|
||||
<!-- Pestaña de Proyectos -->
|
||||
=======
|
||||
<!-- Nueva Pestaña de Proyectos -->
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
<div x-show="activeTab === 'projects'" x-cloak>
|
||||
<div class="space-y-6">
|
||||
<!-- Proyectos Actuales -->
|
||||
@@ -300,6 +341,7 @@
|
||||
transform: translateX(26px);
|
||||
}
|
||||
</style>
|
||||
<<<<<<< HEAD
|
||||
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
@@ -318,4 +360,6 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
=======
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
</x-layouts.app>
|
||||
@@ -49,9 +49,16 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
|
||||
// Proyectos
|
||||
Route::resource('projects', ProjectController::class);
|
||||
<<<<<<< HEAD
|
||||
//Route::get('/projects/{project}', ProjectController::class)->name('projects.show');
|
||||
//Route::get('/projects/{project}', ProjectController::class)->name('projects.show')->middleware('can:view,project'); // Opcional: política de acceso
|
||||
Route::get('/projects/{project}', ProjectShow::class)->name('projects.show')->middleware('auth');
|
||||
=======
|
||||
Route::get('/projects/{project}', ProjectController::class)->name('projects.show');
|
||||
//Route::get('/projects/{project}', ProjectController::class)->name('projects.show')->middleware('can:view,project'); // Opcional: política de acceso
|
||||
//Route::get('/projects/{project}', ProjectShow::class)->name('projects.show');
|
||||
|
||||
>>>>>>> f97a7a84985ea300216ba3ea2ab4c31306e1659a
|
||||
|
||||
// Documentos
|
||||
Route::resource('documents', DocumentController::class);
|
||||
|
||||
Reference in New Issue
Block a user