#20 - wip
This commit is contained in:
		
							
								
								
									
										36
									
								
								app/Enums/VacationType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Enums/VacationType.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Enums; | ||||||
|  |  | ||||||
|  | enum VacationType: string | ||||||
|  | { | ||||||
|  |     case VACATION = "vacation"; | ||||||
|  |     case VACATION_ON_REQUEST = "vacation_on_request"; | ||||||
|  |     case SPECIAL_VACATION = "special_vacation"; | ||||||
|  |     case CHILDCARE_VACATION = "childcare_vacation"; | ||||||
|  |     case TRAINING_VACATION = "training_vacation"; | ||||||
|  |     case UNPAID_VACATION = "unpaid_vacation"; | ||||||
|  |     case VOLUNTEERING_VACATION = "volunteering_vacation"; | ||||||
|  |     case LOOK_FOR_WORK_VACATION = "look_for_work_vacation"; | ||||||
|  |     case TIME_IN_LIEU = "time_in_lieu"; | ||||||
|  |     case SICK_VACATION = "sick_vacation"; | ||||||
|  |  | ||||||
|  |     public function label(): string | ||||||
|  |     { | ||||||
|  |         return __($this->value); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function casesToSelect(): array | ||||||
|  |     { | ||||||
|  |         $cases = collect(VacationType::cases()); | ||||||
|  |  | ||||||
|  |         return $cases->map( | ||||||
|  |             fn(VacationType $enum) => [ | ||||||
|  |                 "label" => $enum->label(), | ||||||
|  |                 "value" => $enum->value, | ||||||
|  |             ], | ||||||
|  |         )->toArray(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								app/Helpers/Rules/MinimumOneVacationDayRule.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Helpers/Rules/MinimumOneVacationDayRule.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Helpers\Rules; | ||||||
|  |  | ||||||
|  | use Closure; | ||||||
|  | use Toby\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class MinimumOneVacationDayRule | ||||||
|  | { | ||||||
|  |     public function check(VacationRequest $vacationRequest, Closure $next) | ||||||
|  |     { | ||||||
|  |         return $next($vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								app/Helpers/Rules/PendingVacationRequestInSameRange.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Helpers/Rules/PendingVacationRequestInSameRange.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Helpers\Rules; | ||||||
|  |  | ||||||
|  | use Closure; | ||||||
|  | use Toby\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class PendingVacationRequestInSameRange | ||||||
|  | { | ||||||
|  |     public function check(VacationRequest $vacationRequest, Closure $next) | ||||||
|  |     { | ||||||
|  |         return $next($vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								app/Helpers/Rules/UsedVacationDaysInSameRange.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Helpers/Rules/UsedVacationDaysInSameRange.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Helpers\Rules; | ||||||
|  |  | ||||||
|  | use Closure; | ||||||
|  | use Toby\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class UsedVacationDaysInSameRange | ||||||
|  | { | ||||||
|  |     public function check(VacationRequest $vacationRequest, Closure $next) | ||||||
|  |     { | ||||||
|  |         return $next($vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								app/Helpers/VacationRequestValidator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Helpers/VacationRequestValidator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Helpers; | ||||||
|  |  | ||||||
|  | use Illuminate\Contracts\Pipeline\Pipeline; | ||||||
|  | use Toby\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class VacationRequestValidator | ||||||
|  | { | ||||||
|  |     protected array $rules = [ | ||||||
|  |  | ||||||
|  |     ]; | ||||||
|  |  | ||||||
|  |     public function __construct(protected Pipeline $pipeline) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function validate(VacationRequest $vacationRequest): void | ||||||
|  |     { | ||||||
|  |         $this->pipeline | ||||||
|  |             ->send($vacationRequest) | ||||||
|  |             ->through($this->rules) | ||||||
|  |             ->via("check") | ||||||
|  |             ->then(fn(VacationRequest $vacationRequest) => $vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								app/Http/Controllers/VacationRequestController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Http/Controllers/VacationRequestController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Http\Controllers; | ||||||
|  |  | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use Inertia\Response; | ||||||
|  | use Toby\Enums\VacationType; | ||||||
|  | use Toby\Http\Resources\VacationRequestResource; | ||||||
|  |  | ||||||
|  | class VacationRequestController extends Controller | ||||||
|  | { | ||||||
|  |     public function index(Request $request): Response | ||||||
|  |     { | ||||||
|  |         $requests = $request->user() | ||||||
|  |             ->vacationRequests() | ||||||
|  |             ->paginate(); | ||||||
|  |  | ||||||
|  |         return inertia("VacationRequest/Index", [ | ||||||
|  |             "requests" => VacationRequestResource::collection($requests), | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function create(): Response | ||||||
|  |     { | ||||||
|  |         return inertia("VacationRequest/Create", [ | ||||||
|  |             "vacationTypes" => VacationType::casesToSelect(), | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -23,6 +23,7 @@ use Illuminate\Routing\Middleware\ValidateSignature; | |||||||
| use Illuminate\Session\Middleware\AuthenticateSession; | use Illuminate\Session\Middleware\AuthenticateSession; | ||||||
| use Illuminate\Session\Middleware\StartSession; | use Illuminate\Session\Middleware\StartSession; | ||||||
| use Illuminate\View\Middleware\ShareErrorsFromSession; | use Illuminate\View\Middleware\ShareErrorsFromSession; | ||||||
|  | use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; | ||||||
| use Toby\Http\Middleware\Authenticate; | use Toby\Http\Middleware\Authenticate; | ||||||
| use Toby\Http\Middleware\HandleInertiaRequests; | use Toby\Http\Middleware\HandleInertiaRequests; | ||||||
| use Toby\Http\Middleware\RedirectIfAuthenticated; | use Toby\Http\Middleware\RedirectIfAuthenticated; | ||||||
| @@ -52,6 +53,7 @@ class Kernel extends HttpKernel | |||||||
|             HandleInertiaRequests::class, |             HandleInertiaRequests::class, | ||||||
|         ], |         ], | ||||||
|         "api" => [ |         "api" => [ | ||||||
|  |             EnsureFrontendRequestsAreStateful::class, | ||||||
|             "throttle:api", |             "throttle:api", | ||||||
|             SubstituteBindings::class, |             SubstituteBindings::class, | ||||||
|         ], |         ], | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								app/Http/Requests/VacationRequestRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/Http/Requests/VacationRequestRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Http\Requests; | ||||||
|  |  | ||||||
|  | use Illuminate\Foundation\Http\FormRequest; | ||||||
|  | use Illuminate\Validation\Rules\Enum; | ||||||
|  | use Toby\Enums\VacationType; | ||||||
|  | use Toby\Rules\YearPeriodExists; | ||||||
|  |  | ||||||
|  | class VacationRequestRequest extends FormRequest | ||||||
|  | { | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             "type" => ["required", new Enum(VacationType::class)], | ||||||
|  |             "from" => ["required", "date_format:Y-m-d", new YearPeriodExists()], | ||||||
|  |             "to" => ["required", "date_format:Y-m-d", new YearPeriodExists()], | ||||||
|  |             "comment" => ["nullable"], | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function data(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             "type" => $this->get("type"), | ||||||
|  |             "from" => $this->get("from"), | ||||||
|  |             "to" => $this->get("to"), | ||||||
|  |             "comment" => $this->get("comment"), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -15,6 +15,7 @@ class HolidayResource extends JsonResource | |||||||
|         return [ |         return [ | ||||||
|             "id" => $this->id, |             "id" => $this->id, | ||||||
|             "name" => $this->name, |             "name" => $this->name, | ||||||
|  |             "date" => $this->date->toDateString(), | ||||||
|             "displayDate" => $this->date->toDisplayString(), |             "displayDate" => $this->date->toDisplayString(), | ||||||
|             "dayOfWeek" => $this->date->dayName, |             "dayOfWeek" => $this->date->dayName, | ||||||
|         ]; |         ]; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ class UserFormDataResource extends JsonResource | |||||||
|             "lastName" => $this->last_name, |             "lastName" => $this->last_name, | ||||||
|             "email" => $this->email, |             "email" => $this->email, | ||||||
|             "employmentForm" => $this->employment_form, |             "employmentForm" => $this->employment_form, | ||||||
|             "employmentDate" => $this->employment_date, |             "employmentDate" => $this->employment_date->toDateString(), | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								app/Http/Resources/VacationRequestResource.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/Http/Resources/VacationRequestResource.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Http\Resources; | ||||||
|  |  | ||||||
|  | use Illuminate\Http\Resources\Json\JsonResource; | ||||||
|  |  | ||||||
|  | class VacationRequestResource extends JsonResource | ||||||
|  | { | ||||||
|  |     public static $wrap = null; | ||||||
|  |  | ||||||
|  |     public function toArray($request): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             "id" => $this->id, | ||||||
|  |             "user" => new UserResource($this->user), | ||||||
|  |             "type" => $this->type->label(), | ||||||
|  |             "from" => $this->from->toDisplayString(), | ||||||
|  |             "to" => $this->to->toDisplayString(), | ||||||
|  |             "commment" => $this->comment, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -23,6 +23,7 @@ use Toby\Enums\EmploymentForm; | |||||||
|  * @property EmploymentForm $employment_form |  * @property EmploymentForm $employment_form | ||||||
|  * @property Carbon $employment_date |  * @property Carbon $employment_date | ||||||
|  * @property Collection $vacationLimits |  * @property Collection $vacationLimits | ||||||
|  |  * @property Collection $vacationRequests | ||||||
|  */ |  */ | ||||||
| class User extends Authenticatable | class User extends Authenticatable | ||||||
| { | { | ||||||
| @@ -46,6 +47,11 @@ class User extends Authenticatable | |||||||
|         return $this->hasMany(VacationLimit::class); |         return $this->hasMany(VacationLimit::class); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function vacationRequests(): HasMany | ||||||
|  |     { | ||||||
|  |         return $this->hasMany(VacationRequest::class); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function scopeSearch(Builder $query, ?string $text): Builder |     public function scopeSearch(Builder $query, ?string $text): Builder | ||||||
|     { |     { | ||||||
|         if ($text === null) { |         if ($text === null) { | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								app/Models/VacationRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/Models/VacationRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Toby\Models; | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Eloquent\Factories\HasFactory; | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  | use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||||
|  | use Illuminate\Support\Carbon; | ||||||
|  | use Toby\Enums\VacationType; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @property int $id | ||||||
|  |  * @property VacationType $type | ||||||
|  |  * @property Carbon $from | ||||||
|  |  * @property Carbon $to | ||||||
|  |  * @property string $comment | ||||||
|  |  * @property User $user | ||||||
|  |  */ | ||||||
|  | class VacationRequest extends Model | ||||||
|  | { | ||||||
|  |     use HasFactory; | ||||||
|  |  | ||||||
|  |     protected $casts = [ | ||||||
|  |         "type" => VacationType::class, | ||||||
|  |         "from" => "date", | ||||||
|  |         "to" => "date", | ||||||
|  |     ]; | ||||||
|  |  | ||||||
|  |     public function user(): BelongsTo | ||||||
|  |     { | ||||||
|  |         return $this->belongsTo(User::class); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -12,6 +12,7 @@ | |||||||
|         "guzzlehttp/guzzle": "^7.0.1", |         "guzzlehttp/guzzle": "^7.0.1", | ||||||
|         "inertiajs/inertia-laravel": "^0.5.1", |         "inertiajs/inertia-laravel": "^0.5.1", | ||||||
|         "laravel/framework": "^8.75", |         "laravel/framework": "^8.75", | ||||||
|  |         "laravel/sanctum": "^2.14", | ||||||
|         "laravel/socialite": "^5.2", |         "laravel/socialite": "^5.2", | ||||||
|         "laravel/telescope": "^4.6", |         "laravel/telescope": "^4.6", | ||||||
|         "laravel/tinker": "^2.5", |         "laravel/tinker": "^2.5", | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										66
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -4,7 +4,7 @@ | |||||||
|         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||||
|         "This file is @generated automatically" |         "This file is @generated automatically" | ||||||
|     ], |     ], | ||||||
|     "content-hash": "e3c6ffae4c01db02d0471c52d2370b79", |     "content-hash": "bf5f7d8f40ecadea64ae8564a3df3110", | ||||||
|     "packages": [ |     "packages": [ | ||||||
|         { |         { | ||||||
|             "name": "asm89/stack-cors", |             "name": "asm89/stack-cors", | ||||||
| @@ -1358,6 +1358,70 @@ | |||||||
|             }, |             }, | ||||||
|             "time": "2022-01-12T16:12:41+00:00" |             "time": "2022-01-12T16:12:41+00:00" | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             "name": "laravel/sanctum", | ||||||
|  |             "version": "v2.14.0", | ||||||
|  |             "source": { | ||||||
|  |                 "type": "git", | ||||||
|  |                 "url": "https://github.com/laravel/sanctum.git", | ||||||
|  |                 "reference": "0647a87140c7522e75826cffcadb3ad6e01f71e9" | ||||||
|  |             }, | ||||||
|  |             "dist": { | ||||||
|  |                 "type": "zip", | ||||||
|  |                 "url": "https://api.github.com/repos/laravel/sanctum/zipball/0647a87140c7522e75826cffcadb3ad6e01f71e9", | ||||||
|  |                 "reference": "0647a87140c7522e75826cffcadb3ad6e01f71e9", | ||||||
|  |                 "shasum": "" | ||||||
|  |             }, | ||||||
|  |             "require": { | ||||||
|  |                 "ext-json": "*", | ||||||
|  |                 "illuminate/contracts": "^6.9|^7.0|^8.0|^9.0", | ||||||
|  |                 "illuminate/database": "^6.9|^7.0|^8.0|^9.0", | ||||||
|  |                 "illuminate/support": "^6.9|^7.0|^8.0|^9.0", | ||||||
|  |                 "php": "^7.2|^8.0" | ||||||
|  |             }, | ||||||
|  |             "require-dev": { | ||||||
|  |                 "mockery/mockery": "^1.0", | ||||||
|  |                 "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", | ||||||
|  |                 "phpunit/phpunit": "^8.0|^9.3" | ||||||
|  |             }, | ||||||
|  |             "type": "library", | ||||||
|  |             "extra": { | ||||||
|  |                 "branch-alias": { | ||||||
|  |                     "dev-master": "2.x-dev" | ||||||
|  |                 }, | ||||||
|  |                 "laravel": { | ||||||
|  |                     "providers": [ | ||||||
|  |                         "Laravel\\Sanctum\\SanctumServiceProvider" | ||||||
|  |                     ] | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "autoload": { | ||||||
|  |                 "psr-4": { | ||||||
|  |                     "Laravel\\Sanctum\\": "src/" | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "notification-url": "https://packagist.org/downloads/", | ||||||
|  |             "license": [ | ||||||
|  |                 "MIT" | ||||||
|  |             ], | ||||||
|  |             "authors": [ | ||||||
|  |                 { | ||||||
|  |                     "name": "Taylor Otwell", | ||||||
|  |                     "email": "taylor@laravel.com" | ||||||
|  |                 } | ||||||
|  |             ], | ||||||
|  |             "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", | ||||||
|  |             "keywords": [ | ||||||
|  |                 "auth", | ||||||
|  |                 "laravel", | ||||||
|  |                 "sanctum" | ||||||
|  |             ], | ||||||
|  |             "support": { | ||||||
|  |                 "issues": "https://github.com/laravel/sanctum/issues", | ||||||
|  |                 "source": "https://github.com/laravel/sanctum" | ||||||
|  |             }, | ||||||
|  |             "time": "2022-01-12T15:07:43+00:00" | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             "name": "laravel/serializable-closure", |             "name": "laravel/serializable-closure", | ||||||
|             "version": "v1.0.5", |             "version": "v1.0.5", | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								config/sanctum.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								config/sanctum.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | use Illuminate\Cookie\Middleware\EncryptCookies; | ||||||
|  | use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; | ||||||
|  |  | ||||||
|  | return [ | ||||||
|  |     'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( | ||||||
|  |         '%s%s', | ||||||
|  |         'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', | ||||||
|  |         env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' | ||||||
|  |     ))), | ||||||
|  |     'guard' => ['web'], | ||||||
|  |     'expiration' => null, | ||||||
|  |     'middleware' => [ | ||||||
|  |         'verify_csrf_token' => VerifyCsrfToken::class, | ||||||
|  |         'encrypt_cookies' => EncryptCookies::class, | ||||||
|  |     ], | ||||||
|  | ]; | ||||||
							
								
								
									
										23
									
								
								database/factories/VacationRequestFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								database/factories/VacationRequestFactory.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Database\Factories; | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Eloquent\Factories\Factory; | ||||||
|  | use Toby\Enums\VacationType; | ||||||
|  | use Toby\Models\User; | ||||||
|  |  | ||||||
|  | class VacationRequestFactory extends Factory | ||||||
|  | { | ||||||
|  |     public function definition(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             "user_id" => User::factory(), | ||||||
|  |             "type" => $this->faker->randomElement(VacationType::cases()), | ||||||
|  |             "from" => $this->faker->date, | ||||||
|  |             "to" => $this->faker->date, | ||||||
|  |             "comment" => $this->faker->boolean ? $this->faker->paragraph() : null, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| use Illuminate\Database\Migrations\Migration; |  | ||||||
| use Illuminate\Database\Schema\Blueprint; |  | ||||||
| use Illuminate\Support\Facades\Schema; |  | ||||||
|  |  | ||||||
| return new class() extends Migration { |  | ||||||
|     public function up(): void |  | ||||||
|     { |  | ||||||
|         Schema::create("personal_access_tokens", function (Blueprint $table): void { |  | ||||||
|             $table->id(); |  | ||||||
|             $table->morphs("tokenable"); |  | ||||||
|             $table->string("name"); |  | ||||||
|             $table->string("token", 64)->unique(); |  | ||||||
|             $table->text("abilities")->nullable(); |  | ||||||
|             $table->timestamp("last_used_at")->nullable(); |  | ||||||
|             $table->timestamps(); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public function down(): void |  | ||||||
|     { |  | ||||||
|         Schema::dropIfExists("personal_access_tokens"); |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Migrations\Migration; | ||||||
|  | use Illuminate\Database\Schema\Blueprint; | ||||||
|  | use Illuminate\Support\Facades\Schema; | ||||||
|  | use Toby\Models\User; | ||||||
|  |  | ||||||
|  | return new class() extends Migration { | ||||||
|  |     public function up(): void | ||||||
|  |     { | ||||||
|  |         Schema::create('vacation_requests', function (Blueprint $table): void { | ||||||
|  |             $table->id(); | ||||||
|  |             $table->foreignIdFor(User::class)->constrained()->cascadeOnDelete(); | ||||||
|  |             $table->string("type"); | ||||||
|  |             $table->date("from"); | ||||||
|  |             $table->date("to"); | ||||||
|  |             $table->text("comment")->nullable(); | ||||||
|  |             $table->timestamps(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function down(): void | ||||||
|  |     { | ||||||
|  |         Schema::dropIfExists('vacation_requests'); | ||||||
|  |     } | ||||||
|  | }; | ||||||
| @@ -28,7 +28,9 @@ class DatabaseSeeder extends Seeder | |||||||
|         User::factory(9)->create(); |         User::factory(9)->create(); | ||||||
|         User::factory([ |         User::factory([ | ||||||
|             "email" => env("LOCAL_EMAIL_FOR_LOGIN_VIA_GOOGLE"), |             "email" => env("LOCAL_EMAIL_FOR_LOGIN_VIA_GOOGLE"), | ||||||
|         ])->create(); |         ]) | ||||||
|  |             ->hasVacationRequests(5) | ||||||
|  |             ->create(); | ||||||
|  |  | ||||||
|         $users = User::all(); |         $users = User::all(); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										132
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										132
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -15,12 +15,14 @@ | |||||||
|                 "@tailwindcss/typography": "^0.5.0", |                 "@tailwindcss/typography": "^0.5.0", | ||||||
|                 "@vue/compiler-sfc": "^3.2.26", |                 "@vue/compiler-sfc": "^3.2.26", | ||||||
|                 "autoprefixer": "^10.4.2", |                 "autoprefixer": "^10.4.2", | ||||||
|  |                 "echarts": "^5.2.2", | ||||||
|                 "flatpickr": "^4.6.9", |                 "flatpickr": "^4.6.9", | ||||||
|                 "laravel-mix": "^6.0.6", |                 "laravel-mix": "^6.0.6", | ||||||
|                 "lodash": "^4.17.21", |                 "lodash": "^4.17.21", | ||||||
|                 "postcss": "^8.4.5", |                 "postcss": "^8.4.5", | ||||||
|                 "tailwindcss": "^3.0.13", |                 "tailwindcss": "^3.0.13", | ||||||
|                 "vue": "^3.2.26", |                 "vue": "^3.2.26", | ||||||
|  |                 "vue-echarts": "^6.0.2", | ||||||
|                 "vue-flatpickr-component": "^9.0.5", |                 "vue-flatpickr-component": "^9.0.5", | ||||||
|                 "vue-loader": "^17.0.0" |                 "vue-loader": "^17.0.0" | ||||||
|             }, |             }, | ||||||
| @@ -3986,6 +3988,20 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", |             "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", | ||||||
|             "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" |             "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/echarts": { | ||||||
|  |             "version": "5.2.2", | ||||||
|  |             "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.2.2.tgz", | ||||||
|  |             "integrity": "sha512-yxuBfeIH5c+0FsoRP60w4De6omXhA06c7eUYBsC1ykB6Ys2yK5fSteIYWvkJ4xJVLQgCvAdO8C4mN6MLeJpBaw==", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "tslib": "2.3.0", | ||||||
|  |                 "zrender": "5.2.1" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/echarts/node_modules/tslib": { | ||||||
|  |             "version": "2.3.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", | ||||||
|  |             "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" | ||||||
|  |         }, | ||||||
|         "node_modules/ee-first": { |         "node_modules/ee-first": { | ||||||
|             "version": "1.1.1", |             "version": "1.1.1", | ||||||
|             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | ||||||
| @@ -7797,6 +7813,11 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", |             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", | ||||||
|             "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" |             "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/resize-detector": { | ||||||
|  |             "version": "0.3.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/resize-detector/-/resize-detector-0.3.0.tgz", | ||||||
|  |             "integrity": "sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==" | ||||||
|  |         }, | ||||||
|         "node_modules/resolve": { |         "node_modules/resolve": { | ||||||
|             "version": "1.21.0", |             "version": "1.21.0", | ||||||
|             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", |             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", | ||||||
| @@ -8854,6 +8875,51 @@ | |||||||
|                 "@vue/shared": "3.2.26" |                 "@vue/shared": "3.2.26" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/vue-echarts": { | ||||||
|  |             "version": "6.0.2", | ||||||
|  |             "resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-6.0.2.tgz", | ||||||
|  |             "integrity": "sha512-9xDokauJtAc389MNKbwi1I0VDmp4Y6ndAJTQ8T9K7H0ffosTe1OJSJbUtkT7/fVLDFzlCcmg2TfAKaMzbpg5yQ==", | ||||||
|  |             "hasInstallScript": true, | ||||||
|  |             "dependencies": { | ||||||
|  |                 "resize-detector": "^0.3.0", | ||||||
|  |                 "vue-demi": "^0.12.1" | ||||||
|  |             }, | ||||||
|  |             "peerDependencies": { | ||||||
|  |                 "@vue/composition-api": "^1.0.5", | ||||||
|  |                 "echarts": "^5.1.2", | ||||||
|  |                 "vue": "^2.6.12 || ^3.1.1" | ||||||
|  |             }, | ||||||
|  |             "peerDependenciesMeta": { | ||||||
|  |                 "@vue/composition-api": { | ||||||
|  |                     "optional": true | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/vue-echarts/node_modules/vue-demi": { | ||||||
|  |             "version": "0.12.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.1.tgz", | ||||||
|  |             "integrity": "sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==", | ||||||
|  |             "hasInstallScript": true, | ||||||
|  |             "bin": { | ||||||
|  |                 "vue-demi-fix": "bin/vue-demi-fix.js", | ||||||
|  |                 "vue-demi-switch": "bin/vue-demi-switch.js" | ||||||
|  |             }, | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">=12" | ||||||
|  |             }, | ||||||
|  |             "funding": { | ||||||
|  |                 "url": "https://github.com/sponsors/antfu" | ||||||
|  |             }, | ||||||
|  |             "peerDependencies": { | ||||||
|  |                 "@vue/composition-api": "^1.0.0-rc.1", | ||||||
|  |                 "vue": "^3.0.0-0 || ^2.6.0" | ||||||
|  |             }, | ||||||
|  |             "peerDependenciesMeta": { | ||||||
|  |                 "@vue/composition-api": { | ||||||
|  |                     "optional": true | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/vue-eslint-parser": { |         "node_modules/vue-eslint-parser": { | ||||||
|             "version": "8.0.1", |             "version": "8.0.1", | ||||||
|             "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", |             "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", | ||||||
| @@ -9444,6 +9510,19 @@ | |||||||
|             "engines": { |             "engines": { | ||||||
|                 "node": ">=12" |                 "node": ">=12" | ||||||
|             } |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/zrender": { | ||||||
|  |             "version": "5.2.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.2.1.tgz", | ||||||
|  |             "integrity": "sha512-M3bPGZuyLTNBC6LiNKXJwSCtglMp8XUEqEBG+2MdICDI3d1s500Y4P0CzldQGsqpRVB7fkvf3BKQQRxsEaTlsw==", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "tslib": "2.3.0" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/zrender/node_modules/tslib": { | ||||||
|  |             "version": "2.3.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", | ||||||
|  |             "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
| @@ -12439,6 +12518,22 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", |             "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", | ||||||
|             "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" |             "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" | ||||||
|         }, |         }, | ||||||
|  |         "echarts": { | ||||||
|  |             "version": "5.2.2", | ||||||
|  |             "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.2.2.tgz", | ||||||
|  |             "integrity": "sha512-yxuBfeIH5c+0FsoRP60w4De6omXhA06c7eUYBsC1ykB6Ys2yK5fSteIYWvkJ4xJVLQgCvAdO8C4mN6MLeJpBaw==", | ||||||
|  |             "requires": { | ||||||
|  |                 "tslib": "2.3.0", | ||||||
|  |                 "zrender": "5.2.1" | ||||||
|  |             }, | ||||||
|  |             "dependencies": { | ||||||
|  |                 "tslib": { | ||||||
|  |                     "version": "2.3.0", | ||||||
|  |                     "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", | ||||||
|  |                     "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "ee-first": { |         "ee-first": { | ||||||
|             "version": "1.1.1", |             "version": "1.1.1", | ||||||
|             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | ||||||
| @@ -15167,6 +15262,11 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", |             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", | ||||||
|             "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" |             "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" | ||||||
|         }, |         }, | ||||||
|  |         "resize-detector": { | ||||||
|  |             "version": "0.3.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/resize-detector/-/resize-detector-0.3.0.tgz", | ||||||
|  |             "integrity": "sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==" | ||||||
|  |         }, | ||||||
|         "resolve": { |         "resolve": { | ||||||
|             "version": "1.21.0", |             "version": "1.21.0", | ||||||
|             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", |             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", | ||||||
| @@ -15964,6 +16064,23 @@ | |||||||
|                 "@vue/shared": "3.2.26" |                 "@vue/shared": "3.2.26" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "vue-echarts": { | ||||||
|  |             "version": "6.0.2", | ||||||
|  |             "resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-6.0.2.tgz", | ||||||
|  |             "integrity": "sha512-9xDokauJtAc389MNKbwi1I0VDmp4Y6ndAJTQ8T9K7H0ffosTe1OJSJbUtkT7/fVLDFzlCcmg2TfAKaMzbpg5yQ==", | ||||||
|  |             "requires": { | ||||||
|  |                 "resize-detector": "^0.3.0", | ||||||
|  |                 "vue-demi": "^0.12.1" | ||||||
|  |             }, | ||||||
|  |             "dependencies": { | ||||||
|  |                 "vue-demi": { | ||||||
|  |                     "version": "0.12.1", | ||||||
|  |                     "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.1.tgz", | ||||||
|  |                     "integrity": "sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==", | ||||||
|  |                     "requires": {} | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "vue-eslint-parser": { |         "vue-eslint-parser": { | ||||||
|             "version": "8.0.1", |             "version": "8.0.1", | ||||||
|             "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", |             "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", | ||||||
| @@ -16364,6 +16481,21 @@ | |||||||
|             "version": "21.0.0", |             "version": "21.0.0", | ||||||
|             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", |             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", | ||||||
|             "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==" |             "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==" | ||||||
|  |         }, | ||||||
|  |         "zrender": { | ||||||
|  |             "version": "5.2.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.2.1.tgz", | ||||||
|  |             "integrity": "sha512-M3bPGZuyLTNBC6LiNKXJwSCtglMp8XUEqEBG+2MdICDI3d1s500Y4P0CzldQGsqpRVB7fkvf3BKQQRxsEaTlsw==", | ||||||
|  |             "requires": { | ||||||
|  |                 "tslib": "2.3.0" | ||||||
|  |             }, | ||||||
|  |             "dependencies": { | ||||||
|  |                 "tslib": { | ||||||
|  |                     "version": "2.3.0", | ||||||
|  |                     "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", | ||||||
|  |                     "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,12 +22,14 @@ | |||||||
|         "@tailwindcss/typography": "^0.5.0", |         "@tailwindcss/typography": "^0.5.0", | ||||||
|         "@vue/compiler-sfc": "^3.2.26", |         "@vue/compiler-sfc": "^3.2.26", | ||||||
|         "autoprefixer": "^10.4.2", |         "autoprefixer": "^10.4.2", | ||||||
|  |         "echarts": "^5.2.2", | ||||||
|         "flatpickr": "^4.6.9", |         "flatpickr": "^4.6.9", | ||||||
|         "laravel-mix": "^6.0.6", |         "laravel-mix": "^6.0.6", | ||||||
|         "lodash": "^4.17.21", |         "lodash": "^4.17.21", | ||||||
|         "postcss": "^8.4.5", |         "postcss": "^8.4.5", | ||||||
|         "tailwindcss": "^3.0.13", |         "tailwindcss": "^3.0.13", | ||||||
|         "vue": "^3.2.26", |         "vue": "^3.2.26", | ||||||
|  |         "vue-echarts": "^6.0.2", | ||||||
|         "vue-flatpickr-component": "^9.0.5", |         "vue-flatpickr-component": "^9.0.5", | ||||||
|         "vue-loader": "^17.0.0" |         "vue-loader": "^17.0.0" | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -47,3 +47,24 @@ | |||||||
|     -webkit-box-shadow: -5px 0 0 #527ABA, 5px 0 0 #527ABA; |     -webkit-box-shadow: -5px 0 0 #527ABA, 5px 0 0 #527ABA; | ||||||
|     box-shadow: -5px 0 0 #527ABA, 5px 0 0 #527ABA; |     box-shadow: -5px 0 0 #527ABA, 5px 0 0 #527ABA; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | ::-webkit-scrollbar { | ||||||
|  |     width: 8px; | ||||||
|  |     height: 8px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ::-webkit-scrollbar-track { | ||||||
|  |     border-radius: 100vh; | ||||||
|  |     background: transparent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ::-webkit-scrollbar-thumb { | ||||||
|  |     border-radius: 8px; | ||||||
|  |     background: #dadce0; | ||||||
|  |     border: 4px solid transparent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ::-webkit-scrollbar-thumb:hover { | ||||||
|  |     background: #dadce0; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										238
									
								
								resources/js/Pages/VacationRequest/Create.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								resources/js/Pages/VacationRequest/Create.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,238 @@ | |||||||
|  | <template> | ||||||
|  |     <InertiaHead title="Składanie wniosku urlopowego" /> | ||||||
|  |     <div class="bg-white sm:rounded-lg shadow-md"> | ||||||
|  |         <div class="p-4 sm:px-6"> | ||||||
|  |             <h2 class="text-lg leading-6 font-medium text-gray-900"> | ||||||
|  |                 Złóż wniosek urlopowy | ||||||
|  |             </h2> | ||||||
|  |         </div> | ||||||
|  |         <form | ||||||
|  |             class="border-t border-gray-200 px-6" | ||||||
|  |             @submit.prevent="createForm" | ||||||
|  |         > | ||||||
|  |             <Listbox | ||||||
|  |                 v-model="form.vacationType" | ||||||
|  |                 as="div" | ||||||
|  |                 class="sm:grid sm:grid-cols-3 py-4 items-center" | ||||||
|  |             > | ||||||
|  |                 <ListboxLabel class="block text-sm font-medium text-gray-700"> | ||||||
|  |                     Rodzaj wniosku | ||||||
|  |                 </ListboxLabel> | ||||||
|  |                 <div class="mt-1 relative sm:mt-0 sm:col-span-2"> | ||||||
|  |                     <ListboxButton | ||||||
|  |                         class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1" | ||||||
|  |                         :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.vacationType, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.vacationType }" | ||||||
|  |                     > | ||||||
|  |                         <span class="block truncate">{{ form.vacationType.label }}</span> | ||||||
|  |                         <span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"> | ||||||
|  |                             <SelectorIcon class="h-5 w-5 text-gray-400" /> | ||||||
|  |                         </span> | ||||||
|  |                     </ListboxButton> | ||||||
|  |  | ||||||
|  |                     <transition | ||||||
|  |                         leave-active-class="transition ease-in duration-100" | ||||||
|  |                         leave-from-class="opacity-100" | ||||||
|  |                         leave-to-class="opacity-0" | ||||||
|  |                     > | ||||||
|  |                         <ListboxOptions | ||||||
|  |                             class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm" | ||||||
|  |                         > | ||||||
|  |                             <ListboxOption | ||||||
|  |                                 v-for="vacationType in vacationTypes" | ||||||
|  |                                 :key="vacationType.value" | ||||||
|  |                                 v-slot="{ active, selected }" | ||||||
|  |                                 as="template" | ||||||
|  |                                 :value="vacationType" | ||||||
|  |                             > | ||||||
|  |                                 <li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"> | ||||||
|  |                                     <span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']"> | ||||||
|  |                                         {{ vacationType.label }} | ||||||
|  |                                     </span> | ||||||
|  |  | ||||||
|  |                                     <span | ||||||
|  |                                         v-if="selected" | ||||||
|  |                                         :class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']" | ||||||
|  |                                     > | ||||||
|  |                                         <CheckIcon class="h-5 w-5" /> | ||||||
|  |                                     </span> | ||||||
|  |                                 </li> | ||||||
|  |                             </ListboxOption> | ||||||
|  |                         </ListboxOptions> | ||||||
|  |                     </transition> | ||||||
|  |                     <p | ||||||
|  |                         v-if="form.errors.vacationType" | ||||||
|  |                         class="mt-2 text-sm text-red-600" | ||||||
|  |                     > | ||||||
|  |                         {{ form.errors.vacationType }} | ||||||
|  |                     </p> | ||||||
|  |                 </div> | ||||||
|  |             </Listbox> | ||||||
|  |             <div class="sm:grid sm:grid-cols-3 py-4 items-center"> | ||||||
|  |                 <label | ||||||
|  |                     for="date_from" | ||||||
|  |                     class="block text-sm font-medium text-gray-700 sm:mt-px" | ||||||
|  |                 > | ||||||
|  |                     Planowany urlop od | ||||||
|  |                 </label> | ||||||
|  |                 <div class="mt-1 sm:mt-0 sm:col-span-2"> | ||||||
|  |                     <FlatPickr | ||||||
|  |                         id="date_from" | ||||||
|  |                         v-model="form.dateFrom" | ||||||
|  |                         :config="fromInputConfig" | ||||||
|  |                         placeholder="Wybierz datę" | ||||||
|  |                         class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm" | ||||||
|  |                         :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.dateFrom, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.dateFrom }" | ||||||
|  |                         @on-change="onFromChange" | ||||||
|  |                     /> | ||||||
|  |                     <p | ||||||
|  |                         v-if="form.errors.dateFrom" | ||||||
|  |                         class="mt-2 text-sm text-red-600" | ||||||
|  |                     > | ||||||
|  |                         {{ form.errors.dateFrom }} | ||||||
|  |                     </p> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="sm:grid sm:grid-cols-3 py-4 items-center"> | ||||||
|  |                 <label | ||||||
|  |                     for="date_from" | ||||||
|  |                     class="block text-sm font-medium text-gray-700 sm:mt-px" | ||||||
|  |                 > | ||||||
|  |                     Planowany urlop do | ||||||
|  |                 </label> | ||||||
|  |                 <div class="mt-1 sm:mt-0 sm:col-span-2"> | ||||||
|  |                     <FlatPickr | ||||||
|  |                         id="date_to" | ||||||
|  |                         v-model="form.dateTo" | ||||||
|  |                         :config="toInputConfig" | ||||||
|  |                         placeholder="Wybierz datę" | ||||||
|  |                         class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm" | ||||||
|  |                         :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.dateTo, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.dateTo }" | ||||||
|  |                         @on-change="onToChange" | ||||||
|  |                     /> | ||||||
|  |                     <p | ||||||
|  |                         v-if="form.errors.dateTo" | ||||||
|  |                         class="mt-2 text-sm text-red-600" | ||||||
|  |                     > | ||||||
|  |                         {{ form.errors.dateTo }} | ||||||
|  |                     </p> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="sm:grid sm:grid-cols-3 py-4 items-center"> | ||||||
|  |                 <span class="block text-sm font-medium text-gray-700 sm:mt-px">Liczba dni urlopu</span> | ||||||
|  |                 <div | ||||||
|  |                     class="mt-1 sm:mt-0 sm:col-span-2 w-full max-w-lg bg-gray-50 border border-gray-300 rounded-md px-4 py-2 inline-flex items-center text-gray-500 sm:text-sm" | ||||||
|  |                 > | ||||||
|  |                     1 | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="sm:grid sm:grid-cols-3 py-4 items-center"> | ||||||
|  |                 <label | ||||||
|  |                     for="comment" | ||||||
|  |                     class="block text-sm font-medium text-gray-700" | ||||||
|  |                 > | ||||||
|  |                     Komentarz | ||||||
|  |                 </label> | ||||||
|  |                 <div class="mt-1 sm:mt-0 sm:col-span-2"> | ||||||
|  |                     <textarea | ||||||
|  |                         id="comment" | ||||||
|  |                         rows="4" | ||||||
|  |                         class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full max-w-lg sm:text-sm border-gray-300 rounded-md" | ||||||
|  |                     /> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="flex justify-end py-3"> | ||||||
|  |                 <div class="space-x-3"> | ||||||
|  |                     <InertiaLink | ||||||
|  |                         href="/vacation-request" | ||||||
|  |                         class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500" | ||||||
|  |                     > | ||||||
|  |                         Anuluj | ||||||
|  |                     </InertiaLink> | ||||||
|  |                     <button | ||||||
|  |                         type="submit" | ||||||
|  |                         :disabled="form.processing" | ||||||
|  |                         class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500" | ||||||
|  |                     > | ||||||
|  |                         Zapisz | ||||||
|  |                     </button> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </form> | ||||||
|  |     </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {useForm} from '@inertiajs/inertia-vue3'; | ||||||
|  | import FlatPickr from 'vue-flatpickr-component'; | ||||||
|  | import {Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions} from '@headlessui/vue'; | ||||||
|  | import {CheckIcon, SelectorIcon} from '@heroicons/vue/solid'; | ||||||
|  | import {reactive} from 'vue'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     dateFrom: 'UserCreate', | ||||||
|  |     components: { | ||||||
|  |         FlatPickr, | ||||||
|  |         Listbox, | ||||||
|  |         ListboxButton, | ||||||
|  |         ListboxLabel, | ||||||
|  |         ListboxOption, | ||||||
|  |         ListboxOptions, | ||||||
|  |         CheckIcon, | ||||||
|  |         SelectorIcon, | ||||||
|  |     }, | ||||||
|  |     props: { | ||||||
|  |         vacationTypes: { | ||||||
|  |             type: Object, | ||||||
|  |             default: () => null, | ||||||
|  |         }, | ||||||
|  |         holidays: { | ||||||
|  |             type: Object, | ||||||
|  |             default: () => null, | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |     setup(props) { | ||||||
|  |         const form = useForm({ | ||||||
|  |             dateFrom: null, | ||||||
|  |             dateTo: null, | ||||||
|  |             vacationType: props.vacationTypes[0], | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         const disableDates = [ | ||||||
|  |             date => (date.getDay() === 0 || date.getDay() === 6), | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         const fromInputConfig = reactive({ | ||||||
|  |             maxDate: null, | ||||||
|  |             disable: disableDates, | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         const toInputConfig = reactive({ | ||||||
|  |             minDate: null, | ||||||
|  |             disable: disableDates, | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         return { | ||||||
|  |             form, | ||||||
|  |             fromInputConfig, | ||||||
|  |             toInputConfig, | ||||||
|  |         }; | ||||||
|  |     }, | ||||||
|  |     methods: { | ||||||
|  |         createForm() { | ||||||
|  |             this.form | ||||||
|  |                 .transform(data => ({ | ||||||
|  |                     ...data, | ||||||
|  |                     vacationType: data.vacationType.value, | ||||||
|  |                 })) | ||||||
|  |                 .post('/vacation-request'); | ||||||
|  |         }, | ||||||
|  |         onFromChange(selectedDates, dateStr) { | ||||||
|  |             this.toInputConfig.minDate = dateStr; | ||||||
|  |         }, | ||||||
|  |         onToChange(selectedDates, dateStr) { | ||||||
|  |             this.fromInputConfig.maxDate = dateStr; | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  | }; | ||||||
|  | </script> | ||||||
							
								
								
									
										223
									
								
								resources/js/Pages/VacationRequest/Index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								resources/js/Pages/VacationRequest/Index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | |||||||
|  | <template> | ||||||
|  |     <InertiaHead title="Twoje wnioski urlopowe" /> | ||||||
|  |     <div class="bg-white sm:rounded-lg shadow-md"> | ||||||
|  |         <div class="flex justify-between items-center p-4 sm:px-6"> | ||||||
|  |             <div> | ||||||
|  |                 <h2 class="text-lg leading-6 font-medium text-gray-900"> | ||||||
|  |                     Twoje wnioski urlopowe | ||||||
|  |                 </h2> | ||||||
|  |             </div> | ||||||
|  |             <div> | ||||||
|  |                 <InertiaLink | ||||||
|  |                     href="vacation-requests/create" | ||||||
|  |                     class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500" | ||||||
|  |                 > | ||||||
|  |                     Dodaj wniosek | ||||||
|  |                 </InertiaLink> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible"> | ||||||
|  |             <table class="min-w-full divide-y divide-gray-200"> | ||||||
|  |                 <thead class="bg-gray-50"> | ||||||
|  |                     <tr> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         > | ||||||
|  |                             Numer | ||||||
|  |                         </th> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         > | ||||||
|  |                             Rodzaj urlopu | ||||||
|  |                         </th> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         > | ||||||
|  |                             Od | ||||||
|  |                         </th> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         > | ||||||
|  |                             Do | ||||||
|  |                         </th> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         > | ||||||
|  |                             Dni urlopu | ||||||
|  |                         </th> | ||||||
|  |                         <th | ||||||
|  |                             scope="col" | ||||||
|  |                             class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider" | ||||||
|  |                         /> | ||||||
|  |                     </tr> | ||||||
|  |                 </thead> | ||||||
|  |                 <tbody class="bg-white divide-y divide-gray-100"> | ||||||
|  |                     <tr | ||||||
|  |                         v-for="request in requests.data" | ||||||
|  |                         :key="request.id" | ||||||
|  |                         class="hover:bg-blumilk-25" | ||||||
|  |                     > | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |                             {{ request.id }} | ||||||
|  |                         </td> | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |                             {{ request.type }} | ||||||
|  |                         </td> | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |                             {{ request.from }} | ||||||
|  |                         </td> | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |                             {{ request.to }} | ||||||
|  |                         </td> | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |                             X | ||||||
|  |                         </td> | ||||||
|  |                         <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right"> | ||||||
|  |                             <Menu | ||||||
|  |                                 as="div" | ||||||
|  |                                 class="relative inline-block text-left" | ||||||
|  |                             > | ||||||
|  |                                 <MenuButton class="rounded-full flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-blumilk-500"> | ||||||
|  |                                     <DotsVerticalIcon | ||||||
|  |                                         class="h-5 w-5" | ||||||
|  |                                         aria-hidden="true" | ||||||
|  |                                     /> | ||||||
|  |                                 </MenuButton> | ||||||
|  |  | ||||||
|  |                                 <transition | ||||||
|  |                                     enter-active-class="transition ease-out duration-100" | ||||||
|  |                                     enter-from-class="transform opacity-0 scale-95" | ||||||
|  |                                     enter-to-class="transform opacity-100 scale-100" | ||||||
|  |                                     leave-active-class="transition ease-in duration-75" | ||||||
|  |                                     leave-from-class="transform opacity-100 scale-100" | ||||||
|  |                                     leave-to-class="transform opacity-0 scale-95" | ||||||
|  |                                 > | ||||||
|  |                                     <MenuItems class="origin-top-right absolute right-0 mt-2 w-56 z-10 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"> | ||||||
|  |                                         <div | ||||||
|  |                                             class="py-1" | ||||||
|  |                                         > | ||||||
|  |                                             <MenuItem | ||||||
|  |                                                 v-slot="{ active }" | ||||||
|  |                                                 class="flex" | ||||||
|  |                                             > | ||||||
|  |                                                 <InertiaLink | ||||||
|  |                                                     :class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'font-medium block px-4 py-2 text-sm']" | ||||||
|  |                                                 > | ||||||
|  |                                                     <PencilIcon | ||||||
|  |                                                         class="mr-2 h-5 w-5 text-blue-500" | ||||||
|  |                                                         aria-hidden="true" | ||||||
|  |                                                     /> Edytuj | ||||||
|  |                                                 </InertiaLink> | ||||||
|  |                                             </MenuItem> | ||||||
|  |                                             <MenuItem | ||||||
|  |                                                 v-slot="{ active }" | ||||||
|  |                                                 class="flex" | ||||||
|  |                                             > | ||||||
|  |                                                 <InertiaLink | ||||||
|  |                                                     as="button" | ||||||
|  |                                                     method="delete" | ||||||
|  |                                                     :preserve-scroll="true" | ||||||
|  |                                                     :class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']" | ||||||
|  |                                                 > | ||||||
|  |                                                     <TrashIcon | ||||||
|  |                                                         class="mr-2 h-5 w-5 text-red-500" | ||||||
|  |                                                     /> Usuń | ||||||
|  |                                                 </InertiaLink> | ||||||
|  |                                             </MenuItem> | ||||||
|  |                                         </div> | ||||||
|  |                                     </MenuItems> | ||||||
|  |                                 </transition> | ||||||
|  |                             </Menu> | ||||||
|  |                         </td> | ||||||
|  |                     </tr> | ||||||
|  |                     <tr | ||||||
|  |                         v-if="! requests.data.length" | ||||||
|  |                     > | ||||||
|  |                         <td | ||||||
|  |                             colspan="100%" | ||||||
|  |                             class="text-center py-4 text-xl leading-5 text-gray-700" | ||||||
|  |                         > | ||||||
|  |                             Brak danych | ||||||
|  |                         </td> | ||||||
|  |                     </tr> | ||||||
|  |                 </tbody> | ||||||
|  |             </table> | ||||||
|  |             <div | ||||||
|  |                 v-if="requests.data.length && requests.meta.last_page !== 1" | ||||||
|  |                 class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6 rounded-b-lg" | ||||||
|  |             > | ||||||
|  |                 <div class="flex-1 flex justify-between sm:hidden"> | ||||||
|  |                     <InertiaLink | ||||||
|  |                         :is="requests.links.prev ? 'InertiaLink': 'span'" | ||||||
|  |                         :href="requests.links.prev" | ||||||
|  |                         class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50" | ||||||
|  |                     > | ||||||
|  |                         Poprzednia | ||||||
|  |                     </InertiaLink> | ||||||
|  |                     <Component | ||||||
|  |                         :is="requests.links.next ? 'InertiaLink': 'span'" | ||||||
|  |                         :href="requests.links.next" | ||||||
|  |                         class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50" | ||||||
|  |                     > | ||||||
|  |                         Następna | ||||||
|  |                     </Component> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between"> | ||||||
|  |                     <div class="text-sm text-gray-700"> | ||||||
|  |                         Wyświetlanie | ||||||
|  |                         <span class="font-medium">{{ requests.meta.from }}</span> | ||||||
|  |                         od | ||||||
|  |                         <span class="font-medium">{{ requests.meta.to }}</span> | ||||||
|  |                         do | ||||||
|  |                         <span class="font-medium">{{ requests.meta.total }}</span> | ||||||
|  |                         wyników | ||||||
|  |                     </div> | ||||||
|  |                     <nav class="relative z-0 inline-flex space-x-1"> | ||||||
|  |                         <template | ||||||
|  |                             v-for="(link, index) in requests.meta.links" | ||||||
|  |                             :key="index" | ||||||
|  |                         > | ||||||
|  |                             <Component | ||||||
|  |                                 :is="link.url ? 'InertiaLink' : 'span'" | ||||||
|  |                                 :href="link.url" | ||||||
|  |                                 :preserve-scroll="true" | ||||||
|  |                                 class="relative inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium" | ||||||
|  |                                 :class="{ 'z-10 bg-blumilk-25 border-blumilk-500 text-blumilk-600': link.active, 'bg-white border-gray-300 text-gray-500': !link.active, 'hover:bg-blumilk-25': link.url, 'border-none': !link.url}" | ||||||
|  |                                 v-text="link.label" | ||||||
|  |                             /> | ||||||
|  |                         </template> | ||||||
|  |                     </nav> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { DotsVerticalIcon, PencilIcon, TrashIcon } from '@heroicons/vue/solid'; | ||||||
|  | import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     name: 'UserIndex', | ||||||
|  |     components: { | ||||||
|  |         DotsVerticalIcon, | ||||||
|  |         PencilIcon, | ||||||
|  |         TrashIcon, | ||||||
|  |         Menu, | ||||||
|  |         MenuButton, | ||||||
|  |         MenuItem, | ||||||
|  |         MenuItems, | ||||||
|  |     }, | ||||||
|  |     props: { | ||||||
|  |         requests: { | ||||||
|  |             type: Object, | ||||||
|  |             default: () => null, | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  | </script> | ||||||
| @@ -323,6 +323,7 @@ export default { | |||||||
|             {name: 'Użytkownicy', href: '/users', current: false}, |             {name: 'Użytkownicy', href: '/users', current: false}, | ||||||
|             {name: 'Dostępne urlopy', href: '/vacation-limits', current: false}, |             {name: 'Dostępne urlopy', href: '/vacation-limits', current: false}, | ||||||
|             {name: 'Dni wolne', href: '/holidays', current: false}, |             {name: 'Dni wolne', href: '/holidays', current: false}, | ||||||
|  |             {name: 'Wnioski urlopowe', href: '/vacation-requests', current: false}, | ||||||
|         ]; |         ]; | ||||||
|         const userNavigation = [ |         const userNavigation = [ | ||||||
|             {name: 'Your Profile', href: '#'}, |             {name: 'Your Profile', href: '#'}, | ||||||
|   | |||||||
| @@ -3,5 +3,15 @@ | |||||||
|   "employment_contract": "Umowa o pracę", |   "employment_contract": "Umowa o pracę", | ||||||
|   "commission_contract": "Umowa zlecenie", |   "commission_contract": "Umowa zlecenie", | ||||||
|   "b2b_contract": "Kontrakt B2B", |   "b2b_contract": "Kontrakt B2B", | ||||||
|   "board_member_contract": "Członek zarządu" |   "board_member_contract": "Członek zarządu", | ||||||
|  |   "vacation": "Urlop wypoczynkowy", | ||||||
|  |   "vacation_on_request": "Urlop na żądanie", | ||||||
|  |   "special_vacation": "Urlop okolicznościowy", | ||||||
|  |   "childcare_vacation": "Opieka nad dzieckiem art 188 kp", | ||||||
|  |   "training_vacation": "Urlop szkoleniowy", | ||||||
|  |   "unpaid_vacation": "Urlop bezpłatny", | ||||||
|  |   "volunteering_vacation": "Wolontariat", | ||||||
|  |   "look_for_work_vacation": "Urlop na poszukiwanie pracy", | ||||||
|  |   "time_in_lieu": "Odbiór za święto", | ||||||
|  |   "sick_vacation": "Zwolnienie lekarskie" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ use Toby\Http\Controllers\LogoutController; | |||||||
| use Toby\Http\Controllers\SelectYearPeriodController; | use Toby\Http\Controllers\SelectYearPeriodController; | ||||||
| use Toby\Http\Controllers\UserController; | use Toby\Http\Controllers\UserController; | ||||||
| use Toby\Http\Controllers\VacationLimitController; | use Toby\Http\Controllers\VacationLimitController; | ||||||
|  | use Toby\Http\Controllers\VacationRequestController; | ||||||
|  |  | ||||||
| Route::middleware("auth")->group(function (): void { | Route::middleware("auth")->group(function (): void { | ||||||
|     Route::get("/", fn() => inertia("Dashboard"))->name("dashboard"); |     Route::get("/", fn() => inertia("Dashboard"))->name("dashboard"); | ||||||
| @@ -22,6 +23,9 @@ Route::middleware("auth")->group(function (): void { | |||||||
|     Route::get("/vacation-limits", [VacationLimitController::class, "edit"])->name("vacation.limits"); |     Route::get("/vacation-limits", [VacationLimitController::class, "edit"])->name("vacation.limits"); | ||||||
|     Route::put("/vacation-limits", [VacationLimitController::class, "update"]); |     Route::put("/vacation-limits", [VacationLimitController::class, "update"]); | ||||||
|  |  | ||||||
|  |     Route::get("/vacation-requests", [VacationRequestController::class, "index"]); | ||||||
|  |     Route::get("/vacation-requests/create", [VacationRequestController::class, "create"]); | ||||||
|  |  | ||||||
|     Route::post("year-periods/{yearPeriod}/select", SelectYearPeriodController::class)->name("year-periods.select"); |     Route::post("year-periods/{yearPeriod}/select", SelectYearPeriodController::class)->name("year-periods.select"); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user