Compare commits
	
		
			3 Commits
		
	
	
		
			7b00d1d3ee
			...
			33149e8b79
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								 | 
						33149e8b79 | |
| 
							
							
								 | 
						50878a9a3c | |
| 
							
							
								 | 
						63799c87ec | 
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Member\Data;
 | 
					namespace App\Member\Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Group;
 | 
				
			||||||
use Spatie\LaravelData\Data;
 | 
					use Spatie\LaravelData\Data;
 | 
				
			||||||
use Spatie\LaravelData\Attributes\MapInputName;
 | 
					use Spatie\LaravelData\Attributes\MapInputName;
 | 
				
			||||||
use Spatie\LaravelData\Attributes\MapOutputName;
 | 
					use Spatie\LaravelData\Attributes\MapOutputName;
 | 
				
			||||||
| 
						 | 
					@ -16,4 +17,13 @@ class GroupData extends Data {
 | 
				
			||||||
        public string $name,
 | 
					        public string $name,
 | 
				
			||||||
    ) {}
 | 
					    ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function fromId(int $id): static {
 | 
				
			||||||
 | 
					        $group = Group::findOrFail($id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return static::from([
 | 
				
			||||||
 | 
					            'name' => $group->name,
 | 
				
			||||||
 | 
					            'id' => $group->id,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,78 +3,44 @@
 | 
				
			||||||
namespace App\Member\Data;
 | 
					namespace App\Member\Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Spatie\LaravelData\Data;
 | 
					use Spatie\LaravelData\Data;
 | 
				
			||||||
use Spatie\LaravelData\Attributes\MapInputName;
 | 
					 | 
				
			||||||
use Spatie\LaravelData\Attributes\MapOutputName;
 | 
					 | 
				
			||||||
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
 | 
					 | 
				
			||||||
use App\Member\Membership;
 | 
					use App\Member\Membership;
 | 
				
			||||||
use App\Member\Member;
 | 
					use App\Member\Member;
 | 
				
			||||||
use App\Activity;
 | 
					 | 
				
			||||||
use App\Lib\Data\DateData;
 | 
					use App\Lib\Data\DateData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[MapInputName(SnakeCaseMapper::class)]
 | 
					 | 
				
			||||||
#[MapOutputName(SnakeCaseMapper::class)]
 | 
					 | 
				
			||||||
class MembershipData extends Data
 | 
					class MembershipData extends Data
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(
 | 
					    public function __construct(
 | 
				
			||||||
        public int $id,
 | 
					        public ?ActivityData $activity = null,
 | 
				
			||||||
        public ActivityData $activity,
 | 
					        public ?SubactivityData $subactivity = null,
 | 
				
			||||||
        public SubactivityData $subactivity,
 | 
					        public ?GroupData $group = null,
 | 
				
			||||||
        public GroupData $group,
 | 
					        public ?DateData $promisedAt = null,
 | 
				
			||||||
        public ?DateData $promisedAt,
 | 
					        public ?DateData $from = null,
 | 
				
			||||||
        public DateData $from,
 | 
					        public bool $isActive = false,
 | 
				
			||||||
        public bool $isActive,
 | 
					        public array $links = [],
 | 
				
			||||||
    ) {}
 | 
					    ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function fromModel(Membership $membership): static
 | 
					    public static function fromModel(Membership $membership): static
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return static::factory()->withoutMagicalCreation()->from([
 | 
					        return static::factory()->withoutMagicalCreation()->from([
 | 
				
			||||||
            'id' => $membership->id,
 | 
					 | 
				
			||||||
            'activity' => $membership->activity,
 | 
					            'activity' => $membership->activity,
 | 
				
			||||||
            'subactivity' => $membership->subactivity,
 | 
					            'subactivity' => $membership?->subactivity,
 | 
				
			||||||
            'is_active' => $membership->isActive(),
 | 
					            'isActive' => $membership->isActive(),
 | 
				
			||||||
            'from' => $membership->from,
 | 
					            'from' => $membership->from,
 | 
				
			||||||
            'group' => $membership->group,
 | 
					            'group' => $membership->group,
 | 
				
			||||||
            'promised_at' => $membership->promised_at,
 | 
					            'promisedAt' => $membership->promised_at,
 | 
				
			||||||
 | 
					            'links' => [
 | 
				
			||||||
 | 
					                'update' => route('membership.update', $membership),
 | 
				
			||||||
 | 
					                'destroy' => route('membership.destroy', $membership),
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @return array<string, mixed>
 | 
					     * @return array<string, mixed>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function with(): array
 | 
					    public static function memberMeta(Member $member): MembershipMeta
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return MembershipMeta::fromMember($member);
 | 
				
			||||||
            // 'human_date' => $this->from->format('d.m.Y'),
 | 
					 | 
				
			||||||
            // 'promised_at_human' => $this->promisedAt?->format('d.m.Y'),
 | 
					 | 
				
			||||||
            // 'promised_at' => $this->promisedAt?->format('Y-m-d'),
 | 
					 | 
				
			||||||
            'links' => [
 | 
					 | 
				
			||||||
                'update' => route('membership.update', ['membership' => $this->id]),
 | 
					 | 
				
			||||||
                'destroy' => route('membership.destroy', ['membership' => $this->id]),
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @return array<string, mixed>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static function memberMeta(Member $member): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $activities = Activity::with('subactivities')->get();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'links' => [
 | 
					 | 
				
			||||||
                'store' => route('member.membership.store', ['member' => $member]),
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            'groups' => NestedGroup::cacheForSelect(),
 | 
					 | 
				
			||||||
            'activities' => $activities->map(fn($activity) => ['id' => $activity->id, 'name' => $activity->name]),
 | 
					 | 
				
			||||||
            'subactivities' => $activities->mapWithKeys(fn($activity) => [$activity->id => $activity->subactivities->map(fn($subactivity) => ['id' => $subactivity->id, 'name' => $subactivity->name, 'is_age_group' => $subactivity->is_age_group])]),
 | 
					 | 
				
			||||||
            'default' => [
 | 
					 | 
				
			||||||
                'group_id' => $member->group_id,
 | 
					 | 
				
			||||||
                'activity_id' => null,
 | 
					 | 
				
			||||||
                'subactivity_id' => null,
 | 
					 | 
				
			||||||
                'promised_at' => null,
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Member\Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Activity;
 | 
				
			||||||
 | 
					use Spatie\LaravelData\Data;
 | 
				
			||||||
 | 
					use Spatie\LaravelData\Attributes\MapInputName;
 | 
				
			||||||
 | 
					use Spatie\LaravelData\Attributes\MapOutputName;
 | 
				
			||||||
 | 
					use Spatie\LaravelData\Mappers\SnakeCaseMapper;
 | 
				
			||||||
 | 
					use App\Member\Member;
 | 
				
			||||||
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[MapInputName(SnakeCaseMapper::class)]
 | 
				
			||||||
 | 
					#[MapOutputName(SnakeCaseMapper::class)]
 | 
				
			||||||
 | 
					class MembershipMeta extends Data
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(
 | 
				
			||||||
 | 
					        public array $links,
 | 
				
			||||||
 | 
					        public Collection $groups,
 | 
				
			||||||
 | 
					        public Collection $activities,
 | 
				
			||||||
 | 
					        public Collection $subactivities,
 | 
				
			||||||
 | 
					        public MembershipData $default,
 | 
				
			||||||
 | 
					    ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function fromMember(Member $member): static
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $activities = Activity::with('subactivities')->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return static::factory()->withoutMagicalCreation()->from([
 | 
				
			||||||
 | 
					            'links' => [
 | 
				
			||||||
 | 
					                'store' => route('member.membership.store', ['member' => $member]),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            'groups' => NestedGroup::cacheForSelect(),
 | 
				
			||||||
 | 
					            'activities' => $activities->map(fn($activity) => ['id' => $activity->id, 'name' => $activity->name]),
 | 
				
			||||||
 | 
					            'subactivities' => $activities->mapWithKeys(fn($activity) => [$activity->id => $activity->subactivities->map(fn($subactivity) => ['id' => $subactivity->id, 'name' => $subactivity->name, 'is_age_group' => $subactivity->is_age_group])]),
 | 
				
			||||||
 | 
					            'default' => MembershipData::from(['group' => $member->group_id]),
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -103,6 +103,8 @@ services:
 | 
				
			||||||
            - ./data/redis:/data
 | 
					            - ./data/redis:/data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    meilisearch:
 | 
					    meilisearch:
 | 
				
			||||||
 | 
					        ports:
 | 
				
			||||||
 | 
					            - "7700:7700"
 | 
				
			||||||
        image: getmeili/meilisearch:v1.6
 | 
					        image: getmeili/meilisearch:v1.6
 | 
				
			||||||
        volumes:
 | 
					        volumes:
 | 
				
			||||||
            - ./data/meilisearch:/meili_data
 | 
					            - ./data/meilisearch:/meili_data
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
.custom-table {
 | 
					.custom-table {
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
    & > thead > th {
 | 
					    & > thead > th, & > thead > tr > th {
 | 
				
			||||||
        @apply text-left px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b;
 | 
					        @apply text-left px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    & > tr {
 | 
					    & > tr, & > tbody > tr {
 | 
				
			||||||
        @apply text-gray-200 transition-all duration-300 rounded hover:bg-gray-800;
 | 
					        @apply text-gray-200 transition-all duration-300 rounded hover:bg-gray-800;
 | 
				
			||||||
        & > td {
 | 
					        & > td {
 | 
				
			||||||
            @apply py-1 px-6;
 | 
					            @apply py-1 px-6;
 | 
				
			||||||
| 
						 | 
					@ -12,10 +12,10 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &.custom-table-sm {
 | 
					    &.custom-table-sm {
 | 
				
			||||||
        & > thead > th {
 | 
					        & > thead > th, & > thead > tr > th {
 | 
				
			||||||
            @apply px-3 py-2;
 | 
					            @apply px-3 py-2;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        & > tr {
 | 
					        & > tr, & > tbody > tr {
 | 
				
			||||||
            & > td {
 | 
					            & > td {
 | 
				
			||||||
                @apply py-1 px-3;
 | 
					                @apply py-1 px-3;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -23,20 +23,11 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &.custom-table-light {
 | 
					    &.custom-table-light {
 | 
				
			||||||
        & > thead > th {
 | 
					        & > thead > th, & > thead >  tr > th {
 | 
				
			||||||
            @apply border-gray-500;
 | 
					            @apply border-gray-500;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        & > td {
 | 
					        & > tr, & > tbody > tr {
 | 
				
			||||||
            &:hover {
 | 
					            @apply hover:bg-gray-700;
 | 
				
			||||||
                @apply bg-gray-700;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.custom-table > * {
 | 
					 | 
				
			||||||
    display: table-row;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.custom-table > * > * {
 | 
					 | 
				
			||||||
    display: table-cell;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,17 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <label class="flex flex-col group" :for="id" :class="sizeClass(size)">
 | 
					    <label class="flex flex-col group" :for="id" :class="sizeClass(size)">
 | 
				
			||||||
        <f-label v-if="label" :required="required" :value="label"></f-label>
 | 
					        <f-label v-if="label" :required="required" :value="label" />
 | 
				
			||||||
        <div class="relative flex-none flex">
 | 
					        <div class="relative flex-none flex">
 | 
				
			||||||
            <select v-model="inner" :disabled="disabled" :name="name" :class="[fieldHeight, fieldAppearance, selectAppearance]">
 | 
					            <select v-model="inner" :disabled="disabled" :name="name" :class="[fieldHeight, fieldAppearance, selectAppearance]">
 | 
				
			||||||
                <option v-if="placeholder" :value="def">{{ placeholder }}</option>
 | 
					                <option v-if="placeholder" :value="def">{{ placeholder }}</option>
 | 
				
			||||||
                <option v-for="option in parsedOptions" :key="option.id" :value="option.id">{{ option.name }}</option>
 | 
					                <option v-for="option in parsedOptions" :key="option.id" :value="option.id">{{ option.name }}</option>
 | 
				
			||||||
            </select>
 | 
					            </select>
 | 
				
			||||||
            <f-hint v-if="hint" :value="hint"></f-hint>
 | 
					            <f-hint v-if="hint" :value="hint" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </label>
 | 
					    </label>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import {computed, ref} from 'vue';
 | 
					import {computed, ref} from 'vue';
 | 
				
			||||||
import useFieldSize from '../../composables/useFieldSize.js';
 | 
					import useFieldSize from '../../composables/useFieldSize.js';
 | 
				
			||||||
import map from 'lodash/map';
 | 
					import map from 'lodash/map';
 | 
				
			||||||
| 
						 | 
					@ -59,11 +59,6 @@ const props = defineProps({
 | 
				
			||||||
        default: '--kein--',
 | 
					        default: '--kein--',
 | 
				
			||||||
        type: String,
 | 
					        type: String,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    def: {
 | 
					 | 
				
			||||||
        required: false,
 | 
					 | 
				
			||||||
        type: Number,
 | 
					 | 
				
			||||||
        default: -1,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    name: {
 | 
					    name: {
 | 
				
			||||||
        required: true,
 | 
					        required: true,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,28 +1,14 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <a v-tooltip="tooltip" :href="href" :target="blank ? '_BLANK' : '_SELF'" class="inline-flex btn btn-sm">
 | 
					    <a v-tooltip="tooltip" :href="href" :target="blank ? '_BLANK' : '_SELF'" class="inline-flex btn btn-sm">
 | 
				
			||||||
        <ui-sprite :src="icon"></ui-sprite>
 | 
					        <ui-sprite :src="icon" />
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
defineProps({
 | 
					const {tooltip, icon, blank = false, href = '#'} = defineProps<{
 | 
				
			||||||
    tooltip: {
 | 
					    tooltip: string,
 | 
				
			||||||
        required: true,
 | 
					    href?: string,
 | 
				
			||||||
        type: String,
 | 
					    blank?: boolean,
 | 
				
			||||||
    },
 | 
					    icon: string,
 | 
				
			||||||
    href: {
 | 
					}>();
 | 
				
			||||||
        type: String,
 | 
					 | 
				
			||||||
        default: () => '#',
 | 
					 | 
				
			||||||
        required: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    blank: {
 | 
					 | 
				
			||||||
        type: Boolean,
 | 
					 | 
				
			||||||
        default: () => false,
 | 
					 | 
				
			||||||
        required: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    icon: {
 | 
					 | 
				
			||||||
        type: String,
 | 
					 | 
				
			||||||
        required: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,5 @@
 | 
				
			||||||
    <svg v-bind="$attrs" class="fill-current"><use :xlink:href="`/sprite.svg#${$attrs.src}`" /></svg>
 | 
					    <svg v-bind="$attrs" class="fill-current"><use :xlink:href="`/sprite.svg#${$attrs.src}`" /></svg>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
export default {};
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,84 +1,73 @@
 | 
				
			||||||
import {ref, inject, onBeforeUnmount} from 'vue';
 | 
					import {ref, inject, onBeforeUnmount} from 'vue';
 | 
				
			||||||
import {router} from '@inertiajs/vue3';
 | 
					import {router} from '@inertiajs/vue3';
 | 
				
			||||||
 | 
					import type {Ref} from 'vue';
 | 
				
			||||||
import useQueueEvents from './useQueueEvents.js';
 | 
					import useQueueEvents from './useQueueEvents.js';
 | 
				
			||||||
 | 
					import { Axios } from 'axios';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function useApiIndex(firstUrl, siteName = null) {
 | 
					export function useApiIndex<D, M extends Custom.PageMetadata>(firstUrl, siteName = null) {
 | 
				
			||||||
    const axios = inject('axios');
 | 
					    const axios = inject<Axios>('axios');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (siteName !== null) {
 | 
					    if (siteName !== null) {
 | 
				
			||||||
        var {startListener, stopListener} = useQueueEvents(siteName, () => reload());
 | 
					        var {startListener, stopListener} = useQueueEvents(siteName, () => reload());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const single = ref(null);
 | 
					    const single: Ref<D|null> = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const url = ref(firstUrl);
 | 
					    const url = ref(firstUrl);
 | 
				
			||||||
    const inner = {
 | 
					    const inner: {data: Ref<D[]|null>, meta: Ref<M|null>} = {
 | 
				
			||||||
        data: ref([]),
 | 
					        data: ref(null),
 | 
				
			||||||
        meta: ref({}),
 | 
					        meta: ref(null),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async function reload(resetPage = true, p = {}) {
 | 
					    async function reload(resetPage = true, p = {}) {
 | 
				
			||||||
        var params = {
 | 
					        const params = {
 | 
				
			||||||
            page: resetPage ? 1 : inner.meta.value.current_page,
 | 
					            page: resetPage ? 1 : inner.meta.value?.current_page,
 | 
				
			||||||
            ...p,
 | 
					            ...p,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var response = (await axios.get(url.value, {params})).data;
 | 
					        const response = (await axios.get(url.value, {params})).data;
 | 
				
			||||||
        inner.data.value = response.data;
 | 
					        inner.data.value = response.data;
 | 
				
			||||||
        inner.meta.value = response.meta;
 | 
					        inner.meta.value = response.meta;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async function reloadPage(page, p = {}) {
 | 
					    async function reloadPage(page: number, p = {}) {
 | 
				
			||||||
 | 
					        if (inner.meta.value?.current_page) {
 | 
				
			||||||
            inner.meta.value.current_page = page;
 | 
					            inner.meta.value.current_page = page;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        await reload(false, p);
 | 
					        await reload(false, p);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function create() {
 | 
					    function create() {
 | 
				
			||||||
        single.value = JSON.parse(JSON.stringify(inner.meta.value.default));
 | 
					        single.value = JSON.parse(JSON.stringify(inner.meta.value?.default));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function edit(model) {
 | 
					    function edit(model: D) {
 | 
				
			||||||
        single.value = JSON.parse(JSON.stringify(model));
 | 
					        single.value = JSON.parse(JSON.stringify(model));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async function submit() {
 | 
					    async function submit() {
 | 
				
			||||||
 | 
					        if (single.value === null) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        single.value.id ? await axios.patch(single.value.links.update, single.value) : await axios.post(inner.meta.value.links.store, single.value);
 | 
					        single.value.id ? await axios.patch(single.value.links.update, single.value) : await axios.post(inner.meta.value.links.store, single.value);
 | 
				
			||||||
        await reload();
 | 
					        await reload();
 | 
				
			||||||
        single.value = null;
 | 
					        single.value = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async function remove(model) {
 | 
					    async function remove(model: D) {
 | 
				
			||||||
        await axios.delete(model.links.destroy);
 | 
					        await axios.delete(model.links.destroy);
 | 
				
			||||||
        await reload();
 | 
					        await reload();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function can(permission) {
 | 
					 | 
				
			||||||
        return inner.meta.value.can[permission];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toFilterString(data) {
 | 
					    function toFilterString(data) {
 | 
				
			||||||
        return btoa(encodeURIComponent(JSON.stringify(data)));
 | 
					        return btoa(encodeURIComponent(JSON.stringify(data)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function requestCallback(successMessage, failureMessage) {
 | 
					 | 
				
			||||||
        return {
 | 
					 | 
				
			||||||
            onSuccess: () => {
 | 
					 | 
				
			||||||
                this.$success(successMessage);
 | 
					 | 
				
			||||||
                reload(false);
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            onFailure: () => {
 | 
					 | 
				
			||||||
                this.$error(failureMessage);
 | 
					 | 
				
			||||||
                reload(false);
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            preserveState: true,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function cancel() {
 | 
					    function cancel() {
 | 
				
			||||||
        single.value = null;
 | 
					        single.value = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function updateUrl(newUrl) {
 | 
					    function updateUrl(newUrl: string) {
 | 
				
			||||||
        url.value = newUrl;
 | 
					        url.value = newUrl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,8 +84,6 @@ export function useApiIndex(firstUrl, siteName = null) {
 | 
				
			||||||
        edit,
 | 
					        edit,
 | 
				
			||||||
        reload,
 | 
					        reload,
 | 
				
			||||||
        reloadPage,
 | 
					        reloadPage,
 | 
				
			||||||
        can,
 | 
					 | 
				
			||||||
        requestCallback,
 | 
					 | 
				
			||||||
        router,
 | 
					        router,
 | 
				
			||||||
        submit,
 | 
					        submit,
 | 
				
			||||||
        remove,
 | 
					        remove,
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,10 @@
 | 
				
			||||||
        </page-header>
 | 
					        </page-header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
 | 
					        <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
 | 
				
			||||||
            <f-text id="completed_at" v-model="single.completed_at" type="date" label="Datum" required></f-text>
 | 
					            <f-text id="completed_at" v-model="single.completed_at" type="date" label="Datum" required />
 | 
				
			||||||
            <f-select id="course_id" v-model="single.course_id" name="course_id" :options="meta.courses" label="Baustein" required></f-select>
 | 
					            <f-select id="course_id" v-model="single.course_id" name="course_id" :options="meta.courses" label="Baustein" required />
 | 
				
			||||||
            <f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required></f-text>
 | 
					            <f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required />
 | 
				
			||||||
            <f-text id="organizer" v-model="single.organizer" label="Veranstalter" required></f-text>
 | 
					            <f-text id="organizer" v-model="single.organizer" label="Veranstalter" required />
 | 
				
			||||||
            <button type="submit" class="btn btn-primary">Absenden</button>
 | 
					            <button type="submit" class="btn btn-primary">Absenden</button>
 | 
				
			||||||
        </form>
 | 
					        </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,18 +23,18 @@
 | 
				
			||||||
                        <th>Veranstaltung</th>
 | 
					                        <th>Veranstaltung</th>
 | 
				
			||||||
                        <th>Veranstalter</th>
 | 
					                        <th>Veranstalter</th>
 | 
				
			||||||
                        <th>Datum</th>
 | 
					                        <th>Datum</th>
 | 
				
			||||||
                        <th></th>
 | 
					                        <th />
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                </thead>
 | 
					                </thead>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <tr v-for="(course, index) in data" :key="index">
 | 
					                <tr v-for="(course, index) in data" :key="index">
 | 
				
			||||||
                    <td v-text="course.course_name"></td>
 | 
					                    <td v-text="course.course_name" />
 | 
				
			||||||
                    <td v-text="course.event_name"></td>
 | 
					                    <td v-text="course.event_name" />
 | 
				
			||||||
                    <td v-text="course.organizer"></td>
 | 
					                    <td v-text="course.organizer" />
 | 
				
			||||||
                    <td v-text="course.completed_at_human"></td>
 | 
					                    <td v-text="course.completed_at_human" />
 | 
				
			||||||
                    <td class="flex">
 | 
					                    <td class="flex">
 | 
				
			||||||
                        <a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(course)"><ui-sprite src="pencil"></ui-sprite></a>
 | 
					                        <a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(course)"><ui-sprite src="pencil" /></a>
 | 
				
			||||||
                        <a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(course)"><ui-sprite src="trash"></ui-sprite></a>
 | 
					                        <a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(course)"><ui-sprite src="trash" /></a>
 | 
				
			||||||
                    </td>
 | 
					                    </td>
 | 
				
			||||||
                </tr>
 | 
					                </tr>
 | 
				
			||||||
            </table>
 | 
					            </table>
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="js" setup>
 | 
					<script lang="js" setup>
 | 
				
			||||||
defineEmits(['close']);
 | 
					defineEmits(['close']);
 | 
				
			||||||
import { useApiIndex } from '../../composables/useApiIndex.js';
 | 
					import { useApiIndex } from '../../composables/useApiIndex.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    url: {
 | 
					    url: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <page-header title="Zahlungen" @close="$emit('close')"> </page-header>
 | 
					    <page-header title="Zahlungen" @close="$emit('close')" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="grow">
 | 
					    <div class="grow">
 | 
				
			||||||
        <table class="custom-table custom-table-light custom-table-sm text-sm">
 | 
					        <table class="custom-table custom-table-light custom-table-sm text-sm">
 | 
				
			||||||
| 
						 | 
					@ -10,15 +10,15 @@
 | 
				
			||||||
            </thead>
 | 
					            </thead>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <tr v-for="(position, index) in data" :key="index">
 | 
					            <tr v-for="(position, index) in data" :key="index">
 | 
				
			||||||
                <td v-text="position.description"></td>
 | 
					                <td v-text="position.description" />
 | 
				
			||||||
                <td v-text="position.invoice.status"></td>
 | 
					                <td v-text="position.invoice.status" />
 | 
				
			||||||
                <td v-text="position.price_human"></td>
 | 
					                <td v-text="position.price_human" />
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
        </table>
 | 
					        </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="js" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
defineEmits(['close']);
 | 
					defineEmits(['close']);
 | 
				
			||||||
import { useApiIndex } from '../../composables/useApiIndex.js';
 | 
					import { useApiIndex } from '../../composables/useApiIndex.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,58 +6,62 @@
 | 
				
			||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
    </page-header>
 | 
					    </page-header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
 | 
					    <form v-if="single && meta !== null" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
 | 
				
			||||||
        <f-select id="group_id" v-model="single.group_id" name="group_id" :options="meta.groups" label="Gruppierung" required />
 | 
					        <f-select id="group_id" v-model="single.group" name="group_id" :options="meta.groups" label="Gruppierung" required />
 | 
				
			||||||
        <f-select id="activity_id" v-model="single.activity_id" name="activity_id" :options="meta.activities" label="Tätigkeit" required />
 | 
					        <f-select id="activity_id" v-model="single.activity" name="activity_id" :options="meta.activities" label="Tätigkeit" required />
 | 
				
			||||||
        <f-select v-if="single.activity_id"
 | 
					        <f-select v-if="single.activity"
 | 
				
			||||||
                  id="subactivity_id"
 | 
					                  id="subactivity_id"
 | 
				
			||||||
                  :model-value="single.subactivity_id"
 | 
					                  :model-value="single.subactivity"
 | 
				
			||||||
                  name="subactivity_id"
 | 
					                  name="subactivity_id"
 | 
				
			||||||
                  :options="meta.subactivities[single.activity_id]"
 | 
					                  :options="meta.subactivities[single.activity.id]"
 | 
				
			||||||
                  label="Untertätigkeit"
 | 
					                  label="Untertätigkeit"
 | 
				
			||||||
                  @update:model-value="setSubactivityId(single, $event)"
 | 
					                  @update:model-value="setSubactivityId(single, $event)"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <f-switch v-if="displayPromisedAt"
 | 
					        <f-switch v-if="displayPromisedAt"
 | 
				
			||||||
                  id="has_promise"
 | 
					                  id="has_promise"
 | 
				
			||||||
                  name="has_promise"
 | 
					                  name="has_promise"
 | 
				
			||||||
                  :model-value="single.promised_at !== null"
 | 
					                  :model-value="single.promisedAt !== null"
 | 
				
			||||||
                  label="Hat Versprechen"
 | 
					                  label="Hat Versprechen"
 | 
				
			||||||
                  @update:model-value="setPromisedAtSwitch(single, $event)"
 | 
					                  @update:model-value="setPromisedAtSwitch(single, $event)"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <f-text v-show="displayPromisedAt && single.promised_at !== null" id="promised_at" v-model="single.promised_at" type="date" label="Versprechensdatum" size="sm" />
 | 
					        <f-text v-show="displayPromisedAt && single.promisedAt !== null" id="promised_at" v-model="single.promisedAt" type="date" label="Versprechensdatum" size="sm" />
 | 
				
			||||||
        <button type="submit" class="btn btn-primary">Absenden</button>
 | 
					        <button type="submit" class="btn btn-primary">Absenden</button>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div v-else class="grow">
 | 
					    <div v-else class="grow">
 | 
				
			||||||
        <table class="custom-table custom-table-light custom-table-sm text-sm">
 | 
					        <table class="custom-table custom-table-light custom-table-sm text-sm">
 | 
				
			||||||
            <thead>
 | 
					            <thead>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
                    <th>Tätigkeit</th>
 | 
					                    <th>Tätigkeit</th>
 | 
				
			||||||
                    <th>Untertätigkeit</th>
 | 
					                    <th>Untertätigkeit</th>
 | 
				
			||||||
                    <th>Datum</th>
 | 
					                    <th>Datum</th>
 | 
				
			||||||
                    <th>Aktiv</th>
 | 
					                    <th>Aktiv</th>
 | 
				
			||||||
                    <th />
 | 
					                    <th />
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
            </thead>
 | 
					            </thead>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
                <tr v-for="(membership, index) in data" :key="index">
 | 
					                <tr v-for="(membership, index) in data" :key="index">
 | 
				
			||||||
                <td v-text="membership.activity_name" />
 | 
					                    <td v-text="membership.activity?.name" />
 | 
				
			||||||
                <td v-text="membership.subactivity_name" />
 | 
					                    <td v-text="membership.subactivity?.name" />
 | 
				
			||||||
                <td v-text="membership.human_date" />
 | 
					                    <td v-text="membership.from?.human" />
 | 
				
			||||||
                <td><ui-boolean-display :value="membership.is_active" dark /></td>
 | 
					                    <td><ui-boolean-display :value="membership.isActive" dark /></td>
 | 
				
			||||||
                    <td class="flex space-x-1">
 | 
					                    <td class="flex space-x-1">
 | 
				
			||||||
                        <a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(membership)"><ui-sprite src="pencil" /></a>
 | 
					                        <a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(membership)"><ui-sprite src="pencil" /></a>
 | 
				
			||||||
                        <a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(membership)"><ui-sprite src="trash" /></a>
 | 
					                        <a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(membership)"><ui-sprite src="trash" /></a>
 | 
				
			||||||
                    </td>
 | 
					                    </td>
 | 
				
			||||||
                </tr>
 | 
					                </tr>
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
        </table>
 | 
					        </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="js" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { computed } from 'vue';
 | 
					import { computed } from 'vue';
 | 
				
			||||||
import dayjs from 'dayjs';
 | 
					import dayjs from 'dayjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineEmits(['close']);
 | 
					defineEmits(['close']);
 | 
				
			||||||
import { useApiIndex } from '../../composables/useApiIndex.js';
 | 
					import { useApiIndex } from '../../composables/useApiIndex.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    url: {
 | 
					    url: {
 | 
				
			||||||
| 
						 | 
					@ -65,14 +69,14 @@ const props = defineProps({
 | 
				
			||||||
        required: true,
 | 
					        required: true,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
const { data, meta, reload, single, create, edit, submit, remove } = useApiIndex(props.url, 'membership');
 | 
					const { data, meta, reload, single, create, edit, submit, remove } = useApiIndex<App.Member.Data.MembershipData, App.Member.Data.MembershipMeta>(props.url, 'membership');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function setPromisedAtSwitch(single, value) {
 | 
					function setPromisedAtSwitch(single, value) {
 | 
				
			||||||
    single.promised_at = value ? dayjs().format('YYYY-MM-DD') : null;
 | 
					    single.promised_at = value ? dayjs().format('YYYY-MM-DD') : null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const displayPromisedAt = computed(function () {
 | 
					const displayPromisedAt = computed(function () {
 | 
				
			||||||
    if (!single.value || !single.value.activity_id || !single.value.subactivity_id) {
 | 
					    if (!single.value || !single.value.activity || !single.value.subactivity) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					declare namespace Custom {
 | 
				
			||||||
 | 
					    export type PageMetadata = {
 | 
				
			||||||
 | 
					        current_page: number;
 | 
				
			||||||
 | 
					        default: object;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -444,13 +444,20 @@ id: number;
 | 
				
			||||||
name: string;
 | 
					name: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
export type MembershipData = {
 | 
					export type MembershipData = {
 | 
				
			||||||
id: number;
 | 
					activity: App.Member.Data.ActivityData | null;
 | 
				
			||||||
activity: App.Member.Data.ActivityData;
 | 
					subactivity: App.Member.Data.SubactivityData | null;
 | 
				
			||||||
subactivity: App.Member.Data.SubactivityData;
 | 
					group: App.Member.Data.GroupData | null;
 | 
				
			||||||
group: App.Member.Data.GroupData;
 | 
					promisedAt: App.Lib.Data.DateData | null;
 | 
				
			||||||
promised_at: App.Lib.Data.DateData | null;
 | 
					from: App.Lib.Data.DateData | null;
 | 
				
			||||||
from: App.Lib.Data.DateData;
 | 
					isActive: boolean;
 | 
				
			||||||
is_active: boolean;
 | 
					links: Array<any>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export type MembershipMeta = {
 | 
				
			||||||
 | 
					links: Array<any>;
 | 
				
			||||||
 | 
					groups: any;
 | 
				
			||||||
 | 
					activities: any;
 | 
				
			||||||
 | 
					subactivities: any;
 | 
				
			||||||
 | 
					default: App.Member.Data.MembershipData;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
export type NestedGroup = {
 | 
					export type NestedGroup = {
 | 
				
			||||||
id: number;
 | 
					id: number;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,14 +37,25 @@ it('testItShowsActivityAndSubactivityNamesOfMember', function () {
 | 
				
			||||||
        ->assertJsonPath('data.0.subactivity.name', 'Wölfling')
 | 
					        ->assertJsonPath('data.0.subactivity.name', 'Wölfling')
 | 
				
			||||||
        ->assertJsonPath('data.0.from.human', '02.11.2022')
 | 
					        ->assertJsonPath('data.0.from.human', '02.11.2022')
 | 
				
			||||||
        ->assertJsonPath('data.0.from.raw', '2022-11-02')
 | 
					        ->assertJsonPath('data.0.from.raw', '2022-11-02')
 | 
				
			||||||
        ->assertJsonPath('data.0.promised_at.raw', now()->format('Y-m-d'))
 | 
					        ->assertJsonPath('data.0.promisedAt.raw', now()->format('Y-m-d'))
 | 
				
			||||||
        ->assertJsonPath('data.0.promised_at.human', now()->format('d.m.Y'))
 | 
					        ->assertJsonPath('data.0.promisedAt.human', now()->format('d.m.Y'))
 | 
				
			||||||
        ->assertJsonPath('data.0.group.id', $group->id)
 | 
					        ->assertJsonPath('data.0.group.id', $group->id)
 | 
				
			||||||
        ->assertJsonPath('data.0.id', $membership->id)
 | 
					 | 
				
			||||||
        ->assertJsonPath('data.0.links.update', route('membership.update', ['membership' => $membership]))
 | 
					        ->assertJsonPath('data.0.links.update', route('membership.update', ['membership' => $membership]))
 | 
				
			||||||
        ->assertJsonPath('data.0.links.destroy', route('membership.destroy', ['membership' => $membership]));
 | 
					        ->assertJsonPath('data.0.links.destroy', route('membership.destroy', ['membership' => $membership]));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					it('activity and subactivity can be null', function () {
 | 
				
			||||||
 | 
					    $this->withoutExceptionHandling()->login()->loginNami();
 | 
				
			||||||
 | 
					    $group = Group::factory()->create(['name' => 'aaaaaaaa']);
 | 
				
			||||||
 | 
					    $member = Member::factory()
 | 
				
			||||||
 | 
					        ->defaults()
 | 
				
			||||||
 | 
					        ->for($group)
 | 
				
			||||||
 | 
					        ->has(Membership::factory()->for($group)->in('€ Mitglied', 122)->from('2022-11-02')->promise(now()))
 | 
				
			||||||
 | 
					        ->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->get("/member/{$member->id}/membership")->assertNull('data.0.subactivity');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
it('returns meta', function () {
 | 
					it('returns meta', function () {
 | 
				
			||||||
    $this->withoutExceptionHandling()->login()->loginNami();
 | 
					    $this->withoutExceptionHandling()->login()->loginNami();
 | 
				
			||||||
    $group = Group::factory()->create(['name' => 'aaaaaaaa']);
 | 
					    $group = Group::factory()->create(['name' => 'aaaaaaaa']);
 | 
				
			||||||
| 
						 | 
					@ -55,10 +66,11 @@ it('returns meta', function () {
 | 
				
			||||||
        ->create();
 | 
					        ->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->get("/member/{$membership->member->id}/membership")
 | 
					    $this->get("/member/{$membership->member->id}/membership")
 | 
				
			||||||
        ->assertNull('meta.default.activity_id')
 | 
					        ->assertNull('meta.default.activity')
 | 
				
			||||||
        ->assertNull('meta.default.subactivity_id')
 | 
					        ->assertNull('meta.default.subactivity')
 | 
				
			||||||
        ->assertNull('meta.default.promised_at')
 | 
					        ->assertNull('meta.default.promisedAt')
 | 
				
			||||||
        ->assertJsonPath('meta.default.group_id', $group->id)
 | 
					        ->assertJsonPath('meta.default.group.id', $group->id)
 | 
				
			||||||
 | 
					        ->assertJsonPath('meta.default.group.name', $group->name)
 | 
				
			||||||
        ->assertJsonPath('meta.groups.0.id', $group->id)
 | 
					        ->assertJsonPath('meta.groups.0.id', $group->id)
 | 
				
			||||||
        ->assertJsonPath('meta.activities.0.id', $membership->activity->id)
 | 
					        ->assertJsonPath('meta.activities.0.id', $membership->activity->id)
 | 
				
			||||||
        ->assertJsonPath('meta.activities.0.name', $membership->activity->name)
 | 
					        ->assertJsonPath('meta.activities.0.name', $membership->activity->name)
 | 
				
			||||||
| 
						 | 
					@ -76,7 +88,7 @@ it('promised at can be null', function () {
 | 
				
			||||||
        ->create();
 | 
					        ->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->get("/member/{$member->id}/membership")
 | 
					    $this->get("/member/{$member->id}/membership")
 | 
				
			||||||
        ->assertJsonPath('data.0.promised_at', null);
 | 
					        ->assertJsonPath('data.0.promisedAt', null);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,7 +100,7 @@ it('testItShowsIfMembershipIsActive', function (Carbon $from, ?Carbon $to, bool
 | 
				
			||||||
        ->create();
 | 
					        ->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->get("/member/{$member->id}/membership")
 | 
					    $this->get("/member/{$member->id}/membership")
 | 
				
			||||||
        ->assertJsonPath('data.0.is_active', $isActive);
 | 
					        ->assertJsonPath('data.0.isActive', $isActive);
 | 
				
			||||||
})->with([
 | 
					})->with([
 | 
				
			||||||
    [now()->subMonths(2), null, true],
 | 
					    [now()->subMonths(2), null, true],
 | 
				
			||||||
    [now()->subMonths(2), now()->subDay(), false],
 | 
					    [now()->subMonths(2), now()->subDay(), false],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,5 +59,5 @@
 | 
				
			||||||
            "@/*": ["./resources/js/*"]
 | 
					            "@/*": ["./resources/js/*"]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "include": ["**/*", "resources/js/components/components.d.ts"]
 | 
					    "include": ["**/*", "resources/types/generated.d.ts", "resources/types/custom.d.ts"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue