diff --git a/.gitignore b/.gitignore index 1b227af..eea0bed 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ .env.testing .phpactor.json .phpunit.result.cache +_ide_helper.php +_ide_helper_models.php +.phpstorm.meta.php Homestead.json Homestead.yaml auth.json @@ -20,7 +23,6 @@ yarn-error.log /.fleet /.idea /.nova -/.vscode /.zed /.claude .mcp.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a815317 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,17 @@ +{ + "recommendations": [ + "bmewburn.vscode-intelephense-client", + "laravel.vscode-laravel", + "onecentlin.laravel-blade", + "open-southeners.laravel-pint", + "mehedidracula.php-namespace-resolver", + "amiralizadeh9480.laravel-extra-intellisense", + "ryannaddy.laravel-artisan", + "mikestead.dotenv", + "bradlc.vscode-tailwindcss" + ], + "unwantedRecommendations": [ + "hbenl.vscode-test-explorer", + "felixfbecker.php-intellisense" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..830f0c2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,134 @@ +{ + "intelephense.environment.phpVersion": "8.4.15", + "intelephense.environment.includePaths": [ + "vendor" + ], + "intelephense.files.exclude": [ + "**/.git/**", + "**/.svn/**", + "**/.hg/**", + "**/CVS/**", + "**/.DS_Store/**", + "**/node_modules/**", + "**/bower_components/**", + "**/vendor/**/{Tests,tests}/**", + "**/.history/**", + "**/vendor/**/{examples,Examples}/**", + "**/storage/framework/**", + "**/bootstrap/cache/**", + "**/public/build/**" + ], + "intelephense.diagnostics.undefinedMethods": true, + "intelephense.diagnostics.undefinedFunctions": true, + "intelephense.diagnostics.undefinedProperties": true, + "intelephense.completion.fullyQualifyGlobalConstantsAndFunctions": false, + "intelephense.completion.insertUseDeclaration": true, + "intelephense.format.enable": false, + "intelephense.stubs": [ + "apache", + "bcmath", + "bz2", + "calendar", + "com_dotnet", + "Core", + "ctype", + "curl", + "date", + "dba", + "dom", + "enchant", + "exif", + "FFI", + "fileinfo", + "filter", + "fpm", + "ftp", + "gd", + "gettext", + "gmp", + "hash", + "iconv", + "imap", + "intl", + "json", + "ldap", + "libxml", + "mbstring", + "meta", + "mysqli", + "oci8", + "odbc", + "openssl", + "pcntl", + "pcre", + "PDO", + "pdo_ibm", + "pdo_mysql", + "pdo_pgsql", + "pdo_sqlite", + "pgsql", + "Phar", + "posix", + "pspell", + "readline", + "Reflection", + "session", + "shmop", + "SimpleXML", + "snmp", + "soap", + "sockets", + "sodium", + "SPL", + "sqlite3", + "standard", + "superglobals", + "sysvmsg", + "sysvsem", + "sysvshm", + "tidy", + "tokenizer", + "xml", + "xmlreader", + "xmlrpc", + "xmlwriter", + "xsl", + "Zend OPcache", + "zip", + "zlib" + ], + "[php]": { + "editor.defaultFormatter": "open-southeners.laravel-pint", + "editor.formatOnSave": true, + "editor.tabSize": 4, + "editor.insertSpaces": true + }, + "[blade]": { + "editor.defaultFormatter": "onecentlin.laravel-blade", + "editor.tabSize": 4, + "editor.insertSpaces": true + }, + "[css]": { + "editor.tabSize": 4, + "editor.insertSpaces": true, + "editor.detectIndentation": false + }, + "laravel-pint.enable": true, + "laravel-pint.executablePath": "vendor/bin/pint", + "laravel-pint.configPath": "pint.json", + "files.associations": { + "*.blade.php": "blade" + }, + "emmet.includeLanguages": { + "blade": "html" + }, + "search.exclude": { + "**/vendor": true, + "**/node_modules": true, + "**/public/build": true, + "**/storage/framework": true, + "_ide_helper.php": true, + "_ide_helper_models.php": true, + ".phpstorm.meta.php": true + } +} diff --git a/app/Enums/AssetType.php b/app/Enums/AssetType.php new file mode 100644 index 0000000..1e8b524 --- /dev/null +++ b/app/Enums/AssetType.php @@ -0,0 +1,27 @@ + 'Photo', + self::RESUME => 'Resume', + self::THREE_D_PRINTS => '3D Print', + }; + } + + public function storageDirectory(): string + { + return match ($this) { + self::THREE_D_PRINTS => '3D_prints', + default => 'photos', + }; + } +} diff --git a/app/Livewire/Auth/ForgotPassword.php b/app/Livewire/Auth/ForgotPassword.php deleted file mode 100644 index a513938..0000000 --- a/app/Livewire/Auth/ForgotPassword.php +++ /dev/null @@ -1,43 +0,0 @@ -validate([ - 'email' => ['required', 'string', 'email'], - ]); - - // We will send the password reset link to this user. Once we have attempted - // to send the link, we will examine the response then see the message we - // need to show to the user. Finally, we'll send out a proper response. - $status = Password::sendResetLink( - $this->only('email') - ); - - if ($status != Password::RESET_LINK_SENT) { - $this->addError('email', __($status)); - - return; - } - - $this->reset('email'); - - session()->flash('status', __($status)); - } -} diff --git a/app/Livewire/Auth/Login.php b/app/Livewire/Auth/Login.php index 00f19ff..dd40a7b 100644 --- a/app/Livewire/Auth/Login.php +++ b/app/Livewire/Auth/Login.php @@ -17,8 +17,6 @@ public function render() public function login(): void { - $this->validate(); - $this->form->authenticate(); Session::regenerate(); diff --git a/app/Livewire/Auth/ResetPassword.php b/app/Livewire/Auth/ResetPassword.php deleted file mode 100644 index d1c310f..0000000 --- a/app/Livewire/Auth/ResetPassword.php +++ /dev/null @@ -1,77 +0,0 @@ -token = $token; - - $this->email = request()->string('email'); - } - - /** - * Reset the password for the given user. - */ - public function resetPassword(): void - { - $this->validate([ - 'token' => ['required'], - 'email' => ['required', 'string', 'email'], - 'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()], - ]); - - // Here we will attempt to reset the user's password. If it is successful we - // will update the password on an actual user model and persist it to the - // database. Otherwise we will parse the error and return the response. - $status = Password::reset( - $this->only('email', 'password', 'password_confirmation', 'token'), - function ($user) { - $user->forceFill([ - 'password' => Hash::make($this->password), - 'remember_token' => Str::random(60), - ])->save(); - - event(new PasswordReset($user)); - } - ); - - // If the password was successfully reset, we will redirect the user back to - // the application's home authenticated view. If there is an error we can - // redirect them back to where they came from with their error message. - if ($status != Password::PASSWORD_RESET) { - $this->addError('email', __($status)); - - return; - } - - Session::flash('status', __($status)); - - $this->redirectRoute('login', navigate: true); - } -} diff --git a/app/Livewire/Forms/PhotoForm.php b/app/Livewire/Forms/PhotoForm.php index e7c9b02..c31aa38 100644 --- a/app/Livewire/Forms/PhotoForm.php +++ b/app/Livewire/Forms/PhotoForm.php @@ -2,30 +2,26 @@ namespace App\Livewire\Forms; +use App\Enums\AssetType; use App\Models\Asset; use Flux\Flux; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; +use Illuminate\Validation\Rule; use Intervention\Image\Drivers\Gd\Driver; use Intervention\Image\ImageManager; -use Livewire\Attributes\Validate; use Livewire\Form; class PhotoForm extends Form { - #[Validate('required|string')] public string $name = ''; - #[Validate('nullable|date')] public string $capturedAt = ''; - #[Validate('nullable|string|max:255')] public string $description = ''; - #[Validate('required|integer|in:1,3', message: 'The Photo Type is Required')] - public int $type = Asset::PHOTO; + public int $type = AssetType::PHOTO->value; - #[Validate('image:mimes:png,jpg,jpeg,gif,jfif')] public $photo; public function store() @@ -72,10 +68,7 @@ public function destroy($id) private function getStorageDirectory(): string { - return match ($this->type) { - Asset::THREE_D_PRINTS => '3D_prints', - default => 'photos', - }; + return AssetType::from($this->type)->storageDirectory(); } private function generateFilename(): string @@ -98,4 +91,26 @@ private function processImage(): void $image->save($this->photo->getRealPath()); } } + + protected function rules(): array + { + return [ + 'name' => 'required|string', + 'capturedAt' => 'nullable|date', + 'description' => 'nullable|string|max:255', + 'type' => [ + 'required', + 'integer', + Rule::in([AssetType::PHOTO->value, AssetType::THREE_D_PRINTS->value]), + ], + 'photo' => 'image:mimes:png,jpg,jpeg,gif,jfif', + ]; + } + + protected function messages(): array + { + return [ + 'type.in' => 'The Photo Type is Required', + ]; + } } diff --git a/app/Livewire/Forms/TechnologyForm.php b/app/Livewire/Forms/TechnologyForm.php index 11ed04f..77d27e6 100644 --- a/app/Livewire/Forms/TechnologyForm.php +++ b/app/Livewire/Forms/TechnologyForm.php @@ -18,9 +18,7 @@ class TechnologyForm extends Form #[Validate('required|string')] public $icon; - public ?int $technologyId; - - public function store() + public function store(): void { $this->validate(); @@ -36,29 +34,4 @@ public function store() Flux::toast(variant: 'success', text: 'Technology Created!', duration: 3000); } - - public function edit(int $technologyId) - { - $technology = Technology::findOrFail($technologyId); - $this->technologyId = $technologyId; - - $this->name = $technology->name; - $this->description = $technology->description; - $this->icon = $technology->icon; - - Flux::modal('edit-technology')->show(); - } - - public function update() - { - $this->validate(); - - Technology::findOrFail($this->technologyId)->update([ - 'name' => $this->name, - 'description' => $this->description, - 'icon' => $this->icon, - ]); - - Flux::toast(variant: 'success', text: 'Technology Updated!', duration: 3000); - } } diff --git a/app/Livewire/Navigation.php b/app/Livewire/Navigation.php index 369cbc2..5f860a8 100644 --- a/app/Livewire/Navigation.php +++ b/app/Livewire/Navigation.php @@ -2,6 +2,7 @@ namespace App\Livewire; +use App\Enums\AssetType; use App\Models\Asset; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; @@ -13,9 +14,9 @@ public function render() { return view('navigation', [ 'resume' => Asset::query() - ->where('type_id', Asset::RESUME) + ->where('type_id', AssetType::RESUME->value) ->latest() - ->first()?->slug + ->first()?->slug, ]); } diff --git a/app/Livewire/Technologies.php b/app/Livewire/Pages/Technologies/Edit.php similarity index 55% rename from app/Livewire/Technologies.php rename to app/Livewire/Pages/Technologies/Edit.php index 58830ba..0e12e86 100644 --- a/app/Livewire/Technologies.php +++ b/app/Livewire/Pages/Technologies/Edit.php @@ -1,27 +1,31 @@ sortBy = 'name'; + $this->sortDirection = 'asc'; + } public function render() { - return view('livewire.technologies'); + return view('livewire.pages.technologies.edit'); } #[Computed] @@ -32,25 +36,14 @@ public function technologies() ->paginate(10); } - public function store() + public function store(): void { $this->createForm->store(); } - public function edit(int $technologyId) - { - $this->editForm->edit($technologyId); - } - - public function update() + #[On('technology-deleted')] + public function refreshTechnologies(): void { - $this->editForm->update(); - } - - public function destroy($id) - { - Technology::findOrFail($id)->delete(); - - Flux::toast(variant: 'success', text: 'Technology Deleted!', duration: 3000); + unset($this->technologies); } } diff --git a/app/Livewire/Pages/Technologies/Show.php b/app/Livewire/Pages/Technologies/Show.php new file mode 100644 index 0000000..73f7282 --- /dev/null +++ b/app/Livewire/Pages/Technologies/Show.php @@ -0,0 +1,16 @@ + Technology::query()->orderBy('name')->get(), + ]); + } +} diff --git a/app/Livewire/Pages/Technologies/Tables/Row.php b/app/Livewire/Pages/Technologies/Tables/Row.php new file mode 100644 index 0000000..301bc50 --- /dev/null +++ b/app/Livewire/Pages/Technologies/Tables/Row.php @@ -0,0 +1,57 @@ +technology = $technology; + $this->name = $technology->name; + $this->description = $technology->description; + $this->icon = $technology->icon; + } + + public function updated(string $property): void + { + if (! in_array($property, ['name', 'description', 'icon'], true)) { + return; + } + + $this->validateOnly($property); + + $this->technology->update([$property => $this->{$property}]); + + Flux::toast(variant: 'success', text: 'Technology Updated!', duration: 2000); + } + + public function destroy(): void + { + $this->technology->delete(); + + Flux::toast(variant: 'success', text: 'Technology Deleted!', duration: 3000); + + $this->dispatch('technology-deleted'); + } + + public function render() + { + return view('livewire.pages.technologies.partials.row'); + } +} diff --git a/app/Livewire/Photos/Gallery.php b/app/Livewire/Photos/Gallery.php index ff44f8c..5f84ae7 100644 --- a/app/Livewire/Photos/Gallery.php +++ b/app/Livewire/Photos/Gallery.php @@ -2,6 +2,7 @@ namespace App\Livewire\Photos; +use App\Enums\AssetType; use App\Livewire\Forms\PhotoForm; use App\Models\Asset; use Livewire\Attributes\Computed; @@ -17,7 +18,7 @@ class Gallery extends Component public string $emptyMessage = 'No Photos'; - public array|int $type = Asset::PHOTO; + public array|int $type = AssetType::PHOTO->value; public PhotoForm $form; diff --git a/app/Livewire/Photos/Uploader.php b/app/Livewire/Photos/Uploader.php index bcea0b0..7ecc584 100644 --- a/app/Livewire/Photos/Uploader.php +++ b/app/Livewire/Photos/Uploader.php @@ -2,8 +2,8 @@ namespace App\Livewire\Photos; +use App\Enums\AssetType; use App\Livewire\Forms\PhotoForm; -use App\Models\Asset; use Livewire\Component; use Livewire\WithFileUploads; @@ -17,7 +17,7 @@ class Uploader extends Component public bool $showGallery = true; - public array|int $galleryType = Asset::PHOTO; + public array|int $galleryType = AssetType::PHOTO->value; public function render() { diff --git a/app/Livewire/Resume.php b/app/Livewire/Resume.php index 647f58c..18e05e8 100644 --- a/app/Livewire/Resume.php +++ b/app/Livewire/Resume.php @@ -2,6 +2,7 @@ namespace App\Livewire; +use App\Enums\AssetType; use App\Models\Asset; use Flux\Flux; use Illuminate\Support\Facades\Storage; @@ -9,6 +10,7 @@ use Livewire\Attributes\Computed; use Livewire\Attributes\Validate; use Livewire\Component; +use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; use Livewire\WithFileUploads; class Resume extends Component @@ -16,7 +18,7 @@ class Resume extends Component use WithFileUploads; #[Validate('required|file|mimes:pdf')] - public $resume; + public ?TemporaryUploadedFile $resume = null; public function render() { @@ -32,7 +34,7 @@ public function store() $path = $this->resume->storePubliclyAs('resumes', $name, 's3'); Asset::create([ - 'type_id' => Asset::RESUME, + 'type_id' => AssetType::RESUME->value, 'slug' => Str::uuid(), 'name' => $name, 'path' => $path, @@ -60,6 +62,6 @@ public function destroy($id) #[Computed] public function resumes() { - return Asset::where('type_id', Asset::RESUME)->get(); + return Asset::where('type_id', AssetType::RESUME->value)->get(); } } diff --git a/app/Livewire/Traits/TableHelpers.php b/app/Livewire/Traits/TableHelpers.php index 914a0b5..18edaec 100644 --- a/app/Livewire/Traits/TableHelpers.php +++ b/app/Livewire/Traits/TableHelpers.php @@ -6,9 +6,9 @@ trait TableHelpers { public string $search = ''; - public $sortBy = 'id'; + public string $sortBy = 'id'; - public $sortDirection = 'desc'; + public string $sortDirection = 'desc'; public int $perPage = 25; diff --git a/app/Models/Asset.php b/app/Models/Asset.php index d967606..8c9d0e3 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -2,17 +2,12 @@ namespace App\Models; +use App\Enums\AssetType; use Carbon\Carbon; use Illuminate\Contracts\Database\Eloquent\Builder; class Asset extends Model { - const PHOTO = 1; - - const RESUME = 2; - - const THREE_D_PRINTS = 3; - protected $fillable = [ 'type_id', 'name', @@ -32,6 +27,7 @@ public static function boot() public function casts(): array { return [ + 'type_id' => AssetType::class, 'data' => 'array', ]; } diff --git a/composer.json b/composer.json index c502feb..12a0004 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,6 @@ "license": "MIT", "require": { "php": "^8.4", - "glhd/laravel-dumper": "^3.0", "intervention/image": "^3.11", "kyledoesdev/essentials": "0.0.6", "laravel/framework": "^12.16", @@ -28,7 +27,9 @@ }, "require-dev": { "barryvdh/laravel-debugbar": "^3.14", + "barryvdh/laravel-ide-helper": "^3.7", "fakerphp/faker": "^1.23", + "glhd/laravel-dumper": "^3.0", "laravel/boost": "^2.2", "laravel/breeze": "^2.2", "laravel/pail": "^1.1", @@ -54,10 +55,13 @@ "scripts": { "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", - "@php artisan package:discover --ansi" + "@php artisan package:discover --ansi", + "@php artisan ide-helper:models --nowrite --no-interaction --ansi" ], "post-update-cmd": [ - "@php artisan vendor:publish --tag=laravel-assets --ansi --force" + "@php artisan vendor:publish --tag=laravel-assets --ansi --force", + "@php artisan ide-helper:generate --ansi", + "@php artisan ide-helper:meta --ansi" ], "post-root-package-install": [ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" diff --git a/composer.lock b/composer.lock index 2fad678..2365059 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9a9251da0a0a54c65674b3401a7d21c4", + "content-hash": "60069dfba7d1057512e3b5bdef6185f9", "packages": [ { "name": "aws/aws-crt-php", @@ -865,69 +865,6 @@ ], "time": "2025-12-03T09:33:47+00:00" }, - { - "name": "glhd/laravel-dumper", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/glhd/laravel-dumper.git", - "reference": "59248e3b7fe6892df6d495f2bb57e456aa0b1b01" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/glhd/laravel-dumper/zipball/59248e3b7fe6892df6d495f2bb57e456aa0b1b01", - "reference": "59248e3b7fe6892df6d495f2bb57e456aa0b1b01", - "shasum": "" - }, - "require": { - "ext-json": "*", - "illuminate/support": "^10|^11|^12|^13", - "php": ">=8.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.9", - "mockery/mockery": "^1.4", - "orchestra/testbench": "^6.47|^7.55|^8.36|^9.15|^10.8|^11|12.x-dev|dev-master|dev-main", - "phpunit/phpunit": "^9|^10.5|^11.5|^12.5|^13.0.5" - }, - "suggest": { - "jdorn/sql-formatter": "Allows better SQL formatting and highlighting" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Glhd\\LaravelDumper\\LaravelDumperServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Glhd\\LaravelDumper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Morrell", - "homepage": "http://www.cmorrell.com" - } - ], - "keywords": [ - "laravel" - ], - "support": { - "issues": "https://github.com/glhd/laravel-dumper/issues", - "source": "https://github.com/glhd/laravel-dumper/tree/3.0.1" - }, - "time": "2026-03-23T14:40:11+00:00" - }, { "name": "graham-campbell/result-type", "version": "v1.1.4", @@ -8200,6 +8137,153 @@ ], "time": "2026-01-23T15:03:22+00:00" }, + { + "name": "barryvdh/laravel-ide-helper", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-ide-helper.git", + "reference": "ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a", + "reference": "ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a", + "shasum": "" + }, + "require": { + "barryvdh/reflection-docblock": "^2.4", + "composer/class-map-generator": "^1.0", + "ext-json": "*", + "illuminate/console": "^11.15 || ^12 || ^13.0", + "illuminate/database": "^11.15 || ^12 || ^13.0", + "illuminate/filesystem": "^11.15 || ^12 || ^13.0", + "illuminate/support": "^11.15 || ^12 || ^13.0", + "php": "^8.2" + }, + "require-dev": { + "ext-pdo_sqlite": "*", + "friendsofphp/php-cs-fixer": "^3", + "illuminate/config": "^11.15 || ^12 || ^13.0", + "illuminate/view": "^11.15 || ^12 || ^13.0", + "larastan/larastan": "^3.1", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^9.2 || ^10 || ^11.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5 || ^11.5.3 || ^12.5.12", + "spatie/phpunit-snapshot-assertions": "^4 || ^5", + "vlucas/phpdotenv": "^5" + }, + "suggest": { + "illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9|^10|^11)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Barryvdh\\LaravelIdeHelper\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.", + "keywords": [ + "autocomplete", + "codeintel", + "dev", + "helper", + "ide", + "laravel", + "netbeans", + "phpdoc", + "phpstorm", + "sublime" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-ide-helper/issues", + "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2026-03-17T14:12:51+00:00" + }, + { + "name": "barryvdh/reflection-docblock", + "version": "v2.4.1", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/ReflectionDocBlock.git", + "reference": "4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b", + "reference": "4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.14|^9" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Barryvdh": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "support": { + "source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.4.1" + }, + "time": "2026-03-05T20:09:01+00:00" + }, { "name": "brianium/paratest", "version": "v7.8.5", @@ -8293,6 +8377,154 @@ ], "time": "2026-01-08T08:02:38+00:00" }, + { + "name": "composer/class-map-generator", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "86d8208fc3c649a3a999daf1a63c25201be2990f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/86d8208fc3c649a3a999daf1a63c25201be2990f", + "reference": "86d8208fc3c649a3a999daf1a63c25201be2990f", + "shasum": "" + }, + "require": { + "composer/pcre": "^2.1 || ^3.1", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7 || ^8" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-deprecation-rules": "^1 || ^2", + "phpstan/phpstan-phpunit": "^1 || ^2", + "phpstan/phpstan-strict-rules": "^1.1 || ^2", + "phpunit/phpunit": "^8", + "symfony/filesystem": "^5.4 || ^6 || ^7 || ^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.7.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2026-05-05T09:17:07+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, { "name": "doctrine/deprecations", "version": "1.1.6", @@ -8536,6 +8768,69 @@ ], "time": "2025-08-08T12:00:00+00:00" }, + { + "name": "glhd/laravel-dumper", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/glhd/laravel-dumper.git", + "reference": "59248e3b7fe6892df6d495f2bb57e456aa0b1b01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/glhd/laravel-dumper/zipball/59248e3b7fe6892df6d495f2bb57e456aa0b1b01", + "reference": "59248e3b7fe6892df6d495f2bb57e456aa0b1b01", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/support": "^10|^11|^12|^13", + "php": ">=8.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.9", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^6.47|^7.55|^8.36|^9.15|^10.8|^11|12.x-dev|dev-master|dev-main", + "phpunit/phpunit": "^9|^10.5|^11.5|^12.5|^13.0.5" + }, + "suggest": { + "jdorn/sql-formatter": "Allows better SQL formatting and highlighting" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Glhd\\LaravelDumper\\LaravelDumperServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Glhd\\LaravelDumper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Morrell", + "homepage": "http://www.cmorrell.com" + } + ], + "keywords": [ + "laravel" + ], + "support": { + "issues": "https://github.com/glhd/laravel-dumper/issues", + "source": "https://github.com/glhd/laravel-dumper/tree/3.0.1" + }, + "time": "2026-03-23T14:40:11+00:00" + }, { "name": "hamcrest/hamcrest-php", "version": "v2.1.1", diff --git a/config/auth.php b/config/auth.php index 0ba5d5d..c645647 100644 --- a/config/auth.php +++ b/config/auth.php @@ -1,5 +1,7 @@ [ 'guard' => env('AUTH_GUARD', 'web'), - 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), ], /* @@ -62,7 +63,7 @@ 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), + 'model' => env('AUTH_MODEL', User::class), ], // 'users' => [ @@ -71,34 +72,6 @@ // ], ], - /* - |-------------------------------------------------------------------------- - | Resetting Passwords - |-------------------------------------------------------------------------- - | - | These configuration options specify the behavior of Laravel's password - | reset functionality, including the table utilized for token storage - | and the user provider that is invoked to actually retrieve users. - | - | The expiry time is the number of minutes that each reset token will be - | considered valid. This security feature keeps tokens short-lived so - | they have less time to be guessed. You may change this as needed. - | - | The throttle setting is the number of seconds a user must wait before - | generating more password reset tokens. This prevents the user from - | quickly generating a very large amount of password reset tokens. - | - */ - - 'passwords' => [ - 'users' => [ - 'provider' => 'users', - 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), - 'expire' => 60, - 'throttle' => 60, - ], - ], - /* |-------------------------------------------------------------------------- | Password Confirmation Timeout diff --git a/database/factories/AssetFactory.php b/database/factories/AssetFactory.php index 2d9f54c..8ad0161 100644 --- a/database/factories/AssetFactory.php +++ b/database/factories/AssetFactory.php @@ -2,12 +2,13 @@ namespace Database\Factories; +use App\Enums\AssetType; use App\Models\Asset; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Asset> + * @extends Factory */ class AssetFactory extends Factory { @@ -21,7 +22,7 @@ public function definition(): array $name = $this->faker->words(3, true); return [ - 'type_id' => $this->faker->randomElement([Asset::PHOTO, Asset::RESUME]), + 'type_id' => $this->faker->randomElement([AssetType::PHOTO->value, AssetType::RESUME->value]), 'name' => $name, 'slug' => Str::slug($name), 'path' => $this->faker->filePath(), @@ -40,7 +41,7 @@ public function definition(): array public function photo(): static { return $this->state(fn (array $attributes) => [ - 'type_id' => Asset::PHOTO, + 'type_id' => AssetType::PHOTO->value, 'mime_type' => $this->faker->randomElement([ 'image/jpeg', 'image/png', @@ -58,7 +59,7 @@ public function photo(): static public function resume(): static { return $this->state(fn (array $attributes) => [ - 'type_id' => Asset::RESUME, + 'type_id' => AssetType::RESUME->value, 'mime_type' => $this->faker->randomElement([ 'application/pdf', ]), diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 05fb5d9..85a84e9 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -21,12 +21,6 @@ public function up(): void $table->timestamps(); }); - Schema::create('password_reset_tokens', function (Blueprint $table) { - $table->string('email')->primary(); - $table->string('token'); - $table->timestamp('created_at')->nullable(); - }); - Schema::create('sessions', function (Blueprint $table) { $table->string('id')->primary(); $table->foreignId('user_id')->nullable()->index(); @@ -43,7 +37,6 @@ public function up(): void public function down(): void { Schema::dropIfExists('users'); - Schema::dropIfExists('password_reset_tokens'); Schema::dropIfExists('sessions'); } }; diff --git a/database/migrations/2026_05_20_223846_drop_password_reset_tokens_table.php b/database/migrations/2026_05_20_223846_drop_password_reset_tokens_table.php new file mode 100644 index 0000000..9c4cc19 --- /dev/null +++ b/database/migrations/2026_05_20_223846_drop_password_reset_tokens_table.php @@ -0,0 +1,22 @@ +string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } +}; diff --git a/resources/css/app.css b/resources/css/app.css index 4a1201a..c2f4ab2 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,6 +1,5 @@ @import 'tailwindcss'; @import '../../vendor/livewire/flux/dist/flux.css'; - @plugin '@tailwindcss/forms'; @plugin '@tailwindcss/typography'; @@ -9,18 +8,6 @@ @source '../../vendor/livewire/flux/stubs/**/*.blade.php'; @source "../views"; -@theme { - --font-sans: Inter, sans-serif; -} - -/* - The default border color has changed to `currentColor` in Tailwind CSS v4, - so we've added these compatibility styles to make sure everything still - looks the same as it did with Tailwind CSS v3. - - If we ever want to remove these styles, we need to add an explicit border - color utility to any element that depends on these defaults. -*/ @layer base { *, ::after, @@ -34,140 +21,18 @@ @custom-variant dark (&:where(.dark, .dark *)); @layer utilities { - [class*=' devicon-'], - [class^='devicon-'] { - margin-left: auto; - margin-right: auto; - } - - [data-flux-editor] [data-slot='content'] code:not(pre code) { - @apply text-zinc-900! dark:bg-zinc-200!; - } - - [data-flux-editor] [data-slot='content'] pre { - @apply text-zinc-900! dark:bg-zinc-200!; - } - - [data-flux-editor] [data-slot='content'] pre > code { - @apply text-zinc-900! dark:bg-zinc-200!; - } - - a.external-link::after { - content: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3ODcxNkMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1hcnJvdy11cC1yaWdodCI+PHBhdGggZD0iTTcgN2gxMHYxMCIvPjxwYXRoIGQ9Ik03IDE3IDE3IDciLz48L3N2Zz4='); - margin-left: 1px; - } - - a.prezet-heading { - margin-right: 8px; - scroll-margin-top: 112px; - } - - lite-youtube { - background-color: #000; - position: relative; - display: block; - contain: content; - background-position: center center; - background-size: cover; - cursor: pointer; - max-width: 720px; - } - - lite-youtube::before { - content: attr(data-title); - display: block; - position: absolute; - top: 0; - background-image: linear-gradient( - 180deg, - rgb(0 0 0 / 67%) 0, - rgb(0 0 0 / 54%) 14%, - rgb(0 0 0 / 15%) 54%, - rgb(0 0 0 / 5%) 72%, - rgb(0 0 0 / 0%) 94% - ); - height: 99px; - width: 100%; - font-family: 'YouTube Noto', Roboto, Arial, Helvetica, sans-serif; - color: hsl(0deg 0% 93.33%); - text-shadow: 0 0 2px rgba(0, 0, 0, 0.5); - font-size: 18px; - padding: 25px 20px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - box-sizing: border-box; - } - - lite-youtube:hover::before { - color: #fff; - } - - lite-youtube::after { - content: ''; - display: block; - padding-bottom: calc(100% / (16 / 9)); - } - - lite-youtube > iframe { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - border: 0; - } - - lite-youtube > .lty-playbtn { - display: block; - width: 100%; - height: 100%; - background: no-repeat center/68px 48px; - background-image: url('data:image/svg+xml;utf8,'); - position: absolute; - cursor: pointer; - z-index: 1; - filter: grayscale(100%); - transition: filter 0.1s cubic-bezier(0, 0, 0.2, 1); - border: 0; - } - - lite-youtube .lty-playbtn:focus, - lite-youtube:hover > .lty-playbtn { - filter: none; - } - - lite-youtube.lyt-activated { - cursor: unset; - } - - lite-youtube.lyt-activated::before, - lite-youtube.lyt-activated > .lty-playbtn { - opacity: 0; - pointer-events: none; - } - - .lyt-visually-hidden { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - } -} + [class*=' devicon-'], + [class^='devicon-'] { + margin-left: auto; + margin-right: auto; + } -@theme { - --color-accent: var(--color-violet-500); - --color-accent-content: var(--color-violet-600); - --color-accent-foreground: var(--color-white); + a.external-link::after { + content: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3ODcxNkMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1hcnJvdy11cC1yaWdodCI+PHBhdGggZD0iTTcgN2gxMHYxMCIvPjxwYXRoIGQ9Ik03IDE3IDE3IDciLz48L3N2Zz4='); + margin-left: 1px; + } } -@layer theme { - .dark { - --color-accent: var(--color-violet-500); - --color-accent-content: var(--color-violet-400); - --color-accent-foreground: var(--color-white); - } -} \ No newline at end of file +@import './components/theme.css'; +@import './components/flux.css'; +@import './components/prezet.css'; diff --git a/resources/css/components/flux.css b/resources/css/components/flux.css new file mode 100644 index 0000000..6a95915 --- /dev/null +++ b/resources/css/components/flux.css @@ -0,0 +1,29 @@ +[data-flux-tab], +[data-flux-navbar-item], +[data-flux-navlist-item], +[data-flux-sidebar-item], +[data-flux-menu-item], +[data-flux-button] { + @apply cursor-pointer; +} + +[data-flux-tab]:disabled, +[data-flux-navbar-item]:disabled, +[data-flux-navlist-item]:disabled, +[data-flux-sidebar-item]:disabled, +[data-flux-menu-item]:disabled, +[data-flux-button]:disabled { + @apply cursor-not-allowed; +} + +[data-flux-editor] [data-slot='content'] code:not(pre code) { + @apply text-zinc-900! dark:bg-zinc-200!; +} + +[data-flux-editor] [data-slot='content'] pre { + @apply text-zinc-900! dark:bg-zinc-200!; +} + +[data-flux-editor] [data-slot='content'] pre > code { + @apply text-zinc-900! dark:bg-zinc-200!; +} \ No newline at end of file diff --git a/resources/css/components/prezet.css b/resources/css/components/prezet.css new file mode 100644 index 0000000..bd013c5 --- /dev/null +++ b/resources/css/components/prezet.css @@ -0,0 +1,99 @@ + a.prezet-heading { + margin-right: 8px; + scroll-margin-top: 112px; + } + + lite-youtube { + background-color: #000; + position: relative; + display: block; + contain: content; + background-position: center center; + background-size: cover; + cursor: pointer; + max-width: 720px; + } + + lite-youtube::before { + content: attr(data-title); + display: block; + position: absolute; + top: 0; + background-image: linear-gradient( + 180deg, + rgb(0 0 0 / 67%) 0, + rgb(0 0 0 / 54%) 14%, + rgb(0 0 0 / 15%) 54%, + rgb(0 0 0 / 5%) 72%, + rgb(0 0 0 / 0%) 94% + ); + height: 99px; + width: 100%; + font-family: 'YouTube Noto', Roboto, Arial, Helvetica, sans-serif; + color: hsl(0deg 0% 93.33%); + text-shadow: 0 0 2px rgba(0, 0, 0, 0.5); + font-size: 18px; + padding: 25px 20px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + box-sizing: border-box; + } + + lite-youtube:hover::before { + color: #fff; + } + + lite-youtube::after { + content: ''; + display: block; + padding-bottom: calc(100% / (16 / 9)); + } + + lite-youtube > iframe { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + border: 0; + } + + lite-youtube > .lty-playbtn { + display: block; + width: 100%; + height: 100%; + background: no-repeat center/68px 48px; + background-image: url('data:image/svg+xml;utf8,'); + position: absolute; + cursor: pointer; + z-index: 1; + filter: grayscale(100%); + transition: filter 0.1s cubic-bezier(0, 0, 0.2, 1); + border: 0; + } + + lite-youtube .lty-playbtn:focus, + lite-youtube:hover > .lty-playbtn { + filter: none; + } + + lite-youtube.lyt-activated { + cursor: unset; + } + + lite-youtube.lyt-activated::before, + lite-youtube.lyt-activated > .lty-playbtn { + opacity: 0; + pointer-events: none; + } + + .lyt-visually-hidden { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; + } \ No newline at end of file diff --git a/resources/css/components/theme.css b/resources/css/components/theme.css new file mode 100644 index 0000000..ade05f1 --- /dev/null +++ b/resources/css/components/theme.css @@ -0,0 +1,15 @@ +@theme { + --font-sans: Inter, sans-serif; + + --color-accent: var(--color-violet-500); + --color-accent-content: var(--color-violet-600); + --color-accent-foreground: var(--color-white); +} + +@layer theme { + .dark { + --color-accent: var(--color-violet-500); + --color-accent-content: var(--color-violet-400); + --color-accent-foreground: var(--color-white); + } +} diff --git a/resources/views/livewire/dashboard.blade.php b/resources/views/livewire/dashboard.blade.php index 75e3074..0c56b3d 100644 --- a/resources/views/livewire/dashboard.blade.php +++ b/resources/views/livewire/dashboard.blade.php @@ -63,7 +63,7 @@ Resumes - + Technology diff --git a/resources/views/livewire/navigation.blade.php b/resources/views/livewire/navigation.blade.php index b3cee59..23cd275 100644 --- a/resources/views/livewire/navigation.blade.php +++ b/resources/views/livewire/navigation.blade.php @@ -125,6 +125,7 @@ -
- {{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }} -
- -
- -
- -
- -
- - {{ __('Email Password Reset Link') }} - -
-
- diff --git a/resources/views/livewire/pages/auth/login.blade.php b/resources/views/livewire/pages/auth/login.blade.php index 1916ca9..848f0ff 100644 --- a/resources/views/livewire/pages/auth/login.blade.php +++ b/resources/views/livewire/pages/auth/login.blade.php @@ -19,13 +19,7 @@
- @if (Route::has('password.request')) - - {{ __('Forgot your password?') }} - - @endif - - + Log In
diff --git a/resources/views/livewire/pages/auth/reset-password.blade.php b/resources/views/livewire/pages/auth/reset-password.blade.php deleted file mode 100644 index b0d2e69..0000000 --- a/resources/views/livewire/pages/auth/reset-password.blade.php +++ /dev/null @@ -1,27 +0,0 @@ -
-
-
- Email - - -
- -
- Password - - -
- -
- Confirm Password - - -
- -
- - {{ __('Reset Password') }} - -
-
-
\ No newline at end of file diff --git a/resources/views/livewire/pages/media/games/edit.blade.php b/resources/views/livewire/pages/media/games/edit.blade.php index ba18627..d857d2b 100644 --- a/resources/views/livewire/pages/media/games/edit.blade.php +++ b/resources/views/livewire/pages/media/games/edit.blade.php @@ -34,7 +34,14 @@ class="w-full md:w-1/4" Name @foreach ($states as $state) - {{ $state->label() }} + + {{ $state->label() }} + @endforeach Actions diff --git a/resources/views/livewire/pages/technologies/edit.blade.php b/resources/views/livewire/pages/technologies/edit.blade.php new file mode 100644 index 0000000..c0d72e5 --- /dev/null +++ b/resources/views/livewire/pages/technologies/edit.blade.php @@ -0,0 +1,85 @@ +
+ Technologies + + {{-- Header & Create Model --}} + +
+
+
Technologies
+
+
+ + Create + +
+
+ + {{-- Table of Technologies --}} +
+
+
+ + @forelse ($this->technologies as $technology) + @if ($loop->first) + + Icon + Name + Description + Icon Class + Actions + + @endif + + + @empty + +
+ No Technologies found. +
+
+ @endforelse +
+
+
+
+
+ + {{-- Create Modal --}} + +
+ Create a new Technology. +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + Create +
+
+
diff --git a/resources/views/livewire/pages/technologies/partials/row.blade.php b/resources/views/livewire/pages/technologies/partials/row.blade.php new file mode 100644 index 0000000..332cbe1 --- /dev/null +++ b/resources/views/livewire/pages/technologies/partials/row.blade.php @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/views/livewire/pages/technologies/show.blade.php b/resources/views/livewire/pages/technologies/show.blade.php new file mode 100644 index 0000000..381ee6c --- /dev/null +++ b/resources/views/livewire/pages/technologies/show.blade.php @@ -0,0 +1,36 @@ +
+ Technologies + + +
+ @foreach ($technologies as $technology) +
+
+ {{-- Front --}} +
+
{{ $technology->name }}
+ + +
+ + {{-- Back --}} +
+
{{ $technology->name }}
+ +

{{ $technology->description }}

+
+
+
+ @endforeach +
+
+
diff --git a/resources/views/livewire/photos/uploader.blade.php b/resources/views/livewire/photos/uploader.blade.php index 1d28c80..f95a1a1 100644 --- a/resources/views/livewire/photos/uploader.blade.php +++ b/resources/views/livewire/photos/uploader.blade.php @@ -12,8 +12,8 @@ - Photo - 3D Print + Photo + 3D Print diff --git a/resources/views/livewire/printing.blade.php b/resources/views/livewire/printing.blade.php index 9636993..9e5e23b 100644 --- a/resources/views/livewire/printing.blade.php +++ b/resources/views/livewire/printing.blade.php @@ -8,7 +8,7 @@ @endauth @@ -19,7 +19,7 @@ diff --git a/resources/views/livewire/technologies.blade.php b/resources/views/livewire/technologies.blade.php deleted file mode 100644 index 69b12b1..0000000 --- a/resources/views/livewire/technologies.blade.php +++ /dev/null @@ -1,160 +0,0 @@ -
- Technologies - - @auth - {{-- Header & Create Model --}} - -
-
-
Technologies
-
-
- - Create - -
-
- - {{-- Table of Technologies --}} -
-
-
- - @forelse ($this->technologies as $technology) - @if ($loop->first) - - Icon - Name - Description - Actions - - @endif - - - - - - - - {{ $technology->name }} - - - - {{ $technology->description }} - - - - - - - - Edit - - Delete - - - - - - @empty - -
- No Technologies found. -
-
- @endforelse -
-
-
-
-
- - {{-- Create Modal --}} - -
- Create a new Technology. -
- -
- -
- -
- -
- -
- -
- -
- - Create -
-
- - {{-- Edit Modal --}} - -
- Edit Technology: {{ $this->editForm->name }} -
- -
-
- -
- -
- -
- -
- -
- -
- - Update -
-
-
- @endauth - - @guest - -
- @foreach (App\Models\Technology::all() as $technology) -
-
- {{-- Front --}} -
-
{{ $technology->name }}
- - -
- - {{-- Back --}} -
-
{{ $technology->name }}
- -

{{ $technology->description }}

-
-
-
- @endforeach -
-
- @endguest -
\ No newline at end of file diff --git a/routes/auth.php b/routes/auth.php index 2217d88..b8deb6b 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -1,20 +1,12 @@ group(function () { Route::livewire('admin', Login::class) ->name('login'); - - Route::livewire('forgot-password', ForgotPassword::class) - ->name('password.request'); - - Route::livewire('reset-password/{token}', ResetPassword::class) - ->name('password.reset'); }); Route::middleware('auth')->group(function () { diff --git a/routes/web.php b/routes/web.php index 3ba8ed3..187a2d4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,14 +16,16 @@ use App\Livewire\Media\Music\Show as ShowMusic; use App\Livewire\Media\Tv\Edit as EditTv; use App\Livewire\Media\Tv\Show as ShowTv; +use App\Livewire\Pages\Technologies\Edit as EditTechnologies; +use App\Livewire\Pages\Technologies\Show as ShowTechnologies; use App\Livewire\Panels; use App\Livewire\Photos\Gallery; use App\Livewire\Photos\Uploader; use App\Livewire\Printing; use App\Livewire\Projects; use App\Livewire\Resume; -use App\Livewire\Technologies; use App\Livewire\WorkHistory; +use Illuminate\Auth\Middleware\Authenticate; use Illuminate\Support\Facades\Route; Route::view('/', 'welcome')->name('welcome'); @@ -31,7 +33,7 @@ /* Career Views */ Route::livewire('/education', Education::class)->name('education'); Route::livewire('/projects', Projects::class)->name('projects'); -Route::livewire('/technology', Technologies::class)->name('technologies'); +Route::livewire('/technology', ShowTechnologies::class)->name('technologies'); Route::livewire('/work_history', WorkHistory::class)->name('work_history'); /* Hobby Views */ @@ -45,7 +47,7 @@ Route::get('/asset/{slug}', AssetController::class)->name('asset'); -Route::middleware(['auth'])->group(function () { +Route::middleware(Authenticate::class)->group(function () { Route::livewire('/dashboard', Dashboard::class)->name('dashboard'); Route::get('/connect/{type}', [ConnectionController::class, 'connect'])->name('connect'); @@ -64,6 +66,7 @@ Route::livewire('/tv/edit', EditTv::class)->name('tv.edit'); Route::livewire('/music/edit', EditMusic::class)->name('music.edit'); Route::livewire('/video_games/edit', EditGames::class)->name('video_games.edit'); + Route::livewire('/technology/edit', EditTechnologies::class)->name('technologies.edit'); }); require __DIR__.'/auth.php'; diff --git a/stubs/action.stub b/stubs/action.stub deleted file mode 100644 index 49c6467..0000000 --- a/stubs/action.stub +++ /dev/null @@ -1,15 +0,0 @@ -call('toggleState', $show->getKey(), $value) ->assertStatus(422); })->with(['total_completion', 'type_id']); - -it('destroys a tv show', function () { - $show = Media::factory()->tv()->create(); - - Livewire::test(Edit::class) - ->call('destroy', $show->getKey()) - ->assertOk(); - - expect(Media::find($show->getKey()))->toBeNull(); -}); diff --git a/vite.config.js b/vite.config.js index a8caeec..7bb2bfc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -23,6 +23,12 @@ export default defineConfig({ delay: 1000, // watchKind: ['add', 'change', 'unlink'], // (default) }, + { + name: 'ide-helper:models', + watch: path.resolve('app/**/*.php'), + run: 'php artisan ide-helper:models --nowrite --no-interaction', + delay: 500, + }, ]), prismjs({ languages: ['php', 'javascript', 'html', 'css', 'bash', 'typescript'],