diff --git a/app/Domains/Admin/Controllers/ManagedTenantContactGetController.php b/app/Domains/Admin/Controllers/ManagedTenantContactGetController.php new file mode 100644 index 0000000..90dcbf8 --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantContactGetController.php @@ -0,0 +1,24 @@ +firstOrFail(); + + return response()->json([ + 'email' => $tenant->email, + 'email_finance' => $tenant->email_finance, + 'postcode' => $tenant->postcode, + 'city' => $tenant->city, + 'saveEndpoint' => '/api/v1/admin/tenants/' . $slug . '/contact', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantContactUpdateController.php b/app/Domains/Admin/Controllers/ManagedTenantContactUpdateController.php new file mode 100644 index 0000000..a102aac --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantContactUpdateController.php @@ -0,0 +1,28 @@ +firstOrFail(); + + $tenant->update([ + 'email' => $request->input('email'), + 'email_finance' => $request->input('email_finance'), + 'postcode' => $request->input('postcode'), + 'city' => $request->input('city'), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Kontaktdaten wurden gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantGdprGetController.php b/app/Domains/Admin/Controllers/ManagedTenantGdprGetController.php new file mode 100644 index 0000000..6cc472d --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantGdprGetController.php @@ -0,0 +1,21 @@ +firstOrFail(); + + return response()->json([ + 'gdpr_text' => $tenant->gdpr_text ?? '', + 'saveEndpoint' => '/api/v1/admin/tenants/' . $slug . '/gdpr', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantGdprUpdateController.php b/app/Domains/Admin/Controllers/ManagedTenantGdprUpdateController.php new file mode 100644 index 0000000..96a3826 --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantGdprUpdateController.php @@ -0,0 +1,25 @@ +firstOrFail(); + + $tenant->update([ + 'gdpr_text' => $request->input('gdpr_text'), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Datenschutzerklärung wurde gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantImpressGetController.php b/app/Domains/Admin/Controllers/ManagedTenantImpressGetController.php new file mode 100644 index 0000000..dd188a8 --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantImpressGetController.php @@ -0,0 +1,21 @@ +firstOrFail(); + + return response()->json([ + 'impress_text' => $tenant->impress_text ?? '', + 'saveEndpoint' => '/api/v1/admin/tenants/' . $slug . '/impress', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantImpressUpdateController.php b/app/Domains/Admin/Controllers/ManagedTenantImpressUpdateController.php new file mode 100644 index 0000000..09e23f1 --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantImpressUpdateController.php @@ -0,0 +1,25 @@ +firstOrFail(); + + $tenant->update([ + 'impress_text' => $request->input('impress_text'), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Impressum wurde gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantPaymentGetController.php b/app/Domains/Admin/Controllers/ManagedTenantPaymentGetController.php new file mode 100644 index 0000000..5d8e258 --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantPaymentGetController.php @@ -0,0 +1,23 @@ +firstOrFail(); + + return response()->json([ + 'account_iban' => $tenant->account_iban, + 'account_bic' => $tenant->account_bic, + 'account_name' => $tenant->account_name, + 'saveEndpoint' => '/api/v1/admin/tenants/' . $slug . '/payment', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/ManagedTenantPaymentUpdateController.php b/app/Domains/Admin/Controllers/ManagedTenantPaymentUpdateController.php new file mode 100644 index 0000000..e01d39a --- /dev/null +++ b/app/Domains/Admin/Controllers/ManagedTenantPaymentUpdateController.php @@ -0,0 +1,27 @@ +firstOrFail(); + + $tenant->update([ + 'account_iban' => $request->input('account_iban'), + 'account_bic' => $request->input('account_bic'), + 'account_name' => $request->input('account_name'), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Bezahldaten wurden gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/TenantContactGetController.php b/app/Domains/Admin/Controllers/TenantContactGetController.php index f69f58e..b660d45 100644 --- a/app/Domains/Admin/Controllers/TenantContactGetController.php +++ b/app/Domains/Admin/Controllers/TenantContactGetController.php @@ -15,6 +15,7 @@ class TenantContactGetController extends CommonController 'email_finance' => $this->tenant->email_finance, 'postcode' => $this->tenant->postcode, 'city' => $this->tenant->city, + 'saveEndpoint' => '/api/v1/admin/tenant/contact', ]); } } diff --git a/app/Domains/Admin/Controllers/TenantCreateController.php b/app/Domains/Admin/Controllers/TenantCreateController.php new file mode 100644 index 0000000..c92e269 --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantCreateController.php @@ -0,0 +1,35 @@ + $request->input('name'), + 'slug' => $request->input('slug'), + 'url' => $request->input('url'), + 'email' => '', + 'email_finance' => '', + 'account_name' => '', + 'account_iban' => '', + 'account_bic' => '', + 'city' => '', + 'postcode' => '', + 'is_active_local_group' => true, + 'has_active_instance' => true, + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Stamm wurde angelegt.', + 'slug' => $tenant->slug, + ]); + } +} diff --git a/app/Domains/Admin/Controllers/TenantEditPageController.php b/app/Domains/Admin/Controllers/TenantEditPageController.php new file mode 100644 index 0000000..dbf22a4 --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantEditPageController.php @@ -0,0 +1,27 @@ +firstOrFail(); + + $inertiaProvider = new InertiaProvider('Admin/TenantEdit', [ + 'tenant' => [ + 'name' => $tenant->name, + 'slug' => $tenant->slug, + 'url' => $tenant->url, + 'is_active_local_group' => $tenant->is_active_local_group, + ], + ]); + return $inertiaProvider->render(); + } +} diff --git a/app/Domains/Admin/Controllers/TenantGdprGetController.php b/app/Domains/Admin/Controllers/TenantGdprGetController.php index c0017b1..d98f35f 100644 --- a/app/Domains/Admin/Controllers/TenantGdprGetController.php +++ b/app/Domains/Admin/Controllers/TenantGdprGetController.php @@ -12,6 +12,7 @@ class TenantGdprGetController extends CommonController { return response()->json([ 'gdpr_text' => $this->tenant->gdpr_text ?? '', + 'saveEndpoint' => '/api/v1/admin/tenant/gdpr', ]); } } diff --git a/app/Domains/Admin/Controllers/TenantGeneralGetController.php b/app/Domains/Admin/Controllers/TenantGeneralGetController.php new file mode 100644 index 0000000..0c3c877 --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantGeneralGetController.php @@ -0,0 +1,24 @@ +firstOrFail(); + + return response()->json([ + 'name' => $tenant->name, + 'slug' => $tenant->slug, + 'url' => $tenant->url, + 'is_active_local_group' => $tenant->is_active_local_group, + 'saveEndpoint' => '/api/v1/admin/tenants/' . $slug . '/general', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/TenantGeneralUpdateController.php b/app/Domains/Admin/Controllers/TenantGeneralUpdateController.php new file mode 100644 index 0000000..3f6277e --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantGeneralUpdateController.php @@ -0,0 +1,27 @@ +firstOrFail(); + + $tenant->update([ + 'name' => $request->input('name'), + 'slug' => $request->input('slug'), + 'url' => $request->input('url'), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Allgemeine Daten wurden gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/TenantImpressGetController.php b/app/Domains/Admin/Controllers/TenantImpressGetController.php index e18b835..6419db4 100644 --- a/app/Domains/Admin/Controllers/TenantImpressGetController.php +++ b/app/Domains/Admin/Controllers/TenantImpressGetController.php @@ -12,6 +12,7 @@ class TenantImpressGetController extends CommonController { return response()->json([ 'impress_text' => $this->tenant->impress_text ?? '', + 'saveEndpoint' => '/api/v1/admin/tenant/impress', ]); } } diff --git a/app/Domains/Admin/Controllers/TenantListApiController.php b/app/Domains/Admin/Controllers/TenantListApiController.php new file mode 100644 index 0000000..12c68e8 --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantListApiController.php @@ -0,0 +1,25 @@ +get()->map(function ($tenant) { + return [ + 'name' => $tenant->name, + 'slug' => $tenant->slug, + 'url' => $tenant->url, + 'is_active_local_group' => $tenant->is_active_local_group, + ]; + }); + + return response()->json(['tenants' => $tenants]); + } +} diff --git a/app/Domains/Admin/Controllers/TenantListPageController.php b/app/Domains/Admin/Controllers/TenantListPageController.php new file mode 100644 index 0000000..2cfbeb7 --- /dev/null +++ b/app/Domains/Admin/Controllers/TenantListPageController.php @@ -0,0 +1,17 @@ +render(); + } +} diff --git a/app/Domains/Admin/Controllers/TenantPaymentGetController.php b/app/Domains/Admin/Controllers/TenantPaymentGetController.php index 0f38df1..1fc3a86 100644 --- a/app/Domains/Admin/Controllers/TenantPaymentGetController.php +++ b/app/Domains/Admin/Controllers/TenantPaymentGetController.php @@ -14,6 +14,7 @@ class TenantPaymentGetController extends CommonController 'account_iban' => $this->tenant->account_iban, 'account_bic' => $this->tenant->account_bic, 'account_name' => $this->tenant->account_name, + 'saveEndpoint' => '/api/v1/admin/tenant/payment', ]); } } diff --git a/app/Domains/Admin/Routes/api.php b/app/Domains/Admin/Routes/api.php index 81a4241..d31a421 100644 --- a/app/Domains/Admin/Routes/api.php +++ b/app/Domains/Admin/Routes/api.php @@ -1,15 +1,28 @@ group(function () { @@ -23,4 +36,23 @@ Route::middleware([IdentifyTenant::class, 'auth', AdminRoleMiddleware::class])-> Route::get('/gdpr', TenantGdprGetController::class); Route::post('/gdpr', TenantGdprUpdateController::class); }); + + Route::middleware(LvOnlyMiddleware::class)->group(function () { + Route::prefix('api/v1/admin/tenants')->group(function () { + Route::get('/list', TenantListApiController::class); + Route::post('/create', TenantCreateController::class); + Route::prefix('/{slug}')->group(function () { + Route::get('/general', TenantGeneralGetController::class); + Route::post('/general', TenantGeneralUpdateController::class); + Route::get('/contact', ManagedTenantContactGetController::class); + Route::post('/contact', ManagedTenantContactUpdateController::class); + Route::get('/payment', ManagedTenantPaymentGetController::class); + Route::post('/payment', ManagedTenantPaymentUpdateController::class); + Route::get('/impress', ManagedTenantImpressGetController::class); + Route::post('/impress', ManagedTenantImpressUpdateController::class); + Route::get('/gdpr', ManagedTenantGdprGetController::class); + Route::post('/gdpr', ManagedTenantGdprUpdateController::class); + }); + }); + }); }); diff --git a/app/Domains/Admin/Routes/web.php b/app/Domains/Admin/Routes/web.php index 2025169..9846e40 100644 --- a/app/Domains/Admin/Routes/web.php +++ b/app/Domains/Admin/Routes/web.php @@ -1,14 +1,22 @@ group(function () { Route::prefix('admin')->group(function () { Route::get('/', AdminDashboardController::class); Route::get('/tenant', TenantPageController::class); + + Route::middleware(LvOnlyMiddleware::class)->group(function () { + Route::get('/tenants', TenantListPageController::class); + Route::get('/tenants/{slug}', TenantEditPageController::class); + }); }); }); diff --git a/app/Domains/Admin/Views/Partials/TenantContact.vue b/app/Domains/Admin/Views/Partials/TenantContact.vue index d6bf63a..11843a5 100644 --- a/app/Domains/Admin/Views/Partials/TenantContact.vue +++ b/app/Domains/Admin/Views/Partials/TenantContact.vue @@ -21,7 +21,8 @@ const form = ref({ }) async function save() { - const response = await request('/api/v1/admin/tenant/contact', { + const saveUrl = props.data.saveEndpoint ?? '/api/v1/admin/tenant/contact' + const response = await request(saveUrl, { method: 'POST', body: form.value, }) diff --git a/app/Domains/Admin/Views/Partials/TenantGdpr.vue b/app/Domains/Admin/Views/Partials/TenantGdpr.vue index 2fdf97a..bf4cb91 100644 --- a/app/Domains/Admin/Views/Partials/TenantGdpr.vue +++ b/app/Domains/Admin/Views/Partials/TenantGdpr.vue @@ -27,7 +27,8 @@ function autoGenerate() { } async function save() { - const response = await request('/api/v1/admin/tenant/gdpr', { + const saveUrl = props.data.saveEndpoint ?? '/api/v1/admin/tenant/gdpr' + const response = await request(saveUrl, { method: 'POST', body: { gdpr_text: content.value }, }) diff --git a/app/Domains/Admin/Views/Partials/TenantGeneral.vue b/app/Domains/Admin/Views/Partials/TenantGeneral.vue new file mode 100644 index 0000000..bce3d10 --- /dev/null +++ b/app/Domains/Admin/Views/Partials/TenantGeneral.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/app/Domains/Admin/Views/Partials/TenantImpress.vue b/app/Domains/Admin/Views/Partials/TenantImpress.vue index 628d311..89f0799 100644 --- a/app/Domains/Admin/Views/Partials/TenantImpress.vue +++ b/app/Domains/Admin/Views/Partials/TenantImpress.vue @@ -16,7 +16,8 @@ const { request } = useAjax() const content = ref(props.data.impress_text ?? '') async function save() { - const response = await request('/api/v1/admin/tenant/impress', { + const saveUrl = props.data.saveEndpoint ?? '/api/v1/admin/tenant/impress' + const response = await request(saveUrl, { method: 'POST', body: { impress_text: content.value }, }) diff --git a/app/Domains/Admin/Views/Partials/TenantPayment.vue b/app/Domains/Admin/Views/Partials/TenantPayment.vue index 0b385ae..82123f6 100644 --- a/app/Domains/Admin/Views/Partials/TenantPayment.vue +++ b/app/Domains/Admin/Views/Partials/TenantPayment.vue @@ -20,7 +20,8 @@ const form = ref({ }) async function save() { - const response = await request('/api/v1/admin/tenant/payment', { + const saveUrl = props.data.saveEndpoint ?? '/api/v1/admin/tenant/payment' + const response = await request(saveUrl, { method: 'POST', body: form.value, }) diff --git a/app/Domains/Admin/Views/TenantEdit.vue b/app/Domains/Admin/Views/TenantEdit.vue new file mode 100644 index 0000000..588d66d --- /dev/null +++ b/app/Domains/Admin/Views/TenantEdit.vue @@ -0,0 +1,52 @@ + + + diff --git a/app/Domains/Admin/Views/TenantList.vue b/app/Domains/Admin/Views/TenantList.vue new file mode 100644 index 0000000..9773fc9 --- /dev/null +++ b/app/Domains/Admin/Views/TenantList.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/app/Middleware/LvOnlyMiddleware.php b/app/Middleware/LvOnlyMiddleware.php new file mode 100644 index 0000000..e368c07 --- /dev/null +++ b/app/Middleware/LvOnlyMiddleware.php @@ -0,0 +1,17 @@ +slug !== 'lv') { + return redirect('/admin')->with('message', 'Diese Funktion ist nur auf LV-Ebene verfügbar.'); + } + + return $next($request); + } +} diff --git a/resources/js/layouts/AdminAppLayout.vue b/resources/js/layouts/AdminAppLayout.vue index efa48a9..b4a1235 100644 --- a/resources/js/layouts/AdminAppLayout.vue +++ b/resources/js/layouts/AdminAppLayout.vue @@ -105,6 +105,11 @@ const props = defineProps({ +