Personal data and password change
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Actions\UpdatePersonalData;
|
||||
|
||||
use App\Repositories\UserRepository;
|
||||
|
||||
class UpdatePersonalDataCommand
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UpdatePersonalDataRequest $request,
|
||||
private readonly UserRepository $users
|
||||
) {}
|
||||
|
||||
public function execute(): UpdatePersonalDataResponse
|
||||
{
|
||||
$this->users->updatePersonalData($this->request);
|
||||
|
||||
$response = new UpdatePersonalDataResponse();
|
||||
$response->success = true;
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Actions\UpdatePersonalData;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UpdatePersonalDataRequest
|
||||
{
|
||||
public function __construct(
|
||||
public readonly User $user,
|
||||
public readonly ?string $nickname,
|
||||
public readonly ?string $email,
|
||||
public readonly ?string $phone,
|
||||
public readonly ?string $address1,
|
||||
public readonly ?string $address2,
|
||||
public readonly ?string $postcode,
|
||||
public readonly ?string $city,
|
||||
public readonly ?string $birthday,
|
||||
public readonly ?string $tetanusVaccination,
|
||||
public readonly ?string $medications,
|
||||
public readonly ?string $allergies,
|
||||
public readonly ?string $intolerances,
|
||||
public readonly ?string $eatingHabits,
|
||||
public readonly ?string $swimmingPermission,
|
||||
public readonly ?string $firstAidPermission,
|
||||
public readonly ?string $bankAccountOwner,
|
||||
public readonly ?string $bankAccountIban,
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Actions\UpdatePersonalData;
|
||||
|
||||
class UpdatePersonalDataResponse
|
||||
{
|
||||
public bool $success;
|
||||
}
|
||||
14
app/Domains/Dashboard/Controllers/MessagesController.php
Normal file
14
app/Domains/Dashboard/Controllers/MessagesController.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Controllers;
|
||||
|
||||
use App\Providers\InertiaProvider;
|
||||
use App\Scopes\CommonController;
|
||||
|
||||
class MessagesController extends CommonController {
|
||||
public function __invoke() {
|
||||
$inertiaProvider = new InertiaProvider('Dashboard/Messages', []);
|
||||
|
||||
return $inertiaProvider->render();
|
||||
}
|
||||
}
|
||||
45
app/Domains/Dashboard/Controllers/PersonalDataController.php
Normal file
45
app/Domains/Dashboard/Controllers/PersonalDataController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Controllers;
|
||||
|
||||
use App\Providers\InertiaProvider;
|
||||
use App\Scopes\CommonController;
|
||||
|
||||
class PersonalDataController extends CommonController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
if (!$this->checkAuth()) {
|
||||
return redirect()->intended('/login');
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
$data = $this->users->getPersonalData($user);
|
||||
|
||||
$inertiaProvider = new InertiaProvider('Dashboard/PersonalData', [
|
||||
'personalData' => [
|
||||
'firstname' => $data['firstname'],
|
||||
'lastname' => $data['lastname'],
|
||||
'birthday' => $data['birthday'],
|
||||
'nickname' => $data['nickname'],
|
||||
'email' => $data['email'],
|
||||
'phone' => $data['phone'],
|
||||
'address1' => $data['address_1'],
|
||||
'address2' => $data['address_2'],
|
||||
'postcode' => $data['postcode'],
|
||||
'city' => $data['city'],
|
||||
'medications' => $data['medications'],
|
||||
'allergies' => $data['allergies'],
|
||||
'intolerances' => $data['intolerances'],
|
||||
'eatingHabits' => $data['eating_habits'],
|
||||
'swimmingPermission' => $data['swimming_permission'],
|
||||
'firstAidPermission' => $data['first_aid_permission'],
|
||||
'bankAccountOwner' => $data['bank_account_owner'],
|
||||
'bankAccountIban' => $data['bank_account_iban'],
|
||||
'tetanusVaccination' => $data['tetanus_vaccination'],
|
||||
],
|
||||
]);
|
||||
|
||||
return $inertiaProvider->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Dashboard\Controllers;
|
||||
|
||||
use App\Domains\Dashboard\Actions\UpdatePersonalData\UpdatePersonalDataCommand;
|
||||
use App\Domains\Dashboard\Actions\UpdatePersonalData\UpdatePersonalDataRequest;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StorePersonalDataController extends CommonController
|
||||
{
|
||||
public function __invoke(Request $request): JsonResponse
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$actionRequest = new UpdatePersonalDataRequest(
|
||||
user: $user,
|
||||
nickname: $request->input('nickname'),
|
||||
email: $request->input('email'),
|
||||
phone: $request->input('phone'),
|
||||
address1: $request->input('address1'),
|
||||
address2: $request->input('address2'),
|
||||
postcode: $request->input('postcode'),
|
||||
city: $request->input('city'),
|
||||
medications: $request->input('medications'),
|
||||
allergies: $request->input('allergies'),
|
||||
intolerances: $request->input('intolerances'),
|
||||
eatingHabits: $request->input('eatingHabits'),
|
||||
swimmingPermission: $request->input('swimmingPermission'),
|
||||
firstAidPermission: $request->input('firstAidPermission'),
|
||||
bankAccountOwner: $request->input('bankAccountOwner'),
|
||||
bankAccountIban: $request->input('bankAccountIban'),
|
||||
birthday: $request->input('birthday'),
|
||||
tetanusVaccination: $request->input('tetanusVaccination'),
|
||||
);
|
||||
|
||||
$command = new UpdatePersonalDataCommand($actionRequest, $this->users);
|
||||
$command->execute();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Deine Daten wurden erfolgreich gespeichert.']);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Domains\Dashboard\Controllers\DashboardController;
|
||||
use App\Domains\Dashboard\Controllers\StorePersonalDataController;
|
||||
use App\Middleware\IdentifyTenant;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
@@ -11,7 +12,10 @@ Route::middleware(IdentifyTenant::class)->group(function () {
|
||||
Route::get('/open-cost-units', [DashboardController::class, 'getOpenCostUnits']);
|
||||
Route::get('/upcoming-events', [DashboardController::class, 'getUpcomingEvents']);
|
||||
Route::get('/my-participations', [DashboardController::class, 'getMyParticipations']);
|
||||
Route::post('/personal-data', StorePersonalDataController::class);
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1 +1,16 @@
|
||||
<?php
|
||||
|
||||
use App\Domains\Dashboard\Controllers\DashboardController;
|
||||
use App\Domains\Dashboard\Controllers\MessagesController;
|
||||
use App\Domains\Dashboard\Controllers\PersonalDataController;
|
||||
use App\Middleware\IdentifyTenant;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware(IdentifyTenant::class)->group(function () {
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/personal-data', PersonalDataController::class);
|
||||
Route::get('/messages', MessagesController::class);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
25
app/Domains/Dashboard/Views/Messages.vue
Normal file
25
app/Domains/Dashboard/Views/Messages.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<script setup>
|
||||
import AppLayout from "../../../../resources/js/layouts/AppLayout.vue";
|
||||
import ShadowedBox from "../../../Views/Components/ShadowedBox.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title='Meine Nachrichten'>
|
||||
<shadowed-box style="width: 95%; margin: 20px auto; padding: 20px; overflow-x: hidden;">
|
||||
Diese Funktion steht aktuell nicht zur Verfügung.<br />
|
||||
Bitte versuche es später noch einmal.
|
||||
</shadowed-box>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 6px;
|
||||
font-size: 0.95rem;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
}
|
||||
</style>
|
||||
@@ -27,8 +27,8 @@ function navigateTo(url) {
|
||||
{{participation.arrivalDateReadable}} - {{participation.departureDateReadable}}
|
||||
</td>
|
||||
<td>
|
||||
<Icon name="euro-sign" style="padding: 5px; font-size: 11pt; color: #ffffff; margin-right: 5px;" :class="participation.needs_payment ? 'bg-red' : 'bg-green'" />
|
||||
<Icon name="award" style="padding: 5px; font-size: 11pt; color: #ffffff; margin-right: 5px;" :class="participation.cocColor" />
|
||||
<Icon name="euro-sign" style="padding: 2px; font-size: 10pt; color: #ffffff; margin-right: 5px;" :class="participation.needs_payment ? 'bg-red' : 'bg-green'" />
|
||||
<Icon name="award" style="padding: 2px; font-size: 10pt; color: #ffffff; margin-right: 5px;" :class="participation.cocColor" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
186
app/Domains/Dashboard/Views/PersonalData.vue
Normal file
186
app/Domains/Dashboard/Views/PersonalData.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { request } from '../../../../resources/js/components/HttpClient.js'
|
||||
import AppLayout from "../../../../resources/js/layouts/AppLayout.vue";
|
||||
import ShadowedBox from "../../../Views/Components/ShadowedBox.vue";
|
||||
import {toast} from "vue3-toastify";
|
||||
|
||||
const props = defineProps({
|
||||
personalData: Object,
|
||||
})
|
||||
|
||||
const form = reactive({
|
||||
nickname: props.personalData.nickname ?? '',
|
||||
email: props.personalData.email ?? '',
|
||||
phone: props.personalData.phone ?? '',
|
||||
address1: props.personalData.address1 ?? '',
|
||||
address2: props.personalData.address2 ?? '',
|
||||
postcode: props.personalData.postcode ?? '',
|
||||
city: props.personalData.city ?? '',
|
||||
birthday: props.personalData.birthday ?? '',
|
||||
tetanusVaccination: props.personalData.tetanusVaccination ?? '',
|
||||
medications: props.personalData.medications ?? '',
|
||||
allergies: props.personalData.allergies ?? '',
|
||||
intolerances: props.personalData.intolerances ?? '',
|
||||
eatingHabits: props.personalData.eatingHabits ?? '',
|
||||
swimmingPermission: props.personalData.swimmingPermission ?? '',
|
||||
firstAidPermission: props.personalData.firstAidPermission ?? '',
|
||||
bankAccountOwner: props.personalData.bankAccountOwner ?? '',
|
||||
bankAccountIban: props.personalData.bankAccountIban ?? '',
|
||||
})
|
||||
|
||||
const saving = ref(false)
|
||||
const successMessage = ref('')
|
||||
const errorMessage = ref('')
|
||||
|
||||
const submit = async () => {
|
||||
saving.value = true
|
||||
successMessage.value = ''
|
||||
errorMessage.value = ''
|
||||
|
||||
const result = await request('/api/v1/dashboard/personal-data', {
|
||||
method: 'POST',
|
||||
body: { ...form },
|
||||
})
|
||||
|
||||
saving.value = false
|
||||
|
||||
if (result?.success) {
|
||||
toast.success(result.message)
|
||||
} else {
|
||||
toast.error(result.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title='Persönliche Daten'>
|
||||
<shadowed-box style="width: 95%; margin: 20px auto; padding: 20px; overflow-x: hidden;">
|
||||
|
||||
<div class="max-w-2xl mx-auto p-6">
|
||||
<form @submit.prevent="submit">
|
||||
<table class="form-table" style="width: 90%; margin: 10px;">
|
||||
|
||||
<!-- Nicht veränderbare Felder -->
|
||||
<tr>
|
||||
<td style="width: 200px; padding: 5px;">Vorname:</td>
|
||||
<td><span class="text-gray-700">{{ personalData.firstname }}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 200px; padding: 5px;">Nachname:</td>
|
||||
<td><span class="text-gray-700">{{ personalData.lastname }}</span></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- Veränderbare Felder -->
|
||||
<tr>
|
||||
<td>Pfadiname:</td>
|
||||
<td><input type="text" v-model="form.nickname" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>E-Mail:</td>
|
||||
<td><input type="email" v-model="form.email" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Telefon:</td>
|
||||
<td><input type="text" v-model="form.phone" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Straße / Hausnummer:</td>
|
||||
<td><input type="text" v-model="form.address1" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Adresszusatz:</td>
|
||||
<td><input type="text" v-model="form.address2" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PLZ:</td>
|
||||
<td><input type="text" v-model="form.postcode" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ort:</td>
|
||||
<td><input type="text" v-model="form.city" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 200px; padding: 5px;">Geburtsdatum:</td>
|
||||
<td><input type="date" v-model="form.birthday" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Medikamente:</td>
|
||||
<td><input type="text" v-model="form.medications" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Allergien:</td>
|
||||
<td><input type="text" v-model="form.allergies" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unverträglichkeiten:</td>
|
||||
<td><input type="text" v-model="form.intolerances" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Letzte Tetanus-Impfung:</td>
|
||||
<td><input type="date" v-model="form.tetanusVaccination" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ernährungsgewohnheiten:</td>
|
||||
<td>
|
||||
<select v-model="form.eatingHabits">
|
||||
<option value="EATING_HABIT_VEGAN">Vegan</option>
|
||||
<option value="EATING_HABIT_VEGETARIAN">Vegetarisch</option>
|
||||
<option value="EATING_HABIT_OMNIVOR">Omnivor</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Badeerlaubnis:</td>
|
||||
<td>
|
||||
<select v-model="form.swimmingPermission">
|
||||
<option value="SWIMMING_PERMISSION_ALLOWED">Erteilt, kann schwimmen</option>
|
||||
<option value="SWIMMING_PERMISSION_LIMITED">Erteilt, kann nicht schwimmen</option>
|
||||
<option value="SWIMMING_PERMISSION_DENIED">Nicht erteilt</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Erste-Hilfe-Erlaubnis:</td>
|
||||
<td>
|
||||
<select v-model="form.firstAidPermission">
|
||||
<option value="FIRST_AID_PERMISSION_ALLOWED">Erweiterte Erste Hilfe erlaubt</option>
|
||||
<option value="FIRST_AID_PERMISSION_DENIED">Erweiterte Erste Hilfe verweigert</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kontoinhaber:</td>
|
||||
<td><input type="text" v-model="form.bankAccountOwner" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IBAN:</td>
|
||||
<td><input type="text" v-model="form.bankAccountIban" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2" class="btn-row" style="padding-top: 20px;">
|
||||
<button type="submit" class="button" :disabled="saving">
|
||||
{{ saving ? 'Wird gespeichert…' : 'Speichern' }}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</shadowed-box>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 6px;
|
||||
font-size: 0.95rem;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user