From c4f98fdb58b4fe0f674bfb4c2a53595600f11c41 Mon Sep 17 00:00:00 2001 From: robonen Date: Thu, 26 May 2022 11:20:47 +0700 Subject: [PATCH 1/3] All models --- backend/app/Models/Offer.php | 36 +++++++++++++++++ backend/app/Models/OfferPhoto.php | 21 ++++++++++ backend/app/Models/Order.php | 35 +++++++++++++++++ backend/app/Models/Review.php | 23 +++++++++++ backend/app/Models/User.php | 14 ++++--- backend/composer.json | 2 +- backend/composer.lock | 2 +- backend/config/auth.php | 5 --- .../2014_10_12_000000_create_users_table.php | 8 ++-- .../2022_05_26_030738_create_offers_table.php | 39 +++++++++++++++++++ ...5_26_035738_create_offer_photos_table.php} | 11 ++---- ...2022_05_26_035905_create_reviews_table.php | 35 +++++++++++++++++ .../2022_05_26_035920_create_orders_table.php | 37 ++++++++++++++++++ backend/routes/web.php | 6 +-- 14 files changed, 248 insertions(+), 26 deletions(-) create mode 100644 backend/app/Models/Offer.php create mode 100644 backend/app/Models/OfferPhoto.php create mode 100644 backend/app/Models/Order.php create mode 100644 backend/app/Models/Review.php create mode 100644 backend/database/migrations/2022_05_26_030738_create_offers_table.php rename backend/database/migrations/{2019_12_14_000001_create_personal_access_tokens_table.php => 2022_05_26_035738_create_offer_photos_table.php} (55%) create mode 100644 backend/database/migrations/2022_05_26_035905_create_reviews_table.php create mode 100644 backend/database/migrations/2022_05_26_035920_create_orders_table.php diff --git a/backend/app/Models/Offer.php b/backend/app/Models/Offer.php new file mode 100644 index 0000000..cbf399f --- /dev/null +++ b/backend/app/Models/Offer.php @@ -0,0 +1,36 @@ + + */ + protected $fillable = [ + 'owner_id', + 'name', + 'type', + 'price', + 'rooms', + 'yandex_mark', + 'text', + 'is_group', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ +// 'is_group' => 'boolean', + ]; +} diff --git a/backend/app/Models/OfferPhoto.php b/backend/app/Models/OfferPhoto.php new file mode 100644 index 0000000..8891912 --- /dev/null +++ b/backend/app/Models/OfferPhoto.php @@ -0,0 +1,21 @@ + + */ + protected $fillable = [ + 'offer_id', + 'file', + ]; +} diff --git a/backend/app/Models/Order.php b/backend/app/Models/Order.php new file mode 100644 index 0000000..5e19055 --- /dev/null +++ b/backend/app/Models/Order.php @@ -0,0 +1,35 @@ + + */ + protected $fillable = [ + 'offer_id', + 'user_id', + 'start_date', + 'end_date', + 'price', + 'discount', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'start_date' => 'datetime', + 'end_date' => 'datetime', + ]; +} diff --git a/backend/app/Models/Review.php b/backend/app/Models/Review.php new file mode 100644 index 0000000..e924c4a --- /dev/null +++ b/backend/app/Models/Review.php @@ -0,0 +1,23 @@ + + */ + protected $fillable = [ + 'offer_id', + 'user_id', + 'comment', + 'rating', + ]; +} diff --git a/backend/app/Models/User.php b/backend/app/Models/User.php index 8996368..0282ad6 100644 --- a/backend/app/Models/User.php +++ b/backend/app/Models/User.php @@ -2,7 +2,6 @@ namespace App\Models; -use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -18,8 +17,12 @@ class User extends Authenticatable * @var array */ protected $fillable = [ - 'name', + 'first_name', + 'last_name', + 'middle_name', 'email', + 'phone', + 'photo', 'password', ]; @@ -30,7 +33,6 @@ class User extends Authenticatable */ protected $hidden = [ 'password', - 'remember_token', ]; /** @@ -38,7 +40,7 @@ class User extends Authenticatable * * @var array */ - protected $casts = [ - 'email_verified_at' => 'datetime', - ]; +// protected $casts = [ +// 'email_verified_at' => 'datetime', +// ]; } diff --git a/backend/composer.json b/backend/composer.json index 164c94b..18a7cbb 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -13,7 +13,7 @@ }, "require-dev": { "fakerphp/faker": "^1.9.1", - "laravel/sail": "^1.0.1", + "laravel/sail": "^1.14", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^6.1", "phpunit/phpunit": "^9.5.10", diff --git a/backend/composer.lock b/backend/composer.lock index d337df3..7b5506a 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1abc7822bd9f28e9a62986817bf04f76", + "content-hash": "3c9da13e09c625e7ca22f1d572bd7f2d", "packages": [ { "name": "brick/math", diff --git a/backend/config/auth.php b/backend/config/auth.php index d8c6cee..2cbf567 100644 --- a/backend/config/auth.php +++ b/backend/config/auth.php @@ -64,11 +64,6 @@ return [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], - - // 'users' => [ - // 'driver' => 'database', - // 'table' => 'users', - // ], ], /* diff --git a/backend/database/migrations/2014_10_12_000000_create_users_table.php b/backend/database/migrations/2014_10_12_000000_create_users_table.php index cf6b776..6d3255e 100644 --- a/backend/database/migrations/2014_10_12_000000_create_users_table.php +++ b/backend/database/migrations/2014_10_12_000000_create_users_table.php @@ -15,11 +15,13 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('name'); + $table->string('first_name'); + $table->string('last_name'); + $table->string('middle_name')->nullable(); $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); + $table->string('phone')->unique()->nullable(); + $table->string('photo')->nullable(); $table->string('password'); - $table->rememberToken(); $table->timestamps(); }); } diff --git a/backend/database/migrations/2022_05_26_030738_create_offers_table.php b/backend/database/migrations/2022_05_26_030738_create_offers_table.php new file mode 100644 index 0000000..a3d0fd1 --- /dev/null +++ b/backend/database/migrations/2022_05_26_030738_create_offers_table.php @@ -0,0 +1,39 @@ +id(); + $table->foreignId('owner_id'); + $table->string('name'); + $table->enum('type', ['studio']); + $table->decimal('price'); + $table->unsignedSmallInteger('rooms'); + $table->string('yandex_mark')->nullable(); + $table->text('text'); + $table->boolean('is_group'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('offers'); + } +}; diff --git a/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php similarity index 55% rename from backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php rename to backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php index fd235f8..6e5f8e5 100644 --- a/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php @@ -13,13 +13,10 @@ return new class extends Migration */ public function up() { - Schema::create('personal_access_tokens', function (Blueprint $table) { + Schema::create('offer_photos', function (Blueprint $table) { $table->id(); - $table->morphs('tokenable'); - $table->string('name'); - $table->string('token', 64)->unique(); - $table->text('abilities')->nullable(); - $table->timestamp('last_used_at')->nullable(); + $table->foreignId('offer_id'); + $table->string('file'); $table->timestamps(); }); } @@ -31,6 +28,6 @@ return new class extends Migration */ public function down() { - Schema::dropIfExists('personal_access_tokens'); + Schema::dropIfExists('offer_photos'); } }; diff --git a/backend/database/migrations/2022_05_26_035905_create_reviews_table.php b/backend/database/migrations/2022_05_26_035905_create_reviews_table.php new file mode 100644 index 0000000..62106f4 --- /dev/null +++ b/backend/database/migrations/2022_05_26_035905_create_reviews_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('offer_id'); + $table->foreignId('user_id'); + $table->text('comment'); + $table->unsignedFloat('rating'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('reviews'); + } +}; diff --git a/backend/database/migrations/2022_05_26_035920_create_orders_table.php b/backend/database/migrations/2022_05_26_035920_create_orders_table.php new file mode 100644 index 0000000..8375b27 --- /dev/null +++ b/backend/database/migrations/2022_05_26_035920_create_orders_table.php @@ -0,0 +1,37 @@ +id(); + $table->foreignId('offer_id'); + $table->foreignId('user_id'); + $table->date('start_date'); + $table->date('end_date'); + $table->decimal('price'); + $table->decimal('discount'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('orders'); + } +}; diff --git a/backend/routes/web.php b/backend/routes/web.php index b130397..edd263d 100644 --- a/backend/routes/web.php +++ b/backend/routes/web.php @@ -13,6 +13,6 @@ use Illuminate\Support\Facades\Route; | */ -Route::get('/', function () { - return view('welcome'); -}); +//Route::get('/', function () { +// return view('welcome'); +//}); From dc539ed9113f4e17c42174e43ae8b89fb03dd1d6 Mon Sep 17 00:00:00 2001 From: robonen Date: Fri, 27 May 2022 12:01:28 +0700 Subject: [PATCH 2/3] Offer and order controllers --- backend/app/Enums/Arrayable.php | 14 ++++ backend/app/Enums/OrderTypesEnum.php | 13 ++++ .../app/Http/Controllers/OfferController.php | 70 +++++++++++++++++++ .../app/Http/Controllers/OrderController.php | 70 +++++++++++++++++++ .../app/Http/Controllers/ReviewController.php | 63 +++++++++++++++++ .../app/Http/Controllers/UserController.php | 63 +++++++++++++++++ backend/app/Http/Requests/BaseRequest.php | 18 +++++ .../app/Http/Requests/StoreOfferRequest.php | 29 ++++++++ .../app/Http/Requests/StoreOrderRequest.php | 23 ++++++ .../app/Http/Requests/UpdateOfferRequest.php | 29 ++++++++ .../app/Http/Requests/UpdateOrderRequest.php | 23 ++++++ backend/app/Http/Resources/OfferResource.php | 19 +++++ backend/app/Http/Resources/OrderResource.php | 19 +++++ backend/app/Http/Resources/ReviewResource.php | 19 +++++ backend/app/Models/Offer.php | 8 ++- backend/app/Models/Order.php | 2 + backend/app/Providers/AuthServiceProvider.php | 2 - backend/database/factories/UserFactory.php | 20 +----- .../2022_05_26_030738_create_offers_table.php | 6 +- backend/database/seeders/DatabaseSeeder.php | 4 +- backend/routes/api.php | 8 +-- 21 files changed, 493 insertions(+), 29 deletions(-) create mode 100644 backend/app/Enums/Arrayable.php create mode 100644 backend/app/Enums/OrderTypesEnum.php create mode 100644 backend/app/Http/Controllers/OfferController.php create mode 100644 backend/app/Http/Controllers/OrderController.php create mode 100644 backend/app/Http/Controllers/ReviewController.php create mode 100644 backend/app/Http/Controllers/UserController.php create mode 100644 backend/app/Http/Requests/BaseRequest.php create mode 100644 backend/app/Http/Requests/StoreOfferRequest.php create mode 100644 backend/app/Http/Requests/StoreOrderRequest.php create mode 100644 backend/app/Http/Requests/UpdateOfferRequest.php create mode 100644 backend/app/Http/Requests/UpdateOrderRequest.php create mode 100644 backend/app/Http/Resources/OfferResource.php create mode 100644 backend/app/Http/Resources/OrderResource.php create mode 100644 backend/app/Http/Resources/ReviewResource.php diff --git a/backend/app/Enums/Arrayable.php b/backend/app/Enums/Arrayable.php new file mode 100644 index 0000000..9480289 --- /dev/null +++ b/backend/app/Enums/Arrayable.php @@ -0,0 +1,14 @@ +validated())); + } + + /** + * Update the specified resource in storage. + * + * @param \App\Http\Requests\UpdateOfferRequest $request + * @param int $id + * @return void + */ + public function update(UpdateOfferRequest $request, int $id): void + { + $offer = Offer::findOrFail($id); + $offer->update($request->validated()); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return void + */ + public function destroy(int $id): void + { + $offer = Offer::findOrFail($id); + $offer->delete(); + } +} diff --git a/backend/app/Http/Controllers/OrderController.php b/backend/app/Http/Controllers/OrderController.php new file mode 100644 index 0000000..ffa1f0f --- /dev/null +++ b/backend/app/Http/Controllers/OrderController.php @@ -0,0 +1,70 @@ +validated())); + } + + /** + * Update the specified resource in storage. + * + * @param \App\Http\Requests\UpdateOfferRequest $request + * @param int $id + * @return void + */ + public function update(UpdateOfferRequest $request, int $id): void + { + $order = Order::findOrFail($id); + $order->update($request->validated()); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return void + */ + public function destroy(int $id): void + { + $order = Order::findOrFail($id); + $order->delete(); + } +} diff --git a/backend/app/Http/Controllers/ReviewController.php b/backend/app/Http/Controllers/ReviewController.php new file mode 100644 index 0000000..e99691c --- /dev/null +++ b/backend/app/Http/Controllers/ReviewController.php @@ -0,0 +1,63 @@ + + */ + public function rules(): array + { + return [ + 'owner_id' => ['required', 'numeric', 'exists:users,id'], + 'name' => ['required', 'string'], + 'type' => ['required', new Enum(OrderTypesEnum::class)], + 'price' => ['required', 'numeric'], + 'rooms' => ['required', 'numeric'], + 'yandex_mark' => ['string'], + 'location' => ['required', 'string'], + 'description' => ['required', 'string'], + 'is_group' => ['required', 'boolean'], + ]; + } +} diff --git a/backend/app/Http/Requests/StoreOrderRequest.php b/backend/app/Http/Requests/StoreOrderRequest.php new file mode 100644 index 0000000..83f8d2e --- /dev/null +++ b/backend/app/Http/Requests/StoreOrderRequest.php @@ -0,0 +1,23 @@ + + */ + public function rules(): array + { + return [ + 'offer_id' => ['required', 'numeric', 'exists:offers,id'], + 'user_id' => ['required', 'numeric', 'exists:users,id'], + 'start_date' => ['required', 'date', 'after_or_equal:today'], + 'end_date' => ['required', 'date', 'after_or_equal:tomorrow'], + 'price' => ['required', 'numeric', 'min:0.1'], + 'discount' => ['required', 'numeric', 'min:0'], + ]; + } +} diff --git a/backend/app/Http/Requests/UpdateOfferRequest.php b/backend/app/Http/Requests/UpdateOfferRequest.php new file mode 100644 index 0000000..8f74124 --- /dev/null +++ b/backend/app/Http/Requests/UpdateOfferRequest.php @@ -0,0 +1,29 @@ + + */ + public function rules(): array + { + return [ + 'owner_id' => ['numeric', 'exists:users,id'], + 'name' => ['string'], + 'type' => [new Enum(OrderTypesEnum::class)], + 'price' => ['numeric'], + 'rooms' => ['numeric'], + 'yandex_mark' => ['string'], + 'location' => ['string'], + 'description' => ['string'], + 'is_group' => ['boolean'], + ]; + } +} diff --git a/backend/app/Http/Requests/UpdateOrderRequest.php b/backend/app/Http/Requests/UpdateOrderRequest.php new file mode 100644 index 0000000..1ff4f25 --- /dev/null +++ b/backend/app/Http/Requests/UpdateOrderRequest.php @@ -0,0 +1,23 @@ + + */ + public function rules(): array + { + return [ + 'offer_id' => ['numeric', 'exists:offers,id'], + 'user_id' => ['numeric', 'exists:users,id'], + 'start_date' => ['date'], + 'end_date' => ['date'], + 'price' => ['numeric', 'min:0.1'], + 'discount' => ['numeric', 'min:0.1'], + ]; + } +} diff --git a/backend/app/Http/Resources/OfferResource.php b/backend/app/Http/Resources/OfferResource.php new file mode 100644 index 0000000..a310268 --- /dev/null +++ b/backend/app/Http/Resources/OfferResource.php @@ -0,0 +1,19 @@ + */ protected $casts = [ -// 'is_group' => 'boolean', + 'type' => OrderTypesEnum::class, + 'price' => 'double', + 'is_group' => 'boolean', ]; } diff --git a/backend/app/Models/Order.php b/backend/app/Models/Order.php index 5e19055..b2606c6 100644 --- a/backend/app/Models/Order.php +++ b/backend/app/Models/Order.php @@ -31,5 +31,7 @@ class Order extends Model protected $casts = [ 'start_date' => 'datetime', 'end_date' => 'datetime', + 'price' => 'double', + 'discount' => 'double', ]; } diff --git a/backend/app/Providers/AuthServiceProvider.php b/backend/app/Providers/AuthServiceProvider.php index 51b351b..71235d4 100644 --- a/backend/app/Providers/AuthServiceProvider.php +++ b/backend/app/Providers/AuthServiceProvider.php @@ -24,7 +24,5 @@ class AuthServiceProvider extends ServiceProvider public function boot() { $this->registerPolicies(); - - // } } diff --git a/backend/database/factories/UserFactory.php b/backend/database/factories/UserFactory.php index 23b61d2..d1b5f38 100644 --- a/backend/database/factories/UserFactory.php +++ b/backend/database/factories/UserFactory.php @@ -18,25 +18,11 @@ class UserFactory extends Factory public function definition() { return [ - 'name' => $this->faker->name(), + 'first_name' => $this->faker->firstName(), + 'last_name' => $this->faker->lastName(), 'email' => $this->faker->unique()->safeEmail(), - 'email_verified_at' => now(), + 'phone' => $this->faker->unique()->e164PhoneNumber(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), ]; } - - /** - * Indicate that the model's email address should be unverified. - * - * @return static - */ - public function unverified() - { - return $this->state(function (array $attributes) { - return [ - 'email_verified_at' => null, - ]; - }); - } } diff --git a/backend/database/migrations/2022_05_26_030738_create_offers_table.php b/backend/database/migrations/2022_05_26_030738_create_offers_table.php index a3d0fd1..5fa50f5 100644 --- a/backend/database/migrations/2022_05_26_030738_create_offers_table.php +++ b/backend/database/migrations/2022_05_26_030738_create_offers_table.php @@ -1,5 +1,6 @@ id(); $table->foreignId('owner_id'); $table->string('name'); - $table->enum('type', ['studio']); + $table->enum('type', OrderTypesEnum::values()); $table->decimal('price'); $table->unsignedSmallInteger('rooms'); $table->string('yandex_mark')->nullable(); - $table->text('text'); + $table->string('location'); + $table->text('description'); $table->boolean('is_group'); $table->timestamps(); }); diff --git a/backend/database/seeders/DatabaseSeeder.php b/backend/database/seeders/DatabaseSeeder.php index c1c48a0..95fd531 100644 --- a/backend/database/seeders/DatabaseSeeder.php +++ b/backend/database/seeders/DatabaseSeeder.php @@ -2,7 +2,7 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; +use App\Models\User; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder @@ -14,7 +14,7 @@ class DatabaseSeeder extends Seeder */ public function run() { - // \App\Models\User::factory(10)->create(); + User::factory(10)->create(); // \App\Models\User::factory()->create([ // 'name' => 'Test User', diff --git a/backend/routes/api.php b/backend/routes/api.php index eb6fa48..1abbc85 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -1,6 +1,7 @@ get('/user', function (Request $request) { - return $request->user(); -}); +Route::apiResource('/offers', OfferController::class); +Route::apiResource('/orders', OrderController::class); From 55bc2e08f8dde302ad457ae1260cef6f6d9b09f8 Mon Sep 17 00:00:00 2001 From: robonen Date: Sat, 28 May 2022 22:55:36 +0700 Subject: [PATCH 3/3] User authentication --- .../Http/Controllers/Auth/LoginController.php | 26 ++++++++ .../Controllers/Auth/LogoutController.php | 17 +++++ .../Auth/RegistrationController.php | 30 +++++++++ .../app/Http/Controllers/ReviewController.php | 63 ------------------- .../app/Http/Controllers/UserController.php | 51 +++------------ backend/app/Http/Kernel.php | 2 +- .../app/Http/Requests/Auth/LoginRequest.php | 21 +++++++ .../Requests/Auth/RegistrationRequest.php | 21 +++++++ .../app/Http/Requests/StoreOfferRequest.php | 7 ++- .../app/Http/Requests/StoreOrderRequest.php | 2 - .../app/Http/Requests/UpdateOfferRequest.php | 7 ++- .../app/Http/Requests/UpdateOrderRequest.php | 2 - .../app/Http/Requests/UpdateUserRequest.php | 22 +++++++ .../{ReviewResource.php => UserResource.php} | 2 +- .../app/Models/{Review.php => Feedback.php} | 3 +- backend/app/Models/Offer.php | 4 +- backend/app/Models/Order.php | 4 -- backend/app/Models/User.php | 9 --- .../2014_10_12_000000_create_users_table.php | 4 +- ...01_create_personal_access_tokens_table.php | 36 +++++++++++ .../2022_05_26_030738_create_offers_table.php | 8 ++- ...05_26_035738_create_offer_photos_table.php | 6 +- ...22_05_26_035905_create_feedback_table.php} | 12 ++-- .../2022_05_26_035920_create_orders_table.php | 16 +++-- backend/routes/api.php | 32 +++++++++- 25 files changed, 260 insertions(+), 147 deletions(-) create mode 100644 backend/app/Http/Controllers/Auth/LoginController.php create mode 100644 backend/app/Http/Controllers/Auth/LogoutController.php create mode 100644 backend/app/Http/Controllers/Auth/RegistrationController.php delete mode 100644 backend/app/Http/Controllers/ReviewController.php create mode 100644 backend/app/Http/Requests/Auth/LoginRequest.php create mode 100644 backend/app/Http/Requests/Auth/RegistrationRequest.php create mode 100644 backend/app/Http/Requests/UpdateUserRequest.php rename backend/app/Http/Resources/{ReviewResource.php => UserResource.php} (90%) rename backend/app/Models/{Review.php => Feedback.php} (87%) create mode 100644 backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php rename backend/database/migrations/{2022_05_26_035905_create_reviews_table.php => 2022_05_26_035905_create_feedback_table.php} (66%) diff --git a/backend/app/Http/Controllers/Auth/LoginController.php b/backend/app/Http/Controllers/Auth/LoginController.php new file mode 100644 index 0000000..ff1dde6 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/LoginController.php @@ -0,0 +1,26 @@ +attempt($request->validated())) + abort(401); + + $token = auth()->user()->createToken('web')->plainTextToken; + + return (new UserResource(auth()->user())) + ->additional(['token' => $token]); + } +} diff --git a/backend/app/Http/Controllers/Auth/LogoutController.php b/backend/app/Http/Controllers/Auth/LogoutController.php new file mode 100644 index 0000000..5ae6f18 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/LogoutController.php @@ -0,0 +1,17 @@ +user()->currentAccessToken()->delete(); + } +} diff --git a/backend/app/Http/Controllers/Auth/RegistrationController.php b/backend/app/Http/Controllers/Auth/RegistrationController.php new file mode 100644 index 0000000..c27ab32 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/RegistrationController.php @@ -0,0 +1,30 @@ +validated(); + $credentials['password'] = Hash::make($credentials['password']); + + auth()->login(User::create($credentials)); + + $token = auth()->user()->createToken('web')->plainTextToken; + + return (new UserResource(auth()->user())) + ->additional(['token' => $token]); + } +} diff --git a/backend/app/Http/Controllers/ReviewController.php b/backend/app/Http/Controllers/ReviewController.php deleted file mode 100644 index e99691c..0000000 --- a/backend/app/Http/Controllers/ReviewController.php +++ /dev/null @@ -1,63 +0,0 @@ -user()); } /** * Update the specified resource in storage. * - * @param \Illuminate\Http\Request $request - * @param int $id - * @return \Illuminate\Http\Response + * @param \App\Http\Requests\UpdateUserRequest $request + * @return void */ - public function update(Request $request, $id) + public function update(UpdateUserRequest $request): void { - // - } - - /** - * Remove the specified resource from storage. - * - * @param int $id - * @return \Illuminate\Http\Response - */ - public function destroy($id) - { - // + auth()->user()->update($request->validated()); } } diff --git a/backend/app/Http/Kernel.php b/backend/app/Http/Kernel.php index c3be254..6ead053 100644 --- a/backend/app/Http/Kernel.php +++ b/backend/app/Http/Kernel.php @@ -39,7 +39,7 @@ class Kernel extends HttpKernel ], 'api' => [ - // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], diff --git a/backend/app/Http/Requests/Auth/LoginRequest.php b/backend/app/Http/Requests/Auth/LoginRequest.php new file mode 100644 index 0000000..9af72c6 --- /dev/null +++ b/backend/app/Http/Requests/Auth/LoginRequest.php @@ -0,0 +1,21 @@ + + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email', 'exists:users'], + 'password' => ['required', 'string'], + ]; + } +} diff --git a/backend/app/Http/Requests/Auth/RegistrationRequest.php b/backend/app/Http/Requests/Auth/RegistrationRequest.php new file mode 100644 index 0000000..ca18e41 --- /dev/null +++ b/backend/app/Http/Requests/Auth/RegistrationRequest.php @@ -0,0 +1,21 @@ + + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email', 'unique:users'], + 'password' => ['required', 'string'], + ]; + } +} diff --git a/backend/app/Http/Requests/StoreOfferRequest.php b/backend/app/Http/Requests/StoreOfferRequest.php index b450247..15615dd 100644 --- a/backend/app/Http/Requests/StoreOfferRequest.php +++ b/backend/app/Http/Requests/StoreOfferRequest.php @@ -15,11 +15,12 @@ class StoreOfferRequest extends BaseRequest public function rules(): array { return [ - 'owner_id' => ['required', 'numeric', 'exists:users,id'], + 'user_id' => ['required', 'numeric', 'exists:users,id'], 'name' => ['required', 'string'], 'type' => ['required', new Enum(OrderTypesEnum::class)], - 'price' => ['required', 'numeric'], - 'rooms' => ['required', 'numeric'], + 'price' => ['required', 'numeric', 'min:0.1'], + 'rooms' => ['required', 'numeric', 'min:1'], + 'space' => ['required', 'numeric', 'min:1'], 'yandex_mark' => ['string'], 'location' => ['required', 'string'], 'description' => ['required', 'string'], diff --git a/backend/app/Http/Requests/StoreOrderRequest.php b/backend/app/Http/Requests/StoreOrderRequest.php index 83f8d2e..ee44d82 100644 --- a/backend/app/Http/Requests/StoreOrderRequest.php +++ b/backend/app/Http/Requests/StoreOrderRequest.php @@ -14,8 +14,6 @@ class StoreOrderRequest extends BaseRequest return [ 'offer_id' => ['required', 'numeric', 'exists:offers,id'], 'user_id' => ['required', 'numeric', 'exists:users,id'], - 'start_date' => ['required', 'date', 'after_or_equal:today'], - 'end_date' => ['required', 'date', 'after_or_equal:tomorrow'], 'price' => ['required', 'numeric', 'min:0.1'], 'discount' => ['required', 'numeric', 'min:0'], ]; diff --git a/backend/app/Http/Requests/UpdateOfferRequest.php b/backend/app/Http/Requests/UpdateOfferRequest.php index 8f74124..4e0903e 100644 --- a/backend/app/Http/Requests/UpdateOfferRequest.php +++ b/backend/app/Http/Requests/UpdateOfferRequest.php @@ -15,11 +15,12 @@ class UpdateOfferRequest extends BaseRequest public function rules(): array { return [ - 'owner_id' => ['numeric', 'exists:users,id'], + 'user_id' => ['numeric', 'exists:users,id'], 'name' => ['string'], 'type' => [new Enum(OrderTypesEnum::class)], - 'price' => ['numeric'], - 'rooms' => ['numeric'], + 'price' => ['numeric', 'min:0.1'], + 'rooms' => ['numeric', 'min:1'], + 'space' => ['numeric', 'min:1'], 'yandex_mark' => ['string'], 'location' => ['string'], 'description' => ['string'], diff --git a/backend/app/Http/Requests/UpdateOrderRequest.php b/backend/app/Http/Requests/UpdateOrderRequest.php index 1ff4f25..abf195d 100644 --- a/backend/app/Http/Requests/UpdateOrderRequest.php +++ b/backend/app/Http/Requests/UpdateOrderRequest.php @@ -14,8 +14,6 @@ class UpdateOrderRequest extends BaseRequest return [ 'offer_id' => ['numeric', 'exists:offers,id'], 'user_id' => ['numeric', 'exists:users,id'], - 'start_date' => ['date'], - 'end_date' => ['date'], 'price' => ['numeric', 'min:0.1'], 'discount' => ['numeric', 'min:0.1'], ]; diff --git a/backend/app/Http/Requests/UpdateUserRequest.php b/backend/app/Http/Requests/UpdateUserRequest.php new file mode 100644 index 0000000..8315f86 --- /dev/null +++ b/backend/app/Http/Requests/UpdateUserRequest.php @@ -0,0 +1,22 @@ + + */ + public function rules() + { + return [ + 'first_name' => ['string'], + 'last_name' => ['string'], + 'middle_name' => ['string'], + 'email' => ['string', 'email', 'unique:users'], + 'phone' => ['string'], + ]; + } +} diff --git a/backend/app/Http/Resources/ReviewResource.php b/backend/app/Http/Resources/UserResource.php similarity index 90% rename from backend/app/Http/Resources/ReviewResource.php rename to backend/app/Http/Resources/UserResource.php index f866bbe..7a74549 100644 --- a/backend/app/Http/Resources/ReviewResource.php +++ b/backend/app/Http/Resources/UserResource.php @@ -4,7 +4,7 @@ namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; -class ReviewResource extends JsonResource +class UserResource extends JsonResource { /** * Transform the resource into an array. diff --git a/backend/app/Models/Review.php b/backend/app/Models/Feedback.php similarity index 87% rename from backend/app/Models/Review.php rename to backend/app/Models/Feedback.php index e924c4a..c453313 100644 --- a/backend/app/Models/Review.php +++ b/backend/app/Models/Feedback.php @@ -5,7 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Review extends Model +class Feedback extends Model { use HasFactory; @@ -15,7 +15,6 @@ class Review extends Model * @var array */ protected $fillable = [ - 'offer_id', 'user_id', 'comment', 'rating', diff --git a/backend/app/Models/Offer.php b/backend/app/Models/Offer.php index 99d752c..edb7327 100644 --- a/backend/app/Models/Offer.php +++ b/backend/app/Models/Offer.php @@ -16,11 +16,12 @@ class Offer extends Model * @var array */ protected $fillable = [ - 'owner_id', + 'user_id', 'name', 'type', 'price', 'rooms', + 'space', 'yandex_mark', 'location', 'description', @@ -34,6 +35,7 @@ class Offer extends Model */ protected $casts = [ 'type' => OrderTypesEnum::class, + 'space' => 'double', 'price' => 'double', 'is_group' => 'boolean', ]; diff --git a/backend/app/Models/Order.php b/backend/app/Models/Order.php index b2606c6..d8c0c20 100644 --- a/backend/app/Models/Order.php +++ b/backend/app/Models/Order.php @@ -17,8 +17,6 @@ class Order extends Model protected $fillable = [ 'offer_id', 'user_id', - 'start_date', - 'end_date', 'price', 'discount', ]; @@ -29,8 +27,6 @@ class Order extends Model * @var array */ protected $casts = [ - 'start_date' => 'datetime', - 'end_date' => 'datetime', 'price' => 'double', 'discount' => 'double', ]; diff --git a/backend/app/Models/User.php b/backend/app/Models/User.php index 0282ad6..0dd1542 100644 --- a/backend/app/Models/User.php +++ b/backend/app/Models/User.php @@ -34,13 +34,4 @@ class User extends Authenticatable protected $hidden = [ 'password', ]; - - /** - * The attributes that should be cast. - * - * @var array - */ -// protected $casts = [ -// 'email_verified_at' => 'datetime', -// ]; } diff --git a/backend/database/migrations/2014_10_12_000000_create_users_table.php b/backend/database/migrations/2014_10_12_000000_create_users_table.php index 6d3255e..02eec63 100644 --- a/backend/database/migrations/2014_10_12_000000_create_users_table.php +++ b/backend/database/migrations/2014_10_12_000000_create_users_table.php @@ -15,8 +15,8 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('first_name'); - $table->string('last_name'); + $table->string('first_name')->nullable(); + $table->string('last_name')->nullable(); $table->string('middle_name')->nullable(); $table->string('email')->unique(); $table->string('phone')->unique()->nullable(); diff --git a/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 0000000..3ce0002 --- /dev/null +++ b/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +} diff --git a/backend/database/migrations/2022_05_26_030738_create_offers_table.php b/backend/database/migrations/2022_05_26_030738_create_offers_table.php index 5fa50f5..186ccf1 100644 --- a/backend/database/migrations/2022_05_26_030738_create_offers_table.php +++ b/backend/database/migrations/2022_05_26_030738_create_offers_table.php @@ -16,16 +16,22 @@ return new class extends Migration { Schema::create('offers', function (Blueprint $table) { $table->id(); - $table->foreignId('owner_id'); $table->string('name'); $table->enum('type', OrderTypesEnum::values()); $table->decimal('price'); $table->unsignedSmallInteger('rooms'); + $table->decimal('space'); $table->string('yandex_mark')->nullable(); $table->string('location'); $table->text('description'); $table->boolean('is_group'); $table->timestamps(); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); }); } diff --git a/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php index 6e5f8e5..4022a15 100644 --- a/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php +++ b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php @@ -15,9 +15,13 @@ return new class extends Migration { Schema::create('offer_photos', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); $table->string('file'); $table->timestamps(); + + $table + ->foreignId('offer_id') + ->constrained() + ->onUpdate('cascade'); }); } diff --git a/backend/database/migrations/2022_05_26_035905_create_reviews_table.php b/backend/database/migrations/2022_05_26_035905_create_feedback_table.php similarity index 66% rename from backend/database/migrations/2022_05_26_035905_create_reviews_table.php rename to backend/database/migrations/2022_05_26_035905_create_feedback_table.php index 62106f4..2c452da 100644 --- a/backend/database/migrations/2022_05_26_035905_create_reviews_table.php +++ b/backend/database/migrations/2022_05_26_035905_create_feedback_table.php @@ -13,13 +13,17 @@ return new class extends Migration */ public function up() { - Schema::create('reviews', function (Blueprint $table) { + Schema::create('feedback', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); - $table->foreignId('user_id'); $table->text('comment'); $table->unsignedFloat('rating'); $table->timestamps(); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('cascade') + ->onUpdate('cascade'); }); } @@ -30,6 +34,6 @@ return new class extends Migration */ public function down() { - Schema::dropIfExists('reviews'); + Schema::dropIfExists('feedback'); } }; diff --git a/backend/database/migrations/2022_05_26_035920_create_orders_table.php b/backend/database/migrations/2022_05_26_035920_create_orders_table.php index 8375b27..aa256a6 100644 --- a/backend/database/migrations/2022_05_26_035920_create_orders_table.php +++ b/backend/database/migrations/2022_05_26_035920_create_orders_table.php @@ -15,13 +15,21 @@ return new class extends Migration { Schema::create('orders', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); - $table->foreignId('user_id'); - $table->date('start_date'); - $table->date('end_date'); $table->decimal('price'); $table->decimal('discount'); $table->timestamps(); + + $table + ->foreignId('offer_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); }); } diff --git a/backend/routes/api.php b/backend/routes/api.php index 1abbc85..42ae39e 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -1,7 +1,11 @@ group(function() { + + Route::post('registration', RegistrationController::class); + Route::post('login', LoginController::class); + + Route::middleware('auth:sanctum')->group(function() { + Route::post('logout', LogoutController::class); + }); + +}); + +Route::middleware('auth:sanctum')->group(function() { + + Route::prefix('user')->group(function() { + Route::get('', [UserController::class, 'index']); + Route::put('', [UserController::class, 'update']); + }); + + Route::apiResource('orders', OrderController::class); + +}); + +Route::apiResource('offers', OfferController::class); + +// TODO: На главной странице 6 самых дорогих квартир +// TODO: Последние добавленные квартиры + фильтры