añadir nuevas funcionalidades
This commit is contained in:
66
app/Livewire/CountrySelect.php
Normal file
66
app/Livewire/CountrySelect.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class CountrySelect extends Component
|
||||
{
|
||||
public $selectedCountry;
|
||||
public $countrySearch = '';
|
||||
public $search = '';
|
||||
public $isOpen = false;
|
||||
public $initialCountry;
|
||||
|
||||
protected $rules = [
|
||||
'selectedCountry' => 'required',
|
||||
];
|
||||
|
||||
public function mount($initialCountry = null)
|
||||
{
|
||||
$this->selectedCountry = $initialCountry;
|
||||
}
|
||||
|
||||
public function selectCountry($code)
|
||||
{
|
||||
$this->selectedCountry = $code;
|
||||
$this->isOpen = false;
|
||||
$this->search = ''; // Limpiar la búsqueda al seleccionar
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$countries = collect(config('countries'))
|
||||
->when($this->search, function($collection) {
|
||||
// Corregimos el filtrado aquí
|
||||
return $collection->filter(function($name, $code) {
|
||||
$searchLower = strtolower($this->search);
|
||||
$nameLower = strtolower($name);
|
||||
$codeLower = strtolower($code);
|
||||
|
||||
return str_contains($nameLower, $searchLower) ||
|
||||
str_contains($codeLower, $searchLower);
|
||||
});
|
||||
});
|
||||
|
||||
return view('livewire.country-select', compact('countries'));
|
||||
}
|
||||
|
||||
public function formattedCountry($code, $name)
|
||||
{
|
||||
return $this->getFlagEmoji($code).' '.$name.' ('.strtoupper($code).')';
|
||||
}
|
||||
|
||||
protected function getFlagEmoji($countryCode)
|
||||
{
|
||||
$countryCode = strtoupper($countryCode);
|
||||
$flagOffset = 0x1F1E6;
|
||||
$asciiOffset = 0x41;
|
||||
|
||||
$firstChar = ord($countryCode[0]) - $asciiOffset + $flagOffset;
|
||||
$secondChar = ord($countryCode[1]) - $asciiOffset + $flagOffset;
|
||||
|
||||
return mb_convert_encoding('&#'.intval($firstChar).';', 'UTF-8', 'HTML-ENTITIES')
|
||||
. mb_convert_encoding('&#'.intval($secondChar).';', 'UTF-8', 'HTML-ENTITIES');
|
||||
}
|
||||
}
|
||||
86
app/Livewire/ImageUploader.php
Normal file
86
app/Livewire/ImageUploader.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ImageUploader extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $image;
|
||||
public $imagePath;
|
||||
public $fieldName; // Nombre del campo para el formulario
|
||||
public $label = 'Subir imagen'; // Etiqueta personalizable
|
||||
public $hover = false;
|
||||
|
||||
// Recibir parámetros si es necesario
|
||||
public function mount($fieldName = 'image_path', $label = 'Subir imagen')
|
||||
{
|
||||
$this->fieldName = $fieldName;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function updatedImage()
|
||||
{
|
||||
$this->validate([
|
||||
'image' => 'image|max:2048', // 2MB Max
|
||||
]);
|
||||
|
||||
// Subir automáticamente al seleccionar
|
||||
$this->uploadImage();
|
||||
}
|
||||
|
||||
public function uploadImage()
|
||||
{
|
||||
$this->validate([
|
||||
'image' => 'required|image|max:2048',
|
||||
]);
|
||||
|
||||
// Guardar la imagen
|
||||
$this->imagePath = $this->image->store('uploads', 'public');
|
||||
// Emitir evento con el nombre del campo y la ruta
|
||||
$this->dispatch('imageUploaded',
|
||||
field: $this->fieldName,
|
||||
path: $this->imagePath
|
||||
);
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'image' => 'required|image|max:2048',
|
||||
]);
|
||||
|
||||
// Guardar la imagen
|
||||
$this->imagePath = $this->image->store('images', 'public');
|
||||
|
||||
// Emitir evento con el nombre del campo y la ruta
|
||||
$this->emit('imageUploaded', [
|
||||
'field' => $this->fieldName,
|
||||
'path' => $this->imagePath
|
||||
]);
|
||||
}
|
||||
|
||||
public function removeImage()
|
||||
{
|
||||
$this->reset(['image', 'imagePath']);
|
||||
|
||||
// Cambiar emit por dispatch en Livewire v3+
|
||||
$this->dispatch('imageRemoved',
|
||||
field: $this->fieldName
|
||||
);
|
||||
}
|
||||
|
||||
public function toggleHover($status)
|
||||
{
|
||||
$this->hover = $status;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.image-uploader');
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,15 @@ use App\Models\Project;
|
||||
use App\Models\Folder;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProjectShow extends Component
|
||||
{
|
||||
|
||||
use WithFileUploads;
|
||||
|
||||
protected $middleware = ['auth']; // Añade esto
|
||||
|
||||
public Project $project;
|
||||
public ?Folder $currentFolder = null;
|
||||
public $expandedFolders = [];
|
||||
@@ -22,8 +25,13 @@ class ProjectShow extends Component
|
||||
public $folderName = '';
|
||||
|
||||
public $selectedFolderId = null;
|
||||
public $showFolderModal = false;
|
||||
public $showUploadModal = false;
|
||||
public $tempFiles = [];
|
||||
public $selectedFiles = []; // Archivos temporales en el modal
|
||||
public $uploadProgress = [];
|
||||
|
||||
|
||||
|
||||
public function mount(Project $project)
|
||||
{
|
||||
$this->project = $project->load('rootFolders');
|
||||
@@ -57,27 +65,27 @@ class ProjectShow extends Component
|
||||
})
|
||||
]
|
||||
]);
|
||||
|
||||
Folder::create([
|
||||
'name' => $this->folderName,
|
||||
'project_id' => $this->project->id,
|
||||
'parent_id' => $this->currentFolder?->id
|
||||
'parent_id' => $this->currentFolder?->id,
|
||||
]);
|
||||
|
||||
$this->hideCreateFolderModal();
|
||||
$this->reset('folderName');
|
||||
$this->project->load('rootFolders'); // Recargar carpetas raíz
|
||||
$this->project->load('rootFolders'); // Recargar carpetas raíz
|
||||
if ($this->currentFolder) {
|
||||
$this->currentFolder->load('children'); // Recargar hijos si está en una subcarpeta
|
||||
}
|
||||
$this->project->refresh();
|
||||
}
|
||||
|
||||
public function uploadFiles(): void
|
||||
/*public function uploadFiles(): void
|
||||
{
|
||||
$this->validate([
|
||||
'files.*' => 'file|max:10240|mimes:pdf,docx,xlsx,jpg,png'
|
||||
]);
|
||||
|
||||
dd($this->files);
|
||||
foreach ($this->files as $file) {
|
||||
Document::create([
|
||||
'name' => $file->getClientOriginalName(),
|
||||
@@ -92,7 +100,7 @@ class ProjectShow extends Component
|
||||
$this->currentFolder->refresh(); // Recargar documentos
|
||||
}
|
||||
$this->reset('files');
|
||||
}
|
||||
}*/
|
||||
|
||||
public function getDocumentsProperty()
|
||||
{
|
||||
@@ -116,11 +124,128 @@ class ProjectShow extends Component
|
||||
return $breadcrumbs;
|
||||
}
|
||||
|
||||
public function showCreateFolderModal()
|
||||
{
|
||||
$this->folderName = '';
|
||||
$this->showFolderModal = true;
|
||||
}
|
||||
|
||||
public function hideCreateFolderModal()
|
||||
{
|
||||
$this->showFolderModal = false;
|
||||
}
|
||||
|
||||
// Método para abrir el modal
|
||||
public function openUploadModal(): void
|
||||
{
|
||||
$this->showUploadModal = true;
|
||||
}
|
||||
|
||||
// Método para manejar archivos seleccionados
|
||||
public function selectFiles($files): void
|
||||
{
|
||||
$this->validate([
|
||||
'selectedFiles.*' => 'file|max:10240|mimes:pdf,docx,xlsx,jpg,png'
|
||||
]);
|
||||
|
||||
$this->selectedFiles = array_merge($this->selectedFiles, $files);
|
||||
}
|
||||
|
||||
// Método para eliminar un archivo de la lista
|
||||
public function removeFile($index): void
|
||||
{
|
||||
unset($this->selectedFiles[$index]);
|
||||
$this->selectedFiles = array_values($this->selectedFiles); // Reindexar array
|
||||
}
|
||||
|
||||
// Método para confirmar y guardar
|
||||
public function uploadFiles(): void
|
||||
{
|
||||
foreach ($this->selectedFiles as $file) {
|
||||
Document::create([
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'file_path' => $file->store("projects/{$this->project->id}/documents"),
|
||||
'project_id' => $this->project->id, // Asegurar que se envía
|
||||
'folder_id' => $this->currentFolder?->id,
|
||||
//'user_id' => Auth::id(),
|
||||
//'status' => 'active' // Añadir si tu modelo lo requiere
|
||||
]);
|
||||
}
|
||||
|
||||
$this->resetUpload();
|
||||
$this->project->refresh();
|
||||
}
|
||||
|
||||
// Método para procesar los archivos
|
||||
protected function processFiles(): void
|
||||
{
|
||||
foreach ($this->files as $file) {
|
||||
Document::create([
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'file_path' => $file->store("projects/{$this->project->id}/documents"),
|
||||
'project_id' => $this->project->id, // Asegurar que se envía
|
||||
'folder_id' => $this->currentFolder?->id,
|
||||
//'user_id' => Auth::id(),
|
||||
//'status' => 'active' // Añadir si tu modelo lo requiere
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Método para resetear
|
||||
public function resetUpload(): void
|
||||
{
|
||||
$this->reset(['selectedFiles', 'showUploadModal', 'uploadProgress']);
|
||||
}
|
||||
|
||||
#[On('upload-progress')]
|
||||
public function updateProgress($name, $progress)
|
||||
{
|
||||
$this->uploadProgress[$name] = $progress;
|
||||
}
|
||||
|
||||
public function addFiles($files)
|
||||
{
|
||||
$this->validate([
|
||||
'selectedFiles.*' => 'file|max:10240|mimes:pdf,docx,xlsx,jpg,png'
|
||||
]);
|
||||
|
||||
$this->selectedFiles = array_merge($this->selectedFiles, $files);
|
||||
}
|
||||
|
||||
public function startUpload()
|
||||
{
|
||||
foreach ($this->selectedFiles as $file) {
|
||||
try {
|
||||
$path = $file->store(
|
||||
"projects/{$this->project->id}/".($this->currentFolder ? "folders/{$this->currentFolder->id}" : ""),
|
||||
'public'
|
||||
);
|
||||
|
||||
Document::create([
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'file_path' => $path,
|
||||
'project_id' => $this->project->id,
|
||||
'folder_id' => $this->currentFolder?->id,
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->addError('upload', "Error subiendo {$file->getClientOriginalName()}: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->resetUpload();
|
||||
$this->project->refresh();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.project-show')
|
||||
->layout('layouts.livewire-app', [
|
||||
'title' => $this->project->name
|
||||
]);
|
||||
return view('livewire.project.show')->layout('components.layouts.documents', [
|
||||
'title' => __('Project: :name', ['name' => $this->project->name]),
|
||||
'breadcrumbs' => [
|
||||
['name' => __('Projects'), 'url' => route('projects.index')],
|
||||
['name' => $this->project->name, 'url' => route('projects.show', $this->project)],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
81
app/Livewire/UserPhotoUpload.php
Normal file
81
app/Livewire/UserPhotoUpload.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\User;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class UserPhotoUpload extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $photo;
|
||||
public $existingPhoto;
|
||||
public $tempPhoto;
|
||||
public $userId;
|
||||
|
||||
protected $listeners = ['photoUpdated' => 'refreshPhoto'];
|
||||
|
||||
public function mount($existingPhoto = null, $userId = null)
|
||||
{
|
||||
$this->existingPhoto = $existingPhoto;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
public function uploadPhoto()
|
||||
{
|
||||
$this->validate([
|
||||
'photo' => 'image|max:2048|mimes:jpg,png,jpeg,gif',
|
||||
]);
|
||||
|
||||
$this->tempPhoto = $this->photo->temporaryUrl();
|
||||
}
|
||||
|
||||
public function updatedPhoto()
|
||||
{
|
||||
$this->validate([
|
||||
'photo' => 'image|max:2048|mimes:jpg,png,jpeg,gif',
|
||||
]);
|
||||
|
||||
$this->tempPhoto = $this->photo->temporaryUrl();
|
||||
|
||||
// Emitir evento con la foto temporal
|
||||
$this->emit('photoUploaded', $this->photo->getRealPath());
|
||||
}
|
||||
|
||||
public function removePhoto()
|
||||
{
|
||||
$this->reset('photo', 'tempPhoto');
|
||||
}
|
||||
|
||||
public function deletePhoto()
|
||||
{
|
||||
if ($this->existingPhoto) {
|
||||
Storage::delete('public/photos/' . $this->existingPhoto);
|
||||
|
||||
if ($this->userId) {
|
||||
$user = User::find($this->userId);
|
||||
$user->update(['profile_photo_path' => null]);
|
||||
}
|
||||
|
||||
$this->existingPhoto = null;
|
||||
$this->emit('photoDeleted');
|
||||
}
|
||||
}
|
||||
|
||||
public function refreshPhoto()
|
||||
{
|
||||
$this->existingPhoto = User::find($this->userId)->profile_photo_path;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.user-photo-upload', [
|
||||
//'photo' => $this->photo,
|
||||
'tempPhoto' => $this->tempPhoto,
|
||||
'existingPhoto' => $this->existingPhoto,
|
||||
]);
|
||||
}
|
||||
}
|
||||
109
app/Livewire/UserTable.php
Normal file
109
app/Livewire/UserTable.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use App\Models\User;
|
||||
|
||||
class UserTable extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public $sortField = 'first_name';
|
||||
public $sortDirection = 'asc';
|
||||
|
||||
public $columns = [
|
||||
'full_name' => true,
|
||||
'is_active' => true,
|
||||
'username' => true,
|
||||
'email' => true,
|
||||
'phone' => false,
|
||||
'access_start' => false,
|
||||
'created_at' => false,
|
||||
'is_active' => false,
|
||||
];
|
||||
|
||||
public $filters = [
|
||||
'full_name' => '',
|
||||
'is_active' => '',
|
||||
'username' => '',
|
||||
'email' => '',
|
||||
'phone' => '',
|
||||
'access_start' => '',
|
||||
'created_at' => ''
|
||||
];
|
||||
|
||||
protected $queryString = [
|
||||
'filters' => ['except' => ''],
|
||||
'columns' => ['except' => '']
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
// Recuperar preferencias de columnas de la sesión
|
||||
$this->columns = session('user_columns', $this->columns);
|
||||
}
|
||||
|
||||
public function updatedColumns()
|
||||
{
|
||||
// Guardar preferencias en sesión
|
||||
session(['user_columns' => $this->columns]);
|
||||
}
|
||||
|
||||
public function sortBy($field)
|
||||
{
|
||||
if ($this->sortField === $field) {
|
||||
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$this->sortField = $field;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$users = User::query()
|
||||
->when($this->filters['full_name'], fn($q, $search) =>
|
||||
$q->whereRaw("CONCAT(title, ' ', first_name, ' ', last_name) LIKE ?", ["%$search%"]))
|
||||
->when($this->sortField === 'full_name', fn($q) =>
|
||||
$q->orderByRaw("CONCAT(title, ' ', first_name, ' ', last_name) " . $this->sortDirection)
|
||||
)
|
||||
->when($this->sortField === 'created_at', fn($q) =>
|
||||
$q->orderBy('created_at', $this->sortDirection)
|
||||
)
|
||||
->when($this->sortField === 'access_start', fn($q) =>
|
||||
$q->orderBy('access_start', $this->sortDirection)
|
||||
)
|
||||
->when(in_array($this->sortField, ['username', 'email', 'phone']), fn($q) =>
|
||||
$q->orderBy($this->sortField, $this->sortDirection)
|
||||
)
|
||||
->when($this->filters['full_name'], fn($q, $search) =>
|
||||
$q->whereRaw("CONCAT(title, ' ', first_name, ' ', last_name) LIKE ?", ["%$search%"]))
|
||||
->when($this->filters['username'], fn($q, $search) =>
|
||||
$q->where('username', 'LIKE', "%$search%"))
|
||||
->when($this->filters['email'], fn($q, $search) =>
|
||||
$q->where('email', 'LIKE', "%$search%"))
|
||||
->when($this->filters['phone'], fn($q, $search) =>
|
||||
$q->where('phone', 'LIKE', "%$search%"))
|
||||
->when($this->filters['access_start'], fn($q, $date) =>
|
||||
$q->whereDate('access_start', $date))
|
||||
->when($this->filters['created_at'], fn($q, $date) =>
|
||||
$q->whereDate('created_at', $date))
|
||||
->paginate(10);
|
||||
|
||||
return view('livewire.user-table', [
|
||||
'users' => $users,
|
||||
'available_columns' => [
|
||||
'full_name' => 'Nombre Completo',
|
||||
'username' => 'Usuario',
|
||||
'email' => 'Correo',
|
||||
'phone' => 'Teléfono',
|
||||
'access_start' => 'Fecha de acceso',
|
||||
'created_at' => 'Fecha creación',
|
||||
'is_active' => 'Estado'
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user