diff --git a/app/Livewire/ProjectCompanies.php b/app/Livewire/ProjectCompanies.php new file mode 100644 index 0000000..68d2f76 --- /dev/null +++ b/app/Livewire/ProjectCompanies.php @@ -0,0 +1,81 @@ +project = $project; + $this->loadCompanies(); + } + + public function loadCompanies() + { + $this->assignedCompanies = $this->project->companies()->withPivot('role_in_project')->get(); + $assignedIds = $this->assignedCompanies->pluck('id')->toArray(); + $this->allCompanies = Company::whereNotIn('id', $assignedIds)->orderBy('name')->get(); + } + + public function assignCompany() + { + $user = Auth::user(); + if (!$user->can('assign users') && !$user->hasRole('Admin')) { + session()->flash('error', 'No tienes permisos para asignar compañías.'); + return; + } + + $this->validate([ + 'selectedCompanyId' => 'required|exists:companies,id', + 'selectedRole' => 'required|in:owner,constructor,subcontractor,consultant,supplier,other', + ]); + + $this->project->companies()->attach($this->selectedCompanyId, [ + 'role_in_project' => $this->selectedRole + ]); + + $this->reset(['selectedCompanyId', 'selectedRole']); + $this->loadCompanies(); + $this->dispatch('notify', 'Compañía asignada al proyecto.'); + } + + public function removeCompany($companyId) + { + $user = Auth::user(); + if (!$user->can('assign users') && !$user->hasRole('Admin')) { + session()->flash('error', 'Sin permisos.'); + return; + } + + $this->project->companies()->detach($companyId); + $this->loadCompanies(); + $this->dispatch('notify', 'Compañía eliminada del proyecto.'); + } + + public function changeRole($companyId, $role) + { + if (!in_array($role, ['owner', 'constructor', 'subcontractor', 'consultant', 'supplier', 'other'])) return; + + $this->project->companies()->updateExistingPivot($companyId, [ + 'role_in_project' => $role + ]); + $this->loadCompanies(); + $this->dispatch('notify', 'Rol actualizado.'); + } + + public function render() + { + return view('livewire.project-companies'); + } +} \ No newline at end of file diff --git a/app/Livewire/ProjectTable.php.bak b/app/Livewire/ProjectTable.php.bak new file mode 100644 index 0000000..a800e1a --- /dev/null +++ b/app/Livewire/ProjectTable.php.bak @@ -0,0 +1,111 @@ +setPrimaryKey('id') + ->setDefaultSort('created_at', 'desc') + ->setTableAttributes(['class' => 'table-auto w-full']) + ->setThAttributes(['class' => 'px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider']) + ->setTdAttributes(['class' => 'px-4 py-2 whitespace-nowrap text-sm text-gray-900']); + + $this->addColumn('name', __('Project Name')) + ->setSortable() + ->setSearchable(); + + $this->addColumn('address', __('Address')) + ->setSortable() + ->setSearchable(); + + $this->addColumn('status', __('Status')) + ->setSortable() + ->setFilterable([ + 'planning' => __('Planning'), + 'in_progress' => __('In progress'), + 'paused' => __('Paused'), + 'completed' => __('Completed'), + ]) + ->setLabel(fn ($value, $row, $column, $component) => + match ($value) { + 'planning' => ''.__('Planning').'', + 'in_progress' => ''.__('In progress').'', + 'paused' => ''.__('Paused').'', + 'completed' => ''.__('Completed').'', + default => $value + } + ); + + $this->addColumn('start_date', __('Start Date')) + ->setSortable() + ->setFormat(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''); + + $this->addColumn('end_date_estimated', __('Estimated End Date')) + ->setSortable() + ->setFormat(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''); + + $this->addColumn('actions', __('Actions')) + ->setLabel(fn ($row) => '
+ '.__('Edit').' +
+ '.csrf_field().' + + +
+
') + ->setHtmlAttribute(['class' => 'text-right']); + } + + public function columns(): array + { + return [ + Column::make(__('Project Name'), 'name') + ->sortable() + ->searchable(), + Column::make(__('Address'), 'address') + ->sortable() + ->searchable(), + Column::make(__('Status'), 'status') + ->sortable() + ->filterable([ + 'planning' => __('Planning'), + 'in_progress' => __('In progress'), + 'paused' => __('Paused'), + 'completed' => __('Completed'), + ]) + ->label(fn ($value, $row, $column) => + match ($value) { + 'planning' => ''.__('Planning').'', + 'in_progress' => ''.__('In progress').'', + 'paused' => ''.__('Paused').'', + 'completed' => ''.__('Completed').'', + default => $value + } + ), + Column::make(__('Start Date'), 'start_date') + ->sortable() + ->format(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''), + Column::make(__('Estimated End Date'), 'end_date_estimated') + ->sortable() + ->format(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''), + Column::make(__('Actions')) + ->label(fn ($row) => '
+ '.__('Edit').' +
+ '.csrf_field().' + + +
+
') + ->htmlAttribute(['class' => 'text-right']), + ]; + } +} diff --git a/app/Models/Company.php b/app/Models/Company.php new file mode 100644 index 0000000..0d8ed7a --- /dev/null +++ b/app/Models/Company.php @@ -0,0 +1,32 @@ +belongsToMany(Project::class, 'company_project') + ->withPivot('role_in_project') + ->withTimestamps(); + } +} diff --git a/app/Models/Project.php b/app/Models/Project.php index 35d782e..892c229 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -34,6 +34,13 @@ class Project extends Model return $this->belongsToMany(User::class)->withPivot('role_in_project'); } + public function companies() + { + return $this->belongsToMany(Company::class, 'company_project') + ->withPivot('role_in_project') + ->withTimestamps(); + } + public function creator() { return $this->belongsTo(User::class, 'created_by'); diff --git a/database/migrations/2026_05_13_075321_create_companies_table.php b/database/migrations/2026_05_13_075321_create_companies_table.php new file mode 100644 index 0000000..de80105 --- /dev/null +++ b/database/migrations/2026_05_13_075321_create_companies_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('name'); + $table->string('tax_id')->nullable()->unique(); + $table->string('address')->nullable(); + $table->string('phone')->nullable(); + $table->string('email')->nullable(); + $table->string('website')->nullable(); + $table->enum('type', ['owner', 'constructor', 'subcontractor', 'consultant', 'supplier', 'other'])->default('other'); + $table->text('notes')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('companies'); + } +}; \ No newline at end of file diff --git a/database/migrations/2026_05_13_075457_create_company_project_table.php b/database/migrations/2026_05_13_075457_create_company_project_table.php new file mode 100644 index 0000000..91634bf --- /dev/null +++ b/database/migrations/2026_05_13_075457_create_company_project_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('company_id')->constrained()->onDelete('cascade'); + $table->foreignId('project_id')->constrained()->onDelete('cascade'); + $table->string('role_in_project'); + $table->timestamps(); + + // Ensure a company is not linked more than once to the same project + $table->unique(['company_id', 'project_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('company_project'); + } +}; \ No newline at end of file diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql new file mode 100644 index 0000000..be317e3 --- /dev/null +++ b/database/schema/mysql-schema.sql @@ -0,0 +1,419 @@ +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `cache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `cache` ( + `key` varchar(255) NOT NULL, + `value` mediumtext NOT NULL, + `expiration` int(11) NOT NULL, + PRIMARY KEY (`key`), + KEY `cache_expiration_index` (`expiration`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `cache_locks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `cache_locks` ( + `key` varchar(255) NOT NULL, + `owner` varchar(255) NOT NULL, + `expiration` int(11) NOT NULL, + PRIMARY KEY (`key`), + KEY `cache_locks_expiration_index` (`expiration`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `failed_jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `failed_jobs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(255) NOT NULL, + `connection` text NOT NULL, + `queue` text NOT NULL, + `payload` longtext NOT NULL, + `exception` longtext NOT NULL, + `failed_at` timestamp NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `features`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `features` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `layer_id` bigint(20) unsigned NOT NULL, + `name` varchar(255) DEFAULT NULL, + `geometry` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`geometry`)), + `properties` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`properties`)), + `template_id` bigint(20) unsigned DEFAULT NULL, + `progress` int(11) NOT NULL DEFAULT 0, + `responsible` varchar(255) DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `features_layer_id_foreign` (`layer_id`), + KEY `features_template_id_foreign` (`template_id`), + CONSTRAINT `features_layer_id_foreign` FOREIGN KEY (`layer_id`) REFERENCES `layers` (`id`) ON DELETE CASCADE, + CONSTRAINT `features_template_id_foreign` FOREIGN KEY (`template_id`) REFERENCES `inspection_templates` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `inspection_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `inspection_templates` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` text DEFAULT NULL, + `project_id` bigint(20) unsigned DEFAULT NULL, + `fields` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`fields`)), + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `phase_id` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `inspection_templates_project_id_foreign` (`project_id`), + KEY `inspection_templates_phase_id_index` (`phase_id`), + CONSTRAINT `inspection_templates_phase_id_foreign` FOREIGN KEY (`phase_id`) REFERENCES `phases` (`id`) ON DELETE SET NULL, + CONSTRAINT `inspection_templates_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `inspections`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `inspections` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint(20) unsigned NOT NULL, + `layer_id` bigint(20) unsigned NOT NULL, + `template_id` bigint(20) unsigned DEFAULT NULL, + `user_id` bigint(20) unsigned NOT NULL, + `data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`data`)), + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `feature_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `inspections_project_id_foreign` (`project_id`), + KEY `inspections_layer_id_foreign` (`layer_id`), + KEY `inspections_template_id_foreign` (`template_id`), + KEY `inspections_user_id_foreign` (`user_id`), + KEY `inspections_feature_id_foreign` (`feature_id`), + CONSTRAINT `inspections_feature_id_foreign` FOREIGN KEY (`feature_id`) REFERENCES `features` (`id`) ON DELETE CASCADE, + CONSTRAINT `inspections_layer_id_foreign` FOREIGN KEY (`layer_id`) REFERENCES `layers` (`id`) ON DELETE CASCADE, + CONSTRAINT `inspections_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, + CONSTRAINT `inspections_template_id_foreign` FOREIGN KEY (`template_id`) REFERENCES `inspection_templates` (`id`) ON DELETE SET NULL, + CONSTRAINT `inspections_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `job_batches`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `job_batches` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `total_jobs` int(11) NOT NULL, + `pending_jobs` int(11) NOT NULL, + `failed_jobs` int(11) NOT NULL, + `failed_job_ids` longtext NOT NULL, + `options` mediumtext DEFAULT NULL, + `cancelled_at` int(11) DEFAULT NULL, + `created_at` int(11) NOT NULL, + `finished_at` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `jobs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `queue` varchar(255) NOT NULL, + `payload` longtext NOT NULL, + `attempts` tinyint(3) unsigned NOT NULL, + `reserved_at` int(10) unsigned DEFAULT NULL, + `available_at` int(10) unsigned NOT NULL, + `created_at` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `jobs_queue_index` (`queue`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `layers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `layers` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint(20) unsigned NOT NULL, + `phase_id` bigint(20) unsigned DEFAULT NULL, + `name` varchar(255) NOT NULL, + `color` varchar(7) NOT NULL DEFAULT '#3b82f6', + `original_file` varchar(255) DEFAULT NULL, + `uploaded_by` bigint(20) unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `layers_project_id_foreign` (`project_id`), + KEY `layers_phase_id_foreign` (`phase_id`), + KEY `layers_uploaded_by_foreign` (`uploaded_by`), + CONSTRAINT `layers_phase_id_foreign` FOREIGN KEY (`phase_id`) REFERENCES `phases` (`id`) ON DELETE SET NULL, + CONSTRAINT `layers_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, + CONSTRAINT `layers_uploaded_by_foreign` FOREIGN KEY (`uploaded_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `media`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `media` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `mediable_type` varchar(255) NOT NULL, + `mediable_id` bigint(20) unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `file_path` varchar(255) NOT NULL, + `file_type` varchar(255) NOT NULL, + `file_extension` varchar(10) NOT NULL, + `file_size` int(10) unsigned NOT NULL, + `category` enum('image','document','other') NOT NULL DEFAULT 'image', + `description` text DEFAULT NULL, + `metadata` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`metadata`)), + `uploaded_by` bigint(20) unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `media_mediable_type_mediable_id_index` (`mediable_type`,`mediable_id`), + KEY `media_uploaded_by_foreign` (`uploaded_by`), + CONSTRAINT `media_uploaded_by_foreign` FOREIGN KEY (`uploaded_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `migrations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `migrations` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `migration` varchar(255) NOT NULL, + `batch` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `model_has_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `model_has_permissions` ( + `permission_id` bigint(20) unsigned NOT NULL, + `model_type` varchar(255) NOT NULL, + `model_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`permission_id`,`model_id`,`model_type`), + KEY `model_has_permissions_model_id_model_type_index` (`model_id`,`model_type`), + CONSTRAINT `model_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `model_has_roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `model_has_roles` ( + `role_id` bigint(20) unsigned NOT NULL, + `model_type` varchar(255) NOT NULL, + `model_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`role_id`,`model_id`,`model_type`), + KEY `model_has_roles_model_id_model_type_index` (`model_id`,`model_type`), + CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `password_reset_tokens`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `password_reset_tokens` ( + `email` varchar(255) NOT NULL, + `token` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `pending_syncs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `pending_syncs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `action` varchar(255) NOT NULL, + `payload` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`payload`)), + `synced_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `pending_syncs_user_id_foreign` (`user_id`), + CONSTRAINT `pending_syncs_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `permissions` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `guard_name` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `permissions_name_guard_name_unique` (`name`,`guard_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `phases`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `phases` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint(20) unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `description` text DEFAULT NULL, + `order` int(11) NOT NULL DEFAULT 0, + `color` varchar(7) NOT NULL DEFAULT '#3b82f6', + `progress_percent` int(11) NOT NULL DEFAULT 0, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `phases_project_id_foreign` (`project_id`), + CONSTRAINT `phases_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `progress_updates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `progress_updates` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `phase_id` bigint(20) unsigned NOT NULL, + `user_id` bigint(20) unsigned NOT NULL, + `progress_percent` int(11) NOT NULL, + `comment` text DEFAULT NULL, + `location` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`location`)), + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `progress_updates_phase_id_foreign` (`phase_id`), + KEY `progress_updates_user_id_foreign` (`user_id`), + CONSTRAINT `progress_updates_phase_id_foreign` FOREIGN KEY (`phase_id`) REFERENCES `phases` (`id`) ON DELETE CASCADE, + CONSTRAINT `progress_updates_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `project_user`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `project_user` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint(20) unsigned NOT NULL, + `user_id` bigint(20) unsigned NOT NULL, + `role_in_project` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `project_user_project_id_foreign` (`project_id`), + KEY `project_user_user_id_foreign` (`user_id`), + CONSTRAINT `project_user_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, + CONSTRAINT `project_user_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `projects`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `projects` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `address` text NOT NULL, + `lat` decimal(10,8) NOT NULL, + `lng` decimal(11,8) NOT NULL, + `start_date` date NOT NULL, + `end_date_estimated` date DEFAULT NULL, + `status` enum('planning','in_progress','paused','completed') NOT NULL DEFAULT 'planning', + `created_by` bigint(20) unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `projects_created_by_foreign` (`created_by`), + CONSTRAINT `projects_created_by_foreign` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `role_has_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `role_has_permissions` ( + `permission_id` bigint(20) unsigned NOT NULL, + `role_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`permission_id`,`role_id`), + KEY `role_has_permissions_role_id_foreign` (`role_id`), + CONSTRAINT `role_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE, + CONSTRAINT `role_has_permissions_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `roles` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `guard_name` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `roles_name_guard_name_unique` (`name`,`guard_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `sessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `sessions` ( + `id` varchar(255) NOT NULL, + `user_id` bigint(20) unsigned DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` text DEFAULT NULL, + `payload` longtext NOT NULL, + `last_activity` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `sessions_user_id_index` (`user_id`), + KEY `sessions_last_activity_index` (`last_activity`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `users` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `email_verified_at` timestamp NULL DEFAULT NULL, + `password` varchar(255) NOT NULL, + `remember_token` varchar(100) DEFAULT NULL, + `locale` varchar(5) NOT NULL DEFAULT 'en', + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `users_email_unique` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +/*M!999999\- enable the sandbox mode */ +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2026_04_27_095918_create_projects_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2026_04_27_095919_create_phases_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2026_04_27_095920_create_layers_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2026_04_27_095921_create_progress_updates_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2026_04_27_095925_create_pending_syncs_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2026_04_27_095925_create_project_user_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2026_04_27_095926_create_permission_tables',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2026_04_28_090208_create_inspection_templates_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2026_04_28_090218_create_inspections_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2026_05_06_122423_create_features_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2026_05_06_122711_update_inspections_feature_id_foreign',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2026_05_06_125429_drop_geojson_data_from_layers',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2026_05_06_172557_add_color_to_layers_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2026_05_09_210000_create_media_table',2); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2026_05_09_220000_add_locale_to_users_table',3); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2026_05_11_115552_add_phase_id_to_inspection_templates',4); diff --git a/resources/views/livewire/project-companies.blade.php b/resources/views/livewire/project-companies.blade.php new file mode 100644 index 0000000..9a581a0 --- /dev/null +++ b/resources/views/livewire/project-companies.blade.php @@ -0,0 +1,76 @@ +
+ @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + + {{-- Asignar compañía --}} + @can('assign users') +
+
+ + +
+
+ + +
+ +
+ @endcan + + {{-- Lista de compañías asignadas --}} + @if($assignedCompanies->isNotEmpty()) +
+ @foreach($assignedCompanies as $company) +
+
+ + {{ strtoupper(substr($company->name, 0, 1)) }} + +
+ {{ $company->name }} + @if($company->tax_id) + {{ $company->tax_id }} + @endif +
+
+
+ @can('assign users') + + + @else + {{ ucfirst($company->pivot->role_in_project) }} + @endcan +
+
+ @endforeach +
+ @else +

{{ __('No companies assigned yet') }}

+ @endif +
\ No newline at end of file diff --git a/resources/views/livewire/project-edit-tabs.blade.php b/resources/views/livewire/project-edit-tabs.blade.php index c8d5926..ea2e578 100644 --- a/resources/views/livewire/project-edit-tabs.blade.php +++ b/resources/views/livewire/project-edit-tabs.blade.php @@ -18,6 +18,12 @@ + + + diff --git a/resources/views/livewire/project-table.blade.php.backup b/resources/views/livewire/project-table.blade.php.backup new file mode 100644 index 0000000..fd5ed6b --- /dev/null +++ b/resources/views/livewire/project-table.blade.php.backup @@ -0,0 +1,3 @@ +
+ {{-- Nothing in the world is as soft and yielding as water. --}} +
diff --git a/resources/views/livewire/template-manager.blade.php.bak b/resources/views/livewire/template-manager.blade.php.bak new file mode 100644 index 0000000..16f9fb1 --- /dev/null +++ b/resources/views/livewire/template-manager.blade.php.bak @@ -0,0 +1,160 @@ +
+
+
+

📋 Templates de inspección

+
+ +
+
+ + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + + {{-- Formulario de creación/edición con diseño de dos columnas --}} + @if($showForm) +
+ + + {{-- Nombre del template --}} + + + + + + {{-- Descripción --}} + + + + + + {{-- Fase asociada (opcional) --}} + + + + + +
+ {{__('Nombre del template')}} + + +
+ {{__('Descripción')}} + + +
+ {{__('Fase asociada (opcional)')}} + + +
+ + {{-- Campos dinámicos --}} +
+

Campos del formulario

+ @foreach($form['fields'] as $index => $field) +
+ {{-- Fila: nombre interno --}} +
+
Nombre interno
+
+
+ {{-- Fila: etiqueta --}} +
+
Etiqueta visible
+
+
+ {{-- Fila: tipo --}} +
+
Tipo de campo
+
+ +
+
+ {{-- Fila: requerido y botón eliminar --}} +
+
Requerido
+
+ + +
+
+ + {{-- Campos adicionales según tipo --}} + @if(in_array($field['type'], ['integer', 'decimal', 'percentage'])) +
+
Mínimo / Máximo / Paso
+
+ + + +
+
+ @elseif($field['type'] === 'select') +
+
Opciones (separadas por coma)
+
+
+ @endif +
+ @endforeach + +
+ +
+ + +
+
+ @endif + + {{-- Tabla de templates existentes --}} +
+ + + + + + + + + + + + @forelse($templates as $template) + + + + + + + + @empty + + + + @endforelse + +
NombreDescripciónFaseCamposAcciones
{{ $template->name }}{{ $template->description ?? '-' }}{{ $template->phase ? $template->phase->name : 'Global' }}{{ count($template->fields) }} + + +
No hay templates creados. Presiona "Nuevo template" para comenzar.
+
+
+
\ No newline at end of file