Basic tenant structure
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@
|
|||||||
Homestead.json
|
Homestead.json
|
||||||
Homestead.yaml
|
Homestead.yaml
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
/docker-compose.yaml
|
||||||
|
|||||||
5
Makefile
5
Makefile
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
FRONTEND_DIR ?= .
|
FRONTEND_DIR ?= .
|
||||||
|
|
||||||
|
setup:
|
||||||
|
rm -f docker-compose.yaml
|
||||||
|
cp docker-compose.dev docker-compose.yaml
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
@cd $(FRONTEND_DIR) && \
|
@cd $(FRONTEND_DIR) && \
|
||||||
export QT_QPA_PLATFORM=offscreen && \
|
export QT_QPA_PLATFORM=offscreen && \
|
||||||
|
|||||||
21
app/Enumerations/CostUnitType.php
Normal file
21
app/Enumerations/CostUnitType.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enumerations;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $name
|
||||||
|
*/
|
||||||
|
class CostUnitType extends CommonModel
|
||||||
|
{
|
||||||
|
public const COST_UNIT_TYPE_EVENT = 'event';
|
||||||
|
public const COST_UNIT_TYPE_RUNNING_JOB = 'running_job';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slug',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
22
app/Enumerations/EatingHabit.php
Normal file
22
app/Enumerations/EatingHabit.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enumerations;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $name
|
||||||
|
*/
|
||||||
|
class EatingHabit extends CommonModel
|
||||||
|
{
|
||||||
|
public const string EATING_HABIT_OMNIVOR = 'EATING_HABIT_OMNIVOR';
|
||||||
|
public const string EATING_HABIT_VEGETARIAN = 'EATING_HABIT_VEGETARIAN';
|
||||||
|
public const string EATING_HABIT_VEGAN = 'EATING_HABIT_VEGAN';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slug',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
22
app/Enumerations/FirstAidPermission.php
Normal file
22
app/Enumerations/FirstAidPermission.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enumerations;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $name
|
||||||
|
*/
|
||||||
|
class FirstAidPermission extends CommonModel
|
||||||
|
{
|
||||||
|
public const string FIRST_AID_PERMISSION_ALLOWED = 'FIRST_AID_PERMISSION_ALLOWED';
|
||||||
|
public const string FIRST_AID_PERMISSION_DENIED = 'FIRST_AID_PERMISSION_DENIED';
|
||||||
|
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slug',
|
||||||
|
'name',
|
||||||
|
'description'
|
||||||
|
];
|
||||||
|
}
|
||||||
26
app/Enumerations/SwimmingPermission.php
Normal file
26
app/Enumerations/SwimmingPermission.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enumerations;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $name
|
||||||
|
*/
|
||||||
|
class SwimmingPermission extends CommonModel
|
||||||
|
{
|
||||||
|
public const string SWIMMING_PERMISSION_ALLOWED = 'SWIMMING_PERMISSION_ALLOWED';
|
||||||
|
public const string SWIMMING_PERMISSION_LIMITED = 'SWIMMING_PERMISSION_LIMITED';
|
||||||
|
public const string SWIMMING_PERMISSION_DENIED = 'SWIMMING_PERMISSION_DENIED';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slug',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
17
app/Enumerations/UserRole.php
Normal file
17
app/Enumerations/UserRole.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enumerations;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
|
||||||
|
class UserRole extends CommonModel {
|
||||||
|
public const USER_ROLE_ADMIN = 'ROLE_ADMINISTRATOR';
|
||||||
|
public const USER_ROLE_GROUP_LEADER = 'ROLE_GROUP_LEADER';
|
||||||
|
public const USER_ROLE_USER = 'ROLE_USER';
|
||||||
|
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'slug'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
abstract class Controller
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
43
app/Installer/DevelopmentDataSeeder.php
Normal file
43
app/Installer/DevelopmentDataSeeder.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Installer;
|
||||||
|
|
||||||
|
use App\Enumerations\UserRole;
|
||||||
|
use App\Models\Tenant;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
class DevelopmentDataSeeder {
|
||||||
|
public function execute() {
|
||||||
|
$this->installTenants();
|
||||||
|
$this->installUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private function installTenants() {
|
||||||
|
Tenant::create([
|
||||||
|
'slug' => 'wilde-moehre',
|
||||||
|
'local_group_name' => 'Stamm Wilde Möhre',
|
||||||
|
'url' => 'wilde-moehre.mareike.local',
|
||||||
|
'account_iban' => 'DE12345678901234567890',
|
||||||
|
'email' => 'test@example1.com',
|
||||||
|
'city' => 'Halle (Saale)',
|
||||||
|
'postcode' => '06120',
|
||||||
|
'is_active_local_group' => true,
|
||||||
|
'has_active_instance' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installUsers() {
|
||||||
|
User::create([
|
||||||
|
'firstname' => 'Development',
|
||||||
|
'lastname' => 'User',
|
||||||
|
'user_role' => UserRole::USER_ROLE_ADMIN,
|
||||||
|
'tenant' => 'lv',
|
||||||
|
'email' => 'th.guenther@saale-mail.de',
|
||||||
|
'password' => bcrypt('development'),
|
||||||
|
'local_group_id' => 1,
|
||||||
|
'username' => 'development',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
app/Installer/ProductionDataSeeder.php
Normal file
71
app/Installer/ProductionDataSeeder.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Installer;
|
||||||
|
|
||||||
|
use App\Enumerations\CostUnitType;
|
||||||
|
use App\Enumerations\EatingHabit;
|
||||||
|
use App\Enumerations\FirstAidPermission;
|
||||||
|
use App\Enumerations\SwimmingPermission;
|
||||||
|
use App\Enumerations\UserRole;
|
||||||
|
use App\Models\Tenant;
|
||||||
|
|
||||||
|
class ProductionDataSeeder {
|
||||||
|
public function execute() {
|
||||||
|
$this->installUserRoles();
|
||||||
|
$this->installCostUnitTypes();
|
||||||
|
$this->installSwimmingPermissions();
|
||||||
|
$this->installEatingHabits();
|
||||||
|
$this->installFirstAidPermissions();
|
||||||
|
$this->installTenants();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installUserRoles() {
|
||||||
|
UserRole::create(['name' => 'Administrator*in', 'slug' => UserRole::USER_ROLE_ADMIN]);
|
||||||
|
UserRole::create(['name' => 'Vorstandsmitglied', 'slug' => UserRole::USER_ROLE_GROUP_LEADER]);
|
||||||
|
UserRole::create(['name' => 'Benutzer*in', 'slug' => UserRole::USER_ROLE_USER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installSwimmingPermissions() {
|
||||||
|
SwimmingPermission::create(['name' => 'Mein Kind darf baden und kann schwimmen', 'slug' => SwimmingPermission::SWIMMING_PERMISSION_ALLOWED]);
|
||||||
|
SwimmingPermission::create(['name' => 'Mein Kind darf baden und kann NICHT schwimmen', 'slug' => SwimmingPermission::SWIMMING_PERMISSION_LIMITED]);
|
||||||
|
SwimmingPermission::create(['name' => 'Mein Kind darf nicht baden', 'slug' => SwimmingPermission::SWIMMING_PERMISSION_DENIED]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installEatingHabits() {
|
||||||
|
EatingHabit::create(['name' => 'Vegan', 'slug' => EatingHabit::EATING_HABIT_VEGAN]);
|
||||||
|
EatingHabit::create(['name' => 'Vegetarisch', 'slug' => EatingHabit::EATING_HABIT_VEGETARIAN]);
|
||||||
|
EatingHabit::create(['name' => 'Omnivor', 'slug' => EatingHabit::EATING_HABIT_OMNIVOR]);
|
||||||
|
|
||||||
|
}
|
||||||
|
private function installFirstAidPermissions() {
|
||||||
|
FirstAidPermission::create([
|
||||||
|
'name' => 'Zugestimmt',
|
||||||
|
'description' => 'Ich STIMME der Anwendung von erweiteren Erste-Hilfe-Maßnahmen an meinem Kind explizit ZU.',
|
||||||
|
'slug' => FirstAidPermission::FIRST_AID_PERMISSION_ALLOWED]);
|
||||||
|
|
||||||
|
FirstAidPermission::create([
|
||||||
|
'name' => 'Verweigert',
|
||||||
|
'description' => 'Ich LEHNE die Anwendung von erweiteren Erste-Hilfe-Maßnahmen an meinem Kind explizit AB.',
|
||||||
|
'slug' => FirstAidPermission::FIRST_AID_PERMISSION_DENIED]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installCostUnitTypes() {
|
||||||
|
CostUnitType::create(['slug' => CostUnitType::COST_UNIT_TYPE_EVENT, 'name' => 'Veranstaltung']);
|
||||||
|
CostUnitType::create(['slug' => CostUnitType::COST_UNIT_TYPE_RUNNING_JOB, 'name' => 'Laufende Tätigkeit']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function installTenants() {
|
||||||
|
Tenant::create([
|
||||||
|
'slug' => 'lv',
|
||||||
|
'local_group_name' => 'Landesunmittelbare Mitglieder',
|
||||||
|
'url' => 'mareike.local',
|
||||||
|
'account_iban' => 'DE12345678901234567890',
|
||||||
|
'email' => 'test@example.com',
|
||||||
|
'city' => 'Lommatzsch',
|
||||||
|
'postcode' => '01623',
|
||||||
|
'is_active_local_group' => true,
|
||||||
|
'has_active_instance' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Middleware;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
24
app/Middleware/IdentifyTenant.php
Normal file
24
app/Middleware/IdentifyTenant.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Middleware;
|
||||||
|
|
||||||
|
use App\Models\Tenant;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
|
class IdentifyTenant
|
||||||
|
{
|
||||||
|
public function handle(Request $request, Closure $next)
|
||||||
|
{
|
||||||
|
$host = $request->getHost();
|
||||||
|
$tenant = Tenant::where(['url' => $host, 'has_active_instance' => true])->first();
|
||||||
|
|
||||||
|
if (! $tenant) {
|
||||||
|
throw new NotFoundHttpException('Tenant not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
app()->instance('tenant', $tenant);
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
app/Models/Tenant.php
Normal file
39
app/Models/Tenant.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Scopes\CommonModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $local_group
|
||||||
|
* @property string $email
|
||||||
|
* @property string $url
|
||||||
|
* @property string $account_iban
|
||||||
|
* @property string $city
|
||||||
|
* @property string $postcode
|
||||||
|
* @property string $gdpr_text
|
||||||
|
* @property string $impress_text
|
||||||
|
* @property string $url_participation_rules
|
||||||
|
* @property boolean $events_allowed
|
||||||
|
* @property boolean $has_active_instance
|
||||||
|
*/
|
||||||
|
class Tenant extends CommonModel
|
||||||
|
{
|
||||||
|
public const PRIMARY_TENANT_NAME = 'LV';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slug',
|
||||||
|
'local_group_name',
|
||||||
|
'email',
|
||||||
|
'url',
|
||||||
|
'account_iban',
|
||||||
|
'city',
|
||||||
|
'postcode',
|
||||||
|
'gdpr_text',
|
||||||
|
'impress_text',
|
||||||
|
'url_participation_rules',
|
||||||
|
'is_active_local_group',
|
||||||
|
'has_active_instance'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -2,15 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
use Notifiable;
|
||||||
use HasFactory, Notifiable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -18,8 +15,28 @@ class User extends Authenticatable
|
|||||||
* @var list<string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'tenant_id',
|
||||||
|
'user_role',
|
||||||
|
'username',
|
||||||
|
'firstname',
|
||||||
|
'nickname',
|
||||||
|
'lastname',
|
||||||
|
'local_group_id',
|
||||||
|
'membership_id',
|
||||||
|
'address_1',
|
||||||
|
'address_2',
|
||||||
|
'postcode',
|
||||||
|
'city',
|
||||||
'email',
|
'email',
|
||||||
|
'phone',
|
||||||
|
'birthday',
|
||||||
|
'medications',
|
||||||
|
'allergies',
|
||||||
|
'intolerances',
|
||||||
|
'eating_habits',
|
||||||
|
'swimming_permission',
|
||||||
|
'first_aid_permission',
|
||||||
|
'bank_account_iban',
|
||||||
'password',
|
'password',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -29,7 +46,6 @@ class User extends Authenticatable
|
|||||||
* @var list<string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password',
|
|
||||||
'remember_token',
|
'remember_token',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@@ -19,6 +20,11 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
//
|
Auth::provider('tenant-users', function ($app, array $config) {
|
||||||
|
return new TenantUserProvider(
|
||||||
|
$app['hash'],
|
||||||
|
$config['model']
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
app/Providers/InertiaProvider.php
Normal file
26
app/Providers/InertiaProvider.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Inertia\Inertia;
|
||||||
|
use Inertia\Response;
|
||||||
|
|
||||||
|
final class InertiaProvider
|
||||||
|
{
|
||||||
|
private string $vueFile;
|
||||||
|
private array $props;
|
||||||
|
|
||||||
|
public function __construct(string $vueFile, array $props) {
|
||||||
|
$this->vueFile = $vueFile;
|
||||||
|
$this->props = $props;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function render() : Response {
|
||||||
|
return Inertia::render(
|
||||||
|
str_replace('/', '/Views/', $this->vueFile),
|
||||||
|
$this->props
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
app/Providers/TenantUserProvider.php
Normal file
23
app/Providers/TenantUserProvider.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Auth\EloquentUserProvider;
|
||||||
|
|
||||||
|
class TenantUserProvider extends EloquentUserProvider
|
||||||
|
{
|
||||||
|
public function retrieveByCredentials(array $credentials)
|
||||||
|
{
|
||||||
|
$query = $this->createModel()->newQuery();
|
||||||
|
|
||||||
|
foreach ($credentials as $key => $value) {
|
||||||
|
if (! str_contains($key, 'password')) {
|
||||||
|
$query->where($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->where('tenant', app('tenant')->slug);
|
||||||
|
|
||||||
|
return $query->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
app/Scopes/CommonModel.php
Normal file
10
app/Scopes/CommonModel.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
abstract class CommonModel extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
13
app/Scopes/InstancedModel.php
Normal file
13
app/Scopes/InstancedModel.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
abstract class InstancedModel extends Model
|
||||||
|
{
|
||||||
|
protected static function booted()
|
||||||
|
{
|
||||||
|
static::addGlobalScope(new SiteScope());
|
||||||
|
}
|
||||||
|
}
|
||||||
14
app/Scopes/SiteScope.php
Normal file
14
app/Scopes/SiteScope.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Scope;
|
||||||
|
|
||||||
|
class SiteScope implements Scope
|
||||||
|
{
|
||||||
|
public function apply(Builder $builder, Model $model): void
|
||||||
|
{
|
||||||
|
$builder->where($model->getTable() . '.tenant', app('tenant')->slug);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Middleware\IdentifyTenant;
|
||||||
use Illuminate\Foundation\Application;
|
use Illuminate\Foundation\Application;
|
||||||
use Illuminate\Foundation\Configuration\Exceptions;
|
use Illuminate\Foundation\Configuration\Exceptions;
|
||||||
use Illuminate\Foundation\Configuration\Middleware;
|
use Illuminate\Foundation\Configuration\Middleware;
|
||||||
@@ -8,10 +9,11 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
->withRouting(
|
->withRouting(
|
||||||
web: __DIR__.'/../routes/web.php',
|
web: __DIR__.'/../routes/web.php',
|
||||||
commands: __DIR__.'/../routes/console.php',
|
commands: __DIR__.'/../routes/console.php',
|
||||||
|
api: __DIR__.'/../routes/api.php',
|
||||||
health: '/up',
|
health: '/up',
|
||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware): void {
|
->withMiddleware(function (Middleware $middleware): void {
|
||||||
//
|
$middleware->append(IdentifyTenant::class);
|
||||||
})
|
})
|
||||||
->withExceptions(function (Exceptions $exceptions): void {
|
->withExceptions(function (Exceptions $exceptions): void {
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
App\Providers\AppServiceProvider::class,
|
App\Providers\AppServiceProvider::class,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"keywords": ["laravel", "framework"],
|
"keywords": ["laravel", "framework"],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.5",
|
||||||
"inertiajs/inertia-laravel": "^2.0",
|
"inertiajs/inertia-laravel": "^2.0",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/tinker": "^2.10.1"
|
"laravel/tinker": "^2.10.1"
|
||||||
|
|||||||
20
composer.lock
generated
20
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": "0e42fe1a7066e7a110e956ae26703d94",
|
"content-hash": "587caff9de06de75c1e22cceac366334",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@@ -2194,16 +2194,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nesbot/carbon",
|
"name": "nesbot/carbon",
|
||||||
"version": "3.11.0",
|
"version": "3.11.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||||
"reference": "bdb375400dcd162624531666db4799b36b64e4a1"
|
"reference": "f438fcc98f92babee98381d399c65336f3a3827f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1",
|
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/f438fcc98f92babee98381d399c65336f3a3827f",
|
||||||
"reference": "bdb375400dcd162624531666db4799b36b64e4a1",
|
"reference": "f438fcc98f92babee98381d399c65336f3a3827f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2227,7 +2227,7 @@
|
|||||||
"phpstan/extension-installer": "^1.4.3",
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
"phpstan/phpstan": "^2.1.22",
|
"phpstan/phpstan": "^2.1.22",
|
||||||
"phpunit/phpunit": "^10.5.53",
|
"phpunit/phpunit": "^10.5.53",
|
||||||
"squizlabs/php_codesniffer": "^3.13.4"
|
"squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"bin/carbon"
|
"bin/carbon"
|
||||||
@@ -2270,14 +2270,14 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "An API extension for DateTime that supports 281 different languages.",
|
"description": "An API extension for DateTime that supports 281 different languages.",
|
||||||
"homepage": "https://carbon.nesbot.com",
|
"homepage": "https://carbonphp.github.io/carbon/",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"date",
|
"date",
|
||||||
"datetime",
|
"datetime",
|
||||||
"time"
|
"time"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"docs": "https://carbon.nesbot.com/docs",
|
"docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html",
|
||||||
"issues": "https://github.com/CarbonPHP/carbon/issues",
|
"issues": "https://github.com/CarbonPHP/carbon/issues",
|
||||||
"source": "https://github.com/CarbonPHP/carbon"
|
"source": "https://github.com/CarbonPHP/carbon"
|
||||||
},
|
},
|
||||||
@@ -2295,7 +2295,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-12-02T21:04:28+00:00"
|
"time": "2026-01-29T09:26:29+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nette/schema",
|
"name": "nette/schema",
|
||||||
@@ -8436,7 +8436,7 @@
|
|||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.2"
|
"php": "^8.5"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.9.0"
|
"plugin-api-version": "2.9.0"
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ return [
|
|||||||
|
|
||||||
'providers' => [
|
'providers' => [
|
||||||
'users' => [
|
'users' => [
|
||||||
'driver' => 'eloquent',
|
'driver' => 'tenant-users',
|
||||||
'model' => env('AUTH_MODEL', App\Models\User::class),
|
'model' => App\Models\User::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
// 'users' => [
|
// 'users' => [
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Factories;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
|
||||||
*/
|
|
||||||
class UserFactory extends Factory
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The current password being used by the factory.
|
|
||||||
*/
|
|
||||||
protected static ?string $password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the model's default state.
|
|
||||||
*
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
public function definition(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => fake()->name(),
|
|
||||||
'email' => fake()->unique()->safeEmail(),
|
|
||||||
'email_verified_at' => now(),
|
|
||||||
'password' => static::$password ??= Hash::make('password'),
|
|
||||||
'remember_token' => Str::random(10),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicate that the model's email address should be unverified.
|
|
||||||
*/
|
|
||||||
public function unverified(): static
|
|
||||||
{
|
|
||||||
return $this->state(fn (array $attributes) => [
|
|
||||||
'email_verified_at' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::create('users', function (Blueprint $table) {
|
|
||||||
$table->id();
|
|
||||||
$table->string('name');
|
|
||||||
$table->string('email')->unique();
|
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
|
||||||
$table->string('password');
|
|
||||||
$table->rememberToken();
|
|
||||||
$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();
|
|
||||||
$table->string('ip_address', 45)->nullable();
|
|
||||||
$table->text('user_agent')->nullable();
|
|
||||||
$table->longText('payload');
|
|
||||||
$table->integer('last_activity')->index();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('users');
|
|
||||||
Schema::dropIfExists('password_reset_tokens');
|
|
||||||
Schema::dropIfExists('sessions');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
32
database/migrations/2026_01_30_140001_create_tenants.php
Normal file
32
database/migrations/2026_01_30_140001_create_tenants.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
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('tenants', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('slug')->unique();
|
||||||
|
$table->string('local_group_name');
|
||||||
|
$table->string('email');
|
||||||
|
$table->string('url');
|
||||||
|
$table->string('account_iban');
|
||||||
|
$table->string('city');
|
||||||
|
$table->string('postcode');
|
||||||
|
$table->string('gdpr_text')-> nullable();
|
||||||
|
$table->string('impress_text')->nullable();
|
||||||
|
$table->string('url_participation_rules')->nullable();
|
||||||
|
$table->boolean('has_active_instance')->default(true);
|
||||||
|
$table->boolean('is_active_local_group')->default(true);
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('tenants');
|
||||||
|
}
|
||||||
|
};
|
||||||
106
database/migrations/2026_01_30_140002_create_users_table.php
Normal file
106
database/migrations/2026_01_30_140002_create_users_table.php
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('user_roles', function (Blueprint $table) {
|
||||||
|
$table->string('slug')->unique()->primary();
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('eating_habits', function (Blueprint $table) {
|
||||||
|
$table->string('slug')->unique()->primary();
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('swimming_permissions', function (Blueprint $table) {
|
||||||
|
$table->string('slug')->unique()->primary();
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('first_aid_permissions', function (Blueprint $table) {
|
||||||
|
$table->string('slug')->unique()->primary();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('description');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('users', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('tenant');
|
||||||
|
$table->string('user_role');
|
||||||
|
$table->string('username')->unique();
|
||||||
|
$table->string('password')->nullable();
|
||||||
|
$table->string('firstname');
|
||||||
|
$table->string('nickname')->nullable();
|
||||||
|
$table->string('lastname');
|
||||||
|
$table->foreignId('local_group_id')->references('id')->on('tenants')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->string('membership_id')->nullable();
|
||||||
|
$table->string('address_1')->nullable();
|
||||||
|
$table->string('address_2')->nullable();
|
||||||
|
$table->string('postcode')->nullable();
|
||||||
|
$table->string('city')->nullable();
|
||||||
|
$table->string('email')->nullable();
|
||||||
|
$table->string('phone')->nullable();
|
||||||
|
$table->date('birthday')->nullable();
|
||||||
|
$table->string('medications')->nullable();
|
||||||
|
$table->string('allergies')->nullable();
|
||||||
|
$table->string('intolerances')->nullable();
|
||||||
|
$table->string('eating_habits')->nullable();
|
||||||
|
$table->string('swimming_permission')->nullable();
|
||||||
|
$table->string('first_aid_permission')->nullable();
|
||||||
|
$table->string('bank_account_iban')->nullable();
|
||||||
|
$table->string('activation_token')->nullable();
|
||||||
|
$table->boolean('activated')->default(false);
|
||||||
|
|
||||||
|
$table->foreign('tenant')->references('slug')->on('tenants')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreign('user_role')->references('slug')->on('user_roles')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreign('swimming_permission')->references('slug')->on('swimming_permissions')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreign('eating_habits')->references('slug')->on('eating_habits')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreign('first_aid_permission')->references('slug')->on('first_aid_permissions')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
|
||||||
|
$table->rememberToken();
|
||||||
|
$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();
|
||||||
|
$table->string('ip_address', 45)->nullable();
|
||||||
|
$table->text('user_agent')->nullable();
|
||||||
|
$table->longText('payload');
|
||||||
|
$table->integer('last_activity')->index();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('users');
|
||||||
|
Schema::dropIfExists('password_reset_tokens');
|
||||||
|
Schema::dropIfExists('sessions');
|
||||||
|
Schema::dropIfExists('user_roles');
|
||||||
|
Schema::dropIfExists('eating_habits');
|
||||||
|
Schema::dropIfExists('swimming_permissions');
|
||||||
|
Schema::dropIfExists('first_aid_permissions');
|
||||||
|
}
|
||||||
|
};
|
||||||
43
database/migrations/2026_01_30_140010_create_cost_units.php
Normal file
43
database/migrations/2026_01_30_140010_create_cost_units.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('cost_unit_types', function (Blueprint $table) {
|
||||||
|
$table->string('slug')->primary();
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Schema::create('cost_units', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('tenant');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('type');
|
||||||
|
$table->dateTime('billing_deadline');
|
||||||
|
$table->float('distance_allowance');
|
||||||
|
$table->boolean('mail_on_new')->default(true);
|
||||||
|
$table->boolean('allow_new')->default(true);
|
||||||
|
$table->boolean('archived')->default(false);
|
||||||
|
$table->string('treasurers');
|
||||||
|
|
||||||
|
$table->foreign('tenant')->references('slug')->on('tenants')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreign('type')->references('slug')->on('cost_unit_types')->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('cost_units');
|
||||||
|
Schema::dropIfExists('cost_unit_types');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Installer\DevelopmentDataSeeder;
|
||||||
|
use App\Installer\ProductionData;
|
||||||
|
use App\Installer\ProductionDataSeeder;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
@@ -15,11 +17,12 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// User::factory(10)->create();
|
$productionSeeeder = new ProductionDataSeeder();
|
||||||
|
$productionSeeeder->execute();
|
||||||
|
|
||||||
User::factory()->create([
|
if (str_ends_with(env('APP_URL'), 'mareike.local')) {
|
||||||
'name' => 'Test User',
|
$deveopmentDataSeeder = new DevelopmentDataSeeder();
|
||||||
'email' => 'test@example.com',
|
$deveopmentDataSeeder->execute();
|
||||||
]);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ services:
|
|||||||
|
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.mareike.rule=Host(`mareike.local`)"
|
- "traefik.http.routers.mareike.rule=Host(`mareike.local`) || Host(`admin.mareike.local`) || Host(`wilde-moehre.mareike.local`)"
|
||||||
- "traefik.http.routers.mareike.entrypoints=websecure"
|
- "traefik.http.routers.mareike.entrypoints=websecure"
|
||||||
- "traefik.http.routers.mareike.tls=true"
|
- "traefik.http.routers.mareike.tls=true"
|
||||||
- "traefik.http.services.mareike.loadbalancer.server.port=80"
|
- "traefik.http.services.mareike.loadbalancer.server.port=80"
|
||||||
|
|
||||||
- "traefik.http.routers.mareike-http.rule=Host(`mareike.local`)"
|
- "traefik.http.routers.mareike-http.rule=Host(`mareike.local`) || Host(`admin.mareike.local`) || Host(`wilde-moehre.mareike.local`)"
|
||||||
- "traefik.http.routers.mareike-http.entrypoints=web"
|
- "traefik.http.routers.mareike-http.entrypoints=web"
|
||||||
- "traefik.http.routers.mareike-http.middlewares=redirect-to-https"
|
- "traefik.http.routers.mareike-http.middlewares=redirect-to-https"
|
||||||
|
|
||||||
@@ -5,43 +5,32 @@ import { InertiaProgress } from '@inertiajs/progress'
|
|||||||
import Vue3Toastify, { toast } from 'vue3-toastify'
|
import Vue3Toastify, { toast } from 'vue3-toastify'
|
||||||
import 'vue3-toastify/dist/index.css'
|
import 'vue3-toastify/dist/index.css'
|
||||||
|
|
||||||
// Optional: Lade-Balken für Inertia
|
|
||||||
InertiaProgress.init()
|
InertiaProgress.init()
|
||||||
|
|
||||||
// Inertia App starten
|
|
||||||
createInertiaApp({
|
createInertiaApp({
|
||||||
// Alle Pages in app/Views/Pages/**/*.vue werden automatisch importiert
|
|
||||||
resolve: name => {
|
resolve: name => {
|
||||||
// Vite scannt die Pages dynamisch
|
const pages = import.meta.glob('@domains/**/*.vue')
|
||||||
const pages = import.meta.glob('@views/**/*.vue')
|
|
||||||
|
|
||||||
// Suche nach der richtigen Page-Datei
|
|
||||||
const key = Object.keys(pages).find(k =>
|
const key = Object.keys(pages).find(k =>
|
||||||
k.endsWith(`/${name}.vue`) || k.endsWith(`/${name}/index.vue`)
|
k.endsWith(`/${name}.vue`) || k.endsWith(`/${name}/index.vue`)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!key) throw new Error(`Page not found: ${name}`)
|
if (!key) throw new Error(`Page not found: ${name}`)
|
||||||
|
|
||||||
// Unterstützt sowohl <script setup> als auch klassische Exports
|
|
||||||
return pages[key]()
|
return pages[key]()
|
||||||
},
|
},
|
||||||
|
|
||||||
// Setup der App
|
|
||||||
setup({ el, App, props, plugin }) {
|
setup({ el, App, props, plugin }) {
|
||||||
const vueApp = createApp({ render: () => h(App, props) })
|
const vueApp = createApp({ render: () => h(App, props) })
|
||||||
|
|
||||||
// Inertia Plugin
|
|
||||||
vueApp.use(plugin)
|
vueApp.use(plugin)
|
||||||
|
|
||||||
// Toastify global verfügbar machen
|
|
||||||
vueApp.use(Vue3Toastify, {
|
vueApp.use(Vue3Toastify, {
|
||||||
autoClose: 3000,
|
autoClose: 3000,
|
||||||
position: 'top-right',
|
position: 'top-right',
|
||||||
pauseOnHover: true,
|
pauseOnHover: true,
|
||||||
})
|
})
|
||||||
vueApp.config.globalProperties.$toast = toast
|
|
||||||
|
|
||||||
// Mounten auf das DOM
|
vueApp.config.globalProperties.$toast = toast
|
||||||
vueApp.mount(el)
|
vueApp.mount(el)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
15
routes/api.php
Normal file
15
routes/api.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
|
||||||
|
|
||||||
|
Route::get('/', ['TestController', 'index']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Route::get('/inertia', function () {
|
||||||
|
return Inertia::render('Pages/Home', [
|
||||||
|
'appName' => config('app.name'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
@@ -15,6 +15,7 @@ export default defineConfig({
|
|||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, 'resources/js'),
|
'@': path.resolve(__dirname, 'resources/js'),
|
||||||
'@views': path.resolve(__dirname, 'app/Views'),
|
'@views': path.resolve(__dirname, 'app/Views'),
|
||||||
|
'@domains': path.resolve(__dirname, 'app/Domains'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user