diff --git a/app/Http/Controllers/ToDoController.php b/app/Http/Controllers/ToDoController.php new file mode 100644 index 0000000..9b3f6a6 --- /dev/null +++ b/app/Http/Controllers/ToDoController.php @@ -0,0 +1,41 @@ +authorize('create', ToDoList::class); + + $toDo = $toDoList->toDos()->create($this->validateData()); + + return (new ToDoResource($toDo)) + ->response() + ->setStatusCode(201); + } + + public function update(ToDoList $toDoList, ToDo $toDo) + { + $this->authorize('update', $toDoList); + + $toDo->update($this->validateData()); + + return (new ToDoResource($toDo)) + ->response() + ->setStatusCode(200); + } + + private function validateData() + { + return request()->validate([ + 'name' => 'required', + ]); + } +} diff --git a/app/Http/Controllers/ToDoListController.php b/app/Http/Controllers/ToDoListController.php new file mode 100644 index 0000000..98fa2a3 --- /dev/null +++ b/app/Http/Controllers/ToDoListController.php @@ -0,0 +1,55 @@ +authorize('create', ToDoList::class); + + $toDoList = request()->user()->toDoLists()->create($this->validateData()); + + return (new ToDoListResource($toDoList)) + ->response() + ->setStatusCode(201); + } + + public function show(ToDoList $toDoList) + { + $this->authorize('view', $toDoList); + + return new ToDoListResource($toDoList); + } + + public function update(ToDoList $toDoList) + { + $this->authorize('update', $toDoList); + + $toDoList->update($this->validateData()); + + return (new ToDoListResource($toDoList)) + ->response() + ->setStatusCode(200); + } + + public function destroy(ToDoList $toDoList) + { + $this->authorize('delete', $toDoList); + + $toDoList->delete(); + + return response([], 204); + } + + private function validateData() + { + return request()->validate([ + 'name' => 'required', + ]); + } +} diff --git a/app/Http/Resources/ToDo.php b/app/Http/Resources/ToDo.php new file mode 100644 index 0000000..6341a48 --- /dev/null +++ b/app/Http/Resources/ToDo.php @@ -0,0 +1,35 @@ + [ + 'type' => 'to-dos', + 'to_do_id' => $this->id, + 'attributes' => [ + 'data' => [ + 'name' => $this->name, + 'order' => $this->order, + 'checked_at' => optional($this->checked_at)->diffForHumans(), + 'last_updated' => $this->updated_at->diffForHumans(), + ] + ] + ], + 'links' => [ + 'self' => url('/to-do-lists/'.$this->to_do_list_id), + ] + ]; + } +} diff --git a/app/Http/Resources/ToDoCollection.php b/app/Http/Resources/ToDoCollection.php new file mode 100644 index 0000000..2d53a16 --- /dev/null +++ b/app/Http/Resources/ToDoCollection.php @@ -0,0 +1,22 @@ + $this->collection, + 'to_dos_count' => $this->count(), + ]; + } +} diff --git a/app/Http/Resources/ToDoList.php b/app/Http/Resources/ToDoList.php new file mode 100644 index 0000000..534445f --- /dev/null +++ b/app/Http/Resources/ToDoList.php @@ -0,0 +1,38 @@ + [ + 'type' => 'to-do-lists', + 'to_do_list_id' => $this->id, + 'attributes' => [ + 'data' => [ + 'name' => $this->name, + 'to_dos' => new ToDoCollection($this->toDos), + 'posted_by' => new UserResource($this->user), + 'last_updated' => $this->updated_at->diffForHumans(), +// 'cover_image' => new ImageResource($this->coverImage), + ] + ] + //'tags' => TagResource::collection($this->tags), + ], + 'links' => [ + 'self' => $this->path(), + ] + ]; + } +} diff --git a/app/Models/ToDo.php b/app/Models/ToDo.php new file mode 100644 index 0000000..e9e975d --- /dev/null +++ b/app/Models/ToDo.php @@ -0,0 +1,18 @@ +belongsTo(ToDoList::class); + } +} diff --git a/app/Models/ToDoList.php b/app/Models/ToDoList.php new file mode 100644 index 0000000..c258cbc --- /dev/null +++ b/app/Models/ToDoList.php @@ -0,0 +1,28 @@ +id; + } + + public function users(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function toDos(): HasMany + { + return $this->hasMany(ToDo::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 5cd1eab..3d8cfcd 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -4,6 +4,7 @@ namespace App; use App\Models\Image; use App\Models\Memo; +use App\Models\ToDoList; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; @@ -82,4 +83,9 @@ class User extends Authenticatable $userImage->path = 'images/default-cover.jpg'; }); } + + public function toDoLists(): HasMany + { + return $this->hasMany(ToDoList::class); + } } diff --git a/app/Policies/ToDoListPolicy.php b/app/Policies/ToDoListPolicy.php new file mode 100644 index 0000000..94289af --- /dev/null +++ b/app/Policies/ToDoListPolicy.php @@ -0,0 +1,94 @@ +id == $toDoList->user_id; + } + + /** + * Determine whether the user can create to do lists. + * + * @param \App\User $user + * @return mixed + */ + public function create(User $user) + { + return true; + } + + /** + * Determine whether the user can update the to do list. + * + * @param \App\User $user + * @param \App\Models\ToDoList $toDoList + * @return mixed + */ + public function update(User $user, ToDoList $toDoList) + { + return $user->id == $toDoList->user_id; + } + + /** + * Determine whether the user can delete the to do list. + * + * @param \App\User $user + * @param \App\Models\ToDoList $toDoList + * @return mixed + */ + public function delete(User $user, ToDoList $toDoList) + { + return $user->id == $toDoList->user_id; + } + + /** + * Determine whether the user can restore the to do list. + * + * @param \App\User $user + * @param \App\Models\ToDoList $toDoList + * @return mixed + */ + public function restore(User $user, ToDoList $toDoList) + { + return false; + } + + /** + * Determine whether the user can permanently delete the to do list. + * + * @param \App\User $user + * @param \App\Models\ToDoList $toDoList + * @return mixed + */ + public function forceDelete(User $user, ToDoList $toDoList) + { + return false; + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 955985f..a1f63e0 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -17,6 +17,7 @@ class AuthServiceProvider extends ServiceProvider // 'App\Model' => 'App\Policies\ModelPolicy', 'App\User' => 'App\Policies\UserPolicy', 'App\Models\Memo' => 'App\Policies\MemoPolicy', + 'App\Models\ToDoList' => 'App\Policies\ToDoListPolicy', ]; /** diff --git a/database/factories/ToDoListFactory.php b/database/factories/ToDoListFactory.php new file mode 100644 index 0000000..6287b75 --- /dev/null +++ b/database/factories/ToDoListFactory.php @@ -0,0 +1,13 @@ +define(ToDoList::class, function (Faker $faker) { + return [ + 'user_id' => factory(\App\User::class), + 'name' => $faker->words(3, [false]), + ]; +}); diff --git a/database/migrations/2020_04_19_144900_create_to_do_lists_table.php b/database/migrations/2020_04_19_144900_create_to_do_lists_table.php new file mode 100644 index 0000000..dc8bd15 --- /dev/null +++ b/database/migrations/2020_04_19_144900_create_to_do_lists_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('to_do_lists'); + } +} diff --git a/database/migrations/2020_04_19_190733_create_to_dos_table.php b/database/migrations/2020_04_19_190733_create_to_dos_table.php new file mode 100644 index 0000000..75061c7 --- /dev/null +++ b/database/migrations/2020_04_19_190733_create_to_dos_table.php @@ -0,0 +1,35 @@ +id(); + $table->unsignedBigInteger('to_do_list_id'); + $table->string('name'); + $table->integer('order')->default(0); + $table->timestamp('checked_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('to_dos'); + } +} diff --git a/package.json b/package.json index d06d4b6..879612a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "eslint-plugin-vue": "^6.2.2", "laravel-mix": "^5.0.1", "laravel-mix-eslint": "^0.1.3", + "laravel-mix-purgecss": "^5.0.0-rc.2", "lodash": "^4.17.13", "resolve-url-loader": "^2.3.1", "sass": "^1.20.1", @@ -32,6 +33,7 @@ "dropzone": "^5.7.0", "laravel-mix-svg-vue": "^0.2.6", "markdown-it": "^10.0.0", - "markdown-it-checkbox": "^1.1.0" + "markdown-it-checkbox": "^1.1.0", + "tailwindcss": "^1.3.5" } } diff --git a/resources/js/components/App.vue b/resources/js/components/App.vue index 41ee1f7..8a80cbe 100644 --- a/resources/js/components/App.vue +++ b/resources/js/components/App.vue @@ -1,10 +1,10 @@