first upload all files
This commit is contained in:
27
Modules/Review/Admin/ProductTabsExtender.php
Normal file
27
Modules/Review/Admin/ProductTabsExtender.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Admin;
|
||||
|
||||
use Modules\Admin\Ui\Tab;
|
||||
use Modules\Admin\Ui\Tabs;
|
||||
|
||||
class ProductTabsExtender
|
||||
{
|
||||
public function extend(Tabs $tabs)
|
||||
{
|
||||
$tabs->group('advanced_information')
|
||||
->add($this->reviews());
|
||||
}
|
||||
|
||||
private function reviews()
|
||||
{
|
||||
if (! request()->routeIs('admin.products.edit')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return tap(new Tab('reviews', trans('review::reviews.tabs.products.reviews')), function (Tab $tab) {
|
||||
$tab->weight(50);
|
||||
$tab->view('review::admin.products.tabs.reviews');
|
||||
});
|
||||
}
|
||||
}
|
||||
26
Modules/Review/Admin/ReviewTable.php
Normal file
26
Modules/Review/Admin/ReviewTable.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Admin;
|
||||
|
||||
use Modules\Admin\Ui\AdminTable;
|
||||
|
||||
class ReviewTable extends AdminTable
|
||||
{
|
||||
/**
|
||||
* Make table response for the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make()
|
||||
{
|
||||
return $this->newTable()
|
||||
->editColumn('product', function ($review) {
|
||||
return $review->product->name;
|
||||
})
|
||||
->editColumn('status', function ($review) {
|
||||
return $review->is_approved
|
||||
? '<span class="dot green"></span>'
|
||||
: '<span class="dot red"></span>';
|
||||
});
|
||||
}
|
||||
}
|
||||
31
Modules/Review/Admin/ReviewTabs.php
Normal file
31
Modules/Review/Admin/ReviewTabs.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Admin;
|
||||
|
||||
use Modules\Admin\Ui\Tab;
|
||||
use Modules\Admin\Ui\Tabs;
|
||||
|
||||
class ReviewTabs extends Tabs
|
||||
{
|
||||
/**
|
||||
* Make new tabs with groups.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function make()
|
||||
{
|
||||
$this->group('review_information', trans('review::reviews.tabs.group.review_information'))
|
||||
->active()
|
||||
->add($this->general());
|
||||
}
|
||||
|
||||
private function general()
|
||||
{
|
||||
return tap(new Tab('review', trans('review::reviews.tabs.general')), function (Tab $tab) {
|
||||
$tab->active();
|
||||
$tab->weight(5);
|
||||
$tab->fields(['rating', 'reviewer_name', 'comment', 'is_approved']);
|
||||
$tab->view('review::admin.reviews.tabs.general');
|
||||
});
|
||||
}
|
||||
}
|
||||
9
Modules/Review/Config/permissions.php
Normal file
9
Modules/Review/Config/permissions.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'admin.reviews' => [
|
||||
'index' => 'review::permissions.index',
|
||||
'edit' => 'review::permissions.edit',
|
||||
'destroy' => 'review::permissions.destroy',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateReviewsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('reviews', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('reviewer_id')->unsigned()->index()->nullable();
|
||||
$table->integer('product_id')->unsigned()->index();
|
||||
$table->integer('rating');
|
||||
$table->string('reviewer_name');
|
||||
$table->text('comment');
|
||||
$table->boolean('is_approved');
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('reviews');
|
||||
}
|
||||
}
|
||||
108
Modules/Review/Entities/Review.php
Normal file
108
Modules/Review/Entities/Review.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Entities;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\User\Entities\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Support\Eloquent\Model;
|
||||
use Modules\Product\Entities\Product;
|
||||
use Modules\Review\Admin\ReviewTable;
|
||||
|
||||
class Review extends Model
|
||||
{
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'is_approved' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = ['rating_percent', 'created_at_formatted'];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::addGlobalScope('approved', function ($query) {
|
||||
$query->where('is_approved', true);
|
||||
});
|
||||
}
|
||||
|
||||
public static function countAndAvgRating(Product $product)
|
||||
{
|
||||
return self::select(DB::raw('count(*) as count, avg(rating) as avg_rating'))
|
||||
->where('product_id', $product->id)
|
||||
->first();
|
||||
}
|
||||
|
||||
public function getAvgRatingAttribute($avgRating)
|
||||
{
|
||||
return $avgRating ?: 0;
|
||||
}
|
||||
|
||||
public function getRatingPercentAttribute()
|
||||
{
|
||||
return ($this->rating / 5) * 100;
|
||||
}
|
||||
|
||||
public function getCreatedAtFormattedAttribute()
|
||||
{
|
||||
return $this->created_at->toFormattedDateString();
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
if ($this->is_approved) {
|
||||
return trans('review::statuses.approved');
|
||||
}
|
||||
|
||||
return trans('review::statuses.unapproved');
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function reviewer()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'reviewer_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table data for the resource
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function table(Request $request)
|
||||
{
|
||||
$query = static::withoutGlobalScope('approved')
|
||||
->with(['product' => function ($query) {
|
||||
$query->withoutGlobalScope('active');
|
||||
}])
|
||||
->when($request->productId, function ($query) use ($request) {
|
||||
return $query->where('product_id', $request->productId);
|
||||
});
|
||||
|
||||
return new ReviewTable($query);
|
||||
}
|
||||
}
|
||||
84
Modules/Review/Http/Controllers/Admin/ReviewController.php
Normal file
84
Modules/Review/Http/Controllers/Admin/ReviewController.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Http\Controllers\Admin;
|
||||
|
||||
use Modules\Review\Entities\Review;
|
||||
use Modules\Admin\Traits\HasCrudActions;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
use Modules\Review\Http\Requests\UpdateReviewRequest;
|
||||
|
||||
class ReviewController
|
||||
{
|
||||
use HasCrudActions;
|
||||
|
||||
/**
|
||||
* Model for the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Review::class;
|
||||
|
||||
/**
|
||||
* Label of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'review::reviews.review';
|
||||
|
||||
/**
|
||||
* View path of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $viewPath = 'review::admin.reviews';
|
||||
|
||||
/**
|
||||
* Form requests for the resource.
|
||||
*
|
||||
* @var array|string
|
||||
*/
|
||||
protected $validation = UpdateReviewRequest::class;
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$review = Review::withoutGlobalScope('approved')->findOrFail($id);
|
||||
|
||||
$tabs = TabManager::get('reviews');
|
||||
|
||||
return view('review::admin.reviews.edit', compact('review', 'tabs'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$review = Review::withoutGlobalScope('approved')->findOrFail($id);
|
||||
|
||||
$review->update(request()->all());
|
||||
|
||||
return back()->withSuccess(trans('admin::messages.resource_saved', ['resource' => $this->getLabel()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy resources by given ids.
|
||||
*
|
||||
* @param string $ids
|
||||
* @return void
|
||||
*/
|
||||
public function destroy($ids)
|
||||
{
|
||||
Review::withoutGlobalScope('approved')
|
||||
->whereIn('id', explode(',', $ids))
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
45
Modules/Review/Http/Controllers/ProductReviewController.php
Normal file
45
Modules/Review/Http/Controllers/ProductReviewController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Http\Controllers;
|
||||
|
||||
use Modules\Review\Entities\Review;
|
||||
use Modules\Product\Entities\Product;
|
||||
use Modules\Review\Http\Requests\StoreReviewRequest;
|
||||
|
||||
class ProductReviewController
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param int $productId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index($productId)
|
||||
{
|
||||
return Review::where('product_id', $productId)->latest()->paginate(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param int $productId
|
||||
* @param \Modules\Review\Http\Requests\StoreReviewRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store($productId, StoreReviewRequest $request)
|
||||
{
|
||||
if (! setting('reviews_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Product::findOrFail($productId)
|
||||
->reviews()
|
||||
->create([
|
||||
'reviewer_id' => auth()->id(),
|
||||
'rating' => $request->rating,
|
||||
'reviewer_name' => $request->reviewer_name,
|
||||
'comment' => $request->comment,
|
||||
'is_approved' => setting('auto_approve_reviews', 0),
|
||||
]);
|
||||
}
|
||||
}
|
||||
30
Modules/Review/Http/Requests/StoreReviewRequest.php
Normal file
30
Modules/Review/Http/Requests/StoreReviewRequest.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Http\Requests;
|
||||
|
||||
use Modules\Core\Http\Requests\Request;
|
||||
|
||||
class StoreReviewRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Available attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $availableAttributes = 'review::attributes';
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'rating' => 'required|numeric',
|
||||
'reviewer_name' => 'required',
|
||||
'comment' => 'required',
|
||||
'captcha' => 'required|captcha',
|
||||
];
|
||||
}
|
||||
}
|
||||
30
Modules/Review/Http/Requests/UpdateReviewRequest.php
Normal file
30
Modules/Review/Http/Requests/UpdateReviewRequest.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Http\Requests;
|
||||
|
||||
use Modules\Core\Http\Requests\Request;
|
||||
|
||||
class UpdateReviewRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Available attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $availableAttributes = 'review::attributes';
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'rating' => 'required|numeric',
|
||||
'reviewer_name' => 'required',
|
||||
'comment' => 'required',
|
||||
'is_approved' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
25
Modules/Review/Providers/ReviewServiceProvider.php
Normal file
25
Modules/Review/Providers/ReviewServiceProvider.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Providers;
|
||||
|
||||
use Modules\Review\Admin\ReviewTabs;
|
||||
use Modules\Support\Traits\AddsAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
use Modules\Review\Admin\ProductTabsExtender;
|
||||
|
||||
class ReviewServiceProvider extends ServiceProvider
|
||||
{
|
||||
use AddsAsset;
|
||||
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
TabManager::register('reviews', ReviewTabs::class);
|
||||
TabManager::extend('products', ProductTabsExtender::class);
|
||||
}
|
||||
}
|
||||
9
Modules/Review/Resources/lang/en/attributes.php
Normal file
9
Modules/Review/Resources/lang/en/attributes.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'rating' => 'Rating',
|
||||
'reviewer_name' => 'Reviewer Name',
|
||||
'comment' => 'Comment',
|
||||
'captcha' => 'Captcha',
|
||||
'is_approved' => 'Status',
|
||||
];
|
||||
5
Modules/Review/Resources/lang/en/messages.php
Normal file
5
Modules/Review/Resources/lang/en/messages.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'submitted_for_approval' => 'Your review is submitted for approval.',
|
||||
];
|
||||
7
Modules/Review/Resources/lang/en/permissions.php
Normal file
7
Modules/Review/Resources/lang/en/permissions.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'index' => 'Index Reviews',
|
||||
'edit' => 'Edit Reviews',
|
||||
'destroy' => 'Delete Reviews',
|
||||
];
|
||||
27
Modules/Review/Resources/lang/en/reviews.php
Normal file
27
Modules/Review/Resources/lang/en/reviews.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'review' => 'Review',
|
||||
'reviews' => 'Reviews',
|
||||
'table' => [
|
||||
'product' => 'Product',
|
||||
'reviewer_name' => 'Reviewer Name',
|
||||
'rating' => 'Rating',
|
||||
'approved' => 'Approved',
|
||||
],
|
||||
'tabs' => [
|
||||
'group' => [
|
||||
'review_information' => 'Review Information',
|
||||
],
|
||||
'general' => 'general',
|
||||
'products' => [
|
||||
'reviews' => 'Reviews',
|
||||
],
|
||||
],
|
||||
'form' => [
|
||||
'approve_this_review' => 'Approve this review',
|
||||
],
|
||||
'shortcuts' => [
|
||||
'back_to_product_edit_page' => 'Back to product edit page',
|
||||
],
|
||||
];
|
||||
5
Modules/Review/Resources/lang/en/sidebar.php
Normal file
5
Modules/Review/Resources/lang/en/sidebar.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'reviews' => 'Reviews',
|
||||
];
|
||||
6
Modules/Review/Resources/lang/en/statuses.php
Normal file
6
Modules/Review/Resources/lang/en/statuses.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'approved' => 'Approved',
|
||||
'unapproved' => 'Unapproved',
|
||||
];
|
||||
33
Modules/Review/Resources/views/admin/products/edit.blade.php
Normal file
33
Modules/Review/Resources/views/admin/products/edit.blade.php
Normal file
@@ -0,0 +1,33 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('admin::resource.edit', ['resource' => trans('review::reviews.review')]))
|
||||
|
||||
<li><a href="{{ route('admin.products.index') }}">{{ trans('product::products.products') }}</a></li>
|
||||
<li><a href="{{ route('admin.products.edit', $productId) }}">{{ trans('admin::resource.edit', ['resource' => trans('product::products.product')]) }}</a></li>
|
||||
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('review::reviews.review')]) }}</li>
|
||||
@endcomponent
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ route('admin.products.reviews.update', [$productId, $review]) }}" class="form-horizontal" id="review-edit-form" novalidate>
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('put') }}
|
||||
|
||||
{!! $tabs->render(compact('review')) !!}
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@push('shortcuts')
|
||||
<dl class="dl-horizontal">
|
||||
<dt><code>b</code></dt>
|
||||
<dd>{{ trans('review::reviews.shortcuts.back_to_product_edit_page') }}</dd>
|
||||
</dl>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
keypressAction([
|
||||
{ key: 'b', route: "{{ route('admin.products.edit', $productId) }}" },
|
||||
]);
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,39 @@
|
||||
@component('admin::components.table', ['id' => 'product-reviews-table'])
|
||||
@slot('thead')
|
||||
<tr>
|
||||
@include('admin::partials.table.select_all')
|
||||
|
||||
<th>{{ trans('review::reviews.table.reviewer_name') }}</th>
|
||||
<th>{{ trans('review::reviews.table.rating') }}</th>
|
||||
<th>{{ trans('review::reviews.table.approved') }}</th>
|
||||
<th data-sort>{{ trans('admin::admin.table.date') }}</th>
|
||||
</tr>
|
||||
@endslot
|
||||
@endcomponent
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
Mousetrap.bind('del', function () {
|
||||
$('#product-reviews-table_wrapper .btn-delete').trigger('click');
|
||||
});
|
||||
|
||||
DataTable.setRoutes('#product-reviews-table', {
|
||||
index: {
|
||||
name: 'admin.reviews.index',
|
||||
params: { productId: '{{ $product->id }}' }
|
||||
},
|
||||
edit: { name: 'admin.reviews.edit' },
|
||||
destroy: { name: 'admin.reviews.destroy' },
|
||||
});
|
||||
|
||||
new DataTable('#product-reviews-table', {
|
||||
columns: [
|
||||
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
|
||||
{ data: 'reviewer_name' },
|
||||
{ data: 'rating' },
|
||||
{ data: 'status', name: 'is_approved', searchable: false },
|
||||
{ data: 'created', name: 'created_at' },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
32
Modules/Review/Resources/views/admin/reviews/edit.blade.php
Normal file
32
Modules/Review/Resources/views/admin/reviews/edit.blade.php
Normal file
@@ -0,0 +1,32 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('admin::resource.edit', ['resource' => trans('review::reviews.review')]))
|
||||
|
||||
<li><a href="{{ route('admin.reviews.index') }}">{{ trans('review::reviews.reviews') }}</a></li>
|
||||
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('review::reviews.review')]) }}</li>
|
||||
@endcomponent
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ route('admin.reviews.update', $review) }}" class="form-horizontal" id="review-edit-form" novalidate>
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('put') }}
|
||||
|
||||
{!! $tabs->render(compact('review')) !!}
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@push('shortcuts')
|
||||
<dl class="dl-horizontal">
|
||||
<dt><code>b</code></dt>
|
||||
<dd>{{ trans('admin::admin.shortcuts.back_to_index', ['name' => trans('review::reviews.review')]) }}</dd>
|
||||
</dl>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
keypressAction([
|
||||
{ key: 'b', route: "{{ route('admin.reviews.index') }}" },
|
||||
]);
|
||||
</script>
|
||||
@endpush
|
||||
41
Modules/Review/Resources/views/admin/reviews/index.blade.php
Normal file
41
Modules/Review/Resources/views/admin/reviews/index.blade.php
Normal file
@@ -0,0 +1,41 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('review::reviews.reviews'))
|
||||
|
||||
<li class="active">{{ trans('review::reviews.reviews') }}</li>
|
||||
@endcomponent
|
||||
|
||||
@component('admin::components.page.index_table')
|
||||
@slot('resource', 'reviews')
|
||||
@slot('name', trans('review::reviews.review'))
|
||||
|
||||
@slot('thead')
|
||||
<tr>
|
||||
@include('admin::partials.table.select_all')
|
||||
|
||||
<th>{{ trans('admin::admin.table.id') }}</th>
|
||||
<th>{{ trans('review::reviews.table.product') }}</th>
|
||||
<th>{{ trans('review::reviews.table.reviewer_name') }}</th>
|
||||
<th>{{ trans('review::reviews.table.rating') }}</th>
|
||||
<th>{{ trans('review::reviews.table.approved') }}</th>
|
||||
<th data-sort>{{ trans('admin::admin.table.date') }}</th>
|
||||
</tr>
|
||||
@endslot
|
||||
@endcomponent
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
new DataTable('#reviews-table .table', {
|
||||
columns: [
|
||||
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
|
||||
{ data: 'id', width: '5%' },
|
||||
{ data: 'product', name: 'product.price', orderable: false, searchable: false, defaultContent: '' },
|
||||
{ data: 'reviewer_name' },
|
||||
{ data: 'rating' },
|
||||
{ data: 'status', name: 'is_approved', searchable: false },
|
||||
{ data: 'created', name: 'created_at' },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{{ Form::select('rating', trans('review::attributes.rating'), $errors, array_combine(range(1, 5), range(1, 5)), $review, ['required' => true]) }}
|
||||
{{ Form::text('reviewer_name', trans('review::attributes.reviewer_name'), $errors, $review, ['required' => true]) }}
|
||||
{{ Form::textarea('comment', trans('review::attributes.comment'), $errors, $review, ['required' => true]) }}
|
||||
{{ Form::checkbox('is_approved', trans('review::attributes.is_approved'), trans('review::reviews.form.approve_this_review'), $errors, $review) }}
|
||||
</div>
|
||||
</div>
|
||||
27
Modules/Review/Routes/admin.php
Normal file
27
Modules/Review/Routes/admin.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('reviews', [
|
||||
'as' => 'admin.reviews.index',
|
||||
'uses' => 'ReviewController@index',
|
||||
'middleware' => 'can:admin.reviews.index',
|
||||
]);
|
||||
|
||||
Route::get('reviews/{id}/edit', [
|
||||
'as' => 'admin.reviews.edit',
|
||||
'uses' => 'ReviewController@edit',
|
||||
'middleware' => 'can:admin.reviews.edit',
|
||||
]);
|
||||
|
||||
Route::put('reviews/{id}', [
|
||||
'as' => 'admin.reviews.update',
|
||||
'uses' => 'ReviewController@update',
|
||||
'middleware' => 'can:admin.reviews.edit',
|
||||
]);
|
||||
|
||||
Route::delete('reviews/{ids?}', [
|
||||
'as' => 'admin.reviews.destroy',
|
||||
'uses' => 'ReviewController@destroy',
|
||||
'middleware' => 'can:admin.reviews.destroy',
|
||||
]);
|
||||
9
Modules/Review/Routes/public.php
Normal file
9
Modules/Review/Routes/public.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Spatie\Honeypot\ProtectAgainstSpam;
|
||||
|
||||
Route::get('products/{productId}/reviews', 'ProductReviewController@index')->name('products.reviews.index');
|
||||
Route::post('products/{productId}/reviews', 'ProductReviewController@store')
|
||||
->name('products.reviews.store')
|
||||
->middleware(ProtectAgainstSpam::class);
|
||||
26
Modules/Review/Sidebar/SidebarExtender.php
Normal file
26
Modules/Review/Sidebar/SidebarExtender.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Review\Sidebar;
|
||||
|
||||
use Maatwebsite\Sidebar\Item;
|
||||
use Maatwebsite\Sidebar\Menu;
|
||||
use Maatwebsite\Sidebar\Group;
|
||||
use Modules\Admin\Sidebar\BaseSidebarExtender;
|
||||
|
||||
class SidebarExtender extends BaseSidebarExtender
|
||||
{
|
||||
public function extend(Menu $menu)
|
||||
{
|
||||
$menu->group(trans('admin::sidebar.content'), function (Group $group) {
|
||||
$group->item(trans('product::sidebar.products'), function (Item $item) {
|
||||
$item->item(trans('review::sidebar.reviews'), function (Item $item) {
|
||||
$item->weight(30);
|
||||
$item->route('admin.reviews.index');
|
||||
$item->authorize(
|
||||
$this->auth->hasAccess('admin.reviews.index')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
27
Modules/Review/composer.json
Normal file
27
Modules/Review/composer.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "fleetcart/review",
|
||||
"description": "The FleetCart Review Module.",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Envay Soft",
|
||||
"email": "envaysoft@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Review\\": ""
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
9
Modules/Review/module.json
Normal file
9
Modules/Review/module.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "Review",
|
||||
"alias": "review",
|
||||
"description": "The FleetCart Review Module.",
|
||||
"priority": 100,
|
||||
"providers": [
|
||||
"Modules\\Review\\Providers\\ReviewServiceProvider"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user