Compare commits

..

No commits in common. "df8a4c258a542294cc40462ee097fa9df6766b84" and "be89d18e74c6514e01bcc1f54bbe7bbbede582e8" have entirely different histories.

61 changed files with 228 additions and 3807 deletions

View File

@ -1,72 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Requests\StoreDepartment;
use App\Http\Requests\UpdateDepartment;
use App\Models\department;
use Notsoweb\Core\Http\Controllers\VueController;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class DepartmentController extends VueController
{
public function __construct()
{
$this->vueRoot('admin.departments');
}
public function index()
{
$q = request()->get('q');
return $this->vuew('index', [
'departments' => department::where('name', 'LIKE', "%{$q}%")
->select([
'id',
'name',
'description',
])
->paginate(config('app.pagination'))
]);
}
public function create()
{
return $this->vuew('create');
}
public function store(StoreDepartment $request)
{
$data = $request->all();
department::create($data);
return $this->index();
}
public function update(UpdateDepartment $request, $department)
{
$data = $request->all();
department::find($department)->update($data);
}
public function destroy($department)
{
department::find($department)->delete();
return $this->index();
}
}

View File

@ -1,74 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Requests\StoreMainRole;
use App\Http\Requests\UpdateMainRole;
use App\Models\department;
use App\Models\mainRole;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Notsoweb\Core\Http\Controllers\VueController;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class MainRoleController extends VueController
{
public function __construct()
{
$this->vueRoot('admin.mainRole');
}
public function index()
{
$q = request()->get('q');
$mainRoles = mainRole::orderBy('name', 'ASC')
->where('name', 'LIKE', "%{$q}%")
->with('department:id,name')
->paginate(config('app.pagination'));
return $this->vuew('index', [
'mainRoles' => $mainRoles,
]);
}
public function create()
{
$department = department::orderBy('name', 'ASC')->get();
return $this->vuew('create', [
'departments' => $department,
]);
}
public function store(StoreMainRole $request)
{
mainRole::create($request->all());
return $this->index();
}
public function update(UpdateMainRole $request, mainRole $mainRole)
{
$mainRole->update($request->all());
}
public function destroy(mainRole $mainRole)
{ try{
$mainRole = mainRole::find($mainRole);
$mainRole->delete();
}catch (\Throwable $th) {
Log::channel('mainRole')->error($th->getMessage());
}
}
}

View File

@ -1,98 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Requests\StoreMainRoleSkills;
use App\Http\Requests\UpdateMainRoleSkills;
use App\Models\mainRole;
use App\Models\MainRoleSkills;
use App\Models\Score;
use App\Models\Skill;
use Illuminate\Support\Facades\Log;
use Notsoweb\Core\Http\Controllers\VueController;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class MainRoleSkillsController extends VueController
{
public function __construct()
{
return $this->vueRoot('admin.mainRoleSkills');
}
public function index()
{
$q = request()->get('q');
$mainRole = mainRole::where('name', 'LIKE', "%{$q}%")->pluck('id');
$skills = Skill::where('name', 'LIKE', "%{$q}%")->pluck('id');
$scores = Score::where('alias', 'LIKE', "%{$q}%")->pluck('id');
$mainRoleSkills = MainRoleSkills::whereIn('main_role_id', $mainRole)
->orWhereIn('skill_id', $skills)
->orWhereIn('scored_id', $scores)
->with([
'mainRole:id,name,department_id',
'mainRole.department:id,name,description',
'skill:id,name,department_id',
'score:id,alias'
])
->paginate(config('app.pagination'));
return $this->vuew('index', [
'mainRoleSkills' => $mainRoleSkills
]);
}
public function create()
{
$mainRoles = mainRole::with('department:id,name')->orderBy('name', 'ASC')->get();
$skills = Skill::with('department:id,name')->orderBy('name', 'ASC')->get();
$scores = Score::orderBy('alias', 'ASC')->get();
return $this->vuew('create', [
'mainRoles' => $mainRoles,
'skills' => $skills,
'scores' => $scores
]);
}
public function store(StoreMainRoleSkills $request)
{
$create = [];
foreach ($request['skills'] as $skill){
$create[] = [
'main_role_id' => $request['main_role_id'],
'skill_id' => $skill['skill_id'],
'scored_id' => $skill['scored_id'],
'created_at' => now(),
'updated_at' => now(),
];
}
MainRoleSkills::insert($create);
return $this->index();
}
public function update(UpdateMainRoleSkills $request, MainRoleSkills $mainRoleSkills)
{
$mainRoleSkills->update($request->all());
}
public function destroy($id)
{
$mainRoleSkill = MainRoleSkills::findOrFail($id);
$mainRoleSkill->delete();
}
}

View File

@ -1,71 +0,0 @@
<?php namespace App\Http\Controllers\Admin;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Models\Score;
use App\Http\Requests\StoreScore;
use App\Http\Requests\UpdateScore;
use Notsoweb\Core\Http\Controllers\VueController;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class ScoreController extends VueController
{
public function __construct()
{
$this->vueRoot('admin.app');
}
public function index()
{
$q = request()->get('q');
return $this->vuew('index', [
'scores' => Score::where('alias', 'LIKE', "%{$q}%")
->orWhere('value', 'LIKE', "%{$q}%")
->select([
'id',
'alias',
'value',
'description',
])
->paginate(config('app.pagination'))
]);
}
public function create()
{
return $this->vuew('create');
}
public function store(StoreScore $request)
{
$data = $request->all();
Score::create($data);
return $this->index();
}
public function update(UpdateScore $request, $score)
{
$data = $request->all();
Score::find($score)->update($data);
}
public function destroy($score)
{
Score::find($score)->delete();
return $this->index();
}
}

View File

@ -1,65 +0,0 @@
<?php namespace App\Http\Controllers\Admin;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Requests\StoreSkill;
use App\Http\Requests\UpdateSkill;
use App\Models\department;
use App\Models\Skill;
use Notsoweb\Core\Http\Controllers\VueController;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class SkillController extends VueController
{
public function __construct()
{
return $this->vueRoot('admin.skills');
}
public function index()
{
$q = request()->get('q');
$skills = Skill::orderBy('name', 'ASC')
->where('name', 'LIKE', "%{$q}%")
->with('department:id,name')
->paginate(config('app.pagination'));
return $this->vuew('index', [
'skills' => $skills,
]);
}
public function create()
{
$department = department::orderBy('name', 'ASC')->get();
return $this->vuew('create', [
'departments' => $department,
]);
}
public function store(StoreSkill $request)
{
Skill::create($request->all());
return $this->index();
}
public function update(UpdateSkill $request, Skill $skill)
{
$skill->update($request->all());
}
public function destroy (Skill $skill)
{
$skill->delete();
}
}

View File

@ -1,39 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class StoreDepartment extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class StoreMainRole extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'department_id' => ['required', 'integer'],
];
}
}

View File

@ -1,41 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class StoreMainRoleSkills extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'main_role_id' => ['required', 'integer'],
'skills' => ['required', 'array', 'min:1'],
'skills.*.skill_id' => ['required', 'integer'],
'skills.*.scored_id' => ['required', 'integer'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class StoreScore extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'alias' => ['required', 'string'],
'value' => ['required', 'string'],
'description' => ['nullable', 'string'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class StoreSkill extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'department_id' => ['required', 'integer'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
/**
* Valida la actualización de los usuarios
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class UpdateDepartment extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class UpdateMainRole extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'department_id' => ['required', 'integer','exists:departments,id'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class UpdateMainRoleSkills extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'main_role_id' => ['required', 'integer'],
'skill_id' => ['required', 'integer'],
'scored_id' => ['required', 'integer'],
];
}
}

View File

@ -1,41 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
/**
* Valida la actualización de los usuarios
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class UpdateScore extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'alias' => ['required', 'string'],
'value' => ['required', 'string'],
'description' => ['nullable', 'string'],
];
}
}

View File

@ -1,40 +0,0 @@
<?php namespace App\Http\Requests;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use Illuminate\Foundation\Http\FormRequest;
/**
* Valida el almacenamiento de un usuario
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class UpdateSkill extends FormRequest
{
/**
* Determinar si el usuario esta autorizado
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Reglas de validación
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'department_id' => ['required', 'integer','exists:departments,id'],
];
}
}

View File

@ -1,45 +0,0 @@
<?php namespace App\Models;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Traits\ModelExtend;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class MainRoleSkills extends Model
{
use HasFactory,
ModelExtend;
/**
* Atributos llenables masivamente
*/
protected $fillable = [
'main_role_id',
'skill_id',
'scored_id',
];
public function mainRole()
{
return $this->belongsTo(mainRole::class, 'main_role_id');
}
public function skill()
{
return $this->belongsTo(Skill::class, 'skill_id');
}
public function score()
{
return $this->belongsTo(Score::class, 'scored_id');
}
}

View File

@ -1,35 +0,0 @@
<?php namespace App\Models;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Traits\ModelExtend;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class Score extends Model
{
use HasFactory,
ModelExtend;
/**
* Atributos llenables masivamente
*/
protected $fillable = [
'alias',
'value',
'description',
];
public function mainRoleSkills()
{
return $this->hasMany(MainRoleSkills::class);
}
}

View File

@ -1,46 +0,0 @@
<?php namespace App\Models;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Traits\ModelExtend;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class Skill extends Model
{
use HasFactory,
ModelExtend;
/**
* Atributos llenables masivamente
*/
protected $fillable = [
'name',
'description',
'department_id',
];
public function department()
{
return $this->belongsTo(department::class);
}
public function mainRoles()
{
return $this->belongsTo(MainRole::class);
}
public function mainRoleSkills()
{
return $this->hasMany(MainRoleSkills::class);
}
}

View File

@ -1,42 +0,0 @@
<?php namespace App\Models;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Traits\ModelExtend;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Descripción
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class department extends Model
{
use HasFactory,
ModelExtend;
/**
* Atributos llenables masivamente
*/
protected $fillable = [
'name',
'description',
];
/**
* Un departamento tiene muchos main roles
*/
public function mainRoles()
{
return $this->hasMany(MainRole::class);
}
public function skills()
{
return $this->hasMany(Skill::class);
}
}

View File

@ -1,53 +0,0 @@
<?php namespace App\Models;
/**
* @copyright Copyright (c) 2023 Notsoweb (https://notsoweb.com) - All rights reserved.
*/
use App\Http\Traits\ModelExtend;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Roles principales del sistema
*
* @author Moisés de Jesús Cortés Castellanos <ing.moisesdejesuscortesc@notsoweb.com>
*
* @version 1.0.0
*/
class MainRole extends Model
{
use HasFactory,
ModelExtend;
/**
* Nombre de la tabla
*/
protected $table = 'main_roles';
/**
* Atributos llenables masivamente
*/
protected $fillable = [
'name',
'description',
'department_id'
];
/**
* Un main role pertenece a un departamento
*/
public function department()
{
return $this->belongsTo(department::class);
}
public function skills()
{
return $this->hasMany(Skill::class);
}
public function mainRoleSkills()
{
return $this->hasMany(MainRoleSkills::class);
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('scores', function (Blueprint $table){
$table->id();
$table->string('alias');
$table->integer('value');
$table->string('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('scores');
}
};

View File

@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('departments', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('departments');
}
};

View File

@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('main_roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description')->nullable();
$table->foreignId('department_id')->constrained('departments')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('main_roles');
}
};

View File

@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('skills', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description');
$table->foreignId('department_id')->constrained('departments')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('skills');
}
};

View File

@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('main_role_skills', function (Blueprint $table) {
$table->id();
$table->foreignId('main_role_id')->constrained('main_roles')->onDelete('cascade');
$table->foreignId('skill_id')->constrained('skills')->onDelete('cascade');
$table->foreignId('scored_id')->constrained('scores')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('main_role_skills');
}
};

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{ {
"name": "Scores", "name": "template-laravel-vuejs",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -1,34 +0,0 @@
<script setup>
defineEmits(['select']);
const props = defineProps({
departments: Object,
});
console.log('Department props:', props.departments);
</script>
<template>
<div class="w-full">
<div class="mb-6">
<h2 class="text-xl font-semibold mb-2">{{ $t('department.select.title') }}</h2>
<p class="text-gray-600">{{ $t('department.select.description') }}</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<button
v-for="department in departments"
:key="department.id"
@click="$emit('select', department)"
class="group p-6 border-2 border-gray-200 rounded-lg hover:border-primary hover:bg-primary/5 transition-all duration-200 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
>
<h3 class="font-semibold text-lg mb-2 group-hover:text-primary transition-colors">
{{ department.name }}
</h3>
<p class="text-gray-600 text-sm">
{{ department.description }}
</p>
</button>
</div>
</div>
</template>

View File

@ -1,53 +0,0 @@
<script setup>
import { computed } from 'vue';
const emit = defineEmits(['select']);
const props = defineProps({
mainRoles: {
type: Object,
required: true
},
selectedDepartment: {
type: Object,
required: true
}
});
const departmentMainRoles = computed(() => {
return props.mainRoles.filter(role =>
role.department && role.department.id === props.selectedDepartment.id
);
});
</script>
<template>
<div class="w-full">
<div class="mb-6">
<h2 class="text-xl font-semibold mb-2">
{{ $t('mainRole.inDepartment', { department: selectedDepartment.name }) }}
</h2>
<p class="text-gray-600">{{ $t('mainRole.select.description') }}</p>
</div>
<div v-if="departmentMainRoles.length > 0" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<button
v-for="mainRole in departmentMainRoles"
:key="mainRole.id"
@click="$emit('select', mainRole)"
class="group p-6 border-2 border-gray-200 rounded-lg hover:border-primary hover:bg-primary/5 transition-all duration-200 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
>
<h3 class="font-semibold text-lg mb-2 group-hover:text-primary transition-colors">
{{ mainRole.name }}
</h3>
<p class="text-gray-600 text-sm">
{{ mainRole.description}}
</p>
</button>
</div>
<div v-else class="text-center py-12">
<p class="text-gray-500 text-lg">{{ $t('mainRole.noRolesInDepartment') }}</p>
</div>
</div>
</template>

View File

@ -1,191 +0,0 @@
<script setup>
import { ref, computed, onMounted, watch } from "vue";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
const emit = defineEmits(["submit", "update:modelValue"]);
const props = defineProps({
form: {
type: Object,
required: true,
},
skills: {
type: Object,
required: true,
},
scores: {
type: Object,
required: true,
},
selectedDepartment: {
type: Object,
required: true,
},
selectedMainRole: {
type: Object,
required: true,
},
modelValue: {
type: Array,
default: () => [],
},
});
const skillId = ref("");
const scoredId = ref("");
const todos = ref([]);
function addTodo() {
if (skillId.value && scoredId.value) {
// Buscar los objetos completos
const selectedSkill = departmentSkills.value.find(
(skill) => skill.id === skillId.value.id || skill.id === skillId.value
);
const selectedScore = props.scores.find(
(score) => score.id === scoredId.value.id || score.id === scoredId.value
);
if (selectedSkill && selectedScore) {
const newItem = {
skill_id: selectedSkill.id,
scored_id: selectedScore.id,
skill_name: selectedSkill.name,
score_alias: selectedScore.alias,
};
todos.value.push(newItem);
// Limpiar los campos
skillId.value = "";
scoredId.value = "";
// Emitir el arreglo actualizado
emit("update:modelValue", todos.value);
}
}
}
function removeTodo(index) {
todos.value.splice(index, 1);
emit("update:modelValue", todos.value);
}
const departmentSkills = computed(() => {
return props.skills.filter(
(skill) => skill.department_id === props.selectedDepartment.id
);
});
const isFormValid = computed(() => {
return todos.value.length > 0;
});
const submitForm = () => {
if (isFormValid.value) {
emit("submit", todos.value);
}
};
onMounted(() => {
if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
todos.value = [...props.modelValue];
}
});
watch(
() => props.modelValue,
(newValue) => {
if (Array.isArray(newValue)) {
todos.value = [...newValue];
}
}
);
</script>
<template>
<div class="w-full">
<div class="mb-6">
<h2 class="text-xl font-semibold mb-2">
{{ $t("skill.assignTo", { role: selectedMainRole.name }) }}
</h2>
<p class="text-gray-600">
{{
$t("skill.assignment.description", {
department: selectedDepartment.name,
})
}}
</p>
</div>
<!-- Formulario para agregar habilidades -->
<div class="bg-white rounded-lg shadow-sm border p-6 mb-6">
<div class="grid gap-6 grid-cols-1 md:grid-cols-2">
<Selectable
id="skill_id"
v-model="skillId"
:options="departmentSkills"
:title="$t('skill.title')"
placeholder="Selecciona una habilidad..."
label="name"
track-by="id"
required
/>
<Selectable
id="scored_id"
v-model="scoredId"
:options="scores"
:title="$t('scores.title')"
placeholder="Selecciona una puntuación..."
label="alias"
track-by="id"
required
/>
</div>
<div class="flex justify-center mt-6">
<button
@click="addTodo"
type="button"
class="rounded-lg px-4 py-2 bg-primary text-white border dark:bg-primary-dark dark:border-primary-dark-on"
>
Agregar Habilidad
</button>
</div>
</div>
<!-- Lista de habilidades agregadas -->
<div class="space-y-3 mb-6">
<template v-for="(todo, index) in todos" :key="index">
<div class="flex bg-white items-center justify-between rounded-lg px-4 py-3 border shadow-sm">
<div class="flex-1">
<div class="font-bold text-black">Habilidad: {{ todo.skill_name }}</div>
<div class="font-bold text-black">Puntuación: {{ todo.score_alias }}</div>
</div>
<div
@click="removeTodo(index)"
class="rounded-lg px-4 py-2 bg-red-600 text-white cursor-pointer hover:bg-red-700 transition-colors"
>
Quitar
</div>
</div>
</template>
<div v-if="todos.length === 0" class="text-gray-500 text-center py-8 bg-gray-50 rounded-lg">
No hay habilidades agregadas
</div>
</div>
<!-- Botón de envío -->
<div class="flex justify-center">
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing || !isFormValid"
type="button"
@click="submitForm"
>
<span>{{ $t("Crear") }}</span>
</PrimaryButton>
</div>
</div>
</template>

View File

@ -1,38 +0,0 @@
<script setup>
defineProps({
currentStep: {
type: Number,
required: true
}
});
const steps = [
{ number: 1, name: 'department.title' },
{ number: 2, name: 'mainRole.title' },
{ number: 3, name: 'skill.title' }
];
</script>
<template>
<div class="w-full pb-4">
<div class="flex items-center justify-center space-x-4 mb-6">
<template v-for="(step, index) in steps" :key="step.number">
<div class="flex items-center">
<div
class="w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium transition-colors"
:class="currentStep >= step.number ? 'bg-primary text-primary-on' : 'bg-gray-300 text-gray-600'"
>
{{ step.number }}
</div>
<span class="ml-2 text-sm font-medium">{{ $t(step.name) }}</span>
</div>
<div
v-if="index < steps.length - 1"
class="w-8 h-1 bg-gray-300 transition-colors"
:class="currentStep > step.number ? 'bg-primary' : ''"
/>
</template>
</div>
</div>
</template>

View File

@ -1,317 +1,228 @@
export default { export default {
"&": "y", '&':'y',
account: { account: {
delete: { delete: {
confirm: confirm:'¿Está seguro de que quiere eliminar su cuenta? Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Por favor, introduzca su contraseña para confirmar que desea eliminar permanentemente su cuenta.',
"¿Está seguro de que quiere eliminar su cuenta? Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Por favor, introduzca su contraseña para confirmar que desea eliminar permanentemente su cuenta.", description:'Eliminar permanentemente su cuenta.',
description: "Eliminar permanentemente su cuenta.", onDelete:'Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Antes de eliminar su cuenta, descargue los datos o la información que desee conservar.',
onDelete: title:'Eliminar cuenta',
"Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Antes de eliminar su cuenta, descargue los datos o la información que desee conservar.", },
title: "Eliminar cuenta", email: {
notifySendVerification:'Se ha enviado un nuevo enlace de verificación a su dirección de correo electrónico.',
sendVerification:'Haga clic aquí para volver a enviar el correo electrónico de verificación.',
unverify: 'Su dirección de correo electrónico no está verificada.',
},
manage:'Administrar cuenta',
password: {
description:'Asegúrese de que su cuenta utiliza una contraseña larga y aleatoria para estar seguro.',
new:'Nueva contraseña',
reset:'Restaurar contraseña',
secure:'Esta es una zona segura de la aplicación. Confirme su contraseña antes de continuar.',
update: 'Actualizar contraseña',
verify:'Por su seguridad, confirme su contraseña para continuar.',
},
profile: {
description:'Actualice la información del perfil de su cuenta y su dirección de correo electrónico.',
title:'Información del perfil',
},
sessions: {
confirm:'Por favor, introduzca su contraseña para confirmar que desea salir de sus otras sesiones de navegación en todos sus dispositivos.',
description: 'Gestiona y cierra tus sesiones activas en otros navegadores y dispositivos.',
last:'Último activo',
logout:'Cerrar otras sesiones del navegador',
onLogout:'Si es necesario, puede cerrar la sesión de todos sus otros navegadores en todos sus dispositivos. A continuación se enumeran algunas de sus sesiones recientes; sin embargo, esta lista puede no ser exhaustiva. Si crees que tu cuenta ha sido comprometida, también deberías actualizar tu contraseña.',
this: 'Dispositivo actual',
title: 'Sesiones del navegador',
},
twoFactor: {
codes:{
regenerate:'Regenerar los códigos de recuperación',
show:'Mostrar códigos de recuperación',
store:'Guarde estos códigos de recuperación en un gestor de contraseñas seguro. Pueden utilizarse para recuperar el acceso a su cuenta si se pierde su dispositivo de autenticación de dos factores.',
},
description:'Añada seguridad adicional a su cuenta mediante la autenticación de dos factores.',
isEnable:'Ha activado la autenticación de dos factores.',
isNotEnable:{
title:'No ha activado la autenticación de dos factores.',
description:'Cuando la autenticación de dos factores está activada, se le pedirá un token seguro y aleatorio durante la autenticación. Puedes recuperar este token desde la aplicación Google Authenticator de tu teléfono.',
},
key:'Llave de configuración',
login: {
onAuth: 'Por favor, confirme el acceso a su cuenta introduciendo el código de autentificación proporcionado por su aplicación de autentificación.',
onRecovery: 'Confirme el acceso a su cuenta introduciendo uno de sus códigos de recuperación de emergencia.',
},
onFinish:'Termina de habilitar la autenticación de dos factores.',
qr: {
isConfirmed: 'La autenticación de dos factores ya está activada. Escanee el siguiente código QR con la aplicación de autenticación de su teléfono o introduzca la clave de configuración.',
onConfirmed: 'Para terminar de habilitar la autenticación de dos factores, escanea el siguiente código QR utilizando la aplicación de autenticación de tu teléfono o introduce la clave de configuración y proporciona el código OTP generado.',
},
recovery: {
code: 'Código de recuperación',
useAuth: 'Utilizar un código de autentificación',
useCode: 'Utiliza un código de recuperación',
},
title:'Autenticación de dos factores',
},
}, },
email: { actions:'Acciones',
notifySendVerification: auth: {
"Se ha enviado un nuevo enlace de verificación a su dirección de correo electrónico.", forgotPassword: {
sendVerification: ask: '¿Olvidaste tu contraseña?',
"Haga clic aquí para volver a enviar el correo electrónico de verificación.", description: '¿Ha olvidado su contraseña? No hay problema. Sólo tienes que indicarnos tu dirección de correo electrónico y te enviaremos un enlace para restablecer la contraseña que te permitirá elegir una nueva.',
unverify: "Su dirección de correo electrónico no está verificada.", sendLink: 'Enviar enlace de recuperación por correo',
title: 'Contraseña olvidada',
},
login: 'Iniciar sesión',
logout: 'Cerrar sesión',
register: {
already: '¿Ya estas registrado?',
me: 'Registrarme',
},
remember: 'Recuerdame',
}, },
manage: "Administrar cuenta", code:'Código',
password: { cancel:'Cancelar',
description: changes:'Cambios',
"Asegúrese de que su cuenta utiliza una contraseña larga y aleatoria para estar seguro.", changelogs: {
new: "Nueva contraseña", title:'Historial de cambios',
reset: "Restaurar contraseña", description: 'Lista de los cambios realizados al sistema.',
secure:
"Esta es una zona segura de la aplicación. Confirme su contraseña antes de continuar.",
update: "Actualizar contraseña",
verify: "Por su seguridad, confirme su contraseña para continuar.",
}, },
profile: { close:"Cerrar",
description: confirm:'Confirmar',
"Actualice la información del perfil de su cuenta y su dirección de correo electrónico.", copyright:'Todos los derechos reservados.',
title: "Información del perfil", contact:'Contacto',
crud: {
create: 'Nuevo registro',
edit: 'Editar registro',
destroy: 'Eliminar registro',
show: 'Más detalles',
}, },
sessions: { date: 'Fecha',
confirm: delete:{
"Por favor, introduzca su contraseña para confirmar que desea salir de sus otras sesiones de navegación en todos sus dispositivos.", confirm: 'Al presionar ELIMINAR el registro se eliminará permanentemente y no podrá recuperarse.',
description: title: 'Eliminar',
"Gestiona y cierra tus sesiones activas en otros navegadores y dispositivos.",
last: "Último activo",
logout: "Cerrar otras sesiones del navegador",
onLogout:
"Si es necesario, puede cerrar la sesión de todos sus otros navegadores en todos sus dispositivos. A continuación se enumeran algunas de sus sesiones recientes; sin embargo, esta lista puede no ser exhaustiva. Si crees que tu cuenta ha sido comprometida, también deberías actualizar tu contraseña.",
this: "Dispositivo actual",
title: "Sesiones del navegador",
}, },
twoFactor: { deleted:'Eliminado',
codes: { description:'Descripción',
regenerate: "Regenerar los códigos de recuperación", details:'Detalles',
show: "Mostrar códigos de recuperación", disable:'Deshabilitar',
store: disabled:'Deshabilitado',
"Guarde estos códigos de recuperación en un gestor de contraseñas seguro. Pueden utilizarse para recuperar el acceso a su cuenta si se pierde su dispositivo de autenticación de dos factores.", done:'Hecho.',
}, edit:'Editar',
description: email:{
"Añada seguridad adicional a su cuenta mediante la autenticación de dos factores.", title:'Correo',
isEnable: "Ha activado la autenticación de dos factores.", verification:'Verificar correo'
isNotEnable: {
title: "No ha activado la autenticación de dos factores.",
description:
"Cuando la autenticación de dos factores está activada, se le pedirá un token seguro y aleatorio durante la autenticación. Puedes recuperar este token desde la aplicación Google Authenticator de tu teléfono.",
},
key: "Llave de configuración",
login: {
onAuth:
"Por favor, confirme el acceso a su cuenta introduciendo el código de autentificación proporcionado por su aplicación de autentificación.",
onRecovery:
"Confirme el acceso a su cuenta introduciendo uno de sus códigos de recuperación de emergencia.",
},
onFinish: "Termina de habilitar la autenticación de dos factores.",
qr: {
isConfirmed:
"La autenticación de dos factores ya está activada. Escanee el siguiente código QR con la aplicación de autenticación de su teléfono o introduzca la clave de configuración.",
onConfirmed:
"Para terminar de habilitar la autenticación de dos factores, escanea el siguiente código QR utilizando la aplicación de autenticación de tu teléfono o introduce la clave de configuración y proporciona el código OTP generado.",
},
recovery: {
code: "Código de recuperación",
useAuth: "Utilizar un código de autentificación",
useCode: "Utiliza un código de recuperación",
},
title: "Autenticación de dos factores",
}, },
}, enable:'Habilitar',
actions: "Acciones", endDate:'Fecha Fin',
auth: { event:'Evento',
forgotPassword: { help: {
ask: "¿Olvidaste tu contraseña?", description:'A continuación se lista la iconografía para entender el funcionamiento del sistema.',
description: home: 'Volver a la pagina de inicio.',
"¿Ha olvidado su contraseña? No hay problema. Sólo tienes que indicarnos tu dirección de correo electrónico y te enviaremos un enlace para restablecer la contraseña que te permitirá elegir una nueva.", title:'Ayuda',
sendLink: "Enviar enlace de recuperación por correo",
title: "Contraseña olvidada",
}, },
login: "Iniciar sesión", history: {
logout: "Cerrar sesión", title:'Historial de acciones',
description:'Historial de acciones realizadas por los usuarios en orden cronológico.'
},
home:'Inicio',
hour:'Hora',
icon:'Icono',
maternal:'Apellido materno',
menu:'Menú',
name:'Nombre',
noRecords:'Sin registros',
notifications: {
readed:'Marcar como leído',
deleted:'Notificación eliminada',
description:'Notificaciones del usuario',
notFound:'Notificación no encontrada',
title:'Notificaciones',
},
password:'Contraseña',
passwordConfirmation:'Confirmar contraseña',
passwordCurrent:'Contraseña actual',
passwordReset:'Restaurar contraseña',
paternal:'Apellido paterno',
phone:'Teléfono',
photo: {
new: 'Seleccionar una nueva foto',
remove:'Remover foto',
title:'Foto',
},
profile:'Perfil',
readed:'Leído',
register: { register: {
already: "¿Ya estas registrado?", agree:'Estoy de acuerdo con los',
me: "Registrarme", privacy:'Política de Privacidad',
signUp:'Registrarme',
terms:'Términos de Servicio',
}, },
remember: "Recuerdame", registers:{
}, title:'Registros',
code: "Código", empty:'Sin registros',
cancel: "Cancelar",
changes: "Cambios",
changelogs: {
title: "Historial de cambios",
description: "Lista de los cambios realizados al sistema.",
},
close: "Cerrar",
confirm: "Confirmar",
copyright: "Todos los derechos reservados.",
contact: "Contacto",
crud: {
create: "Nuevo registro",
edit: "Editar registro",
destroy: "Eliminar registro",
show: "Más detalles",
},
date: "Fecha",
delete: {
confirm:
"Al presionar ELIMINAR el registro se eliminará permanentemente y no podrá recuperarse.",
title: "Eliminar",
},
deleted: "Eliminado",
description: "Descripción",
details: "Detalles",
disable: "Deshabilitar",
disabled: "Deshabilitado",
done: "Hecho.",
edit: "Editar",
email: {
title: "Correo",
verification: "Verificar correo",
},
enable: "Habilitar",
endDate: "Fecha Fin",
event: "Evento",
help: {
description:
"A continuación se lista la iconografía para entender el funcionamiento del sistema.",
home: "Volver a la pagina de inicio.",
title: "Ayuda",
},
history: {
title: "Historial de acciones",
description:
"Historial de acciones realizadas por los usuarios en orden cronológico.",
},
home: "Inicio",
hour: "Hora",
icon: "Icono",
maternal: "Apellido materno",
menu: "Menú",
name: "Nombre",
noRecords: "Sin registros",
notifications: {
readed: "Marcar como leído",
deleted: "Notificación eliminada",
description: "Notificaciones del usuario",
notFound: "Notificación no encontrada",
title: "Notificaciones",
},
password: "Contraseña",
passwordConfirmation: "Confirmar contraseña",
passwordCurrent: "Contraseña actual",
passwordReset: "Restaurar contraseña",
paternal: "Apellido paterno",
phone: "Teléfono",
photo: {
new: "Seleccionar una nueva foto",
remove: "Remover foto",
title: "Foto",
},
profile: "Perfil",
readed: "Leído",
register: {
agree: "Estoy de acuerdo con los",
privacy: "Política de Privacidad",
signUp: "Registrarme",
terms: "Términos de Servicio",
},
registers: {
title: "Registros",
empty: "Sin registros",
},
remove: "Remover",
return: "Regresar",
role: "Rol",
roles: {
create: {
title: "Crear rol",
description: "Estos roles serán usados para dar permisos en el sistema.",
onSuccess: "Rol creado exitosamente",
onError: "Error al crear el role",
}, },
deleted: "Rol eliminado", remove: 'Remover',
title: "Roles", return: 'Regresar',
}, role:'Rol',
save: "Guardar", roles:{
saved: "¡Guardado!", create: {
search: "Buscar", title: 'Crear rol',
selected: "Seleccionado", description: 'Estos roles serán usados para dar permisos en el sistema.',
select: "Seleccionar", onSuccess: 'Rol creado exitosamente',
setting: "Configuración", onError: 'Error al crear el role',
show: { },
all: "Mostrar todo", deleted:'Rol eliminado',
title: "Mostrar", title: 'Roles',
},
startDate: "Fecha de inicio",
status: "Estado",
terms: {
agree: "Estoy de acuerdo con los",
privacy: "Política de privacidad",
service: "Términos de servicio",
},
unknown: "Desconocido",
update: "Actualizar",
updated: "Actualizado",
updateFail: "Error al actualizar",
unreaded: "No leído",
user: "Usuario",
users: {
create: {
title: "Crear usuario",
description:
"Permite crear nuevos usuarios. No olvides otorgarle roles para que pueda acceder a las partes del sistema deseados.",
onSuccess: "Usuario creado",
onError: "Ocurrió un error al crear el usuario",
}, },
deleted: "Usuario eliminado", save:'Guardar',
notFount: "Usuario no encontrado", saved:'¡Guardado!',
password: { search:'Buscar',
description: selected: 'Seleccionado',
"Permite actualizar las contraseñas de los usuarios sobreescribiendola.", select: 'Seleccionar',
title: "Actualizar contraseña", setting: 'Configuración',
show: {
all:'Mostrar todo',
title:'Mostrar',
}, },
roles: { startDate:'Fecha de inicio',
description: status:'Estado',
"Actualiza los roles de los usuarios, permitiendo o denegando los accesos a determinadas áreas.", terms: {
error: { agree:'Estoy de acuerdo con los',
min: "Seleccionar mínimo un role", privacy:'Política de privacidad',
}, service:'Términos de servicio',
title: "Roles de usuario",
}, },
menu: "Menú de usuario", unknown:'Desconocido',
select: "Seleccionar un usuario", update:'Actualizar',
settings: "Ajustes del usuario", updated:'Actualizado',
system: "Usuarios del sistema", updateFail:'Error al actualizar',
title: "Usuarios", unreaded:'No leído',
}, user:'Usuario',
users:{
scores: { create:{
system: "Sistema de puntuación", title:'Crear usuario',
title: "Puntuaciones", description:'Permite crear nuevos usuarios. No olvides otorgarle roles para que pueda acceder a las partes del sistema deseados.',
create: { onSuccess:'Usuario creado',
title: "Crear puntuación", onError:'Ocurrió un error al crear el usuario'
description: "Permite crear nuevas puntuaciones para los usuarios.", },
onSuccess: "Puntuación creada exitosamente", deleted:'Usuario eliminado',
onError: "Error al crear la puntuación", notFount:'Usuario no encontrado',
password: {
description:'Permite actualizar las contraseñas de los usuarios sobreescribiendola.',
title:'Actualizar contraseña',
},
roles: {
description:'Actualiza los roles de los usuarios, permitiendo o denegando los accesos a determinadas áreas.',
error:{
min:'Seleccionar mínimo un role'
},
title:'Roles de usuario',
},
menu:'Menú de usuario',
select:'Seleccionar un usuario',
settings:'Ajustes del usuario',
system:'Usuarios del sistema',
title:'Usuarios',
}, },
}, version:'Versión',
department: { }
system: "Sistema de departamentos",
title: "Departamentos",
create: {
title: "Crear departamento",
description: "Permite crear nuevos departamentos para los usuarios.",
onSuccess: "Departamento creado exitosamente",
onError: "Error al crear el departamento",
},
select:{
title: "Seleccionar un departamento",
description: "Seleccione un departamento para filtrar los roles.",
}
},
mainRole: {
title: "Roles principales",
inDepartment: "Roles principales en el departamento",
system: "Sistema de roles principales",
select:{
description: "Seleccione un rol principal.",
},
create: {
title: "Crear rol principal",
description: "Permite crear nuevos roles principales para los usuarios.",
onSuccess: "Rol principal creado exitosamente",
onError: "Error al crear el rol principal",
},
},
skill: {
title: "Habilidades",
assignTo: "Asignar a rol principal",
system: "Sistema de habilidades",
assignment: {
description: "Asigna una habilidad a un rol principal.",
},
create: {
title: "Crear habilidad",
description:
"Permite crear nuevas habilidades para los roles principales.",
onSuccess: "Habilidad creada exitosamente",
onError: "Error al crear la habilidad",
},
deleted: "Habilidad eliminada",
},
mainRoleSkills: {
system: "Sistema de habilidades de rol principal",
create: {
title: "Crear habilidad de rol principal",
description:
"Permite crear nuevas habilidades para los roles principales.",
onSuccess: "Habilidad de rol principal creada exitosamente",
onError: "Error al crear la habilidad de rol principal",
},
},
version: "Versión",
};

View File

@ -35,7 +35,7 @@ onMounted(()=> {
:title="title" :title="title"
/> />
<div class="flex w-full h-screen"> <div class="flex w-full h-screen">
<div <div
id="sidebar" id="sidebar"
class="fixed w-fit h-screen transition-all duration-300 z-10" class="fixed w-fit h-screen transition-all duration-300 z-10"
:class="{'-translate-x-[16.5rem] md:-translate-x-0':sidebarStatus, '-translate-x-0 md:-translate-x-64':!sidebarStatus}" :class="{'-translate-x-[16.5rem] md:-translate-x-0':sidebarStatus, '-translate-x-0 md:-translate-x-64':!sidebarStatus}"
@ -45,9 +45,9 @@ onMounted(()=> {
@open="sidebarSwitch()" @open="sidebarSwitch()"
> >
<Section name="Principal"> <Section name="Principal">
<Link <Link
icon="home" icon="home"
name="home" name="home"
to="dashboard.index" to="dashboard.index"
/> />
<Link <Link
@ -57,7 +57,7 @@ onMounted(()=> {
/> />
</Section> </Section>
<Section name="Configuraciones"> <Section name="Configuraciones">
<Link <Link
icon="manage_accounts" icon="manage_accounts"
name="profile" name="profile"
to="profile.show" to="profile.show"
@ -69,37 +69,12 @@ onMounted(()=> {
to="dashboard.histories.index" to="dashboard.histories.index"
/> />
</Section> </Section>
<Link <Link
v-if="hasPermission('users.index')" v-if="hasPermission('users.index')"
icon="people" icon="people"
name="users.title" name="users.title"
to="admin.users.index" to="admin.users.index"
/> />
<Link
icon="business_center"
name="Departamentos"
to="admin.departments.index"
/>
<Link
icon="assignment_ind"
name="Rol Principal"
to="admin.mainRoles.index"
/>
<Link
icon="psychology"
name="Habilidades"
to="admin.skills.index"
/>
<Link
icon="leaderboard"
name="Scores"
to="admin.scores.index"
/>
<Link
icon="sports_handball"
name="Roles Puntuados"
to="admin.mainRoleSkills.index"
/>
<Link <Link
icon="history" icon="history"
name="changelogs.title" name="changelogs.title"
@ -118,7 +93,7 @@ onMounted(()=> {
</Section> </Section>
</Sidebar> </Sidebar>
</div> </div>
<div <div
class="flex flex-col w-full transition-all duration-300" class="flex flex-col w-full transition-all duration-300"
:class="{'md:w-[calc(100vw-rem)] md:ml-64':sidebarStatus, 'md:w-screen md:ml-0':!sidebarStatus}" :class="{'md:w-[calc(100vw-rem)] md:ml-64':sidebarStatus, 'md:w-screen md:ml-0':!sidebarStatus}"
> >

View File

@ -1,15 +0,0 @@
import { t } from '@/Lang/i18n';
import { hasPermission } from '@/rolePermission.js';
// Obtener ruta
const goTo = (route) => `admin.scores.${route}`
// Obtener traducción del componente
const transl = (lang) => t(`scores.${lang}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export {
can,
goTo,
transl
}

View File

@ -1,84 +0,0 @@
<script setup>
import { goTo, transl } from './Component';
import { Link, useForm } from '@inertiajs/vue3';
import PrimaryButton from '@/Components/Dashboard/Button/Primary.vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import PageHeader from '@/Components/Dashboard/PageHeader.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
defineProps({
alias: String,
value: Number,
description: String
});
const form = useForm({
alias: '',
value: '',
description: '',
});
const submit = () => form.post(route(goTo('store')), {
onSuccess: () => Notify.success(transl('create.onSuccess')),
onError: () => Notify.error(transl('create.onError')),
onFinish: () => form.reset('password')
});
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
class="btn-icon-primary"
name="arrow_back"
outline
/>
</Link>
</PageHeader>
<div class="w-full pb-8">
<div class="mt-8">
<p
v-text="transl('create.description')"
/>
</div>
</div>
<div class="w-full">
<form @submit.prevent="submit" class="grid gap-4 grid-cols-6">
<Input
id="Alias"
class="col-span-2"
v-model="form.alias"
:onError="form.errors.alias"
autofocus
required
/>
<Input
id="Valor"
class="col-span-2"
v-model="form.value"
:onError="form.errors.value"
autofocus
required
/>
<Input
id="Descrición"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"
autofocus
/>
<div class="col-span-6 flex flex-col items-center justify-end space-y-4 mt-4">
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
v-text="transl('create.title')"
/>
</div>
</form>
</div>
</DashboardLayout>
</template>

View File

@ -1,43 +0,0 @@
<script setup>
import { transl, goTo } from './Component'
import { router } from '@inertiajs/vue3';
import DestroyModal from '@/Components/Dashboard/Modal/Destroy.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
preserveScroll: true,
onSuccess: () => {
props.model.pop;
Notify.success(transl('deleted'));
emit('close');
},
onError: () => {
Notify.info(transl('notFound'));
emit('close');
}
});
</script>
<template>
<DestroyModal
:show="show"
@close="$emit('close')"
@destroy="destroy(model.id)"
>
<Header
:title="model.alias"
:subtitle="model.value"
/>
</DestroyModal>
</template>

View File

@ -1,64 +0,0 @@
<script setup>
import { goTo } from "./Component";
import { useForm } from "@inertiajs/vue3";
import { onUpdated } from "vue";
import Input from "@/Components/Dashboard/Form/Input.vue";
import EditModal from "@/Components/Dashboard/Modal/Edit.vue";
import Header from "@/Components/Dashboard/Modal/Elements/Header.vue";
const emit = defineEmits(["close", "switchModal"]);
const props = defineProps({
show: Boolean,
model: Object,
});
const form = useForm({});
const update = (id) => {
form
.transform((data) => ({
...props.model,
}))
.put(route(goTo("update"), { id }), {
preserveScroll: true,
onSuccess: () => {
Notify.success(lang("updated"));
emit("switchModal");
},
});
};
</script>
<template>
<EditModal :show="show" @close="$emit('close')" @update="update(model.id)">
<Header :title="model.alias" />
<div class="py-2 border-b">
<div class="p-4">
<form>
<div class="grid gap-6 mb-6 lg:grid-cols-2">
<Input
id="Alias"
placeholder="Alias"
v-model="model.alias"
:onError="form.errors.alias"
required
/>
<Input
id="Valor"
v-model="model.value"
:onError="form.errors.value"
required
/>
<Input
id="Descripción"
v-model="model.description"
:onError="form.errors.description"
required
/>
</div>
</form>
</div>
</div>
</EditModal>
</template>

View File

@ -1,158 +0,0 @@
<script setup>
import { transl, can, goTo } from './Component'
import { ref } from 'vue';
import { Link } from '@inertiajs/vue3';
import ModalController from '@/Controllers/ModalController.js';
import SearcherController from '@/Controllers/SearcherController.js';
import SearcherHead from '@/Components/Dashboard/Searcher.vue';
import Table from '@/Components/Dashboard/Table.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
import DestroyView from './Destroy.vue';
import EditView from './Edit.vue';
import ShowView from './Show.vue';
const props = defineProps({
scores: Object
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo('index'));
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const showModal = ref(Modal.showModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link
v-if="can('create')"
:href="route(goTo('create'))"
>
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="scores"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th
class="table-item"
v-text="$t('Alias')"
/>
<th
class="table-item"
v-text="$t('Valor')"
/>
<th
class="table-item"
v-text="$t('Descripción')"
/>
<th
class="table-item w-44"
v-text="$t('actions')"
/>
</template>
<template #body="{items}">
<tr v-for="model in items">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.alias }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.value }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.description }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
:title="$t('crud.show')"
class="btn-icon-primary"
name="visibility"
outline
@click="Modal.switchShowModal(model)"
/>
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t('registers.empty') }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
/>
</DashboardLayout>
</template>

View File

@ -1,41 +0,0 @@
<script setup>
import { can } from './Component'
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
import ShowModal from '@/Components/Dashboard/Modal/Show.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
defineEmits([
'close',
'switchModal'
]);
defineProps({
show: Boolean,
model: Object
});
</script>
<template>
<ShowModal
:show="show"
:editable="can('edit')"
@close="$emit('close')"
@edit="$emit('switchModal')"
editable
>
<Header
:title="model.alias"
>
</Header>
<div class="py-2 border-b">
<div class="px-4 py-2 flex">
<GoogleIcon
class="text-xl text-success"
name="contact_mail"
/>
<div class="pl-3">
</div>
</div>
</div>
</ShowModal>
</template>

View File

@ -1,15 +0,0 @@
import { t } from '@/Lang/i18n';
import { hasPermission } from '@/rolePermission.js';
// Obtener ruta
const goTo = (route) => `admin.departments.${route}`
// Obtener traducción del componente
const transl = (lang) => t(`department.${lang}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export {
can,
goTo,
transl
}

View File

@ -1,73 +0,0 @@
<script setup>
import { goTo, transl } from './Component';
import { Link, useForm } from '@inertiajs/vue3';
import PrimaryButton from '@/Components/Dashboard/Button/Primary.vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import PageHeader from '@/Components/Dashboard/PageHeader.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
defineProps({
name: String,
description: String
});
const form = useForm({
name: '',
description: '',
});
const submit = () => form.post(route(goTo('store')), {
onSuccess: () => Notify.success(transl('create.onSuccess')),
onError: () => Notify.error(transl('create.onError')),
});
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
class="btn-icon-primary"
name="arrow_back"
outline
/>
</Link>
</PageHeader>
<div class="w-full pb-8">
<div class="mt-8">
<p
v-text="transl('create.description')"
/>
</div>
</div>
<div class="w-full">
<form @submit.prevent="submit" class="grid gap-4 grid-cols-6">
<Input
id="Nombre"
class="col-span-2"
v-model="form.name"
:onError="form.errors.name"
autofocus
required
/>
<Input
id="Descrición"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"
autofocus
/>
<div class="col-span-6 flex flex-col items-center justify-end space-y-4 mt-4">
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
v-text="transl('create.title')"
/>
</div>
</form>
</div>
</DashboardLayout>
</template>

View File

@ -1,43 +0,0 @@
<script setup>
import { transl, goTo } from './Component'
import { router } from '@inertiajs/vue3';
import DestroyModal from '@/Components/Dashboard/Modal/Destroy.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
preserveScroll: true,
onSuccess: () => {
props.model.pop;
Notify.success(transl('deleted'));
emit('close');
},
onError: () => {
Notify.info(transl('notFound'));
emit('close');
}
});
</script>
<template>
<DestroyModal
:show="show"
@close="$emit('close')"
@destroy="destroy(model.id)"
>
<Header
:title="model.name"
:subtitle="model.description"
/>
</DestroyModal>
</template>

View File

@ -1,67 +0,0 @@
<script setup>
import { goTo } from './Component';
import { useForm } from '@inertiajs/vue3';
import { onUpdated } from 'vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const form = useForm({});
const update = (id) => {
form.transform(data => ({
...props.model
})).put(route(goTo('update'), {id}),{
preserveScroll: true,
onSuccess: () => {
Notify.success(lang('updated'))
emit('switchModal')
}
});
}
</script>
<template>
<EditModal
:show="show"
@close="$emit('close')"
@update="update(model.id)"
>
<Header
:title="model.name"
/>
<div class="py-2 border-b">
<div class="p-4">
<form>
<div class="grid gap-6 mb-6 lg:grid-cols-2">
<Input
id="Nombre"
placeholder="name"
v-model="model.name"
:onError="form.errors.name"
required
/>
<Input
id="Descripción"
v-model="model.description"
:onError="form.errors.description"
required
/>
</div>
</form>
</div>
</div>
</EditModal>
</template>

View File

@ -1,137 +0,0 @@
<script setup>
import { transl, can, goTo } from './Component'
import { ref } from 'vue';
import { Link } from '@inertiajs/vue3';
import ModalController from '@/Controllers/ModalController.js';
import SearcherController from '@/Controllers/SearcherController.js';
import SearcherHead from '@/Components/Dashboard/Searcher.vue';
import Table from '@/Components/Dashboard/Table.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
import DestroyView from './Destroy.vue';
import EditView from './Edit.vue';
import ShowView from './Show.vue';
const props = defineProps({
departments: Object
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo('index'));
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const showModal = ref(Modal.showModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link
v-if="can('create')"
:href="route(goTo('create'))"
>
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="departments"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th
class="table-item"
v-text="$t('Nombre')"
/>
<th
class="table-item"
v-text="$t('Descripción')"
/>
<th
class="table-item w-44"
v-text="$t('actions')"
/>
</template>
<template #body="{items}">
<tr v-for="model in items">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.description }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t('registers.empty') }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
/>
</DashboardLayout>
</template>

View File

@ -1,41 +0,0 @@
<script setup>
import { can } from './Component'
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
import ShowModal from '@/Components/Dashboard/Modal/Show.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
defineEmits([
'close',
'switchModal'
]);
defineProps({
show: Boolean,
model: Object
});
</script>
<template>
<ShowModal
:show="show"
:editable="can('edit')"
@close="$emit('close')"
@edit="$emit('switchModal')"
editable
>
<Header
:title="model.alias"
>
</Header>
<div class="py-2 border-b">
<div class="px-4 py-2 flex">
<GoogleIcon
class="text-xl text-success"
name="contact_mail"
/>
<div class="pl-3">
</div>
</div>
</div>
</ShowModal>
</template>

View File

@ -1,15 +0,0 @@
import { t } from '@/Lang/i18n';
import { hasPermission } from '@/rolePermission.js';
// Obtener ruta
const goTo = (route) => `admin.mainRoles.${route}`
// Obtener traducción del componente
const transl = (lang) => t(`mainRole.${lang}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export {
can,
goTo,
transl
}

View File

@ -1,89 +0,0 @@
<script setup>
import { goTo, transl } from "./Component";
import { Link, useForm } from "@inertiajs/vue3";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import Input from "@/Components/Dashboard/Form/Input.vue";
import PageHeader from "@/Components/Dashboard/PageHeader.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
defineProps({
departments: Object,
});
const form = useForm({
name: "",
description: "",
department_id: "",
});
const submit = () =>
form
.transform((data) => ({
...data,
department_id: form.department_id?.id,
}))
.post(route(goTo("store")), {
onSuccess: () => Notify.success(transl("create.onSuccess")),
onError: () => Notify.error(transl("create.onError")),
});
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
class="btn-icon-primary"
name="arrow_back"
outline
/>
</Link>
</PageHeader>
<div class="w-full pb-8">
<div class="mt-8">
<p v-text="transl('create.description')" />
</div>
</div>
<div class="w-full">
<form @submit.prevent="submit" class="grid gap-4 grid-cols-6">
<Input
id="Nombre"
class="col-span-2"
v-model="form.name"
:onError="form.errors.name"
autofocus
required
/>
<Input
id="Descrición"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"
autofocus
/>
<Selectable
id="department_id"
class="col-span-3"
v-model="form.department_id"
:options="departments"
:onError="form.errors.department_id"
:title="$t('department.title')"
required
/>
<div
class="col-span-6 flex flex-col items-center justify-end space-y-4 mt-4"
>
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
v-text="transl('create.title')"
/>
</div>
</form>
</div>
</DashboardLayout>
</template>

View File

@ -1,43 +0,0 @@
<script setup>
import { transl, goTo } from './Component'
import { router } from '@inertiajs/vue3';
import DestroyModal from '@/Components/Dashboard/Modal/Destroy.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
preserveScroll: true,
onSuccess: () => {
props.model.pop;
Notify.success(transl('deleted'));
emit('close');
},
onError: () => {
Notify.info(transl('notFound'));
emit('close');
}
});
</script>
<template>
<DestroyModal
:show="show"
@close="$emit('close')"
@destroy="destroy(model.id)"
>
<Header
:title="model.name"
:subtitle="model.description"
/>
</DestroyModal>
</template>

View File

@ -1,67 +0,0 @@
<script setup>
import { goTo } from './Component';
import { useForm } from '@inertiajs/vue3';
import { onUpdated } from 'vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const form = useForm({});
const update = (id) => {
form.transform(data => ({
...props.model
})).put(route(goTo('update'), {id}),{
preserveScroll: true,
onSuccess: () => {
Notify.success(lang('updated'))
emit('switchModal')
}
});
}
</script>
<template>
<EditModal
:show="show"
@close="$emit('close')"
@update="update(model.id)"
>
<Header
:title="model.name"
/>
<div class="py-2 border-b">
<div class="p-4">
<form>
<div class="grid gap-6 mb-6 lg:grid-cols-2">
<Input
id="Nombre"
placeholder="name"
v-model="model.name"
:onError="form.errors.name"
required
/>
<Input
id="Descripción"
v-model="model.description"
:onError="form.errors.description"
required
/>
</div>
</form>
</div>
</div>
</EditModal>
</template>

View File

@ -1,151 +0,0 @@
<script setup>
import { transl, can, goTo } from './Component'
import { ref } from 'vue';
import { Link } from '@inertiajs/vue3';
import ModalController from '@/Controllers/ModalController.js';
import SearcherController from '@/Controllers/SearcherController.js';
import SearcherHead from '@/Components/Dashboard/Searcher.vue';
import Table from '@/Components/Dashboard/Table.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
import DestroyView from './Destroy.vue';
import EditView from './Edit.vue';
import ShowView from './Show.vue';
const props = defineProps({
mainRoles: Object
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo('index'));
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const showModal = ref(Modal.showModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link
v-if="can('create')"
:href="route(goTo('create'))"
>
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="mainRoles"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th
class="table-item"
v-text="$t('Nombre')"
/>
<th
class="table-item"
v-text="$t('Descripción')"
/>
<th
class="table-item"
v-text="$t('Departamento')"
/>
<th
class="table-item w-44"
v-text="$t('actions')"
/>
</template>
<template #body="{items}">
<tr v-for="model in items">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.description }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.department?.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t('registers.empty') }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
/>
</DashboardLayout>
</template>

View File

@ -1,41 +0,0 @@
<script setup>
import { can } from './Component'
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
import ShowModal from '@/Components/Dashboard/Modal/Show.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
defineEmits([
'close',
'switchModal'
]);
defineProps({
show: Boolean,
model: Object
});
</script>
<template>
<ShowModal
:show="show"
:editable="can('edit')"
@close="$emit('close')"
@edit="$emit('switchModal')"
editable
>
<Header
:title="model.alias"
>
</Header>
<div class="py-2 border-b">
<div class="px-4 py-2 flex">
<GoogleIcon
class="text-xl text-success"
name="contact_mail"
/>
<div class="pl-3">
</div>
</div>
</div>
</ShowModal>
</template>

View File

@ -1,15 +0,0 @@
import { t } from '@/Lang/i18n';
import { hasPermission } from '@/rolePermission.js';
// Obtener ruta
const goTo = (route) => `admin.mainRoleSkills.${route}`
// Obtener traducción del componente
const transl = (lang) => t(`mainRoleSkills.${lang}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export{
can,
goTo,
transl
}

View File

@ -1,163 +0,0 @@
<script setup>
import { goTo, transl } from "./Component";
import { Link, useForm } from "@inertiajs/vue3";
import { ref, computed } from "vue";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import SecondaryButton from "@/Components/Dashboard/Button/Secondary.vue";
import PageHeader from "@/Components/Dashboard/PageHeader.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
// Componentes específicos para el flujo
import StepIndicator from "@/Components/App/StepIndicator.vue";
import DepartmentSelector from "@/Components/App/DepartmentSelector.vue";
import MainRoleSelector from "@/Components/App/MainRoleSelector.vue";
import SkillAssignment from "@/Components/App/SkillAssignment.vue";
const props = defineProps({
mainRoles: Object,
skills: Object,
scores: Object,
});
// Estado del flujo
const currentStep = ref(1);
const selectedDepartment = ref(null);
const selectedMainRole = ref(null);
const form = useForm({
main_role_id: "",
skill_id: "",
scored_id: "",
});
// Datos computados
const uniqueDepartments = computed(() => {
const deps = [];
const seen = new Set();
props.mainRoles.forEach((role) => {
if (role.department && !seen.has(role.department.id)) {
seen.add(role.department.id);
deps.push(role.department);
}
});
return deps;
});
// Métodos de navegación
const handleDepartmentSelect = (department) => {
selectedDepartment.value = department;
currentStep.value = 2;
};
const handleMainRoleSelect = (mainRole) => {
selectedMainRole.value = mainRole;
form.main_role_id = mainRole.id;
currentStep.value = 3;
};
const goBack = () => {
if (currentStep.value === 3) {
selectedMainRole.value = null;
form.main_role_id = "";
form.skill_id = "";
form.scored_id = "";
currentStep.value = 2;
} else if (currentStep.value === 2) {
selectedDepartment.value = null;
selectedMainRole.value = null;
form.reset();
currentStep.value = 1;
}
};
const resetFlow = () => {
selectedDepartment.value = null;
selectedMainRole.value = null;
form.reset();
currentStep.value = 1;
};
const submit = (skillArray) => {
const skillsData = skillArray.map(skill => ({
skill_id: skill.skill_id,
scored_id: skill.scored_id,
}));
form
.transform((data) => ({
main_role_id: data.main_role_id,
skills: skillsData
}))
.post(route(goTo("store")), {
onSuccess: () => {
Notify.success(transl("create.onSuccess"));
resetFlow();
},
onError: () => Notify.error(transl("create.onError")),
});
};
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<div class="flex items-center space-x-2">
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
class="btn-icon-primary"
name="arrow_back"
outline
/>
</Link>
</div>
</PageHeader>
<!-- Indicador de progreso componentizado -->
<div class="mt-6">
<StepIndicator :current-step="currentStep" />
<div class="flex justify-center gap-2">
<SecondaryButton v-if="currentStep > 1" @click="goBack" type="button">
<GoogleIcon name="keyboard_backspace" class="mr-2" />
{{ $t("Regresar") }}
</SecondaryButton>
<SecondaryButton
v-if="currentStep > 1"
@click="resetFlow"
type="button"
>
<GoogleIcon name="refresh" class="mr-2" />
{{ $t("Inicio") }}
</SecondaryButton>
</div>
</div>
<!-- Componentes de pasos -->
<DepartmentSelector
v-if="currentStep === 1"
:departments="uniqueDepartments"
@select="handleDepartmentSelect"
/>
<MainRoleSelector
v-if="currentStep === 2"
:main-roles="mainRoles"
:selected-department="selectedDepartment"
@select="handleMainRoleSelect"
/>
<SkillAssignment
v-if="currentStep === 3"
:form="form"
:skills="skills"
:scores="scores"
:selected-department="selectedDepartment"
:selected-main-role="selectedMainRole"
@submit="submit"
/>
</DashboardLayout>
</template>

View File

@ -1,43 +0,0 @@
<script setup>
import { transl, goTo } from './Component'
import { router } from '@inertiajs/vue3';
import DestroyModal from '@/Components/Dashboard/Modal/Destroy.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
preserveScroll: true,
onSuccess: () => {
props.model.pop;
Notify.success(transl('deleted'));
emit('close');
},
onError: () => {
Notify.info(transl('notFound'));
emit('close');
}
});
</script>
<template>
<DestroyModal
:show="show"
@close="$emit('close')"
@destroy="destroy(model.id)"
>
<Header
:title="model.name"
:subtitle="model.description"
/>
</DestroyModal>
</template>

View File

@ -1,67 +0,0 @@
<script setup>
import { goTo } from './Component';
import { useForm } from '@inertiajs/vue3';
import { onUpdated } from 'vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const form = useForm({});
const update = (id) => {
form.transform(data => ({
...props.model
})).put(route(goTo('update'), {id}),{
preserveScroll: true,
onSuccess: () => {
Notify.success(lang('updated'))
emit('switchModal')
}
});
}
</script>
<template>
<EditModal
:show="show"
@close="$emit('close')"
@update="update(model.id)"
>
<Header
:title="model.name"
/>
<div class="py-2 border-b">
<div class="p-4">
<form>
<div class="grid gap-6 mb-6 lg:grid-cols-2">
<Input
id="Nombre"
placeholder="name"
v-model="model.name"
:onError="form.errors.name"
required
/>
<Input
id="Descripción"
v-model="model.description"
:onError="form.errors.description"
required
/>
</div>
</form>
</div>
</div>
</EditModal>
</template>

View File

@ -1,146 +0,0 @@
<script setup>
import { transl, can, goTo } from "./Component";
import { ref, computed } from "vue";
import { Link } from "@inertiajs/vue3";
import ModalController from "@/Controllers/ModalController.js";
import SearcherController from "@/Controllers/SearcherController.js";
import SearcherHead from "@/Components/Dashboard/Searcher.vue";
import Table from "@/Components/Dashboard/Table.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
import DestroyView from "./Destroy.vue";
import EditView from "./Edit.vue";
const props = defineProps({
mainRoleSkills: Object,
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo("index"));
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
const groupedRoles = computed(() => {
const groups = {};
props.mainRoleSkills.data?.forEach(item => {
const key = item.main_role?.id;
if(!groups[key]) groups[key] = { ...item, skills: []};
groups[key].skills.push(item);
})
return Object.values(groups);
});
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link v-if="can('create')" :href="route(goTo('create'))">
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="mainRoleSkills"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th class="table-item" v-text="$t('Departamento')" />
<th class="table-item" v-text="$t('Rol Principal')" />
<th class="table-item" v-text="$t('Habilidades Puntuadas')" />
<th class="table-item w-44" v-text="$t('actions')" />
</template>
<template #body="{ items }">
<tr v-for="group in groupedRoles" :key="group.main_role.id">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ group.main_role?.department?.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ group.main_role?.name }}
</p>
</div>
</div>
</td>
<div>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p v-for="skill in group.skills" :key="skill.id" class="font-semibold">
{{ skill.skill?.name }} - {{ skill.score?.alias }}
</p>
</div>
</div>
</td>
</div>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t("registers.empty") }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
/>
</DashboardLayout>
</template>

View File

@ -1,15 +0,0 @@
import { t } from '@/Lang/i18n';
import { hasPermission } from '@/rolePermission.js';
// Obtener ruta
const goTo = (route) => `admin.skills.${route}`
// Obtener traducción del componente
const transl = (lang) => t(`skill.${lang}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export{
can,
goTo,
transl
}

View File

@ -1,89 +0,0 @@
<script setup>
import { goTo, transl } from "./Component";
import { Link, useForm } from "@inertiajs/vue3";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import Input from "@/Components/Dashboard/Form/Input.vue";
import PageHeader from "@/Components/Dashboard/PageHeader.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
defineProps({
departments: Object,
});
const form = useForm({
name: "",
description: "",
department_id: "",
});
const submit = () =>
form
.transform((data) => ({
...data,
department_id: form.department_id?.id,
}))
.post(route(goTo("store")), {
onSuccess: () => Notify.success(transl("create.onSuccess")),
onError: () => Notify.error(transl("create.onError")),
});
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
class="btn-icon-primary"
name="arrow_back"
outline
/>
</Link>
</PageHeader>
<div class="w-full pb-8">
<div class="mt-8">
<p v-text="transl('create.description')" />
</div>
</div>
<div class="w-full">
<form @submit.prevent="submit" class="grid gap-4 grid-cols-6">
<Input
id="Nombre"
class="col-span-2"
v-model="form.name"
:onError="form.errors.name"
autofocus
required
/>
<Input
id="Descrición"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"
autofocus
/>
<Selectable
id="department_id"
class="col-span-3"
v-model="form.department_id"
:options="departments"
:onError="form.errors.department_id"
:title="$t('department.title')"
required
/>
<div
class="col-span-6 flex flex-col items-center justify-end space-y-4 mt-4"
>
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
v-text="transl('create.title')"
/>
</div>
</form>
</div>
</DashboardLayout>
</template>

View File

@ -1,43 +0,0 @@
<script setup>
import { transl, goTo } from './Component'
import { router } from '@inertiajs/vue3';
import DestroyModal from '@/Components/Dashboard/Modal/Destroy.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
preserveScroll: true,
onSuccess: () => {
props.model.pop;
Notify.success(transl('deleted'));
emit('close');
},
onError: () => {
Notify.info(transl('notFound'));
emit('close');
}
});
</script>
<template>
<DestroyModal
:show="show"
@close="$emit('close')"
@destroy="destroy(model.id)"
>
<Header
:title="model.name"
:subtitle="model.description"
/>
</DestroyModal>
</template>

View File

@ -1,67 +0,0 @@
<script setup>
import { goTo } from './Component';
import { useForm } from '@inertiajs/vue3';
import { onUpdated } from 'vue';
import Input from '@/Components/Dashboard/Form/Input.vue';
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
const emit = defineEmits([
'close',
'switchModal'
]);
const props = defineProps({
show: Boolean,
model: Object
});
const form = useForm({});
const update = (id) => {
form.transform(data => ({
...props.model
})).put(route(goTo('update'), {id}),{
preserveScroll: true,
onSuccess: () => {
Notify.success(lang('updated'))
emit('switchModal')
}
});
}
</script>
<template>
<EditModal
:show="show"
@close="$emit('close')"
@update="update(model.id)"
>
<Header
:title="model.name"
/>
<div class="py-2 border-b">
<div class="p-4">
<form>
<div class="grid gap-6 mb-6 lg:grid-cols-2">
<Input
id="Nombre"
placeholder="name"
v-model="model.name"
:onError="form.errors.name"
required
/>
<Input
id="Descripción"
v-model="model.description"
:onError="form.errors.description"
required
/>
</div>
</form>
</div>
</div>
</EditModal>
</template>

View File

@ -1,149 +0,0 @@
<script setup>
import { transl, can, goTo } from './Component'
import { ref } from 'vue';
import { Link } from '@inertiajs/vue3';
import ModalController from '@/Controllers/ModalController.js';
import SearcherController from '@/Controllers/SearcherController.js';
import SearcherHead from '@/Components/Dashboard/Searcher.vue';
import Table from '@/Components/Dashboard/Table.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
import DestroyView from './Destroy.vue';
import EditView from './Edit.vue';
const props = defineProps({
skills: Object
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo('index'));
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link
v-if="can('create')"
:href="route(goTo('create'))"
>
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="skills"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th
class="table-item"
v-text="$t('Nombre')"
/>
<th
class="table-item"
v-text="$t('Descripción')"
/>
<th
class="table-item"
v-text="$t('Departamento')"
/>
<th
class="table-item w-44"
v-text="$t('actions')"
/>
</template>
<template #body="{items}">
<tr v-for="model in items">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.description }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ model.department?.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t('registers.empty') }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
/>
</DashboardLayout>
</template>

View File

@ -1,28 +1,23 @@
<?php <?php
use App\Http\Controllers\Admin\ScoreController;
use App\Http\Controllers\Admin\UserController; use App\Http\Controllers\Admin\UserController;
use App\Http\Controllers\Dashboard\HistoryLogController; use App\Http\Controllers\Dashboard\HistoryLogController;
use App\Http\Controllers\Dashboard\IndexController; use App\Http\Controllers\Dashboard\IndexController;
use App\Http\Controllers\Dashboard\NotificationController; use App\Http\Controllers\Dashboard\NotificationController;
use App\Http\Controllers\Admin\DepartmentController;
use App\Http\Controllers\Admin\MainRoleController;
use App\Http\Controllers\Admin\MainRoleSkillsController;
use App\Http\Controllers\Admin\SkillController;
use App\Http\Controllers\Developer\RoleController; use App\Http\Controllers\Developer\RoleController;
use App\Http\Controllers\Example\IndexController as ExampleIndexController; use App\Http\Controllers\Example\IndexController as ExampleIndexController;
use App\Models\MainRoleSkills;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
/** /**
* Rutas generales/publicas * Rutas generales/publicas
* *
* Rutas accesibles por todos los usuarios y no usuarios * Rutas accesibles por todos los usuarios y no usuarios
*/ */
Route::redirect('/', '/login'); Route::redirect('/', '/login');
/** /**
* Rutas del Dashboard * Rutas del Dashboard
* *
* El dashboard es el panel de los usuarios de forma general * El dashboard es el panel de los usuarios de forma general
*/ */
Route::prefix('dashboard')->name('dashboard.')->middleware([ Route::prefix('dashboard')->name('dashboard.')->middleware([
@ -49,7 +44,7 @@
/** /**
* Rutas de administrador * Rutas de administrador
* *
* Estas ubicaciones son del administrador, sin embargo el desarrollador * Estas ubicaciones son del administrador, sin embargo el desarrollador
* puede acceder a ellas. * puede acceder a ellas.
*/ */
@ -58,11 +53,6 @@
config('jetstream.auth_session') config('jetstream.auth_session')
])->group(function () { ])->group(function () {
Route::resource('users', UserController::class); Route::resource('users', UserController::class);
Route::resource('scores', ScoreController::class);
Route::resource('departments', DepartmentController::class);
Route::resource('mainRoles', MainRoleController::class);
Route::resource('skills', SkillController::class);
Route::resource('mainRoleSkills', MainRoleSkillsController::class);
Route::prefix('/users')->name('users.')->group(function() Route::prefix('/users')->name('users.')->group(function()
{ {
@ -74,7 +64,7 @@
/** /**
* Rutas solo del desarrollador * Rutas solo del desarrollador
* *
* Son ubicaciones o funciones que pueden llegar a ser muy sensibles en el sistema, por lo que * Son ubicaciones o funciones que pueden llegar a ser muy sensibles en el sistema, por lo que
* solo el desarrollador debe de ser capaz de modificarlas o actualizarlas. * solo el desarrollador debe de ser capaz de modificarlas o actualizarlas.
*/ */
@ -87,9 +77,9 @@
/** /**
* Elementos de la plantilla * Elementos de la plantilla
* *
* Estos son elementos que existen y pueden ser usados en la plantilla, vienen ejemplos de uso. * Estos son elementos que existen y pueden ser usados en la plantilla, vienen ejemplos de uso.
* *
* Estas rutas pueden ser comentadas o eliminadas cuando se finalice un proyecto. Por default estan ocultas * Estas rutas pueden ser comentadas o eliminadas cuando se finalice un proyecto. Por default estan ocultas
* en el dashboard. * en el dashboard.
*/ */
@ -99,4 +89,4 @@
config('jetstream.auth_session') config('jetstream.auth_session')
])->group(function () { ])->group(function () {
Route::get('/', [ExampleIndexController::class, 'index'])->name('index'); Route::get('/', [ExampleIndexController::class, 'index'])->name('index');
}); });