Skip to content

Commit 66c071b

Browse files
authored
Feature/sho 42 review dun produit (#30)
* feat: (SHO-42) add review product fonction * feat: wip * feat:(SHO-42) add review functionnality * fix:(SHO-42) fixint lint error * fix:(SHO-42) remove uneccessary thing(link lib and file) * refact: (SHO-42) refactoring of some file * feat:(SHO-42) change livewire to volt view and add DTO prince * refact:(SHO-42) refactor some component * refact:(SHO-42) refactoring of review list and add factory for review * refact:(SHO-42) adding declare strict * refact:(SHO-42) adding seeder to creat 100 reviews for exist product * feat:(SHO-42 resolve pint error) * feat:(SHO-42) add product title * feat:(SHO-42) change #[On('reviewCreated')] place * feat:(SHO-42) some change based on review added * refact:(SHO-42) add review to refact code to add product view * fix(test):(SHO-42) fixing remove form also to test when set data
1 parent c1ea792 commit 66c071b

File tree

23 files changed

+567
-15
lines changed

23 files changed

+567
-15
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Product;
6+
7+
use App\Models\User;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Shopper\Core\Models\Review;
10+
11+
final class AddProductReviewAction
12+
{
13+
// @phpstan-ignore-next-line
14+
public function execute(Model $reviewrateable, array $data, User $author): Review
15+
{
16+
// @phpstan-ignore-next-line
17+
return $reviewrateable->rating(array_merge($data, ['approved' => true]), $author);
18+
}
19+
}

app/DTO/ProductReviewsData.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\DTO;
6+
7+
use Illuminate\Support\Collection;
8+
9+
class ProductReviewsData
10+
{
11+
public function __construct(
12+
public Collection $reviews,
13+
public float $averageRating = 0,
14+
) {}
15+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Modals\Product;
6+
7+
use App\Actions\Product\AddProductReviewAction;
8+
use App\Models\Product;
9+
use Filament\Notifications\Notification;
10+
use Illuminate\Contracts\View\View;
11+
use Illuminate\Support\Facades\Auth;
12+
use Illuminate\Validation\ValidationException;
13+
use Livewire\Attributes\Validate;
14+
use LivewireUI\Modal\ModalComponent;
15+
16+
final class AddProductReview extends ModalComponent
17+
{
18+
public Product $product;
19+
20+
#[Validate('required|integer|min:1|max:5')]
21+
public int $rating = 1;
22+
23+
#[Validate('nullable|string|max:255')]
24+
public ?string $title = null;
25+
26+
#[Validate('nullable|string|max:255')]
27+
public ?string $content = null;
28+
29+
/**
30+
* @throws ValidationException
31+
*/
32+
public function save(): void
33+
{
34+
app(AddProductReviewAction::class)
35+
->execute($this->product, $this->validate(), Auth::user());
36+
37+
Notification::make()
38+
->title(__('Review added'))
39+
->body(__('The review has been added.'))
40+
->success()
41+
->send();
42+
43+
$this->dispatch('reviewCreated');
44+
45+
$this->closeModal();
46+
}
47+
48+
public function update(int $rate): void
49+
{
50+
$this->rating = $rate;
51+
}
52+
53+
public function render(): View
54+
{
55+
return view('livewire.modals.product.add-product-review');
56+
}
57+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Modals;
6+
7+
use App\DTO\ProductReviewsData;
8+
use App\Models\Product;
9+
use Illuminate\Contracts\View\View;
10+
use Laravelcm\LivewireSlideOvers\SlideOverComponent;
11+
use Livewire\Attributes\Computed;
12+
13+
class ReviewsList extends SlideOverComponent
14+
{
15+
public Product $product;
16+
17+
#[Computed]
18+
public function productReviews(): ProductReviewsData
19+
{
20+
return new ProductReviewsData(
21+
reviews: $this->product->getApprovedRatings($this->product->id),
22+
averageRating: floatval($this->product->averageRating(1)->first())
23+
);
24+
}
25+
26+
public static function panelMaxWidth(): string
27+
{
28+
return 'lg';
29+
}
30+
31+
public function render(): View
32+
{
33+
return view('livewire.modals.reviews-list');
34+
}
35+
}

app/Livewire/Pages/SingleProduct.php

100755100644
File mode changed.

app/Models/Product.php

100755100644
File mode changed.

app/Traits/HasProductRatings.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Traits;
6+
7+
use App\Models\Product;
8+
use Illuminate\Support\Collection;
9+
10+
trait HasProductRatings
11+
{
12+
public float $averageRating = 0;
13+
14+
public float $reviewsCount = 0;
15+
16+
public ?Collection $reviews = null;
17+
18+
public function loadProductRatings(Product $product, int $limit = 3): void
19+
{
20+
// @phpstan-ignore-next-line
21+
$this->averageRating = floatval($product->averageRating(1)->first()) ?? $this->averageRating;
22+
$this->reviewsCount = $product->countRating();
23+
$this->reviews = $product->getApprovedRatings($product->id);
24+
}
25+
}

database/seeders/DatabaseSeeder.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public function run(): void
2626
);
2727

2828
$this->command->info('All products created.');
29+
30+
$this->call(ReviewSeeder::class);
2931
}
3032

3133
protected function withProgressBar(int $total, Closure $createCollectionOfOne): Collection

database/seeders/ReviewSeeder.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Database\Seeders;
6+
7+
use App\Models\Product;
8+
use App\Models\User;
9+
use Illuminate\Database\Seeder;
10+
use Shopper\Core\Models\Review;
11+
12+
class ReviewSeeder extends Seeder
13+
{
14+
/**
15+
* Run the database seeds.
16+
*/
17+
public function run(): void
18+
{
19+
for ($i = 1; $i <= 100; $i++) {
20+
Review::query()->create([
21+
'rating' => fake()->numberBetween(1, 5),
22+
'content' => fake()->realText(),
23+
'reviewrateable_id' => Product::all()->random()->id,
24+
'reviewrateable_type' => 'product',
25+
'approved' => true,
26+
'author_id' => User::all()->random()->id,
27+
'author_type' => User::class,
28+
]);
29+
}
30+
}
31+
}

lang/vendor/shopper/en/pages/products.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
'review_content' => 'Content',
8181
'status' => 'Status',
8282
'rating' => 'Rating',
83+
'rating_count' => ':rating out of :count stars',
8384

8485
'modal' => [
8586
'title' => 'Delete Review',

0 commit comments

Comments
 (0)