Add payment management
This commit is contained in:
parent
9c580b7eb5
commit
1dd676d326
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Views;
|
||||
|
||||
use App\Member\MemberResource;
|
||||
use App\Member\Member;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Payment\Status;
|
||||
use App\Payment\Subscription;
|
||||
use App\Payment\PaymentResource;
|
||||
|
||||
class MemberView {
|
||||
public function index(Request $request) {
|
||||
return [
|
||||
'data' => MemberResource::collection(Member::select('*')->search($request->query('search', null))->with('billKind')->withIsConfirmed()->paginate(15)),
|
||||
'toolbar' => [ ['href' => route('member.index'), 'label' => 'Zurück', 'color' => 'primary', 'icon' => 'plus'] ]
|
||||
];
|
||||
}
|
||||
|
||||
public function paymentCreate($member) {
|
||||
return $this->additional($member, [
|
||||
'model' => [
|
||||
'subscription_id' => $member->subscription_id,
|
||||
'status_id' => Status::default(),
|
||||
'nr' => date('Y'),
|
||||
],
|
||||
'links' => [ ['label' => 'Zurück', 'href' => route('member.payment.index', ['member' => $member]) ] ],
|
||||
'mode' => 'create',
|
||||
]);
|
||||
}
|
||||
|
||||
public function paymentEdit($member, $payment) {
|
||||
return $this->additional($member, [
|
||||
'model' => new PaymentResource($payment),
|
||||
'links' => [ ['label' => 'Zurück', 'href' => route('member.payment.index', ['member' => $member]) ] ],
|
||||
'mode' => 'edit',
|
||||
]);
|
||||
}
|
||||
|
||||
public function paymentIndex($member) {
|
||||
return $this->additional($member, [
|
||||
'model' => null,
|
||||
'links' => [ ['label' => 'Zahlung hinzufügen', 'href' => route('member.payment.create', ['member' => $member]) ] ],
|
||||
'mode' => 'index',
|
||||
]);
|
||||
}
|
||||
|
||||
private function additional($member, $overwrites = []) {
|
||||
return (new MemberResource($member->load('payments')))
|
||||
->additional(array_merge([
|
||||
'subscriptions' => Subscription::get()->pluck('name', 'id'),
|
||||
'statuses' => Status::get()->pluck('name', 'id'),
|
||||
], $overwrites));
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ use App\Activity;
|
|||
use App\Subactivity;
|
||||
use Zoomyboy\LaravelNami\NamiUser;
|
||||
use App\Payment\Subscription;
|
||||
use App\Payment\Payment;
|
||||
|
||||
class Member extends Model
|
||||
{
|
||||
|
@ -87,7 +88,7 @@ class Member extends Model
|
|||
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany(\App\Payment::class)->orderBy('nr');
|
||||
return $this->hasMany(Payment::class)->orderBy('nr');
|
||||
}
|
||||
|
||||
public function way()
|
||||
|
|
|
@ -13,6 +13,7 @@ use App\Bill\BillKind;
|
|||
use App\Activity;
|
||||
use App\Group;
|
||||
use App\Payment\Subscription;
|
||||
use App\Http\Views\MemberView;
|
||||
|
||||
class MemberController extends Controller
|
||||
{
|
||||
|
@ -21,10 +22,10 @@ class MemberController extends Controller
|
|||
session()->put('menu', 'member');
|
||||
session()->put('title', 'Mitglieder');
|
||||
|
||||
return \Inertia::render('member/Index', [
|
||||
'data' => MemberResource::collection(Member::select('*')->search($request->query('search', null))->with('billKind')->withIsConfirmed()->paginate(15)),
|
||||
'toolbar' => [ ['href' => route('member.create'), 'label' => 'Mitglied anlegen', 'color' => 'primary', 'icon' => 'plus'] ],
|
||||
]);
|
||||
$payload = app(MemberView::class)->index($request);
|
||||
$payload['toolbar'] = [ ['href' => route('member.create'), 'label' => 'Mitglied anlegen', 'color' => 'primary', 'icon' => 'plus'] ];
|
||||
|
||||
return \Inertia::render('member/Index', $payload);
|
||||
}
|
||||
|
||||
public function create() {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Member;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use App\Payment\PaymentResource;
|
||||
|
||||
class MemberResource extends JsonResource
|
||||
{
|
||||
|
@ -46,6 +47,7 @@ class MemberResource extends JsonResource
|
|||
'has_nami' => $this->nami_id !== null,
|
||||
'is_confirmed' => $this->is_confirmed,
|
||||
'children_phone' => $this->children_phone,
|
||||
'payments' => PaymentResource::collection($this->whenLoaded('payments')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Payment;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Member\Member;
|
||||
use App\Payment\Status;
|
||||
use App\Payment\Subscription;
|
||||
|
||||
class Payment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $fillable = ['member_id', 'subscription_id', 'nr', 'status_id'];
|
||||
|
||||
public function member() {
|
||||
return $this->belongsTo(Member::class);
|
||||
}
|
||||
|
||||
public function subscription() {
|
||||
return $this->belongsTo(Subscription::class);
|
||||
}
|
||||
|
||||
public function status() {
|
||||
return $this->belongsTo(Status::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace App\Payment;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Member\Member;
|
||||
use App\Member\MemberResource;
|
||||
use App\Http\Views\MemberView;
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
public function index(Request $request, Member $member) {
|
||||
session()->put('menu', 'member');
|
||||
session()->put('title', "Zahlungen für Mitglied {$member->fullname}");
|
||||
|
||||
$payload = app(MemberView::class)->index($request);
|
||||
$payload['single'] = app(MemberView::class)->paymentIndex($member);
|
||||
|
||||
return \Inertia::render('member/Index', $payload);
|
||||
}
|
||||
|
||||
public function create(Member $member, Request $request) {
|
||||
session()->put('menu', 'member');
|
||||
session()->put('title', "Zahlungen für Mitglied {$member->fullname}");
|
||||
|
||||
$payload = app(MemberView::class)->index($request);
|
||||
$payload['single'] = app(MemberView::class)->paymentCreate($member);
|
||||
|
||||
return \Inertia::render('member/Index', $payload);
|
||||
}
|
||||
|
||||
public function store(Request $request, Member $member) {
|
||||
$member->payments()->create($request->validate([
|
||||
'nr' => 'required|numeric',
|
||||
'subscription_id' => 'required|exists:subscriptions,id',
|
||||
'status_id' => 'required|exists:statuses,id',
|
||||
]));
|
||||
|
||||
return redirect()->route('member.payment.index', ['member' => $member]);
|
||||
}
|
||||
|
||||
public function edit(Member $member, Request $request, Payment $payment) {
|
||||
session()->put('menu', 'member');
|
||||
session()->put('title', "Zahlungen für Mitglied {$member->fullname}");
|
||||
|
||||
$payload = app(MemberView::class)->index($request);
|
||||
$payload['single'] = app(MemberView::class)->paymentEdit($member, $payment);
|
||||
|
||||
return \Inertia::render('member/Index', $payload);
|
||||
}
|
||||
|
||||
public function update(Request $request, Member $member, Payment $payment) {
|
||||
$payment->update($request->validate([
|
||||
'nr' => 'required|numeric',
|
||||
'subscription_id' => 'required|exists:subscriptions,id',
|
||||
'status_id' => 'required|exists:statuses,id',
|
||||
]));
|
||||
|
||||
return redirect()->route('member.payment.index', ['member' => $member]);
|
||||
}
|
||||
|
||||
public function destroy(Request $request, Member $member, Payment $payment) {
|
||||
$payment->delete();
|
||||
|
||||
return redirect()->route('member.payment.index', ['member' => $member]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Payment;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PaymentResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'subscription_id' => $this->subscription_id,
|
||||
'subscription_name' => $this->subscription->name,
|
||||
'status_name' => $this->status->name,
|
||||
'status_id' => $this->status->id,
|
||||
'nr' => $this->nr,
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Payment;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Status extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $fillable = ['name', 'is_bill', 'is_remember'];
|
||||
public $timestamps = false;
|
||||
|
||||
public static function default() {
|
||||
return static::where('is_bill', true)->where('is_remember', true)->first()->id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#/bin/bash
|
||||
|
||||
echo "drop database scoutrobot;" | sudo mysql
|
||||
echo "create database scoutrobot;" | sudo mysql
|
||||
|
||||
ssh -l stammsilva zoomyboy.de "mysqldump -u nami -p$SCOUTROBOT_DB_PASSWORD nami" > db.tmp && sudo mysql scoutrobot < db.tmp
|
||||
rm db.tmp
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Payment\Status;
|
||||
|
||||
class CreatePaymentsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('statuses', function($table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->boolean('is_bill');
|
||||
$table->boolean('is_remember');
|
||||
});
|
||||
|
||||
Status::create(['name' => 'Nicht bezahlt', 'is_bill' => true, 'is_remember' => true]);
|
||||
Status::create(['name' => 'Rechnung gestellt', 'is_bill' => false, 'is_remember' => true]);
|
||||
Status::create(['name' => 'Rechnung beglichen', 'is_bill' => false, 'is_remember' => false]);
|
||||
|
||||
Schema::create('payments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nr');
|
||||
$table->foreignId('subscription_id')->constrained();
|
||||
$table->foreignId('status_id')->constrained();
|
||||
$table->foreignId('member_id')->constrained();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('payments');
|
||||
}
|
||||
}
|
|
@ -6,3 +6,4 @@
|
|||
@import "layout";
|
||||
@import "buttons";
|
||||
@import "table";
|
||||
@import "sidebar";
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
@apply bg-primary-500;
|
||||
}
|
||||
}
|
||||
&.btn-primary-light {
|
||||
@apply bg-primary-600 text-primary-800;
|
||||
&:hover {
|
||||
@apply bg-primary-500 text-primary-700;
|
||||
}
|
||||
}
|
||||
&.btn-warning {
|
||||
@apply bg-yellow-700;
|
||||
&:hover {
|
||||
|
@ -34,5 +40,22 @@
|
|||
@apply bg-red-500;
|
||||
}
|
||||
}
|
||||
|
||||
&.label {
|
||||
@apply rounded-full leading-none transition-all normal-case;
|
||||
&.primary {
|
||||
@apply bg-primary-800 text-primary-500;
|
||||
&:hover {
|
||||
@apply text-primary-400 bg-primary-700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.icon {
|
||||
@apply p-0 flex justify-center items-center w-6 h-6;
|
||||
svg {
|
||||
@apply w-3 h-3 text-primary-100 flex-none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.sidebar {
|
||||
@apply fixed w-96 shadow-2xl bg-gray-600 right-0 top-0 h-full;
|
||||
}
|
|
@ -1,6 +1,39 @@
|
|||
.custom-table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
& > header > div {
|
||||
@apply px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b;
|
||||
}
|
||||
|
||||
& > div {
|
||||
@apply text-gray-200 transition-all duration-300 rounded hover:bg-gray-800;
|
||||
& > div {
|
||||
@apply py-1 px-6;
|
||||
}
|
||||
}
|
||||
|
||||
&.custom-table-sm {
|
||||
& > header > div {
|
||||
@apply px-3 py-2;
|
||||
}
|
||||
& > div {
|
||||
& > div {
|
||||
@apply py-1 px-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.custom-table-light {
|
||||
& > header > div {
|
||||
@apply border-gray-500;
|
||||
}
|
||||
& > div {
|
||||
&:hover {
|
||||
@apply bg-gray-700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.custom-table > * {
|
||||
display: table-row;
|
||||
|
|
|
@ -1 +1 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 20 20" id="check" xmlns="http://www.w3.org/2000/svg"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z"/></symbol><symbol viewBox="0 0 20 20" id="close" xmlns="http://www.w3.org/2000/svg"><path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/></symbol><symbol viewBox="0 0 512 512" id="loss" xmlns="http://www.w3.org/2000/svg"><path d="M448 281.6h-25.6c-7.68 0-12.8 5.12-12.8 12.8v115.2h51.2V294.4c0-7.68-5.12-12.8-12.8-12.8zM345.6 230.4H320c-7.68 0-12.8 5.12-12.8 12.8v166.4h51.2V243.2c0-7.68-5.12-12.8-12.8-12.8zM243.2 179.2h-25.6c-7.68 0-12.8 5.12-12.8 12.8v217.6H256V192c0-7.68-5.12-12.8-12.8-12.8zM140.8 102.4h-25.6c-7.68 0-12.8 5.12-12.8 12.8v294.4h51.2V115.2c0-7.68-5.12-12.8-12.8-12.8z"/><path d="M486.4 460.8H51.2V25.6C51.2 10.24 40.96 0 25.6 0 10.24 0 0 10.24 0 25.6v460.8C0 501.76 10.24 512 25.6 512h460.8c15.36 0 25.6-10.24 25.6-25.6 0-15.36-10.24-25.6-25.6-25.6z"/></symbol><symbol viewBox="0 0 512 512" id="money" xmlns="http://www.w3.org/2000/svg"><path d="M330.24 94.72l46.08-53.76C391.68 25.6 381.44 0 358.4 0H153.6c-23.04 0-33.28 25.6-20.48 40.96l46.08 53.76C76.8 145.92 0 289.28 0 386.56 0 506.88 115.2 512 256 512s256-5.12 256-125.44c0-97.28-76.8-240.64-181.76-291.84zM256 281.6c10.24 0 17.92 2.56 25.6 5.12 30.72 10.24 51.2 38.4 51.2 71.68 0 33.28-20.48 61.44-51.2 71.68v30.72h-51.2v-30.72c-30.72-10.24-51.2-38.4-51.2-71.68h51.2c0 15.36 10.24 25.6 25.6 25.6s25.6-10.24 25.6-25.6c0-15.36-10.24-25.6-25.6-25.6-10.24 0-17.92-2.56-25.6-5.12-30.72-10.24-51.2-38.4-51.2-71.68 0-33.28 20.48-61.44 51.2-71.68V153.6h51.2v30.72c30.72 10.24 51.2 38.4 51.2 71.68h-51.2c0-15.36-10.24-25.6-25.6-25.6s-25.6 10.24-25.6 25.6 10.24 25.6 25.6 25.6z"/></symbol><symbol viewBox="0 0 512 512" id="pencil" xmlns="http://www.w3.org/2000/svg"><path d="M51.2 353.28L0 512l158.72-51.2zM87.16 316.492L336.96 66.69l108.61 108.61L195.77 425.102zM504.32 79.36L432.64 7.68c-10.24-10.24-25.6-10.24-35.84 0l-23.04 23.04 107.52 107.52 23.04-23.04c10.24-10.24 10.24-25.6 0-35.84z"/></symbol><symbol viewBox="0 0 512 512" id="user" xmlns="http://www.w3.org/2000/svg"><path d="M0 435.2V512h512v-76.8c0-171.52-512-171.52-512 0z"/><circle cx="256" cy="128" r="128"/></symbol></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 20 20" id="check" xmlns="http://www.w3.org/2000/svg"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z"/></symbol><symbol viewBox="0 0 20 20" id="close" xmlns="http://www.w3.org/2000/svg"><path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/></symbol><symbol viewBox="0 0 512 512" id="loss" xmlns="http://www.w3.org/2000/svg"><path d="M448 281.6h-25.6c-7.68 0-12.8 5.12-12.8 12.8v115.2h51.2V294.4c0-7.68-5.12-12.8-12.8-12.8zM345.6 230.4H320c-7.68 0-12.8 5.12-12.8 12.8v166.4h51.2V243.2c0-7.68-5.12-12.8-12.8-12.8zM243.2 179.2h-25.6c-7.68 0-12.8 5.12-12.8 12.8v217.6H256V192c0-7.68-5.12-12.8-12.8-12.8zM140.8 102.4h-25.6c-7.68 0-12.8 5.12-12.8 12.8v294.4h51.2V115.2c0-7.68-5.12-12.8-12.8-12.8z"/><path d="M486.4 460.8H51.2V25.6C51.2 10.24 40.96 0 25.6 0 10.24 0 0 10.24 0 25.6v460.8C0 501.76 10.24 512 25.6 512h460.8c15.36 0 25.6-10.24 25.6-25.6 0-15.36-10.24-25.6-25.6-25.6z"/></symbol><symbol viewBox="0 0 512 512" id="money" xmlns="http://www.w3.org/2000/svg"><path d="M330.24 94.72l46.08-53.76C391.68 25.6 381.44 0 358.4 0H153.6c-23.04 0-33.28 25.6-20.48 40.96l46.08 53.76C76.8 145.92 0 289.28 0 386.56 0 506.88 115.2 512 256 512s256-5.12 256-125.44c0-97.28-76.8-240.64-181.76-291.84zM256 281.6c10.24 0 17.92 2.56 25.6 5.12 30.72 10.24 51.2 38.4 51.2 71.68 0 33.28-20.48 61.44-51.2 71.68v30.72h-51.2v-30.72c-30.72-10.24-51.2-38.4-51.2-71.68h51.2c0 15.36 10.24 25.6 25.6 25.6s25.6-10.24 25.6-25.6c0-15.36-10.24-25.6-25.6-25.6-10.24 0-17.92-2.56-25.6-5.12-30.72-10.24-51.2-38.4-51.2-71.68 0-33.28 20.48-61.44 51.2-71.68V153.6h51.2v30.72c30.72 10.24 51.2 38.4 51.2 71.68h-51.2c0-15.36-10.24-25.6-25.6-25.6s-25.6 10.24-25.6 25.6 10.24 25.6 25.6 25.6z"/></symbol><symbol viewBox="0 0 512 512" id="pencil" xmlns="http://www.w3.org/2000/svg"><path d="M51.2 353.28L0 512l158.72-51.2zM87.16 316.492L336.96 66.69l108.61 108.61L195.77 425.102zM504.32 79.36L432.64 7.68c-10.24-10.24-25.6-10.24-35.84 0l-23.04 23.04 107.52 107.52 23.04-23.04c10.24-10.24 10.24-25.6 0-35.84z"/></symbol><symbol viewBox="0 0 512 512" id="trash" xmlns="http://www.w3.org/2000/svg"><path d="M486.4 102.4h-128V25.6c0-15.36-10.24-25.6-25.6-25.6H179.2c-15.36 0-25.6 10.24-25.6 25.6v76.8h-128C10.24 102.4 0 112.64 0 128s10.24 25.6 25.6 25.6h460.8c15.36 0 25.6-10.24 25.6-25.6s-10.24-25.6-25.6-25.6zm-179.2 0H204.8V51.2h102.4v51.2zM25.6 204.8l48.64 284.16c2.56 12.8 12.8 23.04 25.6 23.04h312.32c12.8 0 23.04-10.24 25.6-23.04L486.4 204.8H25.6zm128 256c-15.36 0-25.6-10.24-25.6-25.6l-25.6-153.6c0-15.36 10.24-25.6 25.6-25.6s25.6 10.24 25.6 25.6l25.6 153.6c0 15.36-10.24 25.6-25.6 25.6zm128-25.6c0 15.36-10.24 25.6-25.6 25.6s-25.6-10.24-25.6-25.6V281.6c0-15.36 10.24-25.6 25.6-25.6s25.6 10.24 25.6 25.6v153.6zm102.4 0c0 15.36-10.24 25.6-25.6 25.6-15.36 0-25.6-10.24-25.6-25.6l25.6-153.6c0-15.36 10.24-25.6 25.6-25.6s25.6 10.24 25.6 25.6L384 435.2z"/></symbol><symbol viewBox="0 0 512 512" id="user" xmlns="http://www.w3.org/2000/svg"><path d="M0 435.2V512h512v-76.8c0-171.52-512-171.52-512 0z"/><circle cx="256" cy="128" r="128"/></symbol></svg>
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,19 @@
|
|||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M486.4,102.4h-128V25.6c0-15.36-10.24-25.6-25.6-25.6H179.2c-15.36,0-25.6,10.24-25.6,25.6v76.8h-128
|
||||
C10.24,102.4,0,112.64,0,128s10.24,25.6,25.6,25.6h460.8c15.36,0,25.6-10.24,25.6-25.6S501.76,102.4,486.4,102.4z M307.2,102.4
|
||||
H204.8V51.2h102.4V102.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M25.6,204.8l48.64,284.16c2.56,12.8,12.8,23.04,25.6,23.04h312.32c12.8,0,23.04-10.24,25.6-23.04L486.4,204.8H25.6z
|
||||
M153.6,460.8c-15.36,0-25.6-10.24-25.6-25.6l-25.6-153.6c0-15.36,10.24-25.6,25.6-25.6s25.6,10.24,25.6,25.6l25.6,153.6
|
||||
C179.2,450.56,168.96,460.8,153.6,460.8z M281.6,435.2c0,15.36-10.24,25.6-25.6,25.6s-25.6-10.24-25.6-25.6V281.6
|
||||
c0-15.36,10.24-25.6,25.6-25.6s25.6,10.24,25.6,25.6V435.2z M384,435.2c0,15.36-10.24,25.6-25.6,25.6
|
||||
c-15.36,0-25.6-10.24-25.6-25.6l25.6-153.6c0-15.36,10.24-25.6,25.6-25.6s25.6,10.24,25.6,25.6L384,435.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<div class="h-16 px-6 flex justify-between items-center border-b border-solid border-gray-500">
|
||||
<div class="flex items-center">
|
||||
<span class="text-xl font-semibold text-white" v-html="title"></span>
|
||||
<a v-for="link in links.filter(link => link.href === undefined)" v-text="link.label" @click.prevent="$emit(link.event)" href="#" class="btn label btn-primary-light icon"></a>
|
||||
<a v-for="link in links.filter(link => link.href !== undefined)" v-text="link.label" :href="link.href" class="btn label btn-primary-light ml-1"></a>
|
||||
</div>
|
||||
<div class="flex ml-4">
|
||||
<a href="#" @click.prevent="$emit('close')" class="btn label btn-primary-light icon">
|
||||
<sprite class="w-3 h-3" src="close"></sprite>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
links: {
|
||||
default: function() { return []; }
|
||||
},
|
||||
title: {
|
||||
default: function() { return ''; }
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -13,11 +13,11 @@
|
|||
</div>
|
||||
|
||||
<div class="flex-grow ml-56 bg-gray-900 flex flex-col">
|
||||
<div class="h-16 p-6 flex justify-between items-center border-b border-gray-600">
|
||||
<div class="h-16 px-6 flex justify-between items-center border-b border-gray-600">
|
||||
<div class="flex">
|
||||
<span class="text-xl font-semibold text-white" v-html="$page.props.title"></span>
|
||||
<div class="flex ml-4">
|
||||
<inertia-link v-for="link, index in $page.props.toolbar" :key="index" :href="link.href" v-text="link.label" class="rounded-full leading-none px-3 py-2 text-sm" :class="`bg-${link.color}-800 text-${link.color}-500 hover:text-${link.color}-400 hover:bg-${link.color}-700 transition-all transition-300`">
|
||||
<inertia-link v-for="link, index in $page.props.toolbar" :key="index" :href="link.href" v-text="link.label" class="btn label" :class="link.color">
|
||||
<sprite :src="link.icon"></sprite>
|
||||
</inertia-link>
|
||||
</div>
|
||||
|
|
|
@ -1,43 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
<div class="custom-table">
|
||||
<header>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Nachname</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Vorname</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Straße</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">PLZ</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Ort</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Mittendrin</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Nami</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Check</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Rechnung</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Geburtstag</div>
|
||||
<div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Eintritt</div>
|
||||
<div class="px-6 py-3 border-gray-600 border-b"></div>
|
||||
<div>Nachname</div>
|
||||
<div>Vorname</div>
|
||||
<div>Straße</div>
|
||||
<div>PLZ</div>
|
||||
<div>Ort</div>
|
||||
<div>Mittendrin</div>
|
||||
<div>Nami</div>
|
||||
<div>Check</div>
|
||||
<div>Rechnung</div>
|
||||
<div>Geburtstag</div>
|
||||
<div>Eintritt</div>
|
||||
<div></div>
|
||||
</header>
|
||||
|
||||
<div v-for="member, index in data.data" class="text-gray-200 transition-all duration-300 rounded flex items-center hover:bg-gray-800">
|
||||
<div class="py-1 px-6" v-text="member.firstname"></div>
|
||||
<div class="py-1 px-6" v-text="member.lastname"></div>
|
||||
<div class="py-1 px-6" v-text="`${member.address}`"></div>
|
||||
<div class="py-1 px-6" v-text="`${member.zip}`"></div>
|
||||
<div class="py-1 px-6" v-text="`${member.location}`"></div>
|
||||
<div class="py-1 px-6">
|
||||
<div v-for="member, index in data.data">
|
||||
<div v-text="member.firstname"></div>
|
||||
<div v-text="member.lastname"></div>
|
||||
<div v-text="`${member.address}`"></div>
|
||||
<div v-text="`${member.zip}`"></div>
|
||||
<div v-text="`${member.location}`"></div>
|
||||
<div>
|
||||
<v-bool v-model="member.send_newspaper"></v-bool>
|
||||
</div>
|
||||
<div class="py-1 px-6">
|
||||
<div>
|
||||
<v-bool v-model="member.has_nami"></v-bool>
|
||||
</div>
|
||||
<div class="py-1 px-6">
|
||||
<div>
|
||||
<v-bool v-model="member.is_confirmed"></v-bool>
|
||||
</div>
|
||||
<div class="py-1 px-6">
|
||||
<div>
|
||||
<div class="py-1 rounded-full flex text-xs items-center justify-center leading-none bg-primary-900" v-text="member.bill_kind_name" v-if="member.bill_kind_name"></div>
|
||||
<div class="py-1 rounded-full flex text-xs items-center justify-center leading-none" v-else>Kein</div>
|
||||
</div>
|
||||
<div class="py-1 px-6" v-text="`${member.birthday_human}`"></div>
|
||||
<div class="py-1 px-6" v-text="`${member.joined_at_human}`"></div>
|
||||
<div class="py-1 px-6 flex">
|
||||
<div v-text="`${member.birthday_human}`"></div>
|
||||
<div v-text="`${member.joined_at_human}`"></div>
|
||||
<div class="flex">
|
||||
<inertia-link :href="`/member/${member.id}/edit`" class="inline-flex btn btn-warning btn-sm"><sprite src="pencil"></sprite></inertia-link>
|
||||
<inertia-link :href="`/member/${member.id}/payment`" class="inline-flex btn btn-info btn-sm"><sprite src="money"></sprite></inertia-link>
|
||||
</div>
|
||||
|
@ -48,17 +49,30 @@
|
|||
<div class="px-6">
|
||||
<pages class="mt-4" :value="data.meta" :only="['data']"></pages>
|
||||
</div>
|
||||
|
||||
<transition name="sidebar">
|
||||
<payments v-if="single !== null && single.mode === 'index'" v-model="single"></payments>
|
||||
<payment-form v-if="single !== null && single.mode === 'create'" v-model="single"></payment-form>
|
||||
<payment-form v-if="single !== null && single.mode === 'edit'" v-model="single"></payment-form>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import App from '../../layouts/App';
|
||||
import Payments from './Payments.vue';
|
||||
import PaymentForm from './PaymentForm.vue';
|
||||
|
||||
export default {
|
||||
layout: App,
|
||||
|
||||
components: { Payments, PaymentForm },
|
||||
|
||||
props:{
|
||||
data: {}
|
||||
data: {},
|
||||
single: {
|
||||
default: function() { return null; }
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div class="sidebar">
|
||||
<sidebar-header :links="value.links" @close="$inertia.visit('/member')" title="Zahlungen"></sidebar-header>
|
||||
|
||||
<form class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
|
||||
<f-text id="nr" v-model="inner.nr" label="Jahr" required></f-text>
|
||||
<f-select id="subscription_id" :options="value.subscriptions" v-model="inner.subscription_id" label="Beitrag" required></f-select>
|
||||
<f-select id="status_id" :options="value.statuses" v-model="inner.status_id" label="Status" required></f-select>
|
||||
<button type="submit" class="btn btn-primary">Absenden</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarHeader from '../../components/SidebarHeader.vue';
|
||||
|
||||
export default {
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
inner: {},
|
||||
};
|
||||
},
|
||||
|
||||
components: { SidebarHeader },
|
||||
|
||||
props: {
|
||||
value: {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.value.mode === 'create'
|
||||
? this.$inertia.post(`/member/${this.value.data.id}/payment`, this.inner)
|
||||
: this.$inertia.patch(`/member/${this.value.data.id}/payment/${this.inner.id}`, this.inner);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.inner = this.value.model;
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<div class="sidebar">
|
||||
<sidebar-header :links="value.links" @close="$inertia.visit('/member')" title="Zahlungen"></sidebar-header>
|
||||
|
||||
<div class="custom-table custom-table-light custom-table-sm text-sm">
|
||||
<header>
|
||||
<div>Nr</div>
|
||||
<div>Status</div>
|
||||
<div>Beitrag</div>
|
||||
<div></div>
|
||||
</header>
|
||||
|
||||
<div v-for="payment, index in value.data.payments">
|
||||
<div v-text="payment.nr"></div>
|
||||
<div v-text="payment.status_name"></div>
|
||||
<div v-text="payment.subscription_name"></div>
|
||||
<div class="flex">
|
||||
<inertia-link :href="`/member/${value.data.id}/payment/${payment.id}/edit`" class="inline-flex btn btn-warning btn-sm"><sprite src="pencil"></sprite></inertia-link>
|
||||
<inertia-link href="#" @click.prevent="remove(payment)" class="inline-flex btn btn-danger btn-sm"><sprite src="trash"></sprite></inertia-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarHeader from '../../components/SidebarHeader.vue';
|
||||
|
||||
export default {
|
||||
components: { SidebarHeader },
|
||||
|
||||
methods: {
|
||||
remove(payment) {
|
||||
this.$inertia.delete(`/member/${this.value.data.id}/payment/${payment.id}`);
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Member\MemberController;
|
||||
use App\Payment\PaymentController;
|
||||
use App\Payment\SubscriptionController;
|
||||
use App\Member\MemberConfirmController;
|
||||
use App\Http\Controllers\HomeController;
|
||||
|
@ -14,6 +15,7 @@ Route::group(['middleware' => 'auth:web'], function () {
|
|||
Route::get('/', HomeController::class)->name('home');
|
||||
Route::resource('initialize', InitializeController::class);
|
||||
Route::resource('member', MemberController::class);
|
||||
Route::resource('member.payment', PaymentController::class);
|
||||
Route::resource('subscription', SubscriptionController::class);
|
||||
Route::post('/member/{member}/confirm', MemberConfirmController::class);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue