From 182a729a46ed57f38d022db1c333827fb4af19b5 Mon Sep 17 00:00:00 2001 From: Nauris Linde Date: Fri, 24 May 2019 22:32:10 +0300 Subject: [PATCH] WIP: Implemented Education and Experience to backend --- .../Admin/EducationCrudController.php | 72 +++ .../Admin/ExperienceCrudController.php | 74 +++ .../Controllers/Api/EducationController.php | 47 ++ .../Controllers/Api/ExperienceController.php | 47 ++ app/Http/Requests/EducationRequest.php | 56 ++ app/Http/Requests/ExperienceRequest.php | 56 ++ app/Http/Resources/EducationResource.php | 27 + app/Http/Resources/ExperienceResource.php | 29 + app/Models/Education.php | 66 ++ app/Models/Experience.php | 67 +++ database/factories/EducationFactory.php | 25 + database/factories/ExperienceFactory.php | 27 + ...19_05_15_162956_create_education_table.php | 36 ++ ...9_05_15_163004_create_experience_table.php | 38 ++ database/seeds/DatabaseSeeder.php | 2 + database/seeds/EducationTableSeeder.php | 17 + database/seeds/ExperienceTableSeeder.php | 17 + public/js/app.js | 566 +++++++++++------- resources/js/common/api.service.js | 22 + resources/js/pages/experience.vue | 60 +- resources/js/store/actions.type.js | 2 + resources/js/store/education.module.js | 45 ++ resources/js/store/experience.module.js | 45 ++ resources/js/store/index.js | 6 +- resources/js/store/mutations.type.js | 2 + .../base/inc/sidebar_content.blade.php | 2 + routes/api.php | 2 + routes/backpack/custom.php | 4 +- 28 files changed, 1208 insertions(+), 251 deletions(-) create mode 100644 app/Http/Controllers/Admin/EducationCrudController.php create mode 100644 app/Http/Controllers/Admin/ExperienceCrudController.php create mode 100644 app/Http/Controllers/Api/EducationController.php create mode 100644 app/Http/Controllers/Api/ExperienceController.php create mode 100644 app/Http/Requests/EducationRequest.php create mode 100644 app/Http/Requests/ExperienceRequest.php create mode 100644 app/Http/Resources/EducationResource.php create mode 100644 app/Http/Resources/ExperienceResource.php create mode 100644 app/Models/Education.php create mode 100644 app/Models/Experience.php create mode 100644 database/factories/EducationFactory.php create mode 100644 database/factories/ExperienceFactory.php create mode 100644 database/migrations/2019_05_15_162956_create_education_table.php create mode 100644 database/migrations/2019_05_15_163004_create_experience_table.php create mode 100644 database/seeds/EducationTableSeeder.php create mode 100644 database/seeds/ExperienceTableSeeder.php create mode 100644 resources/js/store/education.module.js create mode 100644 resources/js/store/experience.module.js diff --git a/app/Http/Controllers/Admin/EducationCrudController.php b/app/Http/Controllers/Admin/EducationCrudController.php new file mode 100644 index 00000000..0856ea6e --- /dev/null +++ b/app/Http/Controllers/Admin/EducationCrudController.php @@ -0,0 +1,72 @@ +crud->setModel('App\Models\Education'); + $this->crud->setRoute(config('backpack.base.route_prefix') . '/education'); + $this->crud->setEntityNameStrings('education', 'education'); + + /* + |-------------------------------------------------------------------------- + | CrudPanel Configuration + |-------------------------------------------------------------------------- + */ + $this->crud->addColumns([ + ['name' => 'qualification', 'type' => 'text', 'label' => 'Qualification'], + ['name' => 'organisation', 'type' => 'text', 'label' => 'Organisation'], + ['name' => 'from', 'type' => 'date', 'label' => 'From', 'format' => 'Y'], + ['name' => 'to', 'type' => 'date', 'label' => 'To', 'format' => 'Y'], + ['name' => 'ongoing', 'type' => 'boolean', 'label' => 'Ongoing'], + ]); + $this->crud->addFields([ + ['name' => 'qualification', 'type' => 'text', 'label' => 'Qualification'], + ['name' => 'organisation', 'type' => 'text', 'label' => 'Organisation'], + ['name' => 'from', 'type' => 'date_picker', 'label' => 'From', 'date_picker_options' => ['format' => 'yyyy', 'viewMode' => 'years', 'minViewMode' => 'years']], + ['name' => 'to', 'type' => 'date_picker', 'label' => 'To', 'date_picker_options' => ['format' => 'yyyy', 'viewMode' => 'years', 'minViewMode' => 'years']], + ['name' => 'ongoing', 'type' => 'checkbox', 'label' => 'Ongoing'], + ]); + + // add asterisk for fields that are required in EducationRequest + $this->crud->setRequiredFields(StoreRequest::class, 'create'); + $this->crud->setRequiredFields(UpdateRequest::class, 'edit'); + } + + public function store(StoreRequest $request) + { + // your additional operations before save here + $redirect_location = parent::storeCrud($request); + // your additional operations after save here + // use $this->data['entry'] or $this->crud->entry + return $redirect_location; + } + + public function update(UpdateRequest $request) + { + // your additional operations before save here + $redirect_location = parent::updateCrud($request); + // your additional operations after save here + // use $this->data['entry'] or $this->crud->entry + return $redirect_location; + } +} diff --git a/app/Http/Controllers/Admin/ExperienceCrudController.php b/app/Http/Controllers/Admin/ExperienceCrudController.php new file mode 100644 index 00000000..71225a27 --- /dev/null +++ b/app/Http/Controllers/Admin/ExperienceCrudController.php @@ -0,0 +1,74 @@ +crud->setModel('App\Models\Experience'); + $this->crud->setRoute(config('backpack.base.route_prefix') . '/experience'); + $this->crud->setEntityNameStrings('experience', 'experiences'); + + /* + |-------------------------------------------------------------------------- + | CrudPanel Configuration + |-------------------------------------------------------------------------- + */ + $this->crud->addColumns([ + ['name' => 'position', 'type' => 'text', 'label' => 'Position'], + ['name' => 'employer', 'type' => 'text', 'label' => 'Employer'], + ['name' => 'from', 'type' => 'date', 'label' => 'From', 'format' => 'M-Y'], + ['name' => 'to', 'type' => 'date', 'label' => 'To', 'format' => 'M-Y'], + ['name' => 'ongoing', 'type' => 'boolean', 'label' => 'Ongoing'], + ]); + $this->crud->addFields([ + ['name' => 'position', 'type' => 'text', 'label' => 'Position'], + ['name' => 'employer', 'type' => 'text', 'label' => 'Employer'], + ['name' => 'website', 'type' => 'url', 'label' => 'Website'], + ['name' => 'from', 'type' => 'date_picker', 'label' => 'From', 'date_picker_options' => ['format' => 'mm-yyyy', 'viewMode' => 'months', 'minViewMode' => 'months']], + ['name' => 'to', 'type' => 'date_picker', 'label' => 'To', 'date_picker_options' => ['format' => 'mm-yyyy', 'viewMode' => 'months', 'minViewMode' => 'months']], + ['name' => 'ongoing', 'type' => 'checkbox', 'label' => 'Ongoing'], + ['name' => 'logo', 'type' => 'image', 'upload' => true, 'crop' => false, 'aspect_ratio' => 1, 'disk' => 'public'], + ]); + + // add asterisk for fields that are required in ExperienceRequest + $this->crud->setRequiredFields(StoreRequest::class, 'create'); + $this->crud->setRequiredFields(UpdateRequest::class, 'edit'); + } + + public function store(StoreRequest $request) + { + // your additional operations before save here + $redirect_location = parent::storeCrud($request); + // your additional operations after save here + // use $this->data['entry'] or $this->crud->entry + return $redirect_location; + } + + public function update(UpdateRequest $request) + { + // your additional operations before save here + $redirect_location = parent::updateCrud($request); + // your additional operations after save here + // use $this->data['entry'] or $this->crud->entry + return $redirect_location; + } +} diff --git a/app/Http/Controllers/Api/EducationController.php b/app/Http/Controllers/Api/EducationController.php new file mode 100644 index 00000000..4dbe2c70 --- /dev/null +++ b/app/Http/Controllers/Api/EducationController.php @@ -0,0 +1,47 @@ +middleware('api_admin')->except('index', 'show'); + } + + public function index() + { + return EducationResource::collection(Education::all()); + } + + public function show(Education $education) + { + return new EducationResource($education); + } + + public function store(Request $request) + { + $education = Education::create($request->only('position', 'employer', 'website', 'from', 'to', 'ongoing')); + + return new EducationResource($education); + } + + public function update(Education $education, Request $request) + { + $education->update($request->only('position', 'employer', 'website', 'from', 'to', 'ongoing')); + + return new EducationResource($education); + } + + public function destroy(Education $education) + { + $education->delete(); + + return response()->json([], 204); + } +} diff --git a/app/Http/Controllers/Api/ExperienceController.php b/app/Http/Controllers/Api/ExperienceController.php new file mode 100644 index 00000000..820cca8e --- /dev/null +++ b/app/Http/Controllers/Api/ExperienceController.php @@ -0,0 +1,47 @@ +middleware('api_admin')->except('index', 'show'); + } + + public function index() + { + return ExperienceResource::collection(Experience::all()); + } + + public function show(Experience $experience) + { + return new ExperienceResource($experience); + } + + public function store(Request $request) + { + $experience = Experience::create($request->only('position', 'employer', 'website', 'from', 'to', 'ongoing')); + + return new ExperienceResource($experience); + } + + public function update(Experience $experience, Request $request) + { + $experience->update($request->only('position', 'employer', 'website', 'from', 'to', 'ongoing')); + + return new ExperienceResource($experience); + } + + public function destroy(Experience $experience) + { + $experience->delete(); + + return response()->json([], 204); + } +} diff --git a/app/Http/Requests/EducationRequest.php b/app/Http/Requests/EducationRequest.php new file mode 100644 index 00000000..4906daa4 --- /dev/null +++ b/app/Http/Requests/EducationRequest.php @@ -0,0 +1,56 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + // 'name' => 'required|min:5|max:255' + ]; + } + + /** + * Get the validation attributes that apply to the request. + * + * @return array + */ + public function attributes() + { + return [ + // + ]; + } + + /** + * Get the validation messages that apply to the request. + * + * @return array + */ + public function messages() + { + return [ + // + ]; + } +} diff --git a/app/Http/Requests/ExperienceRequest.php b/app/Http/Requests/ExperienceRequest.php new file mode 100644 index 00000000..578c369e --- /dev/null +++ b/app/Http/Requests/ExperienceRequest.php @@ -0,0 +1,56 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + // 'name' => 'required|min:5|max:255' + ]; + } + + /** + * Get the validation attributes that apply to the request. + * + * @return array + */ + public function attributes() + { + return [ + // + ]; + } + + /** + * Get the validation messages that apply to the request. + * + * @return array + */ + public function messages() + { + return [ + // + ]; + } +} diff --git a/app/Http/Resources/EducationResource.php b/app/Http/Resources/EducationResource.php new file mode 100644 index 00000000..8c1ad70b --- /dev/null +++ b/app/Http/Resources/EducationResource.php @@ -0,0 +1,27 @@ + $this->id, + 'qualification' => $this->qualification, + 'organisation' => $this->organisation, + 'from' => $this->from, + 'to' => $this->to, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/ExperienceResource.php b/app/Http/Resources/ExperienceResource.php new file mode 100644 index 00000000..15e42d7e --- /dev/null +++ b/app/Http/Resources/ExperienceResource.php @@ -0,0 +1,29 @@ + $this->id, + 'position' => $this->position, + 'employer' => $this->employer, + 'website' => $this->website, + 'from' => $this->from, + 'to' => $this->to, + 'ongoing' => $this->ongoing, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Models/Education.php b/app/Models/Education.php new file mode 100644 index 00000000..d5c1d302 --- /dev/null +++ b/app/Models/Education.php @@ -0,0 +1,66 @@ +format('Y'); + } + + public function getToAttribute($value) + { + return Carbon::parse($value)->format('Y'); + } +} diff --git a/app/Models/Experience.php b/app/Models/Experience.php new file mode 100644 index 00000000..cc7e7b36 --- /dev/null +++ b/app/Models/Experience.php @@ -0,0 +1,67 @@ +format('M Y'); + } + + public function getToAttribute($value) + { + return Carbon::parse($value)->format('M Y'); + } +} diff --git a/database/factories/EducationFactory.php b/database/factories/EducationFactory.php new file mode 100644 index 00000000..79dcb904 --- /dev/null +++ b/database/factories/EducationFactory.php @@ -0,0 +1,25 @@ +define(Education::class, function (Faker $faker) { + return [ + 'qualification' => $faker->sentence(4), + 'organisation' => $faker->sentence(2), + 'from' => $faker->date, + 'to' => $faker->date, + 'ongoing' => $faker->boolean(25), + ]; +}); diff --git a/database/factories/ExperienceFactory.php b/database/factories/ExperienceFactory.php new file mode 100644 index 00000000..fd575a26 --- /dev/null +++ b/database/factories/ExperienceFactory.php @@ -0,0 +1,27 @@ +define(Experience::class, function (Faker $faker) { + return [ + 'position' => $faker->jobTitle, + 'employer' => $faker->company, + 'website' => $faker->domainName, + 'from' => $faker->date, + 'to' => $faker->date, + 'ongoing' => $faker->boolean(25), + 'logo' => 'experience/' . $faker->image(storage_path('app/public/experience'), 640, 480, 'business', false), + ]; +}); diff --git a/database/migrations/2019_05_15_162956_create_education_table.php b/database/migrations/2019_05_15_162956_create_education_table.php new file mode 100644 index 00000000..5e61eb03 --- /dev/null +++ b/database/migrations/2019_05_15_162956_create_education_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->json('qualification'); + $table->json('organisation'); + $table->date('from'); + $table->date('to')->nullable(); + $table->boolean('ongoing')->default(false); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('education'); + } +} diff --git a/database/migrations/2019_05_15_163004_create_experience_table.php b/database/migrations/2019_05_15_163004_create_experience_table.php new file mode 100644 index 00000000..a0ad60af --- /dev/null +++ b/database/migrations/2019_05_15_163004_create_experience_table.php @@ -0,0 +1,38 @@ +bigIncrements('id'); + $table->json('position'); + $table->string('employer'); + $table->string('website')->nullable(); + $table->date('from'); + $table->date('to')->nullable(); + $table->boolean('ongoing')->default(false); + $table->string('logo')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('experience'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 9cf85f4d..723fa7c0 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -16,6 +16,8 @@ public function run() CategoriesTableSeeder::class, TagsTableSeeder::class, ProjectsTableSeeder::class, + EducationTableSeeder::class, + ExperienceTableSeeder::class, ]); } } diff --git a/database/seeds/EducationTableSeeder.php b/database/seeds/EducationTableSeeder.php new file mode 100644 index 00000000..58ff598f --- /dev/null +++ b/database/seeds/EducationTableSeeder.php @@ -0,0 +1,17 @@ +create(); + } +} diff --git a/database/seeds/ExperienceTableSeeder.php b/database/seeds/ExperienceTableSeeder.php new file mode 100644 index 00000000..09fcf0ce --- /dev/null +++ b/database/seeds/ExperienceTableSeeder.php @@ -0,0 +1,17 @@ +create(); + } +} diff --git a/public/js/app.js b/public/js/app.js index 585b7f31..c2a9baab 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -3306,6 +3306,12 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js"); +/* harmony import */ var _store_actions_type__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../store/actions.type */ "./resources/js/store/actions.type.js"); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + // // // @@ -3384,23 +3390,8 @@ __webpack_require__.r(__webpack_exports__); // // // -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// + + /* harmony default export */ __webpack_exports__["default"] = ({ layout: 'default', metaInfo: function metaInfo() { @@ -3413,6 +3404,19 @@ __webpack_require__.r(__webpack_exports__); sem: __webpack_require__(/*! ../../img/sem.png */ "./resources/img/sem.png"), giraffe360: __webpack_require__(/*! ../../img/giraffe360.svg */ "./resources/img/giraffe360.svg") }; + }, + computed: _objectSpread({}, Object(vuex__WEBPACK_IMPORTED_MODULE_0__["mapGetters"])(['education', 'experience'])), + mounted: function mounted() { + this.fetchEducation(); + this.fetchExperience(); + }, + methods: { + fetchEducation: function fetchEducation() { + this.$store.dispatch(_store_actions_type__WEBPACK_IMPORTED_MODULE_1__["FETCH_EDUCATION"], {}); + }, + fetchExperience: function fetchExperience() { + this.$store.dispatch(_store_actions_type__WEBPACK_IMPORTED_MODULE_1__["FETCH_EXPERIENCE"], {}); + } } }); @@ -33851,139 +33855,102 @@ var render = function() { staticClass: "text-xs-left", attrs: { row: "", wrap: "" } }, - [ - _c( - "v-flex", - { attrs: { xs12: "", sm6: "", "d-flex": "" } }, - [ - _c("v-hover", { - scopedSlots: _vm._u([ - { - key: "default", - fn: function(ref) { - var hover = ref.hover - return _c( - "v-card", - { class: "elevation-" + (hover ? 12 : 1) }, - [ - _c("div", { staticClass: "edu-block" }, [ - _c( - "div", - { staticClass: "edu-session" }, - [_c("span", [_vm._v("2015 - 2017")])] - ), - _vm._v(" "), - _c("div", { staticClass: "pl-5" }, [ - _c( - "h4", - { - staticClass: "block-title title" - }, - [ - _vm._v( - "\n " + - _vm._s( - _vm.$t("rtu_education") - ) + - "\n " - ) - ] - ), - _vm._v(" "), - _c( - "h5", - { - staticClass: - "mb-4 mt-3 subheading" - }, - [ - _vm._v( - "\n " + - _vm._s( - _vm.$t("rtu_address") - ) + - "\n " - ) - ] - ) - ]) - ]) - ] - ) - } - } - ]) - }) - ], - 1 - ), - _vm._v(" "), - _c( + _vm._l(_vm.education, function(school) { + return _c( "v-flex", { attrs: { xs12: "", sm6: "", "d-flex": "" } }, [ _c("v-hover", { - scopedSlots: _vm._u([ - { - key: "default", - fn: function(ref) { - var hover = ref.hover - return _c( - "v-card", - { class: "elevation-" + (hover ? 12 : 1) }, - [ - _c("div", { staticClass: "edu-block" }, [ + scopedSlots: _vm._u( + [ + { + key: "default", + fn: function(ref) { + var hover = ref.hover + return _c( + "v-card", + { + class: "elevation-" + (hover ? 12 : 1) + }, + [ _c( "div", - { staticClass: "edu-session" }, - [_c("span", [_vm._v("2011 - 2015")])] - ), - _vm._v(" "), - _c("div", { staticClass: "pl-5" }, [ - _c( - "h4", - { - staticClass: "block-title title" - }, - [ - _vm._v( - "\n " + - _vm._s( - _vm.$t("lvt_education") - ) + - "\n " - ) - ] - ), - _vm._v(" "), - _c( - "h5", - { - staticClass: - "mb-4 mt-3 subheading" - }, - [ - _vm._v( - "\n " + - _vm._s( - _vm.$t("lvt_address") - ) + - "\n " + { staticClass: "edu-block" }, + [ + _c( + "div", + { staticClass: "edu-session" }, + [ + school.ongoing + ? _c("span", [ + _vm._v( + _vm._s(school.from) + + " - " + + _vm._s( + _vm.$t("present") + ) + ) + ]) + : _c("span", [ + _vm._v( + _vm._s(school.from) + + " - " + + _vm._s(school.to) + ) + ]) + ] + ), + _vm._v(" "), + _c("div", { staticClass: "pl-5" }, [ + _c( + "h4", + { + staticClass: + "block-title title" + }, + [ + _vm._v( + "\n " + + _vm._s( + school.qualification + ) + + "\n " + ) + ] + ), + _vm._v(" "), + _c( + "h5", + { + staticClass: + "mb-4 mt-3 subheading" + }, + [ + _vm._v( + "\n " + + _vm._s( + school.organisation + ) + + "\n " + ) + ] ) - ] - ) - ]) - ]) - ] - ) + ]) + ] + ) + ] + ) + } } - } - ]) + ], + null, + true + ) }) ], 1 ) - ], + }), 1 ) ], @@ -34012,96 +33979,117 @@ var render = function() { attrs: { row: "", wrap: "" } }, [ - _c( - "v-flex", - { attrs: { xs12: "", sm6: "", "d-flex": "" } }, - [ - _c("v-hover", { - scopedSlots: _vm._u([ - { - key: "default", - fn: function(ref) { - var hover = ref.hover - return _c( - "v-card", - { class: "elevation-" + (hover ? 12 : 1) }, - [ - _c( - "div", - { staticClass: "work-exp-block" }, + _vm._l(_vm.experience, function(job) { + return _c( + "v-flex", + { attrs: { xs12: "", sm6: "", "d-flex": "" } }, + [ + _c("v-hover", { + scopedSlots: _vm._u( + [ + { + key: "default", + fn: function(ref) { + var hover = ref.hover + return _c( + "v-card", + { + class: "elevation-" + (hover ? 12 : 1) + }, [ _c( "div", - { - staticClass: - "working-duration title d-block" - }, - [ - _vm._v( - "\n Jan 2019-" + - _vm._s(_vm.$t("present")) + - "\n " - ) - ] - ), - _vm._v(" "), - _c( - "div", - { staticClass: "work-exp-logo" }, - [ - _c("img", { - attrs: { - src: _vm.giraffe360, - width: "123", - alt: "Giraffe360" - } - }) - ] - ), - _vm._v(" "), - _c( - "h4", - { staticClass: "headline mt-3" }, - [ - _vm._v( - _vm._s( - _vm.$t("giraffe360_position") - ) - ) - ] - ), - _vm._v(" "), - _c( - "h6", - { - staticClass: - "color-text title mt-2" - }, + { staticClass: "work-exp-block" }, [ _c( - "a", + "div", { - attrs: { - href: - "https://giraffe360.com", - target: "_blank" - } + staticClass: + "working-duration title d-block" + }, + [ + job.ongoing + ? _c("span", [ + _vm._v( + _vm._s(job.from) + + " - " + + _vm._s( + _vm.$t("present") + ) + ) + ]) + : _c("span", [ + _vm._v( + _vm._s(job.from) + + " - " + + _vm._s(job.to) + ) + ]) + ] + ), + _vm._v(" "), + _c( + "div", + { + staticClass: "work-exp-logo" + }, + [ + _c("img", { + attrs: { + src: _vm.giraffe360, + width: "123", + alt: "Giraffe360" + } + }) + ] + ), + _vm._v(" "), + _c( + "h4", + { + staticClass: "headline mt-3" + }, + [_vm._v(_vm._s(job.position))] + ), + _vm._v(" "), + _c( + "h6", + { + staticClass: + "color-text title mt-2" }, - [_vm._v("Giraffe360")] + [ + _c( + "a", + { + attrs: { + href: job.website, + target: "_blank" + } + }, + [ + _vm._v( + _vm._s(job.employer) + ) + ] + ) + ] ) ] ) ] ) - ] - ) - } - } - ]) - }) - ], - 1 - ), + } + } + ], + null, + true + ) + }) + ], + 1 + ) + }), _vm._v(" "), _c( "v-flex", @@ -34189,7 +34177,7 @@ var render = function() { 1 ) ], - 1 + 2 ) ], 1 @@ -80600,13 +80588,15 @@ new vue__WEBPACK_IMPORTED_MODULE_1___default.a(_objectSpread({ /*!********************************************!*\ !*** ./resources/js/common/api.service.js ***! \********************************************/ -/*! exports provided: default, ProjectsService, CategoriesService */ +/*! exports provided: default, ProjectsService, CategoriesService, EducationService, ExperienceService */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProjectsService", function() { return ProjectsService; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CategoriesService", function() { return CategoriesService; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EducationService", function() { return EducationService; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExperienceService", function() { return ExperienceService; }); /* 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 axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! axios */ "./node_modules/axios/index.js"); @@ -80670,6 +80660,26 @@ var CategoriesService = { return ApiService.get('categories', slug); } }; +var EducationService = { + query: function query(params) { + return ApiService.query('education', { + params: params + }); + }, + get: function get(id) { + return ApiService.get('education', id); + } +}; +var ExperienceService = { + query: function query(params) { + return ApiService.query('experience', { + params: params + }); + }, + get: function get(id) { + return ApiService.get('experience', id); + } +}; /***/ }), @@ -82401,15 +82411,119 @@ __webpack_require__.r(__webpack_exports__); /*!********************************************!*\ !*** ./resources/js/store/actions.type.js ***! \********************************************/ -/*! exports provided: FETCH_PROJECTS, FETCH_CATEGORIES */ +/*! exports provided: FETCH_PROJECTS, FETCH_CATEGORIES, FETCH_EDUCATION, FETCH_EXPERIENCE */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FETCH_PROJECTS", function() { return FETCH_PROJECTS; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FETCH_CATEGORIES", function() { return FETCH_CATEGORIES; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FETCH_EDUCATION", function() { return FETCH_EDUCATION; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FETCH_EXPERIENCE", function() { return FETCH_EXPERIENCE; }); var FETCH_PROJECTS = 'fetchProjects'; var FETCH_CATEGORIES = 'fetchCategories'; +var FETCH_EDUCATION = 'fetchEducation'; +var FETCH_EXPERIENCE = 'fetchExperience'; + +/***/ }), + +/***/ "./resources/js/store/education.module.js": +/*!************************************************!*\ + !*** ./resources/js/store/education.module.js ***! + \************************************************/ +/*! exports provided: state, actions, mutations, getters, default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "state", function() { return state; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "actions", function() { return actions; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mutations", function() { return mutations; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getters", function() { return getters; }); +/* harmony import */ var _common_api_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/common/api.service */ "./resources/js/common/api.service.js"); +/* harmony import */ var _actions_type__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./actions.type */ "./resources/js/store/actions.type.js"); +/* harmony import */ var _mutations_type__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mutations.type */ "./resources/js/store/mutations.type.js"); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + + + +var state = { + education: [] +}; +var actions = _defineProperty({}, _actions_type__WEBPACK_IMPORTED_MODULE_1__["FETCH_EDUCATION"], function (context, params) { + return _common_api_service__WEBPACK_IMPORTED_MODULE_0__["EducationService"].query(params).then(function (_ref) { + var data = _ref.data; + context.commit(_mutations_type__WEBPACK_IMPORTED_MODULE_2__["SET_EDUCATION"], data); + return data; + })["catch"](function (error) { + throw new Error(error); + }); +}); +var mutations = _defineProperty({}, _mutations_type__WEBPACK_IMPORTED_MODULE_2__["SET_EDUCATION"], function (state, education) { + state.education = education; +}); +var getters = { + education: function education(state) { + return state.education; + } +}; +/* harmony default export */ __webpack_exports__["default"] = ({ + state: state, + actions: actions, + mutations: mutations, + getters: getters +}); + +/***/ }), + +/***/ "./resources/js/store/experience.module.js": +/*!*************************************************!*\ + !*** ./resources/js/store/experience.module.js ***! + \*************************************************/ +/*! exports provided: state, actions, mutations, getters, default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "state", function() { return state; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "actions", function() { return actions; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mutations", function() { return mutations; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getters", function() { return getters; }); +/* harmony import */ var _common_api_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/common/api.service */ "./resources/js/common/api.service.js"); +/* harmony import */ var _actions_type__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./actions.type */ "./resources/js/store/actions.type.js"); +/* harmony import */ var _mutations_type__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mutations.type */ "./resources/js/store/mutations.type.js"); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + + + +var state = { + experience: [] +}; +var actions = _defineProperty({}, _actions_type__WEBPACK_IMPORTED_MODULE_1__["FETCH_EXPERIENCE"], function (context, params) { + return _common_api_service__WEBPACK_IMPORTED_MODULE_0__["ExperienceService"].query(params).then(function (_ref) { + var data = _ref.data; + context.commit(_mutations_type__WEBPACK_IMPORTED_MODULE_2__["SET_EXPERIENCE"], data); + return data; + })["catch"](function (error) { + throw new Error(error); + }); +}); +var mutations = _defineProperty({}, _mutations_type__WEBPACK_IMPORTED_MODULE_2__["SET_EXPERIENCE"], function (state, experience) { + state.experience = experience; +}); +var getters = { + experience: function experience(state) { + return state.experience; + } +}; +/* harmony default export */ __webpack_exports__["default"] = ({ + state: state, + actions: actions, + mutations: mutations, + getters: getters +}); /***/ }), @@ -82427,6 +82541,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js"); /* harmony import */ var _project_module__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./project.module */ "./resources/js/store/project.module.js"); /* harmony import */ var _lang_module__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lang.module */ "./resources/js/store/lang.module.js"); +/* harmony import */ var _education_module__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./education.module */ "./resources/js/store/education.module.js"); +/* harmony import */ var _experience_module__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./experience.module */ "./resources/js/store/experience.module.js"); + + @@ -82435,7 +82553,9 @@ vue__WEBPACK_IMPORTED_MODULE_0___default.a.use(vuex__WEBPACK_IMPORTED_MODULE_1__ /* harmony default export */ __webpack_exports__["default"] = (new vuex__WEBPACK_IMPORTED_MODULE_1__["default"].Store({ modules: { lang: _lang_module__WEBPACK_IMPORTED_MODULE_3__["default"], - project: _project_module__WEBPACK_IMPORTED_MODULE_2__["default"] + project: _project_module__WEBPACK_IMPORTED_MODULE_2__["default"], + education: _education_module__WEBPACK_IMPORTED_MODULE_4__["default"], + experience: _experience_module__WEBPACK_IMPORTED_MODULE_5__["default"] } })); @@ -82509,7 +82629,7 @@ var actions = { /*!**********************************************!*\ !*** ./resources/js/store/mutations.type.js ***! \**********************************************/ -/*! exports provided: SET_CATEGORIES, SET_PROJECTS, SET_LOCALE */ +/*! exports provided: SET_CATEGORIES, SET_PROJECTS, SET_LOCALE, SET_EDUCATION, SET_EXPERIENCE */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -82517,9 +82637,13 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SET_CATEGORIES", function() { return SET_CATEGORIES; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SET_PROJECTS", function() { return SET_PROJECTS; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SET_LOCALE", function() { return SET_LOCALE; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SET_EDUCATION", function() { return SET_EDUCATION; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SET_EXPERIENCE", function() { return SET_EXPERIENCE; }); var SET_CATEGORIES = 'setCategories'; var SET_PROJECTS = 'setProjects'; var SET_LOCALE = 'SET_LOCALE'; +var SET_EDUCATION = 'setEducation'; +var SET_EXPERIENCE = 'setExperience'; /***/ }), diff --git a/resources/js/common/api.service.js b/resources/js/common/api.service.js index a993f61b..9fd41246 100644 --- a/resources/js/common/api.service.js +++ b/resources/js/common/api.service.js @@ -63,3 +63,25 @@ export const CategoriesService = { return ApiService.get('categories', slug) } } + +export const EducationService = { + query (params) { + return ApiService.query('education', { + params: params + }) + }, + get (id) { + return ApiService.get('education', id) + } +} + +export const ExperienceService = { + query (params) { + return ApiService.query('experience', { + params: params + }) + }, + get (id) { + return ApiService.get('experience', id) + } +} diff --git a/resources/js/pages/experience.vue b/resources/js/pages/experience.vue index 82592a9d..0f1e1c61 100644 --- a/resources/js/pages/experience.vue +++ b/resources/js/pages/experience.vue @@ -5,38 +5,20 @@

{{ $t('education') }}

- +
- 2015 - 2017 + {{ school.from }} - {{ $t('present') }} + {{ school.from }} - {{ school.to }}

- {{ $t('rtu_education') }} + {{ school.qualification }}

- {{ $t('rtu_address') }} -
-
-
-
-
-
- - - -
-
- 2011 - 2015 -
-
-

- {{ $t('lvt_education') }} -

-
- {{ $t('lvt_address') }} + {{ school.organisation }}
@@ -50,19 +32,20 @@

{{ $t('experience') }}

- +
- Jan 2019-{{ $t('present') }} + {{ job.from }} - {{ $t('present') }} + {{ job.from }} - {{ job.to }}
-

{{ $t('giraffe360_position') }}

+

{{ job.position }}

- Giraffe360 + {{ job.employer }}
@@ -94,6 +77,9 @@ diff --git a/resources/js/store/actions.type.js b/resources/js/store/actions.type.js index c98ce1d0..2acac773 100644 --- a/resources/js/store/actions.type.js +++ b/resources/js/store/actions.type.js @@ -1,2 +1,4 @@ export const FETCH_PROJECTS = 'fetchProjects' export const FETCH_CATEGORIES = 'fetchCategories' +export const FETCH_EDUCATION = 'fetchEducation' +export const FETCH_EXPERIENCE = 'fetchExperience' diff --git a/resources/js/store/education.module.js b/resources/js/store/education.module.js new file mode 100644 index 00000000..e7cb8531 --- /dev/null +++ b/resources/js/store/education.module.js @@ -0,0 +1,45 @@ +import { + EducationService +} from '~/common/api.service' +import { + FETCH_EDUCATION +} from './actions.type' +import { + SET_EDUCATION +} from './mutations.type' + +export const state = { + education: [], +} + +export const actions = { + [FETCH_EDUCATION] (context, params) { + return EducationService.query(params) + .then(({ data }) => { + context.commit(SET_EDUCATION, data) + return data + }) + .catch(error => { + throw new Error(error) + }) + } +} + +export const mutations = { + [SET_EDUCATION] (state, education) { + state.education = education + } +} + +export const getters = { + education (state) { + return state.education + }, +} + +export default { + state, + actions, + mutations, + getters +} diff --git a/resources/js/store/experience.module.js b/resources/js/store/experience.module.js new file mode 100644 index 00000000..f078bdb2 --- /dev/null +++ b/resources/js/store/experience.module.js @@ -0,0 +1,45 @@ +import { + ExperienceService +} from '~/common/api.service' +import { + FETCH_EXPERIENCE +} from './actions.type' +import { + SET_EXPERIENCE, +} from './mutations.type' + +export const state = { + experience: [], +} + +export const actions = { + [FETCH_EXPERIENCE] (context, params) { + return ExperienceService.query(params) + .then(({ data }) => { + context.commit(SET_EXPERIENCE, data) + return data + }) + .catch(error => { + throw new Error(error) + }) + } +} + +export const mutations = { + [SET_EXPERIENCE] (state, experience) { + state.experience = experience + } +} + +export const getters = { + experience (state) { + return state.experience + } +} + +export default { + state, + actions, + mutations, + getters +} diff --git a/resources/js/store/index.js b/resources/js/store/index.js index 9caa68ff..bae0123d 100644 --- a/resources/js/store/index.js +++ b/resources/js/store/index.js @@ -3,12 +3,16 @@ import Vuex from 'vuex' import project from './project.module' import lang from './lang.module' +import education from './education.module' +import experience from './experience.module' Vue.use(Vuex) export default new Vuex.Store({ modules: { lang, - project + project, + education, + experience } }) diff --git a/resources/js/store/mutations.type.js b/resources/js/store/mutations.type.js index 409802c2..02062509 100644 --- a/resources/js/store/mutations.type.js +++ b/resources/js/store/mutations.type.js @@ -1,3 +1,5 @@ export const SET_CATEGORIES = 'setCategories' export const SET_PROJECTS = 'setProjects' export const SET_LOCALE = 'SET_LOCALE' +export const SET_EDUCATION = 'setEducation' +export const SET_EXPERIENCE = 'setExperience' diff --git a/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php b/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php index b38c9606..3acc2123 100644 --- a/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php +++ b/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php @@ -3,4 +3,6 @@
  • Categories
  • Tags
  • Projects
  • +
  • Education
  • +
  • Experience
  • {{ trans('backpack::crud.file_manager') }}
  • diff --git a/routes/api.php b/routes/api.php index 29e5ea0b..0f7d8e0d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -22,4 +22,6 @@ Route::apiResource('projects', 'ProjectController'); Route::apiResource('tags', 'TagController'); Route::apiResource('links', 'LinkController'); + Route::apiResource('education', 'EducationController'); + Route::apiResource('experience', 'ExperienceController'); }); diff --git a/routes/backpack/custom.php b/routes/backpack/custom.php index d80e6f3b..ce0413e7 100644 --- a/routes/backpack/custom.php +++ b/routes/backpack/custom.php @@ -14,4 +14,6 @@ CRUD::resource('category', 'CategoryCrudController'); CRUD::resource('tag', 'TagCrudController'); CRUD::resource('project', 'ProjectCrudController'); -}); // this should be the absolute last line of this file + CRUD::resource('education', 'EducationCrudController'); + CRUD::resource('experience', 'ExperienceCrudController'); +}); // this should be the absolute last line of this file \ No newline at end of file