From a244448aeb2e72fa6e45ffc1f58c9abd37c70881 Mon Sep 17 00:00:00 2001
From: philipp lang <philipp@aweos.de>
Date: Sun, 11 Apr 2021 11:19:55 +0200
Subject: [PATCH] Add: Edit member

---
 app/Member/MemberController.php     | 19 ++++++
 app/Member/MemberResource.php       | 10 +++
 resources/js/app.js                 | 24 +++++---
 resources/js/components/FSelect.vue |  8 +--
 resources/js/components/FText.vue   |  8 +--
 resources/js/layouts/App.vue        |  2 +-
 resources/js/views/member/Edit.vue  | 96 +++++++++++++++++++++++++++++
 resources/js/views/member/Index.vue |  2 +-
 8 files changed, 152 insertions(+), 17 deletions(-)
 create mode 100644 resources/js/views/member/Edit.vue

diff --git a/app/Member/MemberController.php b/app/Member/MemberController.php
index 28c84d0b..b70381bb 100644
--- a/app/Member/MemberController.php
+++ b/app/Member/MemberController.php
@@ -4,6 +4,8 @@ namespace App\Member;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
+use App\Gender;
+use App\Fee;
 
 class MemberController extends Controller
 {
@@ -15,4 +17,21 @@ class MemberController extends Controller
             'data' => MemberResource::collection(Member::search($request->query('search', null))->paginate(15))
         ]);
     }
+
+    public function edit(Member $member, Request $request) {
+        session()->put('menu', 'member');
+        session()->put('title', 'Mitglied bearbeiten');
+
+        return \Inertia::render('member/Edit', [
+            'genders' => Gender::where('is_null', false)->get()->pluck('name', 'id'),
+            'fees' => Fee::get()->pluck('name', 'id'),
+            'data' => new MemberResource($member)
+        ]);
+    }
+
+    public function update(Member $member, Request $request) {
+        $member->update($request->input());
+
+        return redirect()->route('member.index');
+    }
 }
diff --git a/app/Member/MemberResource.php b/app/Member/MemberResource.php
index 20a49e8d..ffd78011 100644
--- a/app/Member/MemberResource.php
+++ b/app/Member/MemberResource.php
@@ -23,6 +23,16 @@ class MemberResource extends JsonResource
             'send_newspaper' => $this->send_newspaper,
             'birthday' => $this->birthday->format('d.m.Y'),
             'joined_at' => $this->joined_at->format('d.m.Y'),
+            'id' => $this->id,
+            'gender_id' => $this->gender_id,
+            'further_address' => $this->further_address,
+            'work_phone' => $this->work_phone,
+            'mobile_phone' => $this->mobile_phone,
+            'main_phone' => $this->main_phone,
+            'email' => $this->email,
+            'email_parents' => $this->email_parents,
+            'fax' => $this->fax,
+            'nami_id' => $this->nami_id,
         ];
     }
 }
diff --git a/resources/js/app.js b/resources/js/app.js
index f99335f5..929ac6e8 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1,16 +1,19 @@
 import Vue from 'vue';
-import { App, plugin } from '@inertiajs/inertia-vue'
+import { App as InertiaApp, plugin } from '@inertiajs/inertia-vue'
 import 'font-awesome/css/font-awesome.css';
 import Echo from 'laravel-echo';
 window.io = require('socket.io-client');
 import Sprite from './components/Sprite.js';
 
 import FText from './components/FText.vue';
+import FSelect from './components/FSelect.vue';
 import Pages from './components/Pages.vue';
 import VBool from './components/VBool.vue';
+import App from './layouts/App.vue';
 
 Vue.use(plugin)
 Vue.component('f-text', FText);
+Vue.component('f-select', FSelect);
 Vue.component('sprite', Sprite);
 Vue.component('pages', Pages);
 Vue.component('v-bool', VBool);
@@ -18,11 +21,18 @@ Vue.component('v-bool', VBool);
 const el = document.getElementById('app')
 
 new Vue({
-  render: h => h(App, {
-    props: {
-      initialPage: JSON.parse(el.dataset.page),
-      resolveComponent: name => require(`./views/${name}`).default,
-    },
-  }),
+    render: h => h(InertiaApp, {
+        props: {
+            initialPage: JSON.parse(el.dataset.page),
+            resolveComponent: name => {
+                var page = require(`./views/${name}`).default;
+
+                if (page.layout === undefined) {
+                    page.layout = App;
+                }
+                return page;
+            }
+        },
+    }),
 }).$mount(el);
 
diff --git a/resources/js/components/FSelect.vue b/resources/js/components/FSelect.vue
index 03921224..e659cb37 100644
--- a/resources/js/components/FSelect.vue
+++ b/resources/js/components/FSelect.vue
@@ -1,19 +1,19 @@
 <template>
     <label class="flex flex-col relative" :for="id" :class="{['h-field-'+size]: inset === true}">
         <div class="relative h-full flex flex-col">
-            <span v-if="label && !inset" class="font-semibold relative z-10 text-gray-700" :class="{
+            <span v-if="label && !inset" class="font-semibold relative z-10 text-gray-400" :class="{
                 'text-xs': size == 'sm',
                 'text-sm': size === null
-            }">{{ label }}<span v-show="required" class="text-red-800">&nbsp;*</span></span>
+            }">{{ label }}<span v-show="required" class="text-red-300">&nbsp;*</span></span>
             <span v-if="label && inset" class="absolute z-10 top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
                 'text-xs': size == 'sm',
                 'text-sm': size === null
             }" v-text="label"></span>
             <div class="relative h-full" :class="{['h-field-'+size]: inset === false}">
                 <select :value="value" @change="trigger"
-                    class="border-gray-400 border-solid bg-white w-full appearance-none outline-none h-full"
+                    class="border-gray-600 border-solid bg-gray-700 w-full appearance-none outline-none h-full"
                     :class="{
-                        'rounded-lg text-sm border-2 p-2 text-gray-800': size === null,
+                        'rounded-lg text-sm border-2 p-2 text-gray-300': size === null,
                         'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
                     }"
                 >
diff --git a/resources/js/components/FText.vue b/resources/js/components/FText.vue
index e88c229f..9a522fe3 100644
--- a/resources/js/components/FText.vue
+++ b/resources/js/components/FText.vue
@@ -1,10 +1,10 @@
 <template>
     <label class="flex flex-col relative" :for="id" :class="{['h-field-'+size]: inset === true}">
         <div class="relative h-full flex flex-col">
-            <span v-if="label && !inset" class="font-semibold relative z-10 text-gray-700" :class="{
+            <span v-if="label && !inset" class="font-semibold relative z-10 text-gray-400" :class="{
                 'text-xs': size == 'sm',
                 'text-sm': size === null
-            }">{{ label }}<span v-show="required" class="text-red-800">&nbsp;*</span></span>
+            }">{{ label }}<span v-show="required" class="text-red-300">&nbsp;*</span></span>
             <span v-if="label && inset" class="absolute z-10 top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
                 'text-xs': size == 'sm',
                 'text-sm': size === null
@@ -12,9 +12,9 @@
             <div class="relative h-full" :class="{['h-field-'+size]: inset === false}">
                 <input :type="type" :name="name" :value="transformedValue" @input="onInput" @change="onChange" :disabled="disabled" :placeholder="placeholder"
                     @focus="onFocus" @blur="onBlur"
-                    class="border-gray-400 border-solid bg-white w-full appearance-none outline-none h-full"
+                    class="border-gray-600 border-solid bg-gray-700 w-full appearance-none outline-none h-full"
                     :class="{
-                        'rounded-lg text-sm border-2 p-2 text-gray-800': size === null,
+                        'rounded-lg text-sm border-2 p-2 text-gray-300': size === null,
                         'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
                     }"
                 />
diff --git a/resources/js/layouts/App.vue b/resources/js/layouts/App.vue
index c83cd8d9..6fb13a46 100644
--- a/resources/js/layouts/App.vue
+++ b/resources/js/layouts/App.vue
@@ -17,7 +17,7 @@
                 </label>
             </div>
 
-            <div class="flex-grow">
+            <div class="flex-grow flex flex-col">
                 <slot></slot>
             </div>
         </div>
diff --git a/resources/js/views/member/Edit.vue b/resources/js/views/member/Edit.vue
new file mode 100644
index 00000000..a5bbd484
--- /dev/null
+++ b/resources/js/views/member/Edit.vue
@@ -0,0 +1,96 @@
+<template>
+    <form class="flex flex-grow relative" @submit.prevent="$inertia.patch(`/member/${inner.id}`, inner)">
+        <!-- ****************************** menu links ******************************* -->
+        <div class="p-6 bg-gray-700 border-r border-gray-600 flex-none w-maxc flex flex-col justify-between">
+            <div class="grid gap-1">
+                <a v-for="item, index in menu" :key="index" href="#" @click.prevent="openMenu(index)" class="rounded py-1 px-3 text-gray-400" :class="index == active ? `bg-gray-600` : ''" v-text="item.title"></a>
+            </div>
+            <div>
+                <button type="submit" class="btn block w-full btn-primary">Speichern</button>
+            </div>
+        </div>
+
+        <div class="flex-grow">
+            <div class="grid grid-cols-2 gap-3 p-4" v-if="menuTitle == 'Stammdaten'">
+                <div>
+                    <f-select id="gender_id" :options="genders" v-model="inner.gender_id" label="Geschlecht" required></f-select>
+                </div>
+                <div>
+                    <f-text id="firstname" v-model="inner.firstname" label="Vorname"></f-text>
+                </div>
+                <div>
+                    <f-text id="lastname" v-model="inner.lastname" label="Nachname"></f-text>
+                </div>
+                <div>
+                    <f-text id="address" v-model="inner.address" label="Adresse"></f-text>
+                </div>
+                <div>
+                    <f-text id="further_address" v-model="inner.further_address" label="Adresszusatz"></f-text>
+                </div>
+                <div>
+                    <f-text id="zip" v-model="inner.zip" label="PLZ"></f-text>
+                </div>
+                <div>
+                    <f-text id="location" v-model="inner.location" label="Ort"></f-text>
+                </div>
+            </div>
+            <div class="grid grid-cols-2 gap-3 p-4" v-if="menuTitle == 'Kontakt'">
+                <div>
+                    <f-text id="main_phone" v-model="inner.main_phone" label="Telefon"></f-text>
+                </div>
+                <div>
+                    <f-text id="mobile_phone" v-model="inner.mobile_phone" label="Handy"></f-text>
+                </div>
+                <div>
+                    <f-text id="work_phone" v-model="inner.work_phone" label="Tel geschäftlich"></f-text>
+                </div>
+                <div>
+                    <f-text id="email" v-model="inner.email" label="E-Mail"></f-text>
+                </div>
+                <div>
+                    <f-text id="email_parents" v-model="inner.email_parents" label="E-Mail eltern"></f-text>
+                </div>
+                <div>
+                    <f-text id="fax" v-model="inner.fax" label="Fax"></f-text>
+                </div>
+            </div>
+        </div>
+    </form>
+</template>
+
+<script>
+export default {
+    data: function() {
+        return {
+            inner: {},
+            active: 0,
+            menu: [
+                { title: 'Stammdaten' },
+                { title: 'Kontakt' },
+            ]
+        };
+    },
+
+    props: {
+        genders: {},
+        fees: {},
+        data: {}
+    },
+
+    methods: {
+        openMenu(index) {
+            this.active = index;
+        }
+    },
+
+    computed: {
+        menuTitle() {
+            return this.menu[this.active].title;
+        }
+    },
+
+    created() {
+        this.inner = this.data;
+    }
+};
+</script>
diff --git a/resources/js/views/member/Index.vue b/resources/js/views/member/Index.vue
index 7f969fe1..4a3c271e 100644
--- a/resources/js/views/member/Index.vue
+++ b/resources/js/views/member/Index.vue
@@ -12,7 +12,7 @@
                 <div class="px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b">Eintritt</div>
             </header>
 
-            <inertia-link :href="`/member/${member.id}`" :key="index" v-for="member, index in data.data" class="text-gray-200 transition-all duration-500 rounded flex hover:bg-gray-600">
+            <inertia-link :href="`/member/${member.id}/edit`" :key="index" v-for="member, index in data.data" class="text-gray-200 transition-all duration-500 rounded flex hover:bg-gray-600">
                 <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>