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');