From ef4aa564f8555ea255ac5e27b604a801ee239e6f Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Thu, 25 Mar 2021 08:29:07 +0600 Subject: [PATCH 01/12] login page update --- resources/js/pages/auth/Login.vue | 38 ++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/resources/js/pages/auth/Login.vue b/resources/js/pages/auth/Login.vue index 9bbd42f..33811ce 100644 --- a/resources/js/pages/auth/Login.vue +++ b/resources/js/pages/auth/Login.vue @@ -9,14 +9,16 @@ Login
-
+
- + +
- + +
@@ -32,27 +34,41 @@ From 8e002941862ae6b1ddb0bfe13ed20157924c9a0b Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Sun, 28 Mar 2021 19:45:06 +0600 Subject: [PATCH 02/12] user api action add redirect to dashboard after login --- public/js/app.js | 222 +++++++++++++++++++------ resources/js/app.js | 25 ++- resources/js/components/Header.vue | 19 +-- resources/js/pages/auth/Login.vue | 3 + resources/js/pages/dashboard/index.vue | 40 ++++- resources/js/store/index.js | 30 ++++ 6 files changed, 261 insertions(+), 78 deletions(-) diff --git a/public/js/app.js b/public/js/app.js index 246cac7..37a5dd6 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1952,16 +1952,10 @@ __webpack_require__.r(__webpack_exports__); // // /* harmony default export */ __webpack_exports__["default"] = ({ - methods: { - logout: function logout() { - var _this = this; - - axios.post('/logout').then(function (response) { - _this.$toast.success({ - title: 'Success!', - message: 'Logout Successful!' - }); - }); + methods: {}, + computed: { + auth: function auth() { + return this.$store.getters.getAuthenticated; } } }); @@ -2050,6 +2044,10 @@ __webpack_require__.r(__webpack_exports__); var user = response.data; _this2.$store.commit('SET_USER', user); + + _this2.$store.commit('SET_AUTHENTICATED', true); + + localStorage.setItem("auth", true); }); } }, @@ -2318,7 +2316,33 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ + methods: { + logout: function logout() { + var _this = this; + + axios.post('/logout').then(function (response) { + _this.$toast.success({ + title: 'Success!', + message: 'Logout Successful!' + }); + + _this.$router.push({ + name: 'login' + }); + }); + } + }, computed: { user: function user() { return this.$store.getters.getUser; @@ -40834,38 +40858,41 @@ var render = function() { 1 ), _vm._v(" "), - _c( - "li", - { staticClass: "nav-item" }, - [ - _c( - "router-link", - { - staticClass: "nav-link", - attrs: { to: { name: "login" } } - }, - [_vm._v("Login")] + _vm.auth + ? _c( + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "dashboard" } } + }, + [_vm._v("Dashboard")] + ) + ], + 1 ) - ], - 1 - ), + : _vm._e(), _vm._v(" "), - _c("li", { staticClass: "nav-item" }, [ - _c( - "a", - { - staticClass: "nav-link", - attrs: { href: "#" }, - on: { - click: function($event) { - $event.preventDefault() - return _vm.logout($event) - } - } - }, - [_vm._v("Logout")] - ) - ]) + !_vm.auth + ? _c( + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "login" } } + }, + [_vm._v("Login")] + ) + ], + 1 + ) + : _vm._e() ]) ] ) @@ -41483,14 +41510,50 @@ var render = function() { var _vm = this var _h = _vm.$createElement var _c = _vm._self._c || _h - return _c("div", { staticClass: "container" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("\n Dashboard\n ") + return _c("div", { staticClass: "container mt-5" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-4" }, [ + _c("div", { staticClass: "list-group" }, [ + _c( + "a", + { + staticClass: "list-group-item list-group-item-action", + attrs: { href: "#" } + }, + [_vm._v("Demo Link")] + ), + _vm._v(" "), + _c( + "a", + { + staticClass: "list-group-item list-group-item-action", + attrs: { href: "#" }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.logout($event) + } + } + }, + [_vm._v("Logout")] + ) + ]) ]), _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _vm._v("\n Welcome, " + _vm._s(_vm.user.name) + "\n ") + _c("div", { staticClass: "col-8" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("\n Dashboard\n ") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _vm._v( + "\n Welcome, " + + _vm._s(_vm.user.name) + + "\n " + ) + ]) + ]) ]) ]) ]) @@ -58791,12 +58854,25 @@ var toastrConfigs = { vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(cxlt_vue2_toastr__WEBPACK_IMPORTED_MODULE_4___default.a, toastrConfigs); vue__WEBPACK_IMPORTED_MODULE_0___default.a.component(vform__WEBPACK_IMPORTED_MODULE_2__["HasError"].name, vform__WEBPACK_IMPORTED_MODULE_2__["HasError"]); vue__WEBPACK_IMPORTED_MODULE_0___default.a.component(vform__WEBPACK_IMPORTED_MODULE_2__["AlertError"].name, vform__WEBPACK_IMPORTED_MODULE_2__["AlertError"]); -vue__WEBPACK_IMPORTED_MODULE_0___default.a.component('app-header', __webpack_require__(/*! ./components/Header.vue */ "./resources/js/components/Header.vue")["default"]); -var app = new vue__WEBPACK_IMPORTED_MODULE_0___default.a({ - el: '#app', - router: _router_index__WEBPACK_IMPORTED_MODULE_1__["default"], - store: _store_index__WEBPACK_IMPORTED_MODULE_3__["default"] -}); +vue__WEBPACK_IMPORTED_MODULE_0___default.a.component('app-header', __webpack_require__(/*! ./components/Header.vue */ "./resources/js/components/Header.vue")["default"]); // check authentication + +var auth = localStorage.getItem("auth"); + +if (auth) { + _store_index__WEBPACK_IMPORTED_MODULE_3__["default"].dispatch('authUser').then(function () { + var app = new vue__WEBPACK_IMPORTED_MODULE_0___default.a({ + el: '#app', + router: _router_index__WEBPACK_IMPORTED_MODULE_1__["default"], + store: _store_index__WEBPACK_IMPORTED_MODULE_3__["default"] + }); + }); +} else { + var app = new vue__WEBPACK_IMPORTED_MODULE_0___default.a({ + el: '#app', + router: _router_index__WEBPACK_IMPORTED_MODULE_1__["default"], + store: _store_index__WEBPACK_IMPORTED_MODULE_3__["default"] + }); +} /***/ }), @@ -59604,13 +59680,16 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js"); +/* harmony import */ var _router__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../router */ "./resources/js/router/index.js"); + vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vuex__WEBPACK_IMPORTED_MODULE_1__["default"]); var store = new vuex__WEBPACK_IMPORTED_MODULE_1__["default"].Store({ state: { message: 'Welcome, Beautiful People!', - user: {} + user: {}, + authenticated: false }, getters: { getMessage: function getMessage(state) { @@ -59618,11 +59697,48 @@ var store = new vuex__WEBPACK_IMPORTED_MODULE_1__["default"].Store({ }, getUser: function getUser(state) { return state.user; + }, + getAuthenticated: function getAuthenticated(state) { + return state.authenticated; } }, mutations: { SET_USER: function SET_USER(state, data) { state.user = data; + }, + SET_AUTHENTICATED: function SET_AUTHENTICATED(state, data) { + state.authenticated = data; + } + }, + actions: { + authUser: function authUser(_ref) { + var commit = _ref.commit, + dispatch = _ref.dispatch; + return axios.get('/api/user').then(function (response) { + commit('SET_AUTHENTICATED', true); + commit('SET_USER', response.data); + localStorage.setItem("auth", true); + + if (_router__WEBPACK_IMPORTED_MODULE_2__["default"].currentRoute.name !== null) { + _router__WEBPACK_IMPORTED_MODULE_2__["default"].push({ + name: 'dashboard' + }); + } + + ; + })["catch"](function () { + commit('SET_AUTHENTICATED', false); + commit('SET_USER', null); + localStorage.removeItem("auth"); + + if (_router__WEBPACK_IMPORTED_MODULE_2__["default"].currentRoute.name !== 'login') { + _router__WEBPACK_IMPORTED_MODULE_2__["default"].push({ + name: 'login' + }); + } + + ; + }); } } }); diff --git a/resources/js/app.js b/resources/js/app.js index 3cc22ba..0b14b45 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -21,8 +21,23 @@ Vue.component(HasError.name, HasError) Vue.component(AlertError.name, AlertError) Vue.component('app-header', require('./components/Header.vue').default); -const app = new Vue({ - el: '#app', - router: routes, - store, -}); +// check authentication +let auth = localStorage.getItem("auth"); + +if(auth){ + store.dispatch('authUser').then(() => { + const app = new Vue({ + el: '#app', + router: routes, + store, + }); + }); +}else { + const app = new Vue({ + el: '#app', + router: routes, + store, + }); +} + + diff --git a/resources/js/components/Header.vue b/resources/js/components/Header.vue index 4cbf2fe..57e1b7a 100644 --- a/resources/js/components/Header.vue +++ b/resources/js/components/Header.vue @@ -17,11 +17,11 @@ - -
@@ -32,13 +32,10 @@ + + diff --git a/resources/js/router/index.js b/resources/js/router/index.js index 581b816..68f5e29 100644 --- a/resources/js/router/index.js +++ b/resources/js/router/index.js @@ -13,6 +13,7 @@ import EditProduct from '../pages/product/edit.vue' // Dashboard Component import Dashboard from '../pages/dashboard/index.vue' +import UserProfile from '../pages/dashboard/profile.vue' // Authentication File import Login from '../pages/auth/Login.vue' @@ -71,6 +72,14 @@ const routes = new VueRouter({ meta: { requiresAuth: true, } + }, + { + path: '/dashboard/profile', + component: UserProfile, + name: 'user-profile', + meta: { + requiresAuth: true, + } } ] }); From 9a17372177c481455f5895bf328c4064763ae09e Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Sun, 28 Mar 2021 20:46:32 +0600 Subject: [PATCH 06/12] user profile update functionality add --- app/Http/Controllers/AuthController.php | 32 +++ public/js/app.js | 331 ++++++++++++++++------- resources/js/pages/dashboard/profile.vue | 33 ++- routes/api.php | 12 +- 4 files changed, 299 insertions(+), 109 deletions(-) create mode 100644 app/Http/Controllers/AuthController.php diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..5ac84ff --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,32 @@ +user(); + + $this->validate($request, [ + 'name' => 'required', + 'email' => "required|unique:users,email, $user->id", + 'password' => 'sometimes|nullable|min:6|confirmed' + ]); + + $user->update([ + 'name' => $request->name, + 'email' => $request->email, + ]); + + if ($request->has('password')) { + $user->update([ + 'password' => bcrypt($request->password) + ]); + } + + return response()->json($user, 200); + } +} diff --git a/public/js/app.js b/public/js/app.js index 4cbe944..9376cb3 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2420,6 +2420,10 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ data: function data() { @@ -2428,7 +2432,7 @@ __webpack_require__.r(__webpack_exports__); name: '', email: '', password: '', - confirm_password: '' + password_confirmation: '' }) }; }, @@ -2437,10 +2441,29 @@ __webpack_require__.r(__webpack_exports__); var user = this.$store.getters.getUser; this.userProfile.name = user.name; this.userProfile.email = user.email; + }, + updateUserProfile: function updateUserProfile() { + var _this = this; + + this.userProfile.post('/api/user').then(function (response) { + // user update on vuex store + _this.$store.commit('SET_USER', response.data); // toast success notification + + + _this.$toast.success({ + title: 'Success!', + message: 'Profile updated successfully.' + }); + }); } }, created: function created() { this.user(); + }, + computed: { + auth: function auth() { + return this.$store.getters.getUser; + } } }); @@ -41739,117 +41762,227 @@ var render = function() { ]), _vm._v(" "), _c("div", { staticClass: "card-body" }, [ - _c("form", { attrs: { action: "" } }, [ - _c("div", { staticClass: "row" }, [ - _c("div", { staticClass: "col-6" }, [ - _c("div", { staticClass: "form-group" }, [ - _c("label", { attrs: { for: "" } }, [_vm._v("Your Name")]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.userProfile.name, - expression: "userProfile.name" - } + _c( + "form", + { + on: { + submit: function($event) { + $event.preventDefault() + return _vm.updateUserProfile() + } + } + }, + [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-6" }, [ + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Your Name") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.userProfile.name, + expression: "userProfile.name" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.userProfile.errors.has("name") + }, + attrs: { type: "text", placeholder: "Your name" }, + domProps: { value: _vm.userProfile.name }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.userProfile, + "name", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.userProfile, field: "name" } + }) ], - staticClass: "form-control", - attrs: { type: "text", placeholder: "Your name" }, - domProps: { value: _vm.userProfile.name }, - on: { - input: function($event) { - if ($event.target.composing) { - return + 1 + ) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-6" }, [ + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Your Email") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.userProfile.email, + expression: "userProfile.email" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.userProfile.errors.has("email") + }, + attrs: { type: "text", placeholder: "Your email" }, + domProps: { value: _vm.userProfile.email }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.userProfile, + "email", + $event.target.value + ) + } } - _vm.$set(_vm.userProfile, "name", $event.target.value) - } - } - }) - ]) - ]), - _vm._v(" "), - _c("div", { staticClass: "col-6" }, [ - _c("div", { staticClass: "form-group" }, [ - _c("label", { attrs: { for: "" } }, [_vm._v("Your Email")]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.userProfile.email, - expression: "userProfile.email" - } + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.userProfile, field: "email" } + }) ], - staticClass: "form-control", - attrs: { type: "text", placeholder: "Your email" }, - domProps: { value: _vm.userProfile.email }, - on: { - input: function($event) { - if ($event.target.composing) { - return + 1 + ) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-6" }, [ + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Your Password") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.userProfile.password, + expression: "userProfile.password" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.userProfile.errors.has("password") + }, + attrs: { type: "text", placeholder: "Your password" }, + domProps: { value: _vm.userProfile.password }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.userProfile, + "password", + $event.target.value + ) + } } - _vm.$set( - _vm.userProfile, - "email", - $event.target.value - ) - } - } - }) + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.userProfile, field: "password" } + }) + ], + 1 + ) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-6" }, [ + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Confirm Password") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.userProfile.password_confirmation, + expression: "userProfile.password_confirmation" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.userProfile.errors.has( + "password_confirmation" + ) + }, + attrs: { + type: "text", + placeholder: "Confirm password" + }, + domProps: { + value: _vm.userProfile.password_confirmation + }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.userProfile, + "password_confirmation", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { + form: _vm.userProfile, + field: "password_confirmation" + } + }) + ], + 1 + ) ]) ]), _vm._v(" "), - _vm._m(0), - _vm._v(" "), - _vm._m(1) - ]), - _vm._v(" "), - _c( - "button", - { staticClass: "btn btn-success", attrs: { type: "submit" } }, - [_vm._v("Save Profile")] - ) - ]) + _c( + "button", + { staticClass: "btn btn-success", attrs: { type: "submit" } }, + [_vm._v("Save Profile")] + ) + ] + ) ]) ]) ]) ]) ]) } -var staticRenderFns = [ - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "col-6" }, [ - _c("div", { staticClass: "form-group" }, [ - _c("label", { attrs: { for: "" } }, [_vm._v("Your Password")]), - _vm._v(" "), - _c("input", { - staticClass: "form-control", - attrs: { type: "text", placeholder: "Your password" } - }) - ]) - ]) - }, - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "col-6" }, [ - _c("div", { staticClass: "form-group" }, [ - _c("label", { attrs: { for: "" } }, [_vm._v("Confirm Password")]), - _vm._v(" "), - _c("input", { - staticClass: "form-control", - attrs: { type: "text", placeholder: "Confirm password" } - }) - ]) - ]) - } -] +var staticRenderFns = [] render._withStripped = true diff --git a/resources/js/pages/dashboard/profile.vue b/resources/js/pages/dashboard/profile.vue index 7b5dc24..970f284 100644 --- a/resources/js/pages/dashboard/profile.vue +++ b/resources/js/pages/dashboard/profile.vue @@ -14,30 +14,34 @@ User Profile
- +
- + +
- + +
- + +
- + +
@@ -60,7 +64,7 @@ export default { name: '', email: '', password: '', - confirm_password: '', + password_confirmation: '', }), } }, @@ -69,10 +73,27 @@ export default { let user = this.$store.getters.getUser; this.userProfile.name = user.name; this.userProfile.email = user.email; + }, + updateUserProfile(){ + this.userProfile.post('/api/user').then(response => { + + // user update on vuex store + this.$store.commit('SET_USER', response.data); + // toast success notification + this.$toast.success({ + title:'Success!', + message:'Profile updated successfully.' + }); + }); } }, created(){ this.user(); + }, + computed: { + auth() { + return this.$store.getters.getUser; + } } } diff --git a/routes/api.php b/routes/api.php index c145102..cc823d6 100644 --- a/routes/api.php +++ b/routes/api.php @@ -14,9 +14,13 @@ | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); -}); - Route::resource('category', 'CategoryController'); Route::resource('product', 'ProductController'); + +Route::middleware(['auth:sanctum'])->group(function () { + Route::get('/user', function (Request $request) { + return $request->user(); + }); + + Route::post('user', 'AuthController@update_user'); +}); From 2b86d503462e7599f021381702aaa85721eeab6f Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Tue, 13 Apr 2021 19:39:53 +0600 Subject: [PATCH 07/12] password update fix on User Profile Update --- app/Http/Controllers/AuthController.php | 2 +- public/js/app.js | 7 +++++-- resources/js/pages/dashboard/profile.vue | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 5ac84ff..7f68bf1 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -21,7 +21,7 @@ public function update_user(Request $request) 'email' => $request->email, ]); - if ($request->has('password')) { + if ($request->password) { $user->update([ 'password' => bcrypt($request->password) ]); diff --git a/public/js/app.js b/public/js/app.js index 9376cb3..7b7646e 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -41888,7 +41888,10 @@ var render = function() { class: { "is-invalid": _vm.userProfile.errors.has("password") }, - attrs: { type: "text", placeholder: "Your password" }, + attrs: { + type: "password", + placeholder: "Your password" + }, domProps: { value: _vm.userProfile.password }, on: { input: function($event) { @@ -41937,7 +41940,7 @@ var render = function() { ) }, attrs: { - type: "text", + type: "password", placeholder: "Confirm password" }, domProps: { diff --git a/resources/js/pages/dashboard/profile.vue b/resources/js/pages/dashboard/profile.vue index 970f284..f0f3344 100644 --- a/resources/js/pages/dashboard/profile.vue +++ b/resources/js/pages/dashboard/profile.vue @@ -33,14 +33,14 @@
- +
- +
From 86915eaedb005c01fcedc90a523e878a72a79e3d Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Tue, 13 Apr 2021 22:22:30 +0600 Subject: [PATCH 08/12] signup page add --- public/js/app.js | 500 +++++++++++++++++++++++++++++ resources/js/components/Header.vue | 4 + resources/js/pages/auth/Signup.vue | 92 ++++++ resources/js/router/index.js | 9 + 4 files changed, 605 insertions(+) create mode 100644 resources/js/pages/auth/Signup.vue diff --git a/public/js/app.js b/public/js/app.js index 7b7646e..262614f 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1951,6 +1951,10 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ methods: {}, computed: { @@ -2056,6 +2060,153 @@ __webpack_require__.r(__webpack_exports__); /***/ }), +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js&": +/*!*****************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js& ***! + \*****************************************************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js"); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vform */ "./node_modules/vform/dist/vform.common.js"); +/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(vform__WEBPACK_IMPORTED_MODULE_1__); + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + +/* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + signupForm: new vform__WEBPACK_IMPORTED_MODULE_1__["Form"]({ + name: '', + email: '', + password: '', + password_confirmation: '' + }) + }; + }, + methods: { + createUser: function createUser() { + var _this = this; + + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee() { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return axios.get('/sanctum/csrf-cookie'); + + case 2: + _context.next = 4; + return _this.signupForm.post('/register'); + + case 4: + _context.next = 6; + return _this.getUserData(); + + case 6: + _this.$toast.success({ + title: 'Success!', + message: 'Your account has been created!' + }); + + _this.$router.push({ + name: 'dashboard' + }); + + case 8: + case "end": + return _context.stop(); + } + } + }, _callee); + }))(); + }, + getUserData: function getUserData() { + var _this2 = this; + + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee2() { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return axios.get('/api/user').then(function (response) { + var user = response.data; + + _this2.$store.commit('SET_USER', user); + + _this2.$store.commit('SET_AUTHENTICATED', true); + + localStorage.setItem("auth", true); + }); + + case 2: + case "end": + return _context2.stop(); + } + } + }, _callee2); + }))(); + } + }, + mounted: function mounted() {} +}); + +/***/ }), + /***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/category/create.vue?vue&type=script&lang=js&": /*!*********************************************************************************************************************************************************************!*\ !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/pages/category/create.vue?vue&type=script&lang=js& ***! @@ -41009,6 +41160,24 @@ var render = function() { ], 1 ) + : _vm._e(), + _vm._v(" "), + !_vm.auth + ? _c( + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "signup" } } + }, + [_vm._v("Signup")] + ) + ], + 1 + ) : _vm._e() ]) ] @@ -41202,6 +41371,259 @@ render._withStripped = true +/***/ }), + +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26&": +/*!*********************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26& ***! + \*********************************************************************************************************************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; }); +var render = function() { + var _vm = this + var _h = _vm.$createElement + var _c = _vm._self._c || _h + return _c("div", [ + _c("div", { staticClass: "container" }, [ + _c("div", { staticClass: "py-5" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-6 offset-3" }, [ + _c("div", { staticClass: "card card-default" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v( + "\n Sign up\n " + ) + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c( + "form", + { + attrs: { action: "", method: "post" }, + on: { + submit: function($event) { + $event.preventDefault() + return _vm.createUser() + } + } + }, + [ + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [_vm._v("Name")]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.signupForm.name, + expression: "signupForm.name" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.signupForm.errors.has("name") + }, + attrs: { type: "text", placeholder: "name" }, + domProps: { value: _vm.signupForm.name }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.signupForm, + "name", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.signupForm, field: "name" } + }) + ], + 1 + ), + _vm._v(" "), + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [_vm._v("Email")]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.signupForm.email, + expression: "signupForm.email" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.signupForm.errors.has("email") + }, + attrs: { type: "text", placeholder: "email" }, + domProps: { value: _vm.signupForm.email }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.signupForm, + "email", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.signupForm, field: "email" } + }) + ], + 1 + ), + _vm._v(" "), + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Password") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.signupForm.password, + expression: "signupForm.password" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.signupForm.errors.has("password") + }, + attrs: { type: "password", placeholder: "password" }, + domProps: { value: _vm.signupForm.password }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.signupForm, + "password", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.signupForm, field: "password" } + }) + ], + 1 + ), + _vm._v(" "), + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Confirm Password") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.signupForm.password_confirmation, + expression: "signupForm.password_confirmation" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.signupForm.errors.has( + "password_confirmation" + ) + }, + attrs: { + type: "password", + placeholder: "confirm password" + }, + domProps: { + value: _vm.signupForm.password_confirmation + }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.signupForm, + "password_confirmation", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _c("has-error", { + attrs: { + form: _vm.signupForm, + field: "password_confirmation" + } + }) + ], + 1 + ), + _vm._v(" "), + _vm._m(0) + ] + ) + ]) + ]) + ]) + ]) + ]) + ]) + ]) +} +var staticRenderFns = [ + function() { + var _vm = this + var _h = _vm.$createElement + var _c = _vm._self._c || _h + return _c("div", { staticClass: "form-group" }, [ + _c( + "button", + { staticClass: "btn btn-success px-4", attrs: { type: "submit" } }, + [_vm._v("Create an Account")] + ) + ]) + } +] +render._withStripped = true + + + /***/ }), /***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/category/create.vue?vue&type=template&id=e4874358&": @@ -59495,6 +59917,75 @@ __webpack_require__.r(__webpack_exports__); +/***/ }), + +/***/ "./resources/js/pages/auth/Signup.vue": +/*!********************************************!*\ + !*** ./resources/js/pages/auth/Signup.vue ***! + \********************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Signup.vue?vue&type=template&id=41792d26& */ "./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26&"); +/* harmony import */ var _Signup_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Signup.vue?vue&type=script&lang=js& */ "./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js"); + + + + + +/* normalize component */ + +var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])( + _Signup_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"], + _Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__["render"], + _Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"], + false, + null, + null, + null + +) + +/* hot reload */ +if (false) { var api; } +component.options.__file = "resources/js/pages/auth/Signup.vue" +/* harmony default export */ __webpack_exports__["default"] = (component.exports); + +/***/ }), + +/***/ "./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js&": +/*!*********************************************************************!*\ + !*** ./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js& ***! + \*********************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Signup_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib??ref--4-0!../../../../node_modules/vue-loader/lib??vue-loader-options!./Signup.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/auth/Signup.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Signup_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); + +/***/ }), + +/***/ "./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26&": +/*!***************************************************************************!*\ + !*** ./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26& ***! + \***************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../node_modules/vue-loader/lib??vue-loader-options!./Signup.vue?vue&type=template&id=41792d26& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/auth/Signup.vue?vue&type=template&id=41792d26&"); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__["render"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_Signup_vue_vue_type_template_id_41792d26___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; }); + + + /***/ }), /***/ "./resources/js/pages/category/create.vue": @@ -60140,6 +60631,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../pages/dashboard/index.vue */ "./resources/js/pages/dashboard/index.vue"); /* harmony import */ var _pages_dashboard_profile_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../pages/dashboard/profile.vue */ "./resources/js/pages/dashboard/profile.vue"); /* harmony import */ var _pages_auth_Login_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../pages/auth/Login.vue */ "./resources/js/pages/auth/Login.vue"); +/* harmony import */ var _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../pages/auth/Signup.vue */ "./resources/js/pages/auth/Signup.vue"); vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vue_router__WEBPACK_IMPORTED_MODULE_1__["default"]); @@ -60155,6 +60647,7 @@ vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vue_router__WEBPACK_IMPORTED_MODU // Authentication File + var routes = new vue_router__WEBPACK_IMPORTED_MODULE_1__["default"]({ mode: 'history', linkExactActiveClass: 'active', @@ -60193,6 +60686,13 @@ var routes = new vue_router__WEBPACK_IMPORTED_MODULE_1__["default"]({ meta: { requiresVisitor: true } + }, { + path: '/auth/signup', + component: _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_12__["default"], + name: 'signup', + meta: { + requiresVisitor: true + } }, { path: '/dashboard', component: _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_9__["default"], diff --git a/resources/js/components/Header.vue b/resources/js/components/Header.vue index 57e1b7a..7134c84 100644 --- a/resources/js/components/Header.vue +++ b/resources/js/components/Header.vue @@ -23,6 +23,10 @@ + +
diff --git a/resources/js/pages/auth/Signup.vue b/resources/js/pages/auth/Signup.vue new file mode 100644 index 0000000..61404fd --- /dev/null +++ b/resources/js/pages/auth/Signup.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/resources/js/router/index.js b/resources/js/router/index.js index 68f5e29..64ea54e 100644 --- a/resources/js/router/index.js +++ b/resources/js/router/index.js @@ -17,6 +17,7 @@ import UserProfile from '../pages/dashboard/profile.vue' // Authentication File import Login from '../pages/auth/Login.vue' +import Signup from '../pages/auth/Signup.vue' const routes = new VueRouter({ mode: 'history', @@ -65,6 +66,14 @@ const routes = new VueRouter({ requiresVisitor: true, } }, + { + path: '/auth/signup', + component: Signup, + name: 'signup', + meta: { + requiresVisitor: true, + } + }, { path: '/dashboard', component: Dashboard, From 329f82094f30a882f372878f54658cf1091d0b92 Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Tue, 13 Apr 2021 23:13:48 +0600 Subject: [PATCH 09/12] project organize and bug fix --- app/Http/Controllers/APIController.php | 16 + app/Http/Controllers/PublicAPIController.php | 16 + public/js/app.js | 359 ++++++++++++------- resources/js/components/Header.vue | 11 +- resources/js/pages/auth/Login.vue | 26 +- resources/js/pages/auth/Signup.vue | 2 +- resources/js/pages/home.vue | 32 +- routes/api.php | 7 +- 8 files changed, 310 insertions(+), 159 deletions(-) create mode 100644 app/Http/Controllers/APIController.php create mode 100644 app/Http/Controllers/PublicAPIController.php diff --git a/app/Http/Controllers/APIController.php b/app/Http/Controllers/APIController.php new file mode 100644 index 0000000..6ba2ae8 --- /dev/null +++ b/app/Http/Controllers/APIController.php @@ -0,0 +1,16 @@ +paginate(12); + + return response()->json($products, 200); + } +} diff --git a/app/Http/Controllers/PublicAPIController.php b/app/Http/Controllers/PublicAPIController.php new file mode 100644 index 0000000..9bc6213 --- /dev/null +++ b/app/Http/Controllers/PublicAPIController.php @@ -0,0 +1,16 @@ +paginate(16); + + return response()->json($products, 200); + } +} diff --git a/public/js/app.js b/public/js/app.js index 262614f..f7c7155 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1955,6 +1955,7 @@ __webpack_require__.r(__webpack_exports__); // // // +// /* harmony default export */ __webpack_exports__["default"] = ({ methods: {}, computed: { @@ -1975,8 +1976,16 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vform */ "./node_modules/vform/dist/vform.common.js"); -/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vform__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js"); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vform */ "./node_modules/vform/dist/vform.common.js"); +/* harmony import */ var vform__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(vform__WEBPACK_IMPORTED_MODULE_1__); + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + // // // @@ -2016,7 +2025,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = ({ data: function data() { return { - loginForm: new vform__WEBPACK_IMPORTED_MODULE_0__["Form"]({ + loginForm: new vform__WEBPACK_IMPORTED_MODULE_1__["Form"]({ email: 'web.zakirbd@gmail.com', password: 'password' }) @@ -2026,33 +2035,66 @@ __webpack_require__.r(__webpack_exports__); login: function login() { var _this = this; - axios.get('/sanctum/csrf-cookie').then(function (response) { - _this.loginForm.post('/login').then(function (response) { - _this.getUserData(); + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee() { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return axios.get('/sanctum/csrf-cookie'); - _this.$toast.success({ - title: 'Success!', - message: 'Welcome, Dear!' - }); + case 2: + _context.next = 4; + return _this.loginForm.post('/login'); - _this.$router.push({ - name: 'dashboard' - }); - }); - }); + case 4: + _context.next = 6; + return _this.getUserData(); + + case 6: + _this.$toast.success({ + title: 'Success!', + message: 'Welcome, Dear!' + }); + + _this.$router.push({ + name: 'dashboard' + }); + + case 8: + case "end": + return _context.stop(); + } + } + }, _callee); + }))(); }, getUserData: function getUserData() { var _this2 = this; - axios.get('/api/user').then(function (response) { - var user = response.data; + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee2() { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return axios.get('/api/user').then(function (response) { + var user = response.data; - _this2.$store.commit('SET_USER', user); + _this2.$store.commit('SET_USER', user); - _this2.$store.commit('SET_AUTHENTICATED', true); + _this2.$store.commit('SET_AUTHENTICATED', true); - localStorage.setItem("auth", true); - }); + localStorage.setItem("auth", true); + }); + + case 2: + case "end": + return _context2.stop(); + } + } + }, _callee2); + }))(); } }, mounted: function mounted() {} @@ -2629,6 +2671,20 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js"); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__); + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +// +// +// +// +// +// // // // @@ -2646,8 +2702,41 @@ __webpack_require__.r(__webpack_exports__); // // /* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + products: [] + }; + }, + methods: { + loadProducts: function loadProducts() { + var _this = this; + + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee() { + var _yield$axios$get, data; + + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return axios.get('/api/products'); + + case 2: + _yield$axios$get = _context.sent; + data = _yield$axios$get.data; + _this.products = data.data; + + case 5: + case "end": + return _context.stop(); + } + } + }, _callee); + }))(); + } + }, mounted: function mounted() { - console.log('Component mounted.'); + this.loadProducts(); } }); @@ -41077,57 +41166,57 @@ var render = function() { attrs: { id: "navbarSupportedContent" } }, [ - _c("ul", { staticClass: "navbar-nav ml-auto" }, [ - _c( - "li", - { staticClass: "nav-item" }, - [ + _vm.auth + ? _c("ul", { staticClass: "navbar-nav ml-auto" }, [ _c( - "router-link", - { - staticClass: "nav-link", - attrs: { to: { name: "home" } } - }, - [_vm._v("Home")] - ) - ], - 1 - ), - _vm._v(" "), - _c( - "li", - { staticClass: "nav-item" }, - [ + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "home" } } + }, + [_vm._v("Home")] + ) + ], + 1 + ), + _vm._v(" "), _c( - "router-link", - { - staticClass: "nav-link", - attrs: { to: { name: "category-list" } } - }, - [_vm._v("Product Category")] - ) - ], - 1 - ), - _vm._v(" "), - _c( - "li", - { staticClass: "nav-item" }, - [ + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "category-list" } } + }, + [_vm._v("Product Category")] + ) + ], + 1 + ), + _vm._v(" "), + _c( + "li", + { staticClass: "nav-item" }, + [ + _c( + "router-link", + { + staticClass: "nav-link", + attrs: { to: { name: "product-list" } } + }, + [_vm._v("Product List")] + ) + ], + 1 + ), + _vm._v(" "), _c( - "router-link", - { - staticClass: "nav-link", - attrs: { to: { name: "product-list" } } - }, - [_vm._v("Product List")] - ) - ], - 1 - ), - _vm._v(" "), - _vm.auth - ? _c( "li", { staticClass: "nav-item" }, [ @@ -41142,10 +41231,9 @@ var render = function() { ], 1 ) - : _vm._e(), - _vm._v(" "), - !_vm.auth - ? _c( + ]) + : _c("ul", { staticClass: "navbar-nav ml-auto" }, [ + _c( "li", { staticClass: "nav-item" }, [ @@ -41159,11 +41247,9 @@ var render = function() { ) ], 1 - ) - : _vm._e(), - _vm._v(" "), - !_vm.auth - ? _c( + ), + _vm._v(" "), + _c( "li", { staticClass: "nav-item" }, [ @@ -41178,8 +41264,7 @@ var render = function() { ], 1 ) - : _vm._e() - ]) + ]) ] ) ], @@ -41342,7 +41427,19 @@ var render = function() { 1 ), _vm._v(" "), - _vm._m(0) + _c("div", { staticClass: "form-group" }, [ + _c( + "button", + { + staticClass: "btn btn-success px-4", + attrs: { + type: "submit", + disabled: _vm.loginForm.busy + } + }, + [_vm._v("Login")] + ) + ]) ] ) ]) @@ -41353,20 +41450,7 @@ var render = function() { ]) ]) } -var staticRenderFns = [ - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "form-group" }, [ - _c( - "button", - { staticClass: "btn btn-success px-4", attrs: { type: "submit" } }, - [_vm._v("Login")] - ) - ]) - } -] +var staticRenderFns = [] render._withStripped = true @@ -41595,7 +41679,19 @@ var render = function() { 1 ), _vm._v(" "), - _vm._m(0) + _c("div", { staticClass: "form-group" }, [ + _c( + "button", + { + staticClass: "btn btn-success px-4", + attrs: { + type: "submit", + disabled: _vm.signupForm.busy + } + }, + [_vm._v("Create an Account")] + ) + ]) ] ) ]) @@ -41606,20 +41702,7 @@ var render = function() { ]) ]) } -var staticRenderFns = [ - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "form-group" }, [ - _c( - "button", - { staticClass: "btn btn-success px-4", attrs: { type: "submit" } }, - [_vm._v("Create an Account")] - ) - ]) - } -] +var staticRenderFns = [] render._withStripped = true @@ -42429,32 +42512,48 @@ var render = function() { var _vm = this var _h = _vm.$createElement var _c = _vm._self._c || _h - return _vm._m(0) -} -var staticRenderFns = [ - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "container" }, [ - _c("div", { staticClass: "row justify-content-center" }, [ - _c("div", { staticClass: "col-md-8" }, [ + return _c("div", { staticClass: "container" }, [ + _c( + "div", + { staticClass: "row" }, + _vm._l(_vm.products, function(product) { + return _c("div", { key: product.id, staticClass: "col-3" }, [ _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Home Component") - ]), + _c("img", { + staticClass: "card-img-top", + staticStyle: { + height: "150px", + "object-fit": "cover", + overflow: "hidden" + }, + attrs: { src: product.image, alt: "..." } + }), _vm._v(" "), _c("div", { staticClass: "card-body" }, [ - _vm._v( - "\n I'm an Home component.\n " + _c("h5", { staticClass: "card-title" }, [ + _vm._v( + "\n " + + _vm._s(product.title) + + "\n " + ) + ]), + _vm._v(" "), + _c( + "a", + { staticClass: "btn btn-primary", attrs: { href: "#" } }, + [_vm._v("Go somewhere")] ) ]) ]) ]) - ]) - ]) - } -] + }), + 0 + ), + _vm._v(" "), + _c("pre", [_vm._v(" " + _vm._s(_vm.products) + "\n ")]) + ]) +} +var staticRenderFns = [] render._withStripped = true diff --git a/resources/js/components/Header.vue b/resources/js/components/Header.vue index 7134c84..a56b2af 100644 --- a/resources/js/components/Header.vue +++ b/resources/js/components/Header.vue @@ -7,7 +7,7 @@
- +
@@ -46,22 +46,20 @@ export default { } }, methods: { - login(){ - axios.get('/sanctum/csrf-cookie').then(response => { - this.loginForm.post('/login').then(response => { - this.getUserData(); + async login(){ + await axios.get('/sanctum/csrf-cookie') + await this.loginForm.post('/login') + await this.getUserData(); - this.$toast.success({ - title:'Success!', - message:'Welcome, Dear!' - }); - - this.$router.push({ name: 'dashboard' }); - }); + this.$toast.success({ + title:'Success!', + message:'Welcome, Dear!' }); + + this.$router.push({ name: 'dashboard' }); }, - getUserData(){ - axios.get('/api/user').then(response => { + async getUserData(){ + await axios.get('/api/user').then(response => { let user = response.data; this.$store.commit('SET_USER', user); this.$store.commit('SET_AUTHENTICATED', true); diff --git a/resources/js/pages/auth/Signup.vue b/resources/js/pages/auth/Signup.vue index 61404fd..b8c4787 100644 --- a/resources/js/pages/auth/Signup.vue +++ b/resources/js/pages/auth/Signup.vue @@ -31,7 +31,7 @@
- +
diff --git a/resources/js/pages/home.vue b/resources/js/pages/home.vue index cb6d5f9..1594683 100644 --- a/resources/js/pages/home.vue +++ b/resources/js/pages/home.vue @@ -1,23 +1,41 @@ diff --git a/routes/api.php b/routes/api.php index cc823d6..e5efbc3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -14,8 +14,6 @@ | */ -Route::resource('category', 'CategoryController'); -Route::resource('product', 'ProductController'); Route::middleware(['auth:sanctum'])->group(function () { Route::get('/user', function (Request $request) { @@ -23,4 +21,9 @@ }); Route::post('user', 'AuthController@update_user'); + Route::resource('category', 'CategoryController'); + Route::resource('product', 'ProductController'); }); + + +Route::get('products', 'PublicAPIController@products'); From ed5c478c40fd3588f68df61948b942b4f673b092 Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Tue, 13 Apr 2021 23:43:02 +0600 Subject: [PATCH 10/12] product factory created and products showing on homepage --- database/factories/ProductFactory.php | 22 +++++ public/js/app.js | 134 ++++++++++++++++++-------- resources/js/pages/home.vue | 30 ++++-- 3 files changed, 139 insertions(+), 47 deletions(-) create mode 100644 database/factories/ProductFactory.php diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php new file mode 100644 index 0000000..be76ccc --- /dev/null +++ b/database/factories/ProductFactory.php @@ -0,0 +1,22 @@ +define(Product::class, function (Faker $faker) { + $title = $this->faker->sentence(8); + $slug = Str::slug($title); + $number = 32; + + return [ + 'title' => $title, + 'slug' => $slug, + 'price' => rand(100, 300), + 'image' => 'https://placeimg.com/640/480/' . $number, + 'description' => $this->faker->text(300), + ]; +}); diff --git a/public/js/app.js b/public/js/app.js index f7c7155..15917b4 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2704,7 +2704,9 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar /* harmony default export */ __webpack_exports__["default"] = ({ data: function data() { return { - products: [] + products: [], + next_page_url: null, + apiCallLoaded: false }; }, methods: { @@ -2725,14 +2727,47 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar _yield$axios$get = _context.sent; data = _yield$axios$get.data; _this.products = data.data; + _this.next_page_url = data.next_page_url; + _this.apiCallLoaded = true; - case 5: + case 7: case "end": return _context.stop(); } } }, _callee); }))(); + }, + loadMoreProducts: function loadMoreProducts(url) { + var _this2 = this; + + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee2() { + var _yield$axios$get2, data, products; + + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return axios.get(url); + + case 2: + _yield$axios$get2 = _context2.sent; + data = _yield$axios$get2.data; + products = data.data; + products.forEach(function (element) { + _this2.products.push(element); + }); // this.products.concat(); + + _this2.next_page_url = data.next_page_url; + + case 7: + case "end": + return _context2.stop(); + } + } + }, _callee2); + }))(); } }, mounted: function mounted() { @@ -42512,45 +42547,66 @@ var render = function() { var _vm = this var _h = _vm.$createElement var _c = _vm._self._c || _h - return _c("div", { staticClass: "container" }, [ - _c( - "div", - { staticClass: "row" }, - _vm._l(_vm.products, function(product) { - return _c("div", { key: product.id, staticClass: "col-3" }, [ - _c("div", { staticClass: "card" }, [ - _c("img", { - staticClass: "card-img-top", - staticStyle: { - height: "150px", - "object-fit": "cover", - overflow: "hidden" - }, - attrs: { src: product.image, alt: "..." } - }), - _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _c("h5", { staticClass: "card-title" }, [ - _vm._v( - "\n " + - _vm._s(product.title) + - "\n " - ) - ]), - _vm._v(" "), - _c( - "a", - { staticClass: "btn btn-primary", attrs: { href: "#" } }, - [_vm._v("Go somewhere")] - ) + return _c("div", { staticClass: "container py-5" }, [ + _c("h2", [_vm._v("Our Products")]), + _vm._v(" "), + _vm.apiCallLoaded + ? _c( + "div", + { staticClass: "row" }, + _vm._l(_vm.products, function(product) { + return _c("div", { key: product.id, staticClass: "col-3 mb-3" }, [ + _c("div", { staticClass: "card" }, [ + _c("img", { + staticClass: "card-img-top", + staticStyle: { + height: "150px", + "object-fit": "cover", + overflow: "hidden" + }, + attrs: { src: product.image, alt: "..." } + }), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("h5", { staticClass: "card-title" }, [ + _vm._v( + "\n " + + _vm._s(product.title) + + "\n " + ) + ]), + _vm._v(" "), + _c( + "a", + { staticClass: "btn btn-primary", attrs: { href: "#" } }, + [_vm._v("Go somewhere")] + ) + ]) + ]) ]) - ]) - ]) - }), - 0 - ), + }), + 0 + ) + : _vm._e(), _vm._v(" "), - _c("pre", [_vm._v(" " + _vm._s(_vm.products) + "\n ")]) + _vm.apiCallLoaded + ? _c("div", { staticClass: "text-center mt-5" }, [ + _c( + "button", + { + staticClass: "btn btn-primary", + attrs: { disabled: !_vm.next_page_url }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.loadMoreProducts(_vm.next_page_url) + } + } + }, + [_vm._v("Load More Products")] + ) + ]) + : _vm._e() ]) } var staticRenderFns = [] diff --git a/resources/js/pages/home.vue b/resources/js/pages/home.vue index 1594683..c0fc641 100644 --- a/resources/js/pages/home.vue +++ b/resources/js/pages/home.vue @@ -1,22 +1,22 @@ @@ -25,6 +25,8 @@ data() { return { products: [], + next_page_url: null, + apiCallLoaded: false, } }, methods: { @@ -32,7 +34,19 @@ let { data } = await axios.get('/api/products'); this.products = data.data; - } + this.next_page_url = data.next_page_url; + this.apiCallLoaded = true; + }, + async loadMoreProducts(url){ + let { data } = await axios.get(url); + + let products = data.data; + products.forEach(element => { + this.products.push(element); + }); + // this.products.concat(); + this.next_page_url = data.next_page_url; + }, }, mounted(){ this.loadProducts(); From 06d018bc4ada813defd8284c13a29639efa05620 Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Wed, 21 Apr 2021 22:14:52 +0600 Subject: [PATCH 11/12] category_id column added to products table category relation to product model category id added when creating and editing a product --- app/Http/Controllers/ProductController.php | 28 ++- app/Product.php | 5 + ...020_07_28_033734_create_products_table.php | 2 + public/js/app.js | 215 +++++++++++++++++- resources/js/pages/product/create.vue | 21 +- resources/js/pages/product/edit.vue | 18 ++ resources/js/pages/product/index.vue | 7 +- 7 files changed, 277 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index f4e0e0b..21cb0d7 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -15,7 +15,7 @@ class ProductController extends Controller */ public function index() { - $products = Product::latest()->get(); + $products = Product::with('category')->latest()->get(); return response()->json($products, 200); } @@ -42,7 +42,8 @@ public function store(Request $request) 'title' => 'required|max:255|unique:products,title', 'price' => 'required|integer', 'image' => 'required|image|max:2048', - 'description' => 'required' + 'description' => 'required', + 'category_id' => 'required', ]); $product = Product::create([ @@ -50,10 +51,11 @@ public function store(Request $request) 'slug' => Str::slug($request->title), 'price' => $request->price, 'description' => $request->description, + 'category_id' => $request->category_id, ]); - if($request->image){ - $imageName = time().'_'. uniqid() .'.'.$request->image->getClientOriginalExtension(); + if ($request->image) { + $imageName = time() . '_' . uniqid() . '.' . $request->image->getClientOriginalExtension(); $request->image->move(public_path('storage/product'), $imageName); $product->image = '/storage/product/' . $imageName; $product->save(); @@ -92,12 +94,13 @@ public function edit(Product $product) * @return \Illuminate\Http\Response */ public function update(Request $request, Product $product) - { + { $this->validate($request, [ 'title' => "required|max:255|unique:products,title, $product->id", 'price' => 'required|integer', 'image' => 'sometimes|nullable|image|max:2048', - 'description' => 'required' + 'description' => 'required', + 'category_id' => 'required', ]); $product->update([ @@ -105,10 +108,11 @@ public function update(Request $request, Product $product) 'slug' => Str::slug($request->title), 'price' => $request->price, 'description' => $request->description, + 'category_id' => $request->category_id, ]); - if($request->image){ - $imageName = time().'_'. uniqid() .'.'.$request->image->getClientOriginalExtension(); + if ($request->image) { + $imageName = time() . '_' . uniqid() . '.' . $request->image->getClientOriginalExtension(); $request->image->move(public_path('storage/product'), $imageName); $product->image = '/storage/product/' . $imageName; $product->save(); @@ -125,16 +129,16 @@ public function update(Request $request, Product $product) */ public function destroy(Product $product) { - if($product){ + if ($product) { $productImage = $product->image; $imagePath = public_path($productImage); - - if($productImage && file_exists($imagePath)){ + + if ($productImage && file_exists($imagePath)) { unlink($imagePath); } $product->delete(); - }else { + } else { return response()->json('Product not found.', 404); } } diff --git a/app/Product.php b/app/Product.php index 7e9f303..e6706b4 100644 --- a/app/Product.php +++ b/app/Product.php @@ -7,4 +7,9 @@ class Product extends Model { protected $guarded = []; + + public function category() + { + return $this->belongsTo(Category::class); + } } diff --git a/database/migrations/2020_07_28_033734_create_products_table.php b/database/migrations/2020_07_28_033734_create_products_table.php index 39bdf89..6f29e34 100644 --- a/database/migrations/2020_07_28_033734_create_products_table.php +++ b/database/migrations/2020_07_28_033734_create_products_table.php @@ -20,7 +20,9 @@ public function up() $table->integer('price'); $table->string('image')->nullable(); $table->text('description')->nullable(); + $table->unsignedBigInteger('category_id'); $table->timestamps(); + $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade'); }); } diff --git a/public/js/app.js b/public/js/app.js index 15917b4..12be9ff 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2835,6 +2835,15 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ @@ -2843,9 +2852,11 @@ __webpack_require__.r(__webpack_exports__); productForm: new vform__WEBPACK_IMPORTED_MODULE_0__["Form"]({ title: '', price: '', + category_id: '', image: '', description: '' - }) + }), + categories: [] }; }, methods: { @@ -2877,7 +2888,17 @@ __webpack_require__.r(__webpack_exports__); var file = e.target.files[0]; // Do some client side validation... this.productForm.image = file; + }, + loadCategories: function loadCategories() { + var _this2 = this; + + axios.get('/api/category').then(function (response) { + _this2.categories = response.data; + }); } + }, + mounted: function mounted() { + this.loadCategories(); } }); @@ -2950,6 +2971,15 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ @@ -2962,7 +2992,8 @@ __webpack_require__.r(__webpack_exports__); description: '', _method: 'put' }), - image: '' + image: '', + categories: [] }; }, methods: { @@ -2975,6 +3006,7 @@ __webpack_require__.r(__webpack_exports__); _this.productForm.title = product.title; _this.productForm.price = product.price; _this.productForm.description = product.description; + _this.productForm.category_id = product.category_id; _this.image = product.image; }); }, @@ -3004,10 +3036,18 @@ __webpack_require__.r(__webpack_exports__); var file = e.target.files[0]; // Do some client side validation... this.productForm.image = file; + }, + loadCategories: function loadCategories() { + var _this3 = this; + + axios.get('/api/category').then(function (response) { + _this3.categories = response.data; + }); } }, mounted: function mounted() { this.loadProductData(); + this.loadCategories(); } }); @@ -3082,6 +3122,9 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar // // // +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ data: function data() { return { @@ -42718,6 +42761,83 @@ var render = function() { 1 ), _vm._v(" "), + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Select Product Category") + ]), + _vm._v(" "), + _c( + "select", + { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.productForm.category_id, + expression: "productForm.category_id" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.productForm.errors.has( + "category_id" + ) + }, + attrs: { name: "category_id" }, + on: { + change: function($event) { + var $$selectedVal = Array.prototype.filter + .call($event.target.options, function(o) { + return o.selected + }) + .map(function(o) { + var val = "_value" in o ? o._value : o.value + return val + }) + _vm.$set( + _vm.productForm, + "category_id", + $event.target.multiple + ? $$selectedVal + : $$selectedVal[0] + ) + } + } + }, + [ + _c( + "option", + { + staticStyle: { display: "none" }, + attrs: { value: "", selected: "" } + }, + [_vm._v("Select Category")] + ), + _vm._v(" "), + _vm._l(_vm.categories, function(category) { + return _c( + "option", + { + key: category.id, + domProps: { value: category.id } + }, + [_vm._v(" " + _vm._s(category.name))] + ) + }) + ], + 2 + ), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.productForm, field: "category_id" } + }) + ], + 1 + ), + _vm._v(" "), _c( "div", { staticClass: "form-group" }, @@ -42975,6 +43095,83 @@ var render = function() { 1 ), _vm._v(" "), + _c( + "div", + { staticClass: "form-group" }, + [ + _c("label", { attrs: { for: "" } }, [ + _vm._v("Select Product Category") + ]), + _vm._v(" "), + _c( + "select", + { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.productForm.category_id, + expression: "productForm.category_id" + } + ], + staticClass: "form-control", + class: { + "is-invalid": _vm.productForm.errors.has( + "category_id" + ) + }, + attrs: { name: "category_id" }, + on: { + change: function($event) { + var $$selectedVal = Array.prototype.filter + .call($event.target.options, function(o) { + return o.selected + }) + .map(function(o) { + var val = "_value" in o ? o._value : o.value + return val + }) + _vm.$set( + _vm.productForm, + "category_id", + $event.target.multiple + ? $$selectedVal + : $$selectedVal[0] + ) + } + } + }, + [ + _c( + "option", + { + staticStyle: { display: "none" }, + attrs: { value: "", selected: "" } + }, + [_vm._v("Select Category")] + ), + _vm._v(" "), + _vm._l(_vm.categories, function(category) { + return _c( + "option", + { + key: category.id, + domProps: { value: category.id } + }, + [_vm._v(" " + _vm._s(category.name))] + ) + }) + ], + 2 + ), + _vm._v(" "), + _c("has-error", { + attrs: { form: _vm.productForm, field: "category_id" } + }) + ], + 1 + ), + _vm._v(" "), _c( "div", { staticClass: "form-group" }, @@ -43227,7 +43424,17 @@ var render = function() { _vm._v(" "), _c("td", [_vm._v(" " + _vm._s(product.title) + " ")]), _vm._v(" "), - _c("td", [_vm._v(" " + _vm._s(product.slug) + " ")]), + _c("td", [ + product.category + ? _c("span", [ + _vm._v( + " " + _vm._s(product.category.name) + " " + ) + ]) + : _c("span", [ + _vm._v(" " + _vm._s(product.category_id) + " ") + ]) + ]), _vm._v(" "), _c( "td", @@ -43289,7 +43496,7 @@ var staticRenderFns = [ _vm._v(" "), _c("th", [_vm._v(" Title ")]), _vm._v(" "), - _c("th", [_vm._v(" Slug ")]), + _c("th", [_vm._v(" Category ")]), _vm._v(" "), _c("th", { staticStyle: { width: "170px" } }, [_vm._v(" Action ")]) ]) diff --git a/resources/js/pages/product/create.vue b/resources/js/pages/product/create.vue index d72516f..87eb623 100644 --- a/resources/js/pages/product/create.vue +++ b/resources/js/pages/product/create.vue @@ -16,6 +16,15 @@ +
+ + + +
@@ -54,9 +63,11 @@ export default { productForm: new Form({ title: '', price: '', + category_id: '', image: '', description: '', }), + categories: [], } }, methods: { @@ -85,11 +96,19 @@ export default { const file = e.target.files[0] // Do some client side validation... this.productForm.image = file + }, + loadCategories(){ + axios.get('/api/category').then(response => { + this.categories = response.data; + }); } + }, + mounted(){ + this.loadCategories(); } } \ No newline at end of file + diff --git a/resources/js/pages/product/edit.vue b/resources/js/pages/product/edit.vue index fe4a2cf..26f81e8 100644 --- a/resources/js/pages/product/edit.vue +++ b/resources/js/pages/product/edit.vue @@ -16,6 +16,15 @@
+
+ + + +
@@ -68,6 +77,7 @@ export default { _method: 'put', }), image: '', + categories: [], } }, methods: { @@ -80,6 +90,7 @@ export default { this.productForm.title = product.title; this.productForm.price = product.price; this.productForm.description = product.description; + this.productForm.category_id = product.category_id; this.image = product.image; }); }, @@ -107,10 +118,17 @@ export default { const file = e.target.files[0] // Do some client side validation... this.productForm.image = file + }, + + loadCategories(){ + axios.get('/api/category').then(response => { + this.categories = response.data; + }); } }, mounted(){ this.loadProductData(); + this.loadCategories(); } } diff --git a/resources/js/pages/product/index.vue b/resources/js/pages/product/index.vue index 4a36172..4553369 100644 --- a/resources/js/pages/product/index.vue +++ b/resources/js/pages/product/index.vue @@ -15,7 +15,7 @@ Id Image Title - Slug + Category Action @@ -28,7 +28,10 @@
{{ product.title }} - {{ product.slug }} + + {{ product.category.name }} + {{ product.category_id }} + Edit Delete From e36bc117e83ff0b04924bd391f30c65be427362b Mon Sep 17 00:00:00 2001 From: Zakir Hossen Date: Thu, 22 Apr 2021 11:09:31 +0600 Subject: [PATCH 12/12] Product details page added --- app/Http/Controllers/PublicAPIController.php | 13 +- public/js/app.js | 346 +++++++++++++++++-- resources/js/pages/home.vue | 6 +- resources/js/pages/productDetails.vue | 54 +++ resources/js/router/index.js | 6 + routes/api.php | 1 + 6 files changed, 390 insertions(+), 36 deletions(-) create mode 100644 resources/js/pages/productDetails.vue diff --git a/app/Http/Controllers/PublicAPIController.php b/app/Http/Controllers/PublicAPIController.php index 9bc6213..9c9f404 100644 --- a/app/Http/Controllers/PublicAPIController.php +++ b/app/Http/Controllers/PublicAPIController.php @@ -9,8 +9,19 @@ class PublicAPIController extends Controller { public function products() { - $products = Product::latest()->paginate(16); + $products = Product::with('category')->latest()->paginate(16); return response()->json($products, 200); } + + public function product_details($slug) + { + $product = Product::with('category')->where('slug', $slug)->first(); + + if ($product) { + return response()->json($product, 200); + } else { + return response()->json('not found', 404); + } + } } diff --git a/public/js/app.js b/public/js/app.js index 12be9ff..34470af 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2701,6 +2701,10 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar // // // +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ data: function data() { return { @@ -3177,6 +3181,99 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar /***/ }), +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/productDetails.vue?vue&type=script&lang=js&": +/*!********************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/pages/productDetails.vue?vue&type=script&lang=js& ***! + \********************************************************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js"); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__); + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +/* harmony default export */ __webpack_exports__["default"] = ({ + data: function data() { + return { + product: [], + apiCallLoaded: false + }; + }, + methods: { + loadProductData: function loadProductData() { + var _this = this; + + return _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee() { + var slug, _yield$axios$get, data; + + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + slug = _this.$route.params.slug; + _context.next = 3; + return axios.get('/api/products/' + slug); + + case 3: + _yield$axios$get = _context.sent; + data = _yield$axios$get.data; + _this.product = data; + + case 6: + case "end": + return _context.stop(); + } + } + }, _callee); + }))(); + } + }, + mounted: function mounted() { + this.loadProductData(); + } +}); + +/***/ }), + /***/ "./node_modules/bootstrap/dist/js/bootstrap.js": /*!*****************************************************!*\ !*** ./node_modules/bootstrap/dist/js/bootstrap.js ***! @@ -42610,21 +42707,48 @@ var render = function() { attrs: { src: product.image, alt: "..." } }), _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _c("h5", { staticClass: "card-title" }, [ - _vm._v( - "\n " + - _vm._s(product.title) + - "\n " + _c( + "div", + { staticClass: "card-body" }, + [ + _c( + "div", + { staticClass: "mb-2 d-flex justify-content-between" }, + [ + _c( + "label", + { staticClass: "badge badge-danger mb-3" }, + [_vm._v(" " + _vm._s(product.category.name) + " ")] + ), + _vm._v(" "), + _c("h4", [_vm._v("$" + _vm._s(product.price))]) + ] + ), + _vm._v(" "), + _c("h5", { staticClass: "card-title" }, [ + _vm._v( + "\n " + + _vm._s(product.title) + + "\n " + ) + ]), + _vm._v(" "), + _c( + "router-link", + { + staticClass: "btn btn-primary", + attrs: { + to: { + name: "product-details", + params: { slug: product.slug } + } + } + }, + [_vm._v("View Product")] ) - ]), - _vm._v(" "), - _c( - "a", - { staticClass: "btn btn-primary", attrs: { href: "#" } }, - [_vm._v("Go somewhere")] - ) - ]) + ], + 1 + ) ]) ]) }), @@ -43519,6 +43643,85 @@ render._withStripped = true +/***/ }), + +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c&": +/*!************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c& ***! + \************************************************************************************************************************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; }); +var render = function() { + var _vm = this + var _h = _vm.$createElement + var _c = _vm._self._c || _h + return _c("div", { staticClass: "container py-5" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-8" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _c("h2", [_vm._v(" " + _vm._s(_vm.product.title) + " ")]) + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", [ + _c("img", { + staticClass: "img-fluid", + attrs: { src: _vm.product.image, alt: "" } + }) + ]), + _vm._v(" "), + _c("div", { staticClass: "mt-3" }, [ + _c("label", { staticClass: "badge badge-danger mb-3" }, [ + _vm._v(" " + _vm._s(_vm.product.category.name) + " ") + ]), + _vm._v(" "), + _c("h3", [_vm._v("$" + _vm._s(_vm.product.price))]) + ]), + _vm._v(" "), + _c("div", { staticClass: "mt-2" }, [ + _vm._v( + "\n " + + _vm._s(_vm.product.description) + + "\n " + ) + ]) + ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-4" }, [ + _c("div", { staticClass: "card" }, [ + _c( + "div", + { staticClass: "card-body" }, + [ + _c( + "router-link", + { + staticClass: "btn btn-primary", + attrs: { to: { name: "home" } } + }, + [_vm._v("Go to Home")] + ) + ], + 1 + ) + ]) + ]) + ]) + ]) +} +var staticRenderFns = [] +render._withStripped = true + + + /***/ }), /***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js": @@ -60969,6 +61172,75 @@ __webpack_require__.r(__webpack_exports__); +/***/ }), + +/***/ "./resources/js/pages/productDetails.vue": +/*!***********************************************!*\ + !*** ./resources/js/pages/productDetails.vue ***! + \***********************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./productDetails.vue?vue&type=template&id=7aa8967c& */ "./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c&"); +/* harmony import */ var _productDetails_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./productDetails.vue?vue&type=script&lang=js& */ "./resources/js/pages/productDetails.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js"); + + + + + +/* normalize component */ + +var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])( + _productDetails_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"], + _productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__["render"], + _productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"], + false, + null, + null, + null + +) + +/* hot reload */ +if (false) { var api; } +component.options.__file = "resources/js/pages/productDetails.vue" +/* harmony default export */ __webpack_exports__["default"] = (component.exports); + +/***/ }), + +/***/ "./resources/js/pages/productDetails.vue?vue&type=script&lang=js&": +/*!************************************************************************!*\ + !*** ./resources/js/pages/productDetails.vue?vue&type=script&lang=js& ***! + \************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_productDetails_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib??ref--4-0!../../../node_modules/vue-loader/lib??vue-loader-options!./productDetails.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/productDetails.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_productDetails_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); + +/***/ }), + +/***/ "./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c&": +/*!******************************************************************************!*\ + !*** ./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c& ***! + \******************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../node_modules/vue-loader/lib??vue-loader-options!./productDetails.vue?vue&type=template&id=7aa8967c& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/pages/productDetails.vue?vue&type=template&id=7aa8967c&"); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__["render"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_productDetails_vue_vue_type_template_id_7aa8967c___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; }); + + + /***/ }), /***/ "./resources/js/router/index.js": @@ -60984,16 +61256,17 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue-router */ "./node_modules/vue-router/dist/vue-router.esm.js"); /* harmony import */ var _pages_home_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../pages/home.vue */ "./resources/js/pages/home.vue"); -/* harmony import */ var _pages_category_index_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../pages/category/index.vue */ "./resources/js/pages/category/index.vue"); -/* harmony import */ var _pages_category_create_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../pages/category/create.vue */ "./resources/js/pages/category/create.vue"); -/* harmony import */ var _pages_category_edit_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../pages/category/edit.vue */ "./resources/js/pages/category/edit.vue"); -/* harmony import */ var _pages_product_index_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../pages/product/index.vue */ "./resources/js/pages/product/index.vue"); -/* harmony import */ var _pages_product_create_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../pages/product/create.vue */ "./resources/js/pages/product/create.vue"); -/* harmony import */ var _pages_product_edit_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../pages/product/edit.vue */ "./resources/js/pages/product/edit.vue"); -/* harmony import */ var _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../pages/dashboard/index.vue */ "./resources/js/pages/dashboard/index.vue"); -/* harmony import */ var _pages_dashboard_profile_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../pages/dashboard/profile.vue */ "./resources/js/pages/dashboard/profile.vue"); -/* harmony import */ var _pages_auth_Login_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../pages/auth/Login.vue */ "./resources/js/pages/auth/Login.vue"); -/* harmony import */ var _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../pages/auth/Signup.vue */ "./resources/js/pages/auth/Signup.vue"); +/* harmony import */ var _pages_productDetails_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../pages/productDetails.vue */ "./resources/js/pages/productDetails.vue"); +/* harmony import */ var _pages_category_index_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../pages/category/index.vue */ "./resources/js/pages/category/index.vue"); +/* harmony import */ var _pages_category_create_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../pages/category/create.vue */ "./resources/js/pages/category/create.vue"); +/* harmony import */ var _pages_category_edit_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../pages/category/edit.vue */ "./resources/js/pages/category/edit.vue"); +/* harmony import */ var _pages_product_index_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../pages/product/index.vue */ "./resources/js/pages/product/index.vue"); +/* harmony import */ var _pages_product_create_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../pages/product/create.vue */ "./resources/js/pages/product/create.vue"); +/* harmony import */ var _pages_product_edit_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../pages/product/edit.vue */ "./resources/js/pages/product/edit.vue"); +/* harmony import */ var _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../pages/dashboard/index.vue */ "./resources/js/pages/dashboard/index.vue"); +/* harmony import */ var _pages_dashboard_profile_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../pages/dashboard/profile.vue */ "./resources/js/pages/dashboard/profile.vue"); +/* harmony import */ var _pages_auth_Login_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../pages/auth/Login.vue */ "./resources/js/pages/auth/Login.vue"); +/* harmony import */ var _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../pages/auth/Signup.vue */ "./resources/js/pages/auth/Signup.vue"); vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vue_router__WEBPACK_IMPORTED_MODULE_1__["default"]); @@ -61003,6 +61276,7 @@ vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vue_router__WEBPACK_IMPORTED_MODU + // Dashboard Component @@ -61019,56 +61293,60 @@ var routes = new vue_router__WEBPACK_IMPORTED_MODULE_1__["default"]({ name: 'home' }, { path: '/category', - component: _pages_category_index_vue__WEBPACK_IMPORTED_MODULE_3__["default"], + component: _pages_category_index_vue__WEBPACK_IMPORTED_MODULE_4__["default"], name: 'category-list' }, { path: '/category/create', - component: _pages_category_create_vue__WEBPACK_IMPORTED_MODULE_4__["default"], + component: _pages_category_create_vue__WEBPACK_IMPORTED_MODULE_5__["default"], name: 'create-category' }, { path: '/category/edit/:id', - component: _pages_category_edit_vue__WEBPACK_IMPORTED_MODULE_5__["default"], + component: _pages_category_edit_vue__WEBPACK_IMPORTED_MODULE_6__["default"], name: 'edit-category' }, { path: '/product', - component: _pages_product_index_vue__WEBPACK_IMPORTED_MODULE_6__["default"], + component: _pages_product_index_vue__WEBPACK_IMPORTED_MODULE_7__["default"], name: 'product-list' }, { path: '/product/create', - component: _pages_product_create_vue__WEBPACK_IMPORTED_MODULE_7__["default"], + component: _pages_product_create_vue__WEBPACK_IMPORTED_MODULE_8__["default"], name: 'create-product' }, { path: '/product/edit/:id', - component: _pages_product_edit_vue__WEBPACK_IMPORTED_MODULE_8__["default"], + component: _pages_product_edit_vue__WEBPACK_IMPORTED_MODULE_9__["default"], name: 'edit-product' }, { path: '/auth/login', - component: _pages_auth_Login_vue__WEBPACK_IMPORTED_MODULE_11__["default"], + component: _pages_auth_Login_vue__WEBPACK_IMPORTED_MODULE_12__["default"], name: 'login', meta: { requiresVisitor: true } }, { path: '/auth/signup', - component: _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_12__["default"], + component: _pages_auth_Signup_vue__WEBPACK_IMPORTED_MODULE_13__["default"], name: 'signup', meta: { requiresVisitor: true } }, { path: '/dashboard', - component: _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_9__["default"], + component: _pages_dashboard_index_vue__WEBPACK_IMPORTED_MODULE_10__["default"], name: 'dashboard', meta: { requiresAuth: true } }, { path: '/dashboard/profile', - component: _pages_dashboard_profile_vue__WEBPACK_IMPORTED_MODULE_10__["default"], + component: _pages_dashboard_profile_vue__WEBPACK_IMPORTED_MODULE_11__["default"], name: 'user-profile', meta: { requiresAuth: true } + }, { + path: '/product/:slug', + component: _pages_productDetails_vue__WEBPACK_IMPORTED_MODULE_3__["default"], + name: 'product-details' }] }); /* harmony default export */ __webpack_exports__["default"] = (routes); diff --git a/resources/js/pages/home.vue b/resources/js/pages/home.vue index c0fc641..b4107cd 100644 --- a/resources/js/pages/home.vue +++ b/resources/js/pages/home.vue @@ -6,10 +6,14 @@
...
+
+ +

${{ product.price }}

+
{{ product.title }}
- Go somewhere + View Product
diff --git a/resources/js/pages/productDetails.vue b/resources/js/pages/productDetails.vue new file mode 100644 index 0000000..5fb9e8b --- /dev/null +++ b/resources/js/pages/productDetails.vue @@ -0,0 +1,54 @@ + + + diff --git a/resources/js/router/index.js b/resources/js/router/index.js index 64ea54e..e833a08 100644 --- a/resources/js/router/index.js +++ b/resources/js/router/index.js @@ -4,6 +4,7 @@ import VueRouter from 'vue-router'; Vue.use(VueRouter); import Home from '../pages/home.vue' +import ProductDetails from '../pages/productDetails.vue' import CategoryList from '../pages/category/index.vue' import CreateCategory from '../pages/category/create.vue' import EditCategory from '../pages/category/edit.vue' @@ -89,6 +90,11 @@ const routes = new VueRouter({ meta: { requiresAuth: true, } + }, + { + path: '/product/:slug', + component: ProductDetails, + name: 'product-details', } ] }); diff --git a/routes/api.php b/routes/api.php index e5efbc3..68461ce 100644 --- a/routes/api.php +++ b/routes/api.php @@ -27,3 +27,4 @@ Route::get('products', 'PublicAPIController@products'); +Route::get('products/{slug}', 'PublicAPIController@product_details'); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy