Compare commits
4 Commits
343b0d418d
...
6d204b948e
Author | SHA1 | Date |
---|---|---|
philipp lang | 6d204b948e | |
philipp lang | 977e427abb | |
philipp lang | 46e070a029 | |
philipp lang | 84e05fbc52 |
|
@ -1,5 +1,10 @@
|
||||||
# Letzte Änderungen
|
# Letzte Änderungen
|
||||||
|
|
||||||
|
### 1.10.16
|
||||||
|
|
||||||
|
- Rechnungen und Erinnerungen werden nun automatisch täglich um 10 Uhr verschickt
|
||||||
|
- Es kann eingestellt werden, nach wie vielen Wochen an Rechnungen erinnert werden soll (Standard: 12)
|
||||||
|
|
||||||
### 1.10.15
|
### 1.10.15
|
||||||
|
|
||||||
- "Für Mitglieder zusätzlich abfragen" kann nun im Formular auch gesetzt werden, wenn ein NaMi Feld ausgewählt ist.
|
- "Für Mitglieder zusätzlich abfragen" kann nun im Formular auch gesetzt werden, wenn ein NaMi Feld ausgewählt ist.
|
||||||
|
|
|
@ -21,7 +21,9 @@ class UserResource extends JsonResource
|
||||||
public function toArray($request): array
|
public function toArray($request): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $this->name,
|
'firstname' => $this->firstname,
|
||||||
|
'lastname' => $this->lastname,
|
||||||
|
'avatar_url' => $this->getGravatarUrl(),
|
||||||
'email' => $this->email,
|
'email' => $this->email,
|
||||||
'avatar' => [
|
'avatar' => [
|
||||||
'src' => Storage::url('avatar.png'),
|
'src' => Storage::url('avatar.png'),
|
||||||
|
|
|
@ -22,4 +22,9 @@ class User extends Authenticatable
|
||||||
{
|
{
|
||||||
$this->notify(new ResetPassword($token));
|
$this->notify(new ResetPassword($token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getGravatarUrl(): string
|
||||||
|
{
|
||||||
|
return 'https://www.gravatar.com/avatar/' . hash('sha256', $this->email);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ class UserFactory extends Factory
|
||||||
return [
|
return [
|
||||||
'email' => $this->faker->safeEmail,
|
'email' => $this->faker->safeEmail,
|
||||||
'password' => Hash::make('password'),
|
'password' => Hash::make('password'),
|
||||||
'name' => $this->faker->firstName,
|
'firstname' => $this->faker->firstName,
|
||||||
|
'lastname' => $this->faker->lastName,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('firstname')->after('name')->nullable();
|
||||||
|
$table->string('lastname')->after('name')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (User::get() as $user) {
|
||||||
|
$user->update([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (DB::table('users')->get() as $user) {
|
||||||
|
[$firstname, $lastname] = explode(' ', $user->name);
|
||||||
|
DB::table('users')->where('id', $user->id)->update(['firstname' => $firstname, 'lastname' => $lastname]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('firstname')->nullable(false)->change();
|
||||||
|
$table->string('lastname')->nullable(false)->change();
|
||||||
|
$table->dropColumn('name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('name');
|
||||||
|
});
|
||||||
|
foreach (DB::table('users')->get() as $user) {
|
||||||
|
DB::table('users')->where('id', $user->id)->update(['name' => $user->firstname . ' ' . $user->lastname]);
|
||||||
|
}
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('firstname');
|
||||||
|
$table->dropColumn('lastname');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,7 +5,7 @@
|
||||||
<page-title>{{ title }}</page-title>
|
<page-title>{{ title }}</page-title>
|
||||||
<slot name="toolbar"></slot>
|
<slot name="toolbar"></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-2 ml-2">
|
<div class="flex items-center space-x-4 ml-2">
|
||||||
<a v-if="$attrs.onClose" href="#" class="btn label btn-primary-light icon" @click.prevent="$emit('close')">
|
<a v-if="$attrs.onClose" href="#" class="btn label btn-primary-light icon" @click.prevent="$emit('close')">
|
||||||
<ui-sprite class="w-3 h-3" src="close"></ui-sprite>
|
<ui-sprite class="w-3 h-3" src="close"></ui-sprite>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
</template>
|
</template>
|
||||||
<template #right>
|
<template #right>
|
||||||
<slot name="right"></slot>
|
<slot name="right"></slot>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<div class="rounded-full overflow-hidden border-2 border-solid border-gray-300">
|
||||||
|
<img :src="$page.props.auth.user.avatar_url" class="w-8 h-8 object-cover" />
|
||||||
|
</div>
|
||||||
|
<div class="text-gray-300" v-text="`${$page.props.auth.user.firstname} ${$page.props.auth.user.lastname}`"></div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</page-header>
|
</page-header>
|
||||||
|
|
||||||
|
|
|
@ -49,17 +49,17 @@
|
||||||
<f-text id="email" v-model="inner.email" size="sm" label="E-Mail"></f-text>
|
<f-text id="email" v-model="inner.email" size="sm" label="E-Mail"></f-text>
|
||||||
<f-text id="email_parents" v-model="inner.email_parents" size="sm" label="E-Mail eltern"></f-text>
|
<f-text id="email_parents" v-model="inner.email_parents" size="sm" label="E-Mail eltern"></f-text>
|
||||||
<f-text id="fax" v-model="inner.fax" size="sm" label="Fax"></f-text>
|
<f-text id="fax" v-model="inner.fax" size="sm" label="Fax"></f-text>
|
||||||
<f-textarea id="letter_address" v-model="inner.letter_address" class="sm:col-span-2" rows="3" label="Brief-Adresse" size="sm"></f-textarea>
|
<f-textarea id="letter_address" v-model="inner.letter_address" class="sm:col-span-2" :rows="3" label="Brief-Adresse" size="sm"></f-textarea>
|
||||||
</div>
|
</div>
|
||||||
</ui-box>
|
</ui-box>
|
||||||
<ui-box heading="System">
|
<ui-box heading="System">
|
||||||
<div class="grid gap-3">
|
<div class="grid gap-3">
|
||||||
<f-select id="bill_kind" v-model="inner.bill_kind" :options="meta.billKinds" label="Rechnung versenden über" name="bill_kind" size="sm"></f-select>
|
<f-select id="bill_kind" v-model="inner.bill_kind" :options="meta.billKinds" label="Rechnung versenden über" name="bill_kind" size="sm"></f-select>
|
||||||
<f-select id="subscription_id" v-model="inner.subscription_id" :options="meta.subscriptions" label="Beitrag" name="subscription_id" size="sm"></f-select>
|
<f-select id="subscription_id" v-model="inner.subscription_id" :options="meta.subscriptions" label="Beitrag" name="subscription_id" size="sm"></f-select>
|
||||||
<f-switch id="has_nami" v-model="inner.has_nami" size="sm" label="In Nami eintragen"></f-switch>
|
<f-switch id="has_nami" v-model="inner.has_nami" name="has_nami" size="sm" label="In Nami eintragen"></f-switch>
|
||||||
<f-switch id="send_newspaper" v-model="inner.send_newspaper" label="Mittendrin versenden" size="sm"></f-switch>
|
<f-switch id="send_newspaper" v-model="inner.send_newspaper" name="send_newspaper" label="Mittendrin versenden" size="sm"></f-switch>
|
||||||
<f-text id="joined_at" v-model="inner.joined_at" class="sm:col-span-2" type="date" label="Eintrittsdatum" size="sm" required></f-text>
|
<f-text id="joined_at" v-model="inner.joined_at" class="sm:col-span-2" type="date" label="Eintrittsdatum" size="sm" required></f-text>
|
||||||
<f-textarea id="comment" v-model="inner.comment" rows="3" class="col-span-2" label="Kommentar" size="sm"></f-textarea>
|
<f-textarea id="comment" v-model="inner.comment" :rows="3" class="col-span-2" label="Kommentar" size="sm"></f-textarea>
|
||||||
<div v-if="mode === 'create' || (original.has_nami === false && inner.has_nami === true)" class="contents">
|
<div v-if="mode === 'create' || (original.has_nami === false && inner.has_nami === true)" class="contents">
|
||||||
<f-select
|
<f-select
|
||||||
id="first_activity_id"
|
id="first_activity_id"
|
||||||
|
@ -86,36 +86,44 @@
|
||||||
<ui-box heading="Prävention">
|
<ui-box heading="Prävention">
|
||||||
<div class="grid sm:grid-cols-[minmax(min-content,max-content)_minmax(min-content,max-content)] gap-2">
|
<div class="grid sm:grid-cols-[minmax(min-content,max-content)_minmax(min-content,max-content)] gap-2">
|
||||||
<div class="grid grid-cols-[minmax(min-content,max-content)_8rem] gap-1">
|
<div class="grid grid-cols-[minmax(min-content,max-content)_8rem] gap-1">
|
||||||
<f-switch id="has_efz" v-model="hasEfz" size="sm" label="Führungszeugnis eingesehen"></f-switch>
|
<f-switch id="has_efz" v-model="hasEfz" name="has_efz" size="sm" label="Führungszeugnis eingesehen"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.efz !== null" id="efz" v-model="inner.efz" type="date" label="am" size="sm"></f-text>
|
<f-text v-if="inner.efz !== null" id="efz" v-model="inner.efz" type="date" label="am" size="sm"></f-text>
|
||||||
</div>
|
</div>
|
||||||
<f-switch id="has_ps" v-model="hasPs" size="sm" label="Hat Präventionsschulung"></f-switch>
|
<f-switch id="has_ps" v-model="hasPs" name="has_ps" size="sm" label="Hat Präventionsschulung"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.ps_at !== null" id="ps_at" v-model="inner.ps_at" type="date" label="am" size="sm"></f-text>
|
<f-text v-if="inner.ps_at !== null" id="ps_at" v-model="inner.ps_at" type="date" label="am" size="sm"></f-text>
|
||||||
</div>
|
</div>
|
||||||
<f-switch id="has_more_ps" v-model="hasMorePs" size="sm" label="Hat Vertiefungsschulung"></f-switch>
|
<f-switch id="has_more_ps" v-model="hasMorePs" name="has_more_ps" size="sm" label="Hat Vertiefungsschulung"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.more_ps_at !== null" id="more_ps_at" v-model="inner.more_ps_at" type="date" label="am" size="sm"></f-text>
|
<f-text v-if="inner.more_ps_at !== null" id="more_ps_at" v-model="inner.more_ps_at" type="date" label="am" size="sm"></f-text>
|
||||||
</div>
|
</div>
|
||||||
<f-switch id="is_recertified" v-model="isRecertified" size="sm" label="Hat Rezertifizierung"></f-switch>
|
<f-switch id="is_recertified" v-model="isRecertified" name="is_recertified" size="sm" label="Hat Rezertifizierung"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.recertified_at !== null" id="recertified_at" v-model="inner.recertified_at" type="date" label="am" size="sm"></f-text>
|
<f-text v-if="inner.recertified_at !== null" id="recertified_at" v-model="inner.recertified_at" type="date" label="am" size="sm"></f-text>
|
||||||
</div>
|
</div>
|
||||||
<f-switch id="has_without_education" v-model="hasWithoutEducation" label="Einsatz ohne Schulung" size="sm"></f-switch>
|
<f-switch id="has_without_education" v-model="hasWithoutEducation" name="has_without_education" label="Einsatz ohne Schulung" size="sm"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.without_education_at !== null" id="without_education_at" v-model="inner.without_education_at" type="date" label="am" size="sm"></f-text>
|
<f-text
|
||||||
|
v-if="inner.without_education_at !== null"
|
||||||
|
id="without_education_at"
|
||||||
|
v-model="inner.without_education_at"
|
||||||
|
name="without_education_at"
|
||||||
|
type="date"
|
||||||
|
label="am"
|
||||||
|
size="sm"
|
||||||
|
></f-text>
|
||||||
</div>
|
</div>
|
||||||
<f-switch id="has_without_efz" v-model="hasWithoutEfz" size="sm" label="Einsatz ohne EFZ"></f-switch>
|
<f-switch id="has_without_efz" v-model="hasWithoutEfz" name="has_without_efz" size="sm" label="Einsatz ohne EFZ"></f-switch>
|
||||||
<div>
|
<div>
|
||||||
<f-text v-if="inner.without_efz_at !== null" id="without_efz_at" v-model="inner.without_efz_at" type="date" label="am" size="sm"></f-text>
|
<f-text v-if="inner.without_efz_at !== null" id="without_efz_at" v-model="inner.without_efz_at" type="date" label="am" size="sm"></f-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid gap-1">
|
<div class="grid gap-1">
|
||||||
<f-switch id="has_svk" v-model="inner.has_svk" size="sm" label="SVK unterschrieben"></f-switch>
|
<f-switch id="has_svk" v-model="inner.has_svk" name="has_svk" size="sm" label="SVK unterschrieben"></f-switch>
|
||||||
<f-switch id="has_vk" v-model="inner.has_vk" size="sm" label="Verhaltenskodex unterschrieben"></f-switch>
|
<f-switch id="has_vk" v-model="inner.has_vk" name="has_vk" size="sm" label="Verhaltenskodex unterschrieben"></f-switch>
|
||||||
<f-switch id="multiply_pv" v-model="inner.multiply_pv" label="Multiplikator*in Präventionsschulung" size="sm"></f-switch>
|
<f-switch id="multiply_pv" v-model="inner.multiply_pv" name="multiply_pv" label="Multiplikator*in Präventionsschulung" size="sm"></f-switch>
|
||||||
<f-switch id="multiply_more_pv" v-model="inner.multiply_more_pv" label="Multiplikator*in Vertiefungsschulung" size="sm"></f-switch>
|
<f-switch id="multiply_more_pv" v-model="inner.multiply_more_pv" name="multiply_more_pv" label="Multiplikator*in Vertiefungsschulung" size="sm"></f-switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ui-box>
|
</ui-box>
|
||||||
|
|
|
@ -1,27 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
<div class="grid gap-3">
|
<div class="grid gap-3">
|
||||||
<ui-text-display class="col-start-1" label="Führungszeugnis eingesehen"
|
<ui-text-display class="col-start-1" label="Führungszeugnis eingesehen" :value="inner.efz_human ? inner.efz_human : 'nie'"></ui-text-display>
|
||||||
:value="inner.efz_human ? inner.efz_human : 'nie'"></ui-text-display>
|
<ui-text-display class="col-start-1" label="Präventionsschulung" :value="inner.ps_at_human ? inner.ps_at_human : 'nie'"></ui-text-display>
|
||||||
<ui-text-display class="col-start-1" label="Präventionsschulung"
|
<ui-text-display class="col-start-1" label="Rezertifizierung" :value="inner.recertified_at_human ? inner.recertified_at_human : 'nie'"></ui-text-display>
|
||||||
:value="inner.ps_at_human ? inner.ps_at_human : 'nie'"></ui-text-display>
|
<ui-text-display class="col-start-1" label="Vertiefungsschulung" :value="inner.more_ps_at_human ? inner.more_ps_at_human : 'nie'"></ui-text-display>
|
||||||
<ui-text-display class="col-start-1" label="Rezertifizierung"
|
<ui-text-display class="col-start-1" label="Einsatz ohne Schulung" :value="inner.without_education_at_human ? inner.without_education_at_human : 'nie'"></ui-text-display>
|
||||||
:value="inner.recertified_at_human ? inner.recertified_at_human : 'nie'"></ui-text-display>
|
<ui-text-display class="col-start-1" label="Einsatz ohne EFZ" :value="inner.without_efz_at_human ? inner.without_efz_at_human : 'nie'"></ui-text-display>
|
||||||
<ui-text-display class="col-start-1" label="Vertiefungsschulung"
|
|
||||||
:value="inner.more_ps_at_human ? inner.more_ps_at_human : 'nie'"></ui-text-display>
|
|
||||||
<ui-text-display class="col-start-1" label="Einsatz ohne Schulung"
|
|
||||||
:value="inner.without_education_at_human ? inner.without_education_at_human : 'nie'"></ui-text-display>
|
|
||||||
<ui-text-display class="col-start-1" label="Einsatz ohne EFZ"
|
|
||||||
:value="inner.without_efz_at_human ? inner.without_efz_at_human : 'nie'"></ui-text-display>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid gap-3 content-start">
|
<div class="grid gap-3 content-start">
|
||||||
<ui-boolean-display :value="inner.has_vk" long-label="Verhaltenskodex unterschrieben"
|
<ui-boolean-display :value="inner.has_vk" long-label="Verhaltenskodex unterschrieben" label="VK"></ui-boolean-display>
|
||||||
label="VK"></ui-boolean-display>
|
|
||||||
<ui-boolean-display :value="inner.has_svk" long-label="SVK unterschrieben" label="SVK"></ui-boolean-display>
|
<ui-boolean-display :value="inner.has_svk" long-label="SVK unterschrieben" label="SVK"></ui-boolean-display>
|
||||||
<ui-boolean-display :value="inner.multiply_pv" long-label="Multiplikator*in Präventionsschulung"
|
<ui-boolean-display :value="inner.multiply_pv" long-label="Multiplikator*in Präventionsschulung" label="Multipl. PS"></ui-boolean-display>
|
||||||
label="Multipl. PS"></ui-boolean-display>
|
<ui-boolean-display :value="inner.multiply_more_pv" long-label="Multiplikator*in Vertiefungsschulung" label="Multipl. VS"></ui-boolean-display>
|
||||||
<ui-boolean-display :value="inner.multiply_more_pv" long-label="Multiplikator*in Vertiefungsschulung"
|
|
||||||
label="Multipl. VS"></ui-boolean-display>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -25,6 +25,19 @@ class DashboardTest extends TestCase
|
||||||
$this->assertInertiaHas('Example', $response, 'blocks.0.title');
|
$this->assertInertiaHas('Example', $response, 'blocks.0.title');
|
||||||
$this->assertInertiaHas('exa', $response, 'blocks.0.component');
|
$this->assertInertiaHas('exa', $response, 'blocks.0.component');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItDisplaysUserAvatar(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
|
||||||
|
$this->login()->loginNami();
|
||||||
|
auth()->user()->update(['firstname' => 'Bob', 'lastname' => 'Dylan', 'email' => 'max@email.com']);
|
||||||
|
|
||||||
|
$this->get('/')
|
||||||
|
->assertInertiaPath('auth.user.firstname', 'Bob')
|
||||||
|
->assertInertiaPath('auth.user.avatar_url', 'https://www.gravatar.com/avatar/' . hash('sha256', 'max@email.com'))
|
||||||
|
->assertInertiaPath('auth.user.lastname', 'Dylan');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExampleBlock extends Block
|
class ExampleBlock extends Block
|
||||||
|
|
Loading…
Reference in New Issue