diff --git a/.github/workflows/setup-in-laravel.yml b/.github/workflows/setup-in-laravel.yml index ed52424e..adc09007 100644 --- a/.github/workflows/setup-in-laravel.yml +++ b/.github/workflows/setup-in-laravel.yml @@ -61,6 +61,6 @@ jobs: composer config minimum-stability dev git clone --branch ${{ steps.extract_branch.outputs.branch }} https://github.com/backstagephp/cms.git composer config repositories.backstage-packages path "cms/packages/*" - composer require backstage/cms:dev-${{ steps.extract_branch.outputs.branch }} + composer require backstage/cms:${{ steps.extract_branch.outputs.branch }}-dev composer update --no-interaction php artisan backstage:install diff --git a/composer.json b/composer.json index 4d840df5..65fe0d66 100644 --- a/composer.json +++ b/composer.json @@ -46,6 +46,7 @@ "codewithdennis/filament-select-tree": "^4.0", "filament/filament": "^4.0", "nette/php-generator": "^4.1", + "phiki/phiki": "^2.0", "saade/filament-adjacency-list": "^4.0", "spatie/laravel-package-tools": "^1.18", "spatie/once": "^3.1", @@ -56,7 +57,7 @@ "laravel/pint": "^1.14", "nunomaduro/collision": "^8.1.1||^7.10.0", "larastan/larastan": "^3.7", - "orchestra/testbench": "^9.0.0||^8.22.0", + "orchestra/testbench": "^10.0", "pestphp/pest": "^4.1", "pestphp/pest-plugin-arch": "^4.0", "pestphp/pest-plugin-laravel": "^4.0", @@ -73,6 +74,7 @@ "Backstage\\Fields\\": "packages/fields/src/", "Backstage\\Fields\\Database\\Factories\\": "packages/fields/database/factories/", "Backstage\\Media\\": "packages/media/src/", + "Backstage\\UploadcareField\\": "packages/uploadcare-field/src/", "Backstage\\Database\\Factories\\": "database/factories/", "Backstage\\Database\\Seeders\\": "database/seeders/" }, @@ -82,7 +84,8 @@ }, "autoload-dev": { "psr-4": { - "Backstage\\Tests\\": "tests/" + "Backstage\\Tests\\": "tests/", + "Backstage\\UploadcareField\\Tests\\": "packages/uploadcare-field/tests/" } }, "scripts": { @@ -124,4 +127,4 @@ ], "minimum-stability": "dev", "prefer-stable": true -} \ No newline at end of file +} diff --git a/config/backstage/media.php b/config/backstage/media.php new file mode 100644 index 00000000..13749395 --- /dev/null +++ b/config/backstage/media.php @@ -0,0 +1,73 @@ + [ + 'image/jpeg', + 'image/png', + 'image/webp', + 'image/svg+xml', + 'video/mp4', + 'video/webm', + 'audio/mpeg', + 'audio/ogg', + 'application/pdf', + ], + + 'directory' => 'media', + + 'disk' => config('filament.filesystem_disk', 'public'), + + 'should_preserve_filenames' => false, + + 'should_register_navigation' => true, + + 'visibility' => 'public', + + /* + |-------------------------------------------------------------------------- + | Tenancy + |-------------------------------------------------------------------------- + | + */ + 'is_tenant_aware' => true, + 'tenant_ownership_relationship_name' => 'site', + 'tenant_relationship' => 'site', + 'tenant_model' => Site::class, + + /* + |-------------------------------------------------------------------------- + | Model and resource + |-------------------------------------------------------------------------- + | + */ + 'model' => \Backstage\Media\Models\Media::class, + + 'user_model' => User::class, + + 'resources' => [ + 'label' => 'Media', + 'plural_label' => 'Media', + 'navigation_group' => null, + 'navigation_label' => 'Media', + 'navigation_icon' => 'heroicon-o-photo', + 'navigation_sort' => null, + 'navigation_count_badge' => false, + 'resource' => \Backstage\Media\Resources\MediaResource::class, + ], + + 'file_upload' => [ + 'models' => [ + Content::class, + ], + ], +]; diff --git a/database/migrations/2025_02_15_123430_create_media_relationships_table.php b/database/migrations/2025_02_15_123430_create_media_relationships_table.php index e7194908..f537b980 100644 --- a/database/migrations/2025_02_15_123430_create_media_relationships_table.php +++ b/database/migrations/2025_02_15_123430_create_media_relationships_table.php @@ -21,8 +21,10 @@ public function up(): void ->on(app(config('backstage.media.model', \Backstage\Media\Models\Media::class))->getTable()) ->cascadeOnDelete(); - // Polymorphic model relationship - $table->morphs('model'); + // Polymorphic model relationship (String ID support) + $table->string('model_type'); + $table->string('model_id', 36); + $table->index(['model_type', 'model_id']); // Optional position for each relationship $table->unsignedInteger('position')->nullable(); diff --git a/database/migrations/2025_11_06_120044_create_translated_attributes_table.php b/database/migrations/2025_11_06_120044_create_translated_attributes_table.php new file mode 100644 index 00000000..c20965a9 --- /dev/null +++ b/database/migrations/2025_11_06_120044_create_translated_attributes_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('code', 5); + + $table->foreign('code') + ->references('code') + ->on('languages') + ->onDelete('cascade'); + + $table->ulidMorphs('translatable'); + + $table->longText('attribute'); + $table->longText('translated_attribute')->nullable(); + $table->timestamp('translated_at')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + }); + } + + public function down() + { + Schema::dropIfExists('translated_attributes'); + } +}; diff --git a/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php b/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php new file mode 100644 index 00000000..8e943428 --- /dev/null +++ b/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php @@ -0,0 +1,24 @@ +getTable(), function (Blueprint $table) { + $table->text('alt')->nullable()->after('height'); + }); + } + + public function down(): void + { + $model = config('backstage.media.model'); + Schema::table((new $model)->getTable(), function (Blueprint $table) { + $table->dropColumn('alt'); + }); + } +}; diff --git a/database/seeders/BackstageSeeder.php b/database/seeders/BackstageSeeder.php index e23fc063..f66e65de 100644 --- a/database/seeders/BackstageSeeder.php +++ b/database/seeders/BackstageSeeder.php @@ -12,7 +12,6 @@ use Backstage\Models\Language; use Backstage\Models\Site; use Backstage\Models\Type; -use Backstage\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Str; @@ -173,47 +172,5 @@ public function run(): void (string) Str::uuid() => ['type' => 'form', 'data' => ['slug' => 'contact']], ]), ]), 'values')->create(); - - User::factory([ - 'name' => 'Mark', - 'email' => 'mark@vk10.nl', - 'password' => 'mark@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Rob', - 'email' => 'rob@vk10.nl', - 'password' => 'rob@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Mathieu', - 'email' => 'mathieu@vk10.nl', - 'password' => 'mathieu@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Bas', - 'email' => 'bas@vk10.nl', - 'password' => 'bas@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Yoni', - 'email' => 'yoni@vk10.nl', - 'password' => 'yoni@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Patrick', - 'email' => 'patrick@vk10.nl', - 'password' => 'patrick@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Sandro', - 'email' => 'sandro@vk10.nl', - 'password' => 'sandro@vk10.nl', - ])->create(); } } diff --git a/packages/core/composer.json b/packages/core/composer.json index 66efb195..2aba3df5 100644 --- a/packages/core/composer.json +++ b/packages/core/composer.json @@ -37,6 +37,7 @@ "backstage/media": "self.version", "backstage/redirects": "self.version", "backstage/ai": "self.version", + "backstage/users": "self.version", "baspa/laravel-timezones": "^1.2", "codewithdennis/filament-select-tree": "^4.0", "filament/filament": "^4.0", diff --git a/packages/core/config/backstage/cms.php b/packages/core/config/backstage/cms.php index 4b1001c9..9578e907 100644 --- a/packages/core/config/backstage/cms.php +++ b/packages/core/config/backstage/cms.php @@ -22,7 +22,7 @@ Backstage\Resources\SettingResource::class, Backstage\Resources\SiteResource::class, Backstage\Resources\TagResource::class, - Backstage\Media\Resources\MediaResource::class, + // Backstage\Resources\MediaResource::class, // Backstage\Resources\TemplateResource::class, Backstage\Resources\TypeResource::class, Backstage\Resources\UserResource::class, diff --git a/packages/core/database/migrations/2025_02_15_123430_create_media_relationships_table.php b/packages/core/database/migrations/2025_02_15_123430_create_media_relationships_table.php index e7194908..f537b980 100644 --- a/packages/core/database/migrations/2025_02_15_123430_create_media_relationships_table.php +++ b/packages/core/database/migrations/2025_02_15_123430_create_media_relationships_table.php @@ -21,8 +21,10 @@ public function up(): void ->on(app(config('backstage.media.model', \Backstage\Media\Models\Media::class))->getTable()) ->cascadeOnDelete(); - // Polymorphic model relationship - $table->morphs('model'); + // Polymorphic model relationship (String ID support) + $table->string('model_type'); + $table->string('model_id', 36); + $table->index(['model_type', 'model_id']); // Optional position for each relationship $table->unsignedInteger('position')->nullable(); diff --git a/packages/core/database/migrations/2025_11_06_120044_create_translated_attributes_table.php b/packages/core/database/migrations/2025_11_06_120044_create_translated_attributes_table.php new file mode 100644 index 00000000..8b112883 --- /dev/null +++ b/packages/core/database/migrations/2025_11_06_120044_create_translated_attributes_table.php @@ -0,0 +1,39 @@ +id(); + $table->string('code', 5); + + $table->foreign('code') + ->references('code') + ->on('languages') + ->onDelete('cascade'); + + $table->ulidMorphs('translatable'); + + $table->longText('attribute'); + $table->longText('translated_attribute')->nullable(); + $table->timestamp('translated_at')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + }); + } + + public function down() + { + Schema::dropIfExists('translated_attributes'); + } +}; diff --git a/packages/core/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php b/packages/core/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php new file mode 100644 index 00000000..8e943428 --- /dev/null +++ b/packages/core/database/migrations/2025_11_06_120623_add_alt_column_to_media_table.php @@ -0,0 +1,24 @@ +getTable(), function (Blueprint $table) { + $table->text('alt')->nullable()->after('height'); + }); + } + + public function down(): void + { + $model = config('backstage.media.model'); + Schema::table((new $model)->getTable(), function (Blueprint $table) { + $table->dropColumn('alt'); + }); + } +}; diff --git a/packages/core/database/migrations/2025_12_08_000000_make_media_relationships_model_id_string.php b/packages/core/database/migrations/2025_12_08_000000_make_media_relationships_model_id_string.php new file mode 100644 index 00000000..5173344e --- /dev/null +++ b/packages/core/database/migrations/2025_12_08_000000_make_media_relationships_model_id_string.php @@ -0,0 +1,25 @@ +string('model_id', 36)->change(); + $table->string('model_type')->change(); + }); + } + + public function down(): void + { + Schema::table('media_relationships', function (Blueprint $table) { + // Revert to typical big integer if needed (unsafe if data exists) + // $table->unsignedBigInteger('model_id')->change(); + }); + } +}; diff --git a/packages/core/database/migrations/2025_12_10_080000_update_media_relationships_indexes.php b/packages/core/database/migrations/2025_12_10_080000_update_media_relationships_indexes.php new file mode 100644 index 00000000..f94f0cf0 --- /dev/null +++ b/packages/core/database/migrations/2025_12_10_080000_update_media_relationships_indexes.php @@ -0,0 +1,63 @@ +dropForeign(['media_ulid']); + }); + } catch (\Illuminate\Database\QueryException $e) { + // Ignore if foreign key does not exist + } + + // 2. Try to drop unique index (might fail if already dropped) + try { + Schema::table('media_relationships', function (Blueprint $table) { + $table->dropUnique(['media_ulid', 'model_type', 'model_id']); + }); + } catch (\Illuminate\Database\QueryException $e) { + // Ignore if index does not exist + } + + // 3. Try to add new index (might fail if already exists) + try { + Schema::table('media_relationships', function (Blueprint $table) { + $table->index(['model_type', 'model_id', 'position']); + }); + } catch (\Illuminate\Database\QueryException $e) { + // Ignore if index already exists + } + + // 4. Re-add foreign key (using safe 'foreign' method) + Schema::table('media_relationships', function (Blueprint $table) { + // We use a separate call here to ensure we don't catch unexpected errors in the definition + // But we might want to check if it exists? + // Generically adding a FK usually fails if it exists with same name. + // Since we know we tried to drop it in step 1, this should be safe unless step 1 failed unrelatedly. + // However, to be extra safe against "Constraint already exists": + try { + $table->foreign('media_ulid') + ->references('ulid') + ->on(app(config('backstage.media.model', \Backstage\Media\Models\Media::class))->getTable()) + ->cascadeOnDelete(); + } catch (\Illuminate\Database\QueryException $e) { + // assume it exists if it fails + } + }); + } + + public function down(): void + { + Schema::table('media_relationships', function (Blueprint $table) { + $table->dropIndex(['model_type', 'model_id', 'position']); + $table->unique(['media_ulid', 'model_type', 'model_id']); + }); + } +}; diff --git a/packages/core/database/migrations/2025_12_10_080001_update_translatable_column.php b/packages/core/database/migrations/2025_12_10_080001_update_translatable_column.php new file mode 100644 index 00000000..3638e863 --- /dev/null +++ b/packages/core/database/migrations/2025_12_10_080001_update_translatable_column.php @@ -0,0 +1,21 @@ +string('translatable_id', 36)->change(); + $table->string('translatable_type', 36)->change(); + }); + } + + public function down() + { + Schema::dropIfExists('translated_attributes'); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132457_1_add_sub_navigation_preference_to_users_table.php b/packages/core/database/migrations/2026_01_13_132457_1_add_sub_navigation_preference_to_users_table.php new file mode 100644 index 00000000..aa033921 --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132457_1_add_sub_navigation_preference_to_users_table.php @@ -0,0 +1,31 @@ +enum('sub_navigation_preference', ['start', 'end', 'top']) + ->default('top') + ->after('remember_token') + ->comment('The user\'s preference for the sub navigation position. The default is top.'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table(config('users.eloquent.user.table', 'users'), function (Blueprint $table) { + $table->dropColumn('sub_navigation_preference'); + }); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132457_1_create_user_logins_table.php b/packages/core/database/migrations/2026_01_13_132457_1_create_user_logins_table.php new file mode 100644 index 00000000..3d8736f7 --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132457_1_create_user_logins_table.php @@ -0,0 +1,41 @@ +id(); + $table->unsignedBigInteger('user_id')->nullable(); + + $table->string('type')->nullable(); + $table->string('url')->nullable(); + $table->string('referrer')->nullable(); + $table->text('inputs')->nullable(); + $table->string('user_agent')->nullable(); + $table->string('ip_address')->nullable(); + $table->string('hostname')->nullable(); + $table->string('isp')->nullable(); + $table->string('org')->nullable(); + $table->string('city')->nullable(); + $table->string('region')->nullable(); + $table->string('country_code', 2)->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists(config('users.eloquent.user_login.table', 'user_logins')); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132457_create_permission_tables.php b/packages/core/database/migrations/2026_01_13_132457_create_permission_tables.php new file mode 100644 index 00000000..aec7e091 --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132457_create_permission_tables.php @@ -0,0 +1,142 @@ +engine('InnoDB'); + $table->bigIncrements('id'); // permission id + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { + // $table->engine('InnoDB'); + $table->bigIncrements('id'); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { + $table->unsignedBigInteger($pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary( + [$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary' + ); + } else { + $table->primary( + [$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary' + ); + } + + }); + + Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { + $table->unsignedBigInteger($pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary( + [$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary' + ); + } else { + $table->primary( + [$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary' + ); + } + }); + + Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { + $table->unsignedBigInteger($pivotPermission); + $table->unsignedBigInteger($pivotRole); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $tableNames = config('permission.table_names'); + + throw_if(empty($tableNames), Exception::class, 'Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132458_2_add_width_preference_to_users_table.php b/packages/core/database/migrations/2026_01_13_132458_2_add_width_preference_to_users_table.php new file mode 100644 index 00000000..a10223af --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132458_2_add_width_preference_to_users_table.php @@ -0,0 +1,31 @@ +enum('width_preference', ['full', '7xl']) + ->default('7xl') + ->after('remember_token') + ->comment('The user\'s preference for the content width. The default is 7xl.'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table(config('users.eloquent.user.table', 'users'), function (Blueprint $table) { + $table->dropColumn('width_preference'); + }); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132458_2_create_user_traffic_table.php b/packages/core/database/migrations/2026_01_13_132458_2_create_user_traffic_table.php new file mode 100644 index 00000000..44cb05dd --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132458_2_create_user_traffic_table.php @@ -0,0 +1,38 @@ +id(); + $table->unsignedBigInteger('user_id')->nullable(); + + $table->string('method', 10); + $table->string('path'); + $table->text('full_url'); + $table->ipAddress('ip')->nullable(); + $table->text('user_agent')->nullable(); + $table->text('referer')->nullable(); + $table->string('route_name')->nullable(); + $table->string('route_action')->nullable(); + $table->json('route_parameters')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists(config('users.eloquent.user_traffic.table', 'user_traffic')); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132459_3_user_password_nullable.php b/packages/core/database/migrations/2026_01_13_132459_3_user_password_nullable.php new file mode 100644 index 00000000..7d7340ec --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132459_3_user_password_nullable.php @@ -0,0 +1,28 @@ +string('password')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table(config('users.eloquent.user.table', 'users'), function (Blueprint $table) { + $table->string('password')->nullable(false)->change(); + }); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132500_4_create_user_notification_preferences_table.php b/packages/core/database/migrations/2026_01_13_132500_4_create_user_notification_preferences_table.php new file mode 100644 index 00000000..a8de8e71 --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132500_4_create_user_notification_preferences_table.php @@ -0,0 +1,32 @@ +id(); + $table->unsignedBigInteger('user_id'); + + $table->string('navigation_type'); + $table->timestamps(); + + $table->unique(['user_id', 'navigation_type']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists(config('users.eloquent.user_notification_preferences.table', 'user_notification_preferences')); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132501_5_drop_user_traffic_table.php b/packages/core/database/migrations/2026_01_13_132501_5_drop_user_traffic_table.php new file mode 100644 index 00000000..4a548c6d --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132501_5_drop_user_traffic_table.php @@ -0,0 +1,20 @@ +text('url')->change(); + }); + } + + public function down(): void + { + Schema::table(config('users.eloquent.user_login.table', 'user_logins'), function (Blueprint $table) { + $table->string('url', 255)->change(); + }); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_132544_create_personal_access_tokens_table.php b/packages/core/database/migrations/2026_01_13_132544_create_personal_access_tokens_table.php new file mode 100644 index 00000000..40ff706e --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_132544_create_personal_access_tokens_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('tokenable'); + $table->text('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable()->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/packages/core/database/migrations/2026_01_13_133157_7_add_deleted_add_to_users_tabe.php b/packages/core/database/migrations/2026_01_13_133157_7_add_deleted_add_to_users_tabe.php new file mode 100644 index 00000000..1698f9e4 --- /dev/null +++ b/packages/core/database/migrations/2026_01_13_133157_7_add_deleted_add_to_users_tabe.php @@ -0,0 +1,26 @@ +getTable(), 'deleted_at')) { + $table->softDeletes(); + } + }); + } + + public function down(): void + { + Schema::table(config('users.eloquent.user.table', 'users'), function (Blueprint $table) { + if (Schema::hasColumn($table->getTable(), 'deleted_at')) { + $table->dropSoftDeletes(); + } + }); + } +}; diff --git a/packages/core/database/seeders/BackstageSeeder.php b/packages/core/database/seeders/BackstageSeeder.php index e23fc063..f66e65de 100644 --- a/packages/core/database/seeders/BackstageSeeder.php +++ b/packages/core/database/seeders/BackstageSeeder.php @@ -12,7 +12,6 @@ use Backstage\Models\Language; use Backstage\Models\Site; use Backstage\Models\Type; -use Backstage\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Str; @@ -173,47 +172,5 @@ public function run(): void (string) Str::uuid() => ['type' => 'form', 'data' => ['slug' => 'contact']], ]), ]), 'values')->create(); - - User::factory([ - 'name' => 'Mark', - 'email' => 'mark@vk10.nl', - 'password' => 'mark@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Rob', - 'email' => 'rob@vk10.nl', - 'password' => 'rob@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Mathieu', - 'email' => 'mathieu@vk10.nl', - 'password' => 'mathieu@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Bas', - 'email' => 'bas@vk10.nl', - 'password' => 'bas@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Yoni', - 'email' => 'yoni@vk10.nl', - 'password' => 'yoni@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Patrick', - 'email' => 'patrick@vk10.nl', - 'password' => 'patrick@vk10.nl', - ])->create(); - - User::factory([ - 'name' => 'Sandro', - 'email' => 'sandro@vk10.nl', - 'password' => 'sandro@vk10.nl', - ])->create(); } } diff --git a/packages/core/resources/views/components/page.blade.php b/packages/core/resources/views/components/page.blade.php index 745cbbde..da122ed7 100644 --- a/packages/core/resources/views/components/page.blade.php +++ b/packages/core/resources/views/components/page.blade.php @@ -5,7 +5,7 @@