Selaa lähdekoodia

feat: laundry master

Muhammad Iqbal Afandi 3 vuotta sitten
vanhempi
commit
e35b0c8bb9

+ 111
- 0
app/Http/Controllers/LaundryController.php Näytä tiedosto

@@ -0,0 +1,111 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use App\Http\Controllers\Controller;
6
+use App\Http\Requests\Laundry\StoreLaundryRequest;
7
+use App\Http\Requests\Laundry\UpdateLaundryRequest;
8
+use App\Models\Laundry;
9
+
10
+class LaundryController extends Controller
11
+{
12
+    /**
13
+     * Display a listing of the resource.
14
+     *
15
+     * @return \Inertia\Response
16
+     */
17
+    public function index()
18
+    {
19
+        return inertia('laundry/Index', [
20
+            'laundries' => Laundry::latest()
21
+                ->filter(request()->search)
22
+                ->paginate(10)
23
+                ->withQueryString()
24
+                ->through(fn($laundry) => [
25
+                    'id' => $laundry->id,
26
+                    'name' => $laundry->name,
27
+                    'price' => $laundry->price,
28
+                    'unit' => $laundry->unit,
29
+                ]),
30
+        ]);
31
+    }
32
+
33
+    /**
34
+     * Show the form for creating a new resource.
35
+     *
36
+     * @return \Inertia\Response
37
+     */
38
+    public function create()
39
+    {
40
+        return inertia('laundry/Create');
41
+    }
42
+
43
+    /**
44
+     * Store a newly created resource in storage.
45
+     *
46
+     * @param  \Illuminate\Http\Request  $request
47
+     * @return \Illuminate\Http\Response
48
+     */
49
+    public function store(StoreLaundryRequest $request)
50
+    {
51
+        Laundry::create($request->validated());
52
+
53
+        return to_route('laundries.index')->with('success', __('messages.success.store.laundry'));
54
+    }
55
+
56
+    /**
57
+     * Display the specified resource.
58
+     *
59
+     * @param  int  $id
60
+     * @return \Inertia\Response
61
+     */
62
+    public function show($id)
63
+    {
64
+        //
65
+    }
66
+
67
+    /**
68
+     * Show the form for editing the specified resource.
69
+     *
70
+     * @param  Laundry  $laundry
71
+     * @return \Inertia\Response
72
+     */
73
+    public function edit(Laundry $laundry)
74
+    {
75
+        return inertia('laundry/Edit', [
76
+            'laundry' => [
77
+                'id' => $laundry->id,
78
+                'name' => $laundry->name,
79
+                'price' => $laundry->getRawOriginal('price'),
80
+                'unit' => $laundry->unit,
81
+            ],
82
+        ]);
83
+    }
84
+
85
+    /**
86
+     * Update the specified resource in storage.
87
+     *
88
+     * @param  \Illuminate\Http\Request  $request
89
+     * @param  Laundry  $laundry
90
+     * @return \Illuminate\Http\Response
91
+     */
92
+    public function update(UpdateLaundryRequest $request, Laundry $laundry)
93
+    {
94
+        $laundry->update($request->validated());
95
+
96
+        return back()->with('success', __('messages.success.update.laundry'));
97
+    }
98
+
99
+    /**
100
+     * Remove the specified resource from storage.
101
+     *
102
+     * @param  Laundry  $laundry
103
+     * @return \Illuminate\Http\Response
104
+     */
105
+    public function destroy(Laundry $laundry)
106
+    {
107
+        $laundry->delete();
108
+
109
+        return to_route('laundries.index')->with('success', __('messages.success.destroy.laundry'));
110
+    }
111
+}

+ 32
- 0
app/Http/Requests/Laundry/StoreLaundryRequest.php Näytä tiedosto

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Http\Requests\Laundry;
4
+
5
+use Illuminate\Foundation\Http\FormRequest;
6
+
7
+class StoreLaundryRequest extends FormRequest
8
+{
9
+    /**
10
+     * Determine if the user is authorized to make this request.
11
+     *
12
+     * @return bool
13
+     */
14
+    public function authorize()
15
+    {
16
+        return true;
17
+    }
18
+
19
+    /**
20
+     * Get the validation rules that apply to the request.
21
+     *
22
+     * @return array
23
+     */
24
+    public function rules()
25
+    {
26
+        return [
27
+            'name' => 'required|string|max:50',
28
+            'price' => 'required|integer|numeric',
29
+            'unit' => 'required|string|max:50',
30
+        ];
31
+    }
32
+}

+ 32
- 0
app/Http/Requests/Laundry/UpdateLaundryRequest.php Näytä tiedosto

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Http\Requests\Laundry;
4
+
5
+use Illuminate\Foundation\Http\FormRequest;
6
+
7
+class UpdateLaundryRequest extends FormRequest
8
+{
9
+    /**
10
+     * Determine if the user is authorized to make this request.
11
+     *
12
+     * @return bool
13
+     */
14
+    public function authorize()
15
+    {
16
+        return true;
17
+    }
18
+
19
+    /**
20
+     * Get the validation rules that apply to the request.
21
+     *
22
+     * @return array
23
+     */
24
+    public function rules()
25
+    {
26
+        return [
27
+            'name' => 'required|string|max:50',
28
+            'price' => 'required|integer|numeric',
29
+            'unit' => 'required|string|max:50',
30
+        ];
31
+    }
32
+}

+ 11
- 0
app/Models/Helpers/HasHelper.php Näytä tiedosto

@@ -0,0 +1,11 @@
1
+<?php
2
+
3
+namespace App\Models\Helpers;
4
+
5
+trait HasHelper
6
+{
7
+    protected function setRupiahFormat(int $number)
8
+    {
9
+        return 'Rp. ' . number_format($number, '2', ',', '.');
10
+    }
11
+}

+ 28
- 1
app/Models/Laundry.php Näytä tiedosto

@@ -2,16 +2,43 @@
2 2
 
3 3
 namespace App\Models;
4 4
 
5
+use App\Models\Helpers\HasHelper;
6
+use Illuminate\Database\Eloquent\Casts\Attribute;
5 7
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6 8
 use Illuminate\Database\Eloquent\Model;
7 9
 
8 10
 class Laundry extends Model
9 11
 {
10
-    use HasFactory;
12
+    use HasFactory, HasHelper;
11 13
 
12 14
     protected $fillable = [
13 15
         'name',
14 16
         'price',
15 17
         'unit',
16 18
     ];
19
+
20
+    protected function unit(): Attribute
21
+    {
22
+        return Attribute::make(
23
+            set:fn($value) => strtoupper($value)
24
+        );
25
+    }
26
+
27
+    protected function price(): Attribute
28
+    {
29
+        return Attribute::make(
30
+            get:fn($value) => $this->setRupiahFormat($value)
31
+        );
32
+    }
33
+
34
+    public function scopeFilter($query, $search)
35
+    {
36
+        $query->when($search ?? null, function ($query, $search) {
37
+            $query->where(function ($query) use ($search) {
38
+                $query->where('name', 'like', '%' . $search . '%')
39
+                    ->orWhere('price', 'like', '%' . $search . '%')
40
+                    ->orWhere('unit', 'like', '%' . $search . '%');
41
+            });
42
+        });
43
+    }
17 44
 }

+ 3
- 0
lang/id/messages.php Näytä tiedosto

@@ -25,16 +25,19 @@ return [
25 25
             'user' => 'Akun user berhasil ditambahkan',
26 26
             'customer' => 'Akun customer berhasil ditambahkan',
27 27
             'outlet' => 'Data outlet berhasil ditambahkan',
28
+            'laundry' => 'Data laundry berhasil ditambahkan',
28 29
         ],
29 30
         'update' => [
30 31
             'user' => 'Akun user berhasil diubah',
31 32
             'customer' => 'Akun customer berhasil diubah',
32 33
             'outlet' => 'Data outlet berhasil diubah',
34
+            'laundry' => 'Data laundry berhasil diubah',
33 35
         ],
34 36
         'destroy' => [
35 37
             'user' => 'Akun user berhasil dihapus',
36 38
             'customer' => 'Akun customer berhasil dihapus',
37 39
             'outlet' => 'Data outlet berhasil dihapus',
40
+            'laundry' => 'Data laundry berhasil dihapus',
38 41
         ],
39 42
     ],
40 43
 

+ 1
- 1
lang/id/validation.php Näytä tiedosto

@@ -61,7 +61,7 @@ return [
61 61
     'image' => 'Harus gambar.',
62 62
     'in' => 'The selected Nilai is invalid.',
63 63
     'in_array' => 'Nilai does not exist in :other.',
64
-    'integer' => 'Nilai harus be an integer.',
64
+    'integer' => 'Nilai harus integer.',
65 65
     'ip' => 'Nilai harus be a valid IP address.',
66 66
     'ipv4' => 'Nilai harus be a valid IPv4 address.',
67 67
     'ipv6' => 'Nilai harus be a valid IPv6 address.',

+ 1897
- 0
public/js/resources_js_pages_laundry_Create_vue.js
File diff suppressed because it is too large
Näytä tiedosto


+ 13
- 0
public/js/resources_js_pages_laundry_Edit_jsx.js Näytä tiedosto

@@ -0,0 +1,13 @@
1
+(self["webpackChunk"] = self["webpackChunk"] || []).push([["resources_js_pages_laundry_Edit_jsx"],{
2
+
3
+/***/ "./resources/js/pages/laundry/Edit.jsx":
4
+/*!*********************************************!*\
5
+  !*** ./resources/js/pages/laundry/Edit.jsx ***!
6
+  \*********************************************/
7
+/***/ (() => {
8
+
9
+
10
+
11
+/***/ })
12
+
13
+}]);

+ 2312
- 0
public/js/resources_js_pages_laundry_Edit_vue.js
File diff suppressed because it is too large
Näytä tiedosto


+ 2152
- 0
public/js/resources_js_pages_laundry_Index_vue.js
File diff suppressed because it is too large
Näytä tiedosto


+ 25
- 1
public/js/vue.js Näytä tiedosto

@@ -36083,6 +36083,30 @@ var map = {
36083 36083
 		"./resources/js/pages/customer/Index.vue",
36084 36084
 		"resources_js_pages_customer_Index_vue"
36085 36085
 	],
36086
+	"./laundry/Create": [
36087
+		"./resources/js/pages/laundry/Create.vue",
36088
+		"resources_js_pages_laundry_Create_vue"
36089
+	],
36090
+	"./laundry/Create.vue": [
36091
+		"./resources/js/pages/laundry/Create.vue",
36092
+		"resources_js_pages_laundry_Create_vue"
36093
+	],
36094
+	"./laundry/Edit": [
36095
+		"./resources/js/pages/laundry/Edit.vue",
36096
+		"resources_js_pages_laundry_Edit_vue"
36097
+	],
36098
+	"./laundry/Edit.vue": [
36099
+		"./resources/js/pages/laundry/Edit.vue",
36100
+		"resources_js_pages_laundry_Edit_vue"
36101
+	],
36102
+	"./laundry/Index": [
36103
+		"./resources/js/pages/laundry/Index.vue",
36104
+		"resources_js_pages_laundry_Index_vue"
36105
+	],
36106
+	"./laundry/Index.vue": [
36107
+		"./resources/js/pages/laundry/Index.vue",
36108
+		"resources_js_pages_laundry_Index_vue"
36109
+	],
36086 36110
 	"./outlet/Create": [
36087 36111
 		"./resources/js/pages/outlet/Create.vue",
36088 36112
 		"resources_js_pages_outlet_Create_vue"
@@ -36248,7 +36272,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
36248 36272
 /******/ 		// This function allow to reference async chunks
36249 36273
 /******/ 		__webpack_require__.u = (chunkId) => {
36250 36274
 /******/ 			// return url for filenames based on template
36251
-/******/ 			return "js/" + chunkId + ".js?id=" + {"resources_js_pages_auth_ForgotPassword_vue":"70818f45cbbab151","resources_js_pages_auth_Login_vue":"c4cf6fd873885e8f","resources_js_pages_auth_ResetPassword_vue":"adb7b3ce1defe237","resources_js_pages_auth_VerifyEmail_vue":"766e409b18e8e260","resources_js_pages_customer_Create_vue":"043463d47e5a7d20","resources_js_pages_customer_Edit_vue":"ad87bcdaff2e284c","resources_js_pages_customer_Index_vue":"c9964211a38d2db5","resources_js_pages_outlet_Create_vue":"610831f5d05c5c2f","resources_js_pages_outlet_Edit_vue":"fb9c21c755b35f2b","resources_js_pages_outlet_Index_vue":"84c5671f63445ef0","resources_js_pages_user_Create_vue":"c40384f40ba5a089","resources_js_pages_user_Edit_vue":"a880111a8912f84c","resources_js_pages_user_Index_vue":"62f17f79119649c8"}[chunkId] + "";
36275
+/******/ 			return "js/" + chunkId + ".js?id=" + {"resources_js_pages_auth_ForgotPassword_vue":"70818f45cbbab151","resources_js_pages_auth_Login_vue":"c4cf6fd873885e8f","resources_js_pages_auth_ResetPassword_vue":"adb7b3ce1defe237","resources_js_pages_auth_VerifyEmail_vue":"766e409b18e8e260","resources_js_pages_customer_Create_vue":"043463d47e5a7d20","resources_js_pages_customer_Edit_vue":"ad87bcdaff2e284c","resources_js_pages_customer_Index_vue":"c9964211a38d2db5","resources_js_pages_laundry_Create_vue":"954d4dad399640b9","resources_js_pages_laundry_Edit_vue":"f751616dc7a87eb5","resources_js_pages_laundry_Index_vue":"c995220ff8690d76","resources_js_pages_outlet_Create_vue":"610831f5d05c5c2f","resources_js_pages_outlet_Edit_vue":"fb9c21c755b35f2b","resources_js_pages_outlet_Index_vue":"84c5671f63445ef0","resources_js_pages_user_Create_vue":"c40384f40ba5a089","resources_js_pages_user_Edit_vue":"a880111a8912f84c","resources_js_pages_user_Index_vue":"62f17f79119649c8"}[chunkId] + "";
36252 36276
 /******/ 		};
36253 36277
 /******/ 	})();
36254 36278
 /******/ 	

+ 49
- 0
resources/js/pages/laundry/Create.vue Näytä tiedosto

@@ -0,0 +1,49 @@
1
+<script setup>
2
+import { Head, useForm } from '@inertiajs/inertia-vue3'
3
+
4
+import AppButtonCreate from '@/components/AppButtonCreate.vue'
5
+import AppTextInput from '@/components/AppTextInput.vue'
6
+import DefaultLayout from '@/layouts/DefaultLayout.vue'
7
+
8
+const form = useForm({
9
+  name: '',
10
+  price: '',
11
+  unit: '',
12
+})
13
+
14
+const submit = () => {
15
+  form.post(route('laundries.store'))
16
+}
17
+</script>
18
+
19
+<template>
20
+  <Head title="Tambah tipe Laundry" />
21
+
22
+  <DefaultLayout>
23
+    <CRow>
24
+      <CCol md="8">
25
+        <CCard color="light" class="border-light">
26
+          <CForm @submit.prevent="submit">
27
+            <CRow class="p-4">
28
+              <CCol md="6" class="mb-4">
29
+                <AppTextInput label="Nama" placeholder="nama" :error="form.errors.name" v-model="form.name" />
30
+              </CCol>
31
+
32
+              <CCol md="6" class="mb-4">
33
+                <AppTextInput label="Harga" placeholder="harga" :error="form.errors.price" v-model="form.price" />
34
+              </CCol>
35
+
36
+              <CCol md="6" class="mb-4">
37
+                <AppTextInput label="Satuan" placeholder="unit" :error="form.errors.unit" v-model="form.unit" />
38
+              </CCol>
39
+            </CRow>
40
+
41
+            <CCardFooter class="d-flex justify-content-end">
42
+              <AppButtonCreate :disabled="form.processing">Tambah tipe Laundry</AppButtonCreate>
43
+            </CCardFooter>
44
+          </CForm>
45
+        </CCard>
46
+      </CCol>
47
+    </CRow>
48
+  </DefaultLayout>
49
+</template>

+ 66
- 0
resources/js/pages/laundry/Edit.vue Näytä tiedosto

@@ -0,0 +1,66 @@
1
+<script setup>
2
+import { Head, useForm } from '@inertiajs/inertia-vue3'
3
+
4
+import AppTextInput from '@/components/AppTextInput.vue'
5
+import AppButtonCreate from '@/components/AppButtonCreate.vue'
6
+import AppButtonDelete from '@/components/AppButtonDelete.vue'
7
+import AppButtonAction from '@/components/AppButtonAction.vue'
8
+import AppModalAlert from '@/components/AppModalAlert.vue'
9
+import DefaultLayout from '@/layouts/DefaultLayout.vue'
10
+
11
+const props = defineProps({
12
+  laundry: Object,
13
+})
14
+
15
+const form = useForm({
16
+  name: props.laundry.name,
17
+  price: props.laundry.price,
18
+  unit: props.laundry.unit,
19
+})
20
+
21
+const submit = () => {
22
+  form.put(route('laundries.update', props.laundry.id))
23
+}
24
+</script>
25
+
26
+<template>
27
+  <Head title="Ubah tipe Laundry" />
28
+
29
+  <DefaultLayout v-slot="{ toggleModalAlert }">
30
+    <CRow>
31
+      <CCol md="8">
32
+        <CCard color="light" class="border-light">
33
+          <CForm @submit.prevent="submit">
34
+            <CRow class="p-4">
35
+              <CCol md="6" class="mb-4">
36
+                <AppTextInput label="Nama" placeholder="nama" :error="form.errors.name" v-model="form.name" />
37
+              </CCol>
38
+
39
+              <CCol md="6" class="mb-4">
40
+                <AppTextInput label="Harga" placeholder="harga" :error="form.errors.price" v-model="form.price" />
41
+              </CCol>
42
+
43
+              <CCol md="6" class="mb-4">
44
+                <AppTextInput label="Satuan" placeholder="unit" :error="form.errors.unit" v-model="form.unit" />
45
+              </CCol>
46
+            </CRow>
47
+
48
+            <CCardFooter class="d-flex justify-content-between">
49
+              <AppButtonAction @click="toggleModalAlert">Hapus tipe Laundry</AppButtonAction>
50
+
51
+              <AppModalAlert>
52
+                Anda yakin ingin mengahapus tipe laundry ini?
53
+
54
+                <template #footer>
55
+                  <AppButtonDelete :href="route('laundries.destroy', laundry.id)">Hapus tipe Laundry</AppButtonDelete>
56
+                </template>
57
+              </AppModalAlert>
58
+
59
+              <AppButtonCreate :disabled="form.processing">Ubah tipe Laundry</AppButtonCreate>
60
+            </CCardFooter>
61
+          </CForm>
62
+        </CCard>
63
+      </CCol>
64
+    </CRow>
65
+  </DefaultLayout>
66
+</template>

+ 55
- 0
resources/js/pages/laundry/Index.vue Näytä tiedosto

@@ -0,0 +1,55 @@
1
+<script setup>
2
+import { Head } from '@inertiajs/inertia-vue3'
3
+
4
+import AppTable from '@/components/AppTable.vue'
5
+import AppButtonMove from '@/components/AppButtonMove.vue'
6
+import AppButtonDetail from '@/components/AppButtonDetail.vue'
7
+import AppPagination from '@/components/AppPagination.vue'
8
+import DefaultLayout from '@/layouts/DefaultLayout.vue'
9
+
10
+defineProps({
11
+  laundries: Object,
12
+})
13
+</script>
14
+
15
+<template>
16
+  <Head title="Daftar Tipe Laundry" />
17
+
18
+  <DefaultLayout>
19
+    <CRow class="mb-4">
20
+      <CCol></CCol>
21
+
22
+      <CCol xs="auto">
23
+        <AppButtonMove :href="route('laundries.create')">Tambah tipe Laundry</AppButtonMove>
24
+      </CCol>
25
+    </CRow>
26
+
27
+    <CRow>
28
+      <CCol>
29
+        <AppTable>
30
+          <template #table-head>
31
+            <CTableRow>
32
+              <CTableHeaderCell>Nama</CTableHeaderCell>
33
+              <CTableHeaderCell>Harga</CTableHeaderCell>
34
+              <CTableHeaderCell>Satuan</CTableHeaderCell>
35
+            </CTableRow>
36
+          </template>
37
+          <template #table-body>
38
+            <CTableRow v-for="laundry in laundries.data" :key="laundry.id">
39
+              <CTableDataCell>{{ laundry.name }}</CTableDataCell>
40
+              <CTableDataCell>{{ laundry.price }}</CTableDataCell>
41
+              <CTableDataCell>{{ laundry.unit }}</CTableDataCell>
42
+              <CTableDataCell>
43
+                <AppButtonDetail :href="route('laundries.edit', laundry.id)" />
44
+              </CTableDataCell>
45
+            </CTableRow>
46
+          </template>
47
+        </AppTable>
48
+      </CCol>
49
+    </CRow>
50
+
51
+    <CRow>
52
+      <AppPagination :links="laundries.links" />
53
+    </CRow>
54
+  </DefaultLayout>
55
+</template>

+ 3
- 0
routes/web.php Näytä tiedosto

@@ -1,6 +1,7 @@
1 1
 <?php
2 2
 
3 3
 use App\Http\Controllers\CustomerController;
4
+use App\Http\Controllers\LaundryController;
4 5
 use App\Http\Controllers\OutletController;
5 6
 use App\Http\Controllers\UserController;
6 7
 use Illuminate\Support\Facades\Route;
@@ -27,6 +28,8 @@ Route::middleware(['auth'])->group(function () {
27 28
     Route::resource('/customers', CustomerController::class);
28 29
 
29 30
     Route::resource('/outlets', OutletController::class);
31
+
32
+    Route::resource('/laundries', LaundryController::class);
30 33
 });
31 34
 
32 35
 require __DIR__ . '/auth.php';