customer & review
This commit is contained in:
commit
149c98ff03
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Criteria;
|
||||
|
||||
use Prettus\Repository\Contracts\CriteriaInterface;
|
||||
use Prettus\Repository\Contracts\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class MyCriteria.
|
||||
*
|
||||
* @package namespace App\Criteria;
|
||||
*/
|
||||
class MyCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* Apply criteria in query repository
|
||||
*
|
||||
* @param string $model
|
||||
* @param RepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($model, RepositoryInterface $repository)
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Webkul\Ui\DataGrid\Facades\DataGrid;
|
||||
|
||||
|
||||
/**
|
||||
* Customer DataGrid
|
||||
*
|
||||
* @author Rahul Shukla <rahulshukla.symfony517@webkul.com> @rahul-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
|
||||
class CustomerDataGrid
|
||||
{
|
||||
/**
|
||||
* The CustomerDataGrid
|
||||
* implementation.
|
||||
*
|
||||
* @var CustomerDataGrid
|
||||
*/
|
||||
|
||||
public function createCustomerDataGrid()
|
||||
{
|
||||
|
||||
return DataGrid::make([
|
||||
'name' => 'Customer',
|
||||
'table' => 'customers',
|
||||
'select' => 'id',
|
||||
'perpage' => 10,
|
||||
'aliased' => false, //use this with false as default and true in case of joins
|
||||
|
||||
'massoperations' =>[
|
||||
[
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'method' => 'DELETE',
|
||||
'label' => 'Delete',
|
||||
'type' => 'button',
|
||||
],
|
||||
],
|
||||
|
||||
'actions' => [
|
||||
[
|
||||
'type' => 'Edit',
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'confirm_text' => 'Do you really want to do this?',
|
||||
'icon' => 'icon pencil-lg-icon',
|
||||
], [
|
||||
'type' => 'Delete',
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'confirm_text' => 'Do you really want to do this?',
|
||||
'icon' => 'icon trash-icon',
|
||||
],
|
||||
],
|
||||
|
||||
'join' => [
|
||||
// [
|
||||
// 'join' => 'leftjoin',
|
||||
// 'table' => 'roles as r',
|
||||
// 'primaryKey' => 'u.role_id',
|
||||
// 'condition' => '=',
|
||||
// 'secondaryKey' => 'r.id',
|
||||
// ]
|
||||
],
|
||||
|
||||
//use aliasing on secodary columns if join is performed
|
||||
|
||||
'columns' => [
|
||||
|
||||
[
|
||||
'name' => 'id',
|
||||
'alias' => 'customerId',
|
||||
'type' => 'number',
|
||||
'label' => 'ID',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'first_name',
|
||||
'alias' => 'customerFirstName',
|
||||
'type' => 'string',
|
||||
'label' => 'Name',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'email',
|
||||
'alias' => 'customerEmail',
|
||||
'type' => 'string',
|
||||
'label' => 'Email',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'phone',
|
||||
'alias' => 'customerPhone',
|
||||
'type' => 'number',
|
||||
'label' => 'Phone',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'customer_group_id',
|
||||
'alias' => 'customerGroupId',
|
||||
'type' => 'number',
|
||||
'label' => 'Customer Group',
|
||||
'sortable' => true,
|
||||
],
|
||||
],
|
||||
|
||||
//don't use aliasing in case of filters
|
||||
|
||||
'filterable' => [
|
||||
|
||||
[
|
||||
'name' => 'id',
|
||||
'alias' => 'customerId',
|
||||
'type' => 'number',
|
||||
'label' => 'ID',
|
||||
],
|
||||
[
|
||||
'name' => 'first_name',
|
||||
'alias' => 'customerFirstName',
|
||||
'type' => 'string',
|
||||
'label' => 'Name',
|
||||
],
|
||||
[
|
||||
'name' => 'phone',
|
||||
'alias' => 'customerPhone',
|
||||
'type' => 'number',
|
||||
'label' => 'Phone',
|
||||
],
|
||||
[
|
||||
'name' => 'email',
|
||||
'alias' => 'customerEmail',
|
||||
'type' => 'string',
|
||||
'label' => 'Comment',
|
||||
],
|
||||
[
|
||||
'name' => 'customer_group_id',
|
||||
'alias' => 'customerGroupId',
|
||||
'type' => 'number',
|
||||
'label' => 'Status',
|
||||
],
|
||||
],
|
||||
|
||||
//don't use aliasing in case of searchables
|
||||
|
||||
'searchable' => [
|
||||
[
|
||||
'column' => 'first_name',
|
||||
'type' => 'string',
|
||||
'label' => 'Title',
|
||||
],
|
||||
[
|
||||
'column' => 'email',
|
||||
'type' => 'string',
|
||||
'label' => 'Rating',
|
||||
],
|
||||
],
|
||||
|
||||
//list of viable operators that will be used
|
||||
'operators' => [
|
||||
'eq' => "=",
|
||||
'lt' => "<",
|
||||
'gt' => ">",
|
||||
'lte' => "<=",
|
||||
'gte' => ">=",
|
||||
'neqs' => "<>",
|
||||
'neqn' => "!=",
|
||||
'like' => "like",
|
||||
'nlike' => "not like",
|
||||
],
|
||||
// 'css' => []
|
||||
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
|
||||
return $this->createCustomerDataGrid()->render();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Webkul\Ui\DataGrid\Facades\DataGrid;
|
||||
|
||||
|
||||
/**
|
||||
* Review DataGrid
|
||||
*
|
||||
* @author Rahul Shukla <rahulshukla.symfony517@webkul.com> @rahul-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
|
||||
class CustomerReviewDataGrid
|
||||
{
|
||||
/**
|
||||
* The CustomerReviewDataGrid
|
||||
* implementation.
|
||||
*
|
||||
* @var ReviewsDataGrid
|
||||
* for Reviews
|
||||
*/
|
||||
|
||||
public function createCustomerReviewDataGrid()
|
||||
{
|
||||
|
||||
return DataGrid::make([
|
||||
'name' => 'Review',
|
||||
'table' => 'product_reviews',
|
||||
'select' => 'id',
|
||||
'perpage' => 10,
|
||||
'aliased' => false, //use this with false as default and true in case of joins
|
||||
|
||||
'massoperations' =>[
|
||||
[
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'method' => 'DELETE',
|
||||
'label' => 'Delete',
|
||||
'type' => 'button',
|
||||
],
|
||||
],
|
||||
|
||||
'actions' => [
|
||||
[
|
||||
'type' => 'Edit',
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'confirm_text' => 'Do you really want to do this?',
|
||||
'icon' => 'icon pencil-lg-icon',
|
||||
], [
|
||||
'type' => 'Delete',
|
||||
'route' => route('admin.datagrid.delete'),
|
||||
'confirm_text' => 'Do you really want to do this?',
|
||||
'icon' => 'icon trash-icon',
|
||||
],
|
||||
],
|
||||
|
||||
'join' => [
|
||||
// [
|
||||
// 'join' => 'leftjoin',
|
||||
// 'table' => 'roles as r',
|
||||
// 'primaryKey' => 'u.role_id',
|
||||
// 'condition' => '=',
|
||||
// 'secondaryKey' => 'r.id',
|
||||
// ]
|
||||
],
|
||||
|
||||
//use aliasing on secodary columns if join is performed
|
||||
|
||||
'columns' => [
|
||||
|
||||
[
|
||||
'name' => 'id',
|
||||
'alias' => 'reviewId',
|
||||
'type' => 'number',
|
||||
'label' => 'ID',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'title',
|
||||
'alias' => 'titleName',
|
||||
'type' => 'string',
|
||||
'label' => 'Title',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'rating',
|
||||
'alias' => 'productRating',
|
||||
'type' => 'number',
|
||||
'label' => 'Rating',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'comment',
|
||||
'alias' => 'productComment',
|
||||
'type' => 'string',
|
||||
'label' => 'Comment',
|
||||
'sortable' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'status',
|
||||
'alias' => 'countryStatus',
|
||||
'type' => 'number',
|
||||
'label' => 'Status',
|
||||
'sortable' => true,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
//don't use aliasing in case of filters
|
||||
|
||||
'filterable' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'alias' => 'countryId',
|
||||
'type' => 'number',
|
||||
'label' => 'ID',
|
||||
],
|
||||
[
|
||||
'name' => 'title',
|
||||
'alias' => 'titleName',
|
||||
'type' => 'string',
|
||||
'label' => 'Title',
|
||||
],
|
||||
[
|
||||
'name' => 'rating',
|
||||
'alias' => 'productRating',
|
||||
'type' => 'number',
|
||||
'label' => 'Rating',
|
||||
],
|
||||
[
|
||||
'name' => 'comment',
|
||||
'alias' => 'productComment',
|
||||
'type' => 'string',
|
||||
'label' => 'Comment',
|
||||
],
|
||||
[
|
||||
'name' => 'status',
|
||||
'alias' => 'countryStatus',
|
||||
'type' => 'number',
|
||||
'label' => 'Code',
|
||||
],
|
||||
],
|
||||
|
||||
//don't use aliasing in case of searchables
|
||||
|
||||
'searchable' => [
|
||||
[
|
||||
'column' => 'title',
|
||||
'type' => 'string',
|
||||
'label' => 'Title',
|
||||
],
|
||||
[
|
||||
'column' => 'rating',
|
||||
'type' => 'number',
|
||||
'label' => 'Rating',
|
||||
],
|
||||
],
|
||||
|
||||
//list of viable operators that will be used
|
||||
'operators' => [
|
||||
'eq' => "=",
|
||||
'lt' => "<",
|
||||
'gt' => ">",
|
||||
'lte' => "<=",
|
||||
'gte' => ">=",
|
||||
'neqs' => "<>",
|
||||
'neqn' => "!=",
|
||||
'like' => "like",
|
||||
'nlike' => "not like",
|
||||
],
|
||||
// 'css' => []
|
||||
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return $this->createCustomerReviewDataGrid()->render();
|
||||
}
|
||||
}
|
||||
|
|
@ -36,12 +36,44 @@ Route::group(['middleware' => ['web']], function () {
|
|||
'redirect' => 'admin.session.create'
|
||||
])->name('admin.session.destroy');
|
||||
|
||||
//orders page
|
||||
|
||||
|
||||
// Dashboard Route
|
||||
Route::get('/dashboard', 'Webkul\Admin\Http\Controllers\DashboardController@index')->name('admin.dashboard.index');
|
||||
Route::get('dashboard', 'Webkul\Admin\Http\Controllers\DashboardController@index')->name('admin.dashboard.index');
|
||||
|
||||
//Customers Management Routes
|
||||
|
||||
Route::get('customer', 'Webkul\Core\Http\Controllers\CustomerController@index')->defaults('_config', [
|
||||
'view' => 'admin::customers.index'
|
||||
])->name('admin.customer.index');
|
||||
|
||||
Route::get('customer/orders', 'Webkul\Core\Http\Controllers\CustomerController@index')->defaults('_config',[
|
||||
'view' => 'admin::customers.orders.index'
|
||||
])->name('admin.customer.orders.index');
|
||||
|
||||
Route::get('customer/reviews', 'Webkul\Shop\Http\Controllers\ReviewController@index')->defaults('_config',[
|
||||
'view' => 'admin::customers.review.index'
|
||||
])->name('admin.customer.review.index');
|
||||
|
||||
Route::get('customer/reviews/edit/{id}', 'Webkul\Shop\Http\Controllers\ReviewController@edit')->defaults('_config',[
|
||||
'view' => 'admin::customers.review.edit'
|
||||
])->name('admin.customer.review.edit');
|
||||
|
||||
Route::put('customer/reviews/edit/{id}', 'Webkul\Shop\Http\Controllers\ReviewController@update')->defaults('_config', [
|
||||
'redirect' => 'admin.customer.review.index'
|
||||
])->name('admin.customer.review.update');
|
||||
|
||||
Route::get('customer/edit/{id}', 'Webkul\Core\Http\Controllers\CustomerController@edit')->defaults('_config',[
|
||||
'view' => 'admin::customers.edit'
|
||||
])->name('admin.customer.edit');
|
||||
|
||||
Route::put('customer/reviews/edit/{id}', 'Webkul\Core\Http\Controllers\CustomerController@update')->defaults('_config', [
|
||||
'redirect' => 'admin.customer.index'
|
||||
])->name('admin.customer.update');
|
||||
|
||||
// dummy number i.e-1 is used for creating view only
|
||||
|
||||
Route::get('customer/orders/1', 'Webkul\User\Http\Controllers\UserController@index')->defaults('_config', [
|
||||
'view' => 'admin::customers.orders.order'
|
||||
])->name('admin.customer.orders.order');
|
||||
|
||||
// Catalog Routes
|
||||
Route::prefix('catalog')->group(function () {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,18 @@ class EventServiceProvider extends ServiceProvider
|
|||
|
||||
$menu->add('catalog.families', 'Families', 'admin.catalog.families.index', 4);
|
||||
|
||||
$menu->add('customers', 'Customers', 'admin.customer.index', 5, 'customer-icon');
|
||||
|
||||
$menu->add('customers.customers', 'Customers', 'admin.customer.index', 1, '');
|
||||
|
||||
$menu->add('customers.orders', 'Orders', 'admin.customer.orders.index', 2, '');
|
||||
|
||||
$menu->add('customers.reviews', 'Review', 'admin.customer.review.index', 3, '');
|
||||
|
||||
// $menu->add('customers.blocked_customer', 'Blocked Customers', 'admin.account.edit', 2, '');
|
||||
|
||||
// $menu->add('customers.allowed_customer', 'Allowed Customers', 'admin.account.edit', 4, '');
|
||||
|
||||
$menu->add('configuration', 'Configure', 'admin.account.edit', 6, 'configuration-icon');
|
||||
|
||||
$menu->add('configuration.account', 'My Account', 'admin.account.edit', 1);
|
||||
|
|
|
|||
|
|
@ -274,3 +274,28 @@ body {
|
|||
}
|
||||
|
||||
// admin dashboard css ends here
|
||||
|
||||
|
||||
// customer oder css for admin start here
|
||||
|
||||
.order-place-detail {
|
||||
|
||||
.order-account-information {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.address {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.payment-shipping{
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.order-products{
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// customer oder css for admin end here
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ return [
|
|||
'value_per_channel' => 'Value Per Channel',
|
||||
'is_filterable' => 'Use in Layered Navigation',
|
||||
'is_configurable' => 'Use To Create Configurable Product',
|
||||
'admin_name' => 'Admin Name'
|
||||
'admin_name' => 'Admin Name',
|
||||
'is_visible_on_front' => 'Visible on Product View Page on Front-end'
|
||||
],
|
||||
'families' => [
|
||||
'families' => 'Families',
|
||||
|
|
@ -264,5 +265,24 @@ return [
|
|||
'content' => 'Content',
|
||||
'channels' => 'Channel'
|
||||
],
|
||||
],
|
||||
'customers' => [
|
||||
'customers' => [
|
||||
'title' => 'Customers',
|
||||
'first_name' => 'First Name',
|
||||
'last_name' => 'Last Name',
|
||||
'gender' => 'Gender',
|
||||
'email' => 'Email',
|
||||
'date_of_birth' => 'Date of Birth',
|
||||
'phone' => 'Phone',
|
||||
'customer_group' => 'Customer Group'
|
||||
],
|
||||
'reviews' => [
|
||||
'title' => 'Title',
|
||||
'name' => 'Reviews',
|
||||
'rating' => 'Rating',
|
||||
'status' => 'Status',
|
||||
'comment' => 'Comment'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
@ -154,6 +154,14 @@
|
|||
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="is_visible_on_front">{{ __('admin::app.catalog.attributes.is_visible_on_front') }}</label>
|
||||
<select class="control" id="is_visible_on_front" name="is_visible_on_front">
|
||||
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
|
|
|||
|
|
@ -210,6 +210,18 @@
|
|||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="is_visible_on_front">{{ __('admin::app.catalog.attributes.is_visible_on_front') }}</label>
|
||||
<select class="control" id="is_visible_on_front" name="is_visible_on_front">
|
||||
<option value="0" {{ $attribute->is_visible_on_front ? '' : 'selected' }}>
|
||||
{{ __('admin::app.catalog.attributes.no') }}
|
||||
</option>
|
||||
<option value="1" {{ $attribute->is_visible_on_front ? 'selected' : '' }}>
|
||||
{{ __('admin::app.catalog.attributes.yes') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<div class="control-group">
|
||||
<select class="control" id="channel-switcher" name="channel">
|
||||
@foreach(core()->getAllChannels() as $channelModel)
|
||||
|
||||
|
||||
<option value="{{ $channelModel->code }}" {{ ($channelModel->code) == $channel ? 'selected' : '' }}>
|
||||
{{ $channelModel->name }}
|
||||
</option>
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div class="control-group">
|
||||
<select class="control" id="locale-switcher" name="locale">
|
||||
@foreach(core()->getAllLocales() as $localeModel)
|
||||
|
||||
|
||||
<option value="{{ $localeModel->code }}" {{ ($localeModel->code) == $locale ? 'selected' : '' }}>
|
||||
{{ $localeModel->name }}
|
||||
</option>
|
||||
|
|
@ -61,8 +61,8 @@
|
|||
@foreach($attributeGroup->custom_attributes as $attribute)
|
||||
|
||||
@if(!$product->super_attributes->contains($attribute))
|
||||
|
||||
<?php
|
||||
|
||||
<?php
|
||||
$validations = [];
|
||||
$disabled = false;
|
||||
if($product->type == 'configurable' && in_array($attribute->code, ['price', 'cost', 'special_price', 'special_price_from', 'special_price_to', 'width', 'height', 'depth', 'weight'])) {
|
||||
|
|
@ -79,7 +79,7 @@
|
|||
}
|
||||
|
||||
$validations = implode('|', array_filter($validations));
|
||||
?>
|
||||
?>
|
||||
|
||||
@if(view()->exists($typeView = 'admin::catalog.products.field-types.' . $attribute->type))
|
||||
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
array_push($channel_locale, $locale);
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@if(count($channel_locale))
|
||||
<span class="locale">[{{ implode(' - ', $channel_locale) }}]</span>
|
||||
@endif
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
@endif
|
||||
|
||||
@endif
|
||||
|
||||
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
|
|
@ -120,11 +120,11 @@
|
|||
@endforeach
|
||||
|
||||
@if ($form_accordians)
|
||||
|
||||
|
||||
@foreach ($form_accordians->items as $accordian)
|
||||
|
||||
@include ($accordian['view'])
|
||||
|
||||
|
||||
@endforeach
|
||||
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<form method="POST" action="{{ route('admin.customer.update', $customer->id) }}">
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
{{ __('admin::app.customers.customers.title') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.account.save-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
|
||||
<input name="_method" type="hidden" value="PUT">
|
||||
|
||||
<accordian :title="'{{ __('admin::app.account.general') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" > {{ __('admin::app.customers.customers.first_name') }}</label>
|
||||
<input type="text" class="control" name="first_name" value="{{$customer->first_name}}"/>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" > {{ __('admin::app.customers.customers.last_name') }}</label>
|
||||
<input type="text" class="control" name="last_name" value="{{$customer->last_name}}"/>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" > {{ __('admin::app.customers.customers.email') }}</label>
|
||||
<input type="text" class="control" name="email" value="{{$customer->email}}"/>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="email">{{ __('admin::app.customers.customers.gender') }}</label>
|
||||
<select name="gender" class="control" value="{{ $customer->gender }}" v-validate="'required'">
|
||||
<option value="Male">Male</option>
|
||||
<option value="Female">Female</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="dob">{{ __('admin::app.customers.customers.date_of_birth') }}</label>
|
||||
<input type="date" class="control" name="date_of_birth" value="{{ $customer->date_of_birth }}" v-validate="'required'">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="phone">{{ __('admin::app.customers.customers.phone') }}</label>
|
||||
<input type="text" class="control" name="phone" value="{{ $customer->phone }}" v-validate="'required'">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" >{{ __('admin::app.customers.customers.customer_group') }}</label>
|
||||
<select class="control" name="customer_group_id">
|
||||
<option value="1"> 1 </option>
|
||||
<option value="2"> 2 </option>
|
||||
<option value="3"> 3 </option>
|
||||
<option value="4"> 4 </option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@stop
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.customers.customers.title') }}</h1>
|
||||
</div>
|
||||
<div class="page-action">
|
||||
<a href="{{ route('admin.users.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('Add Customer') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
@inject('customer','Webkul\Admin\DataGrids\CustomerDataGrid')
|
||||
{!! $customer->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>Customers</h1>
|
||||
</div>
|
||||
<div class="page-action">
|
||||
<a href="{{ route('admin.users.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('Add Customer') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
|
||||
@extends('admin::layouts.master')
|
||||
|
||||
@section('content-wrapper')
|
||||
|
||||
|
||||
<div class="order-place-detail">
|
||||
|
||||
<div class="order-account-information">
|
||||
<accordian :title="'Order and Account'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="order-information">
|
||||
<div class="order-info">
|
||||
<span>Order Information <span >
|
||||
<span class="edit">
|
||||
Edit
|
||||
</span>
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Order Date
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
August 4,2018,9:05:36:AM
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Order Status
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
Pending
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Channel
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
Web Store-en_GB
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="account-information">
|
||||
<div class="account-info">
|
||||
<span>Account Information <span >
|
||||
<span class="edit">
|
||||
Edit
|
||||
</span>
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span >
|
||||
Customer Name
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span class="name">
|
||||
Lee Stoike
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Email
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
lee.stoike@examplemail.com
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-account">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Contact Number
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
9876543210
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
|
||||
<div class="address">
|
||||
|
||||
<accordian :title="'Address'" :active="true">
|
||||
|
||||
<div slot="body">
|
||||
|
||||
<div class="address-information">
|
||||
<div class="address-name">
|
||||
<span> Shipping Address <span >
|
||||
<span class="edit">
|
||||
Edit
|
||||
</span>
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
<div class="address-detail">
|
||||
<span> 0933 Crossing Suite 12B </span>
|
||||
<span> Dallas , Texas <span>
|
||||
<span> United States </span>
|
||||
<span> 75001 </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="address-information">
|
||||
<div class="address-name">
|
||||
<span> Billing Address <span >
|
||||
<span class="edit">
|
||||
Edit
|
||||
</span>
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
<div class="address-detail">
|
||||
<span> 0933 Crossing Suite 12B </span>
|
||||
<span> Dallas , Texas <span>
|
||||
<span> United States </span>
|
||||
<span> 75001 </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="payment-shipping">
|
||||
<accordian :title="'Payment and Shipping'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="payment-information">
|
||||
<div class="title">
|
||||
<span>Payment Information <span >
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
|
||||
<div class="payment-info">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Payment Method
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
Bank Wire Transfer
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="payment-info">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Currency
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
US Dollar
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="payment-information">
|
||||
<div class="title">
|
||||
<span> Shipping Information <span >
|
||||
</div>
|
||||
<div class="horizotal-rule"> </div>
|
||||
|
||||
<div class="payment-info">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Shipping Method
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
Flat Rate-Fixed-$10.00
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="payment-info">
|
||||
<div class="left-content">
|
||||
<span>
|
||||
Expected Delivery
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<span>
|
||||
3 Days
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
|
||||
<div class="order-products">
|
||||
|
||||
<accordian :title="'Products Ordered'" :active="true">
|
||||
|
||||
<div slot="body">
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>SKU</th>
|
||||
<th>Product Name</th>
|
||||
<th>Item Status</th>
|
||||
<th>Price</th>
|
||||
<th>Qty</th>
|
||||
<th>Row total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PROD124</td>
|
||||
<td>Apple iPhone 7- White-32GB</td>
|
||||
<td>Packed (2)</td>
|
||||
<td>$350.00</td>
|
||||
<td>2</td>
|
||||
<td>$700.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PROD128</td>
|
||||
<td>Blue Linen T-Shirt for Men- Small- Red</td>
|
||||
<td>Shipped (2)</td>
|
||||
<td>$45.00</td>
|
||||
<td>2</td>
|
||||
<td>$35.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="total">
|
||||
|
||||
<div class="calculate">
|
||||
|
||||
<div class="sub-total">
|
||||
<span class="left">
|
||||
Subtotal
|
||||
</span>
|
||||
<span class="middle">
|
||||
-
|
||||
</span>
|
||||
<span class="right">
|
||||
$805.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="ship-handle">
|
||||
<span class="left">
|
||||
Shipping & handling
|
||||
</span>
|
||||
<span class="middle">
|
||||
-
|
||||
</span>
|
||||
<span class="right">
|
||||
$5.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="discount">
|
||||
<span class="left">
|
||||
Discounts
|
||||
</span>
|
||||
<span class="middle">
|
||||
-
|
||||
</span>
|
||||
<span class="right">
|
||||
$15.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="grand-total">
|
||||
<span class="left">
|
||||
Grand Total
|
||||
</span>
|
||||
<span class="middle">
|
||||
-
|
||||
</span>
|
||||
<span class="right">
|
||||
$15.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="due">
|
||||
<span class="left">
|
||||
Total Due
|
||||
</span>
|
||||
<span class="middle">
|
||||
-
|
||||
</span>
|
||||
<span class="right">
|
||||
$15.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<form method="POST" action="{{ route('admin.customer.review.update', $review->id) }}">
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
{{ __('admin::app.customers.reviews.name') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.account.save-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
|
||||
<input name="_method" type="hidden" value="PUT">
|
||||
|
||||
<accordian :title="'{{ __('admin::app.account.general') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" > {{ __('admin::app.customers.reviews.title') }}</label>
|
||||
<input type="text" class="control" id="name" name="name" value="{{$review->title}}" disabled/>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" >{{ __('admin::app.customers.reviews.rating') }}</label>
|
||||
@for($i = 1; $i <= $review->rating ; $i++)
|
||||
<span class="stars">
|
||||
<span class="icon star-icon"></span>
|
||||
</span>
|
||||
@endfor
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" >{{ __('admin::app.customers.reviews.status') }}</label>
|
||||
<select class="control" name="status">
|
||||
<option value="1">
|
||||
1
|
||||
</option>
|
||||
<option value="2">
|
||||
2
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="name" >{{ __('admin::app.customers.reviews.comment') }}</label>
|
||||
<textarea class="control" disabled> {{$review->comment}}</textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@stop
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.customers.reviews.name') }}</h1>
|
||||
</div>
|
||||
<div class="page-action">
|
||||
{{-- <a href="{{ route('admin.users.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('Add Customer') }}
|
||||
</a> --}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
@inject('review','Webkul\Admin\DataGrids\CustomerReviewDataGrid')
|
||||
{!! $review->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class CreateAttributesTable extends Migration
|
|||
$table->boolean('is_filterable')->default(0);
|
||||
$table->boolean('is_configurable')->default(0);
|
||||
$table->boolean('is_user_defined')->default(1);
|
||||
$table->boolean('is_visible_on_front')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ class AttributeTableSeeder extends Seeder
|
|||
[
|
||||
'code' => 'sku',
|
||||
'admin_name' => 'SKU',
|
||||
'en' => [
|
||||
'name' => 'SKU'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'SKU'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'position' => 1,
|
||||
'is_unique' => 1,
|
||||
|
|
@ -29,9 +29,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'name',
|
||||
'admin_name' => 'Name',
|
||||
'en' => [
|
||||
'name' => 'Name'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Name'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'position' => 2,
|
||||
'is_required' => 1,
|
||||
|
|
@ -43,9 +43,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'url_key',
|
||||
'admin_name' => 'URL Key',
|
||||
'en' => [
|
||||
'name' => 'URL Key'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'URL Key'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'position' => 3,
|
||||
'is_unique' => 1,
|
||||
|
|
@ -58,9 +58,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'new_from',
|
||||
'admin_name' => 'New From',
|
||||
'en' => [
|
||||
'name' => 'New From'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'New From'
|
||||
// ],
|
||||
'type' => 'datetime',
|
||||
'position' => 4,
|
||||
'is_required' => 0,
|
||||
|
|
@ -72,9 +72,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'new_to',
|
||||
'admin_name' => 'New To',
|
||||
'en' => [
|
||||
'name' => 'New To'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'New To'
|
||||
// ],
|
||||
'type' => 'datetime',
|
||||
'position' => 5,
|
||||
'is_required' => 0,
|
||||
|
|
@ -86,9 +86,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'visible_individually',
|
||||
'admin_name' => 'Visible Individually',
|
||||
'en' => [
|
||||
'name' => 'Visible Individually'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Visible Individually'
|
||||
// ],
|
||||
'type' => 'boolean',
|
||||
'position' => 6,
|
||||
'is_required' => 1,
|
||||
|
|
@ -100,9 +100,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'status',
|
||||
'admin_name' => 'Status',
|
||||
'en' => [
|
||||
'name' => 'Status'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Status'
|
||||
// ],
|
||||
'type' => 'boolean',
|
||||
'position' => 7,
|
||||
'is_required' => 1,
|
||||
|
|
@ -114,9 +114,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'short_description',
|
||||
'admin_name' => 'Short Description',
|
||||
'en' => [
|
||||
'name' => 'Short Description'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Short Description'
|
||||
// ],
|
||||
'type' => 'textarea',
|
||||
'position' => 8,
|
||||
'is_required' => 1,
|
||||
|
|
@ -128,9 +128,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'description',
|
||||
'admin_name' => 'Description',
|
||||
'en' => [
|
||||
'name' => 'Description'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Description'
|
||||
// ],
|
||||
'type' => 'textarea',
|
||||
'position' => 9,
|
||||
'is_required' => 1,
|
||||
|
|
@ -142,9 +142,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'price',
|
||||
'admin_name' => 'Price',
|
||||
'en' => [
|
||||
'name' => 'Price'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Price'
|
||||
// ],
|
||||
'type' => 'price',
|
||||
'position' => 10,
|
||||
'is_required' => 1,
|
||||
|
|
@ -156,9 +156,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'cost',
|
||||
'admin_name' => 'Cost',
|
||||
'en' => [
|
||||
'name' => 'Cost'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Cost'
|
||||
// ],
|
||||
'type' => 'price',
|
||||
'position' => 11,
|
||||
'is_required' => 0,
|
||||
|
|
@ -170,9 +170,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'special_price',
|
||||
'admin_name' => 'Special Price',
|
||||
'en' => [
|
||||
'name' => 'Special Price'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Special Price'
|
||||
// ],
|
||||
'type' => 'price',
|
||||
'position' => 12,
|
||||
'is_required' => 0,
|
||||
|
|
@ -184,9 +184,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'special_price_from',
|
||||
'admin_name' => 'Special Price From',
|
||||
'en' => [
|
||||
'name' => 'Special Price From'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Special Price From'
|
||||
// ],
|
||||
'type' => 'date',
|
||||
'position' => 13,
|
||||
'is_required' => 0,
|
||||
|
|
@ -198,9 +198,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'special_price_to',
|
||||
'admin_name' => 'Special Price To',
|
||||
'en' => [
|
||||
'name' => 'Special Price To'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Special Price To'
|
||||
// ],
|
||||
'type' => 'date',
|
||||
'position' => 14,
|
||||
'is_required' => 0,
|
||||
|
|
@ -212,9 +212,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'meta_title',
|
||||
'admin_name' => 'Meta Title',
|
||||
'en' => [
|
||||
'name' => 'Meta Description'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Meta Description'
|
||||
// ],
|
||||
'type' => 'textarea',
|
||||
'position' => 15,
|
||||
'is_required' => 0,
|
||||
|
|
@ -226,9 +226,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'meta_keywords',
|
||||
'admin_name' => 'Meta Keywords',
|
||||
'en' => [
|
||||
'name' => 'Meta Keywords'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Meta Keywords'
|
||||
// ],
|
||||
'type' => 'textarea',
|
||||
'position' => 16,
|
||||
'is_required' => 0,
|
||||
|
|
@ -240,9 +240,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'meta_description',
|
||||
'admin_name' => 'Meta Description',
|
||||
'en' => [
|
||||
'name' => 'Meta Description'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Meta Description'
|
||||
// ],
|
||||
'type' => 'textarea',
|
||||
'position' => 17,
|
||||
'is_required' => 0,
|
||||
|
|
@ -254,9 +254,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'width',
|
||||
'admin_name' => 'Width',
|
||||
'en' => [
|
||||
'name' => 'Width'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Width'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'validation' => 'numeric',
|
||||
'position' => 18,
|
||||
|
|
@ -269,9 +269,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'height',
|
||||
'admin_name' => 'Height',
|
||||
'en' => [
|
||||
'name' => 'Height'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Height'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'validation' => 'numeric',
|
||||
'position' => 19,
|
||||
|
|
@ -284,9 +284,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'depth',
|
||||
'admin_name' => 'Depth',
|
||||
'en' => [
|
||||
'name' => 'Depth'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Depth'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'validation' => 'numeric',
|
||||
'position' => 20,
|
||||
|
|
@ -299,9 +299,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'weight',
|
||||
'admin_name' => 'Weight',
|
||||
'en' => [
|
||||
'name' => 'Weight'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Weight'
|
||||
// ],
|
||||
'type' => 'text',
|
||||
'validation' => 'numeric',
|
||||
'position' => 21,
|
||||
|
|
@ -314,9 +314,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'color',
|
||||
'admin_name' => 'Color',
|
||||
'en' => [
|
||||
'name' => 'Color'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Color'
|
||||
// ],
|
||||
'type' => 'select',
|
||||
'position' => 22,
|
||||
'is_required' => 0,
|
||||
|
|
@ -356,9 +356,9 @@ class AttributeTableSeeder extends Seeder
|
|||
], [
|
||||
'code' => 'size',
|
||||
'admin_name' => 'Size',
|
||||
'en' => [
|
||||
'name' => 'Size'
|
||||
],
|
||||
// 'en' => [
|
||||
// 'name' => 'Size'
|
||||
// ],
|
||||
'type' => 'select',
|
||||
'position' => 23,
|
||||
'is_required' => 0,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Attribute extends TranslatableModel
|
|||
{
|
||||
public $translatedAttributes = ['name'];
|
||||
|
||||
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable'];
|
||||
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable', 'is_visible_on_front'];
|
||||
|
||||
protected $with = ['options'];
|
||||
|
||||
|
|
@ -22,14 +22,6 @@ class Attribute extends TranslatableModel
|
|||
return $this->hasMany(AttributeOption::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options.
|
||||
*/
|
||||
public function filter_attributes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include popular users.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webkul\Core\Models\Channel as ChannelModel;
|
||||
use Webkul\Core\Models\Locale as LocaleModel;
|
||||
use Webkul\Core\Models\Currency as CurrencyModel;
|
||||
|
|
@ -14,7 +15,12 @@ class Core
|
|||
* @return Collection
|
||||
*/
|
||||
public function getAllChannels() {
|
||||
return ChannelModel::all();
|
||||
static $channels;
|
||||
|
||||
if($channels)
|
||||
return $channels;
|
||||
|
||||
return $channels = ChannelModel::all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -23,7 +29,12 @@ class Core
|
|||
* @return mixed
|
||||
*/
|
||||
public function getCurrentChannel() {
|
||||
return ChannelModel::first();
|
||||
static $channel;
|
||||
|
||||
if($channel)
|
||||
return $channel;
|
||||
|
||||
return $channel = ChannelModel::first();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +43,12 @@ class Core
|
|||
* @return string
|
||||
*/
|
||||
public function getCurrentChannelCode() {
|
||||
return ($channel = $this->getCurrentChannel()) ? $channel->code : '';
|
||||
static $channelCode;
|
||||
|
||||
if($channelCode)
|
||||
return $channelCode;
|
||||
|
||||
return ($channel = $this->getCurrentChannel()) ? $channelCode = $channel->code : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +57,12 @@ class Core
|
|||
* @return Collection
|
||||
*/
|
||||
public function getAllLocales() {
|
||||
return LocaleModel::all();
|
||||
static $locales;
|
||||
|
||||
if($locales)
|
||||
return $locales;
|
||||
|
||||
return $locales = LocaleModel::all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,7 +72,12 @@ class Core
|
|||
*/
|
||||
public function getAllCurrencies()
|
||||
{
|
||||
return CurrencyModel::all();
|
||||
static $currencies;
|
||||
|
||||
if($currencies)
|
||||
return $currencies;
|
||||
|
||||
return $currencies = CurrencyModel::all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -61,9 +87,12 @@ class Core
|
|||
*/
|
||||
public function getCurrentCurrency()
|
||||
{
|
||||
$currency = CurrencyModel::first();
|
||||
static $currency;
|
||||
|
||||
return $currency;
|
||||
if($currency)
|
||||
return $currency;
|
||||
|
||||
return $currency = CurrencyModel::first();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,7 +102,12 @@ class Core
|
|||
*/
|
||||
public function getCurrentCurrencyCode()
|
||||
{
|
||||
return ($currency = $this->getCurrentCurrency()) ? $currency->code : '';
|
||||
static $currencyCode;
|
||||
|
||||
if($currencyCode)
|
||||
return $currencyCode;
|
||||
|
||||
return ($currency = $this->getCurrentCurrency()) ? $currencyCode = $currency->code : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -83,7 +117,12 @@ class Core
|
|||
*/
|
||||
public function getCurrentCurrencySymbol()
|
||||
{
|
||||
return $this->getCurrentCurrency()->symbol;
|
||||
static $currencySymbol;
|
||||
|
||||
if($currencySymbol)
|
||||
return $currencySymbol;
|
||||
|
||||
return $currencySymbol = $this->getCurrentCurrency()->symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,7 +138,9 @@ class Core
|
|||
|
||||
$channel = $this->getCurrentChannel();
|
||||
|
||||
$currencyCode = $channel->base_currency->code;
|
||||
$currencyCode = $channel->base_currency;
|
||||
|
||||
// $currencyCode = $channel->base_currency->code;
|
||||
|
||||
return currency($price, $currencyCode);
|
||||
}
|
||||
|
|
@ -171,4 +212,25 @@ class Core
|
|||
}
|
||||
|
||||
// $timezonelist = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);
|
||||
|
||||
|
||||
/**
|
||||
* Format date using current channel.
|
||||
*
|
||||
* @param date|null $date
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
public function formatDate($date = null, $format = 'd-m-Y H:i:s')
|
||||
{
|
||||
$channel = $this->getCurrentChannel();
|
||||
|
||||
if (is_null($date)) {
|
||||
$date = Carbon::now();
|
||||
}
|
||||
|
||||
$date->setTimezone($channel->timezone);
|
||||
|
||||
return $date->format($format);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Core\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Webkul\Customer\Models\Customer;
|
||||
|
||||
/**
|
||||
* Customer controlller for the customer
|
||||
* to show customer data on admin login
|
||||
*
|
||||
* @author Rahul Shukla <rahulshukla.symfony517@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CustomerController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$customer = Customer::find($id);
|
||||
|
||||
dd($customer->customerGroup->group_name);
|
||||
|
||||
return view($this->_config['view'],compact('customer'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$customer = Customer::find($id);
|
||||
|
||||
$customer->update(request()->all(), [$id]);
|
||||
|
||||
session()->flash('success', 'Customer updated successfully.');
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Core\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
use Webkul\Product\Repositories\ProductReviewRepository as ProductReview;
|
||||
|
||||
/**
|
||||
* Review controller
|
||||
*
|
||||
* @author Rahul Shukla <rahulshukla.symfony517@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class ReviewController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* ProductRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* ProductReviewRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $productReview;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @param Webkul\Product\Repositories\ProductReviewRepository $productReview
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Product $product, ProductReview $productReview)
|
||||
{
|
||||
$this->product = $product;
|
||||
|
||||
$this->productReview = $productReview;
|
||||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request , $id)
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'comment' => 'required',
|
||||
]);
|
||||
|
||||
$input=$request->all();
|
||||
|
||||
$input['product_id']=$id;
|
||||
|
||||
$input['customer_id']=1;
|
||||
|
||||
$this->productReview->create($input);
|
||||
|
||||
session()->flash('success', 'Review submitted successfully.');
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
{
|
||||
$results = [];
|
||||
|
||||
while (list($key, $values) = each($input)) {
|
||||
foreach ($input as $key => $values) {
|
||||
if (empty($values)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
$results = array_merge($results, $append);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class CustomerController extends Controller
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('customer');
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace Webkul\Customer\Models;
|
|||
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Webkul\Customer\Models\CustomersGroups;
|
||||
|
||||
// use Webkul\User\Notifications\AdminResetPassword;
|
||||
|
||||
|
|
@ -15,5 +16,27 @@ class Customer extends Authenticatable
|
|||
use Notifiable;
|
||||
|
||||
protected $table = 'customers';
|
||||
|
||||
protected $fillable = ['first_name', 'last_name', 'gender', 'date_of_birth','phone','email','customer_group_id','subscribed_to_news_letter'];
|
||||
|
||||
protected $hidden = ['password','remember_token'];
|
||||
|
||||
protected $with = ['customerGroup'];
|
||||
|
||||
/**
|
||||
* Get the customer full name.
|
||||
*/
|
||||
public function getNameAttribute() {
|
||||
return ucfirst($this->first_name) . ' ' . ucfirst($this->last_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the customer group that owns the customer.
|
||||
*/
|
||||
public function customerGroup()
|
||||
{
|
||||
return $this->belongsTo(CustomersGroups::class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Contracts\Criteria;
|
||||
|
||||
use Prettus\Repository\Contracts\CriteriaInterface;
|
||||
use Prettus\Repository\Contracts\RepositoryInterface;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Product\AbstractProduct;
|
||||
|
||||
/**
|
||||
* Class MyCriteria.
|
||||
*
|
||||
* @package namespace App\Criteria;
|
||||
*/
|
||||
class AttributeToSelectCriteria extends AbstractProduct implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* @var AttributeRepository
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* @var array|string
|
||||
*/
|
||||
protected $attributeToSelect;
|
||||
|
||||
/**
|
||||
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AttributeRepository $attribute)
|
||||
{
|
||||
$this->attribute = $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attributes in attributeToSelect variable
|
||||
*
|
||||
* @param array|string $attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function addAttribueToSelect($attributes)
|
||||
{
|
||||
$this->attributeToSelect = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply criteria in query repository
|
||||
*
|
||||
* @param string $model
|
||||
* @param RepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($model, RepositoryInterface $repository)
|
||||
{
|
||||
$model = $model->select('products.*');
|
||||
|
||||
foreach ($this->attributeToSelect as $code) {
|
||||
$attribute = $this->attribute->findOneByField('code', $code);
|
||||
|
||||
if(!$attribute)
|
||||
continue;
|
||||
|
||||
$productValueAlias = 'pav_' . $attribute->code;
|
||||
|
||||
$model = $model->leftJoin('product_attribute_values as ' . $productValueAlias, function($qb) use($attribute, $productValueAlias) {
|
||||
|
||||
$qb = $this->applyChannelLocaleFilter($attribute, $qb, $productValueAlias);
|
||||
|
||||
$qb->on('products.id', $productValueAlias . '.product_id')
|
||||
->where($productValueAlias . '.attribute_id', $attribute->id);
|
||||
});
|
||||
|
||||
$model = $model->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Contracts\Criteria;
|
||||
|
||||
use Prettus\Repository\Contracts\CriteriaInterface;
|
||||
use Prettus\Repository\Contracts\RepositoryInterface;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Product\AbstractProduct;
|
||||
|
||||
/**
|
||||
* Class MyCriteria.
|
||||
*
|
||||
* @package namespace App\Criteria;
|
||||
*/
|
||||
class FilterByAttributesCriteria extends AbstractProduct implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* @var AttributeRepository
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AttributeRepository $attribute)
|
||||
{
|
||||
$this->attribute = $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply criteria in query repository
|
||||
*
|
||||
* @param string $model
|
||||
* @param RepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($model, RepositoryInterface $repository)
|
||||
{
|
||||
$model = $model->leftJoin('products as variants', 'products.id', '=', 'variants.parent_id');
|
||||
|
||||
$model = $model->where(function($query1) use($model) {
|
||||
$aliases = [
|
||||
'products' => 'filter_',
|
||||
'variants' => 'variant_filter_'
|
||||
];
|
||||
|
||||
foreach($aliases as $table => $alias) {
|
||||
$query1 = $query1->orWhere(function($query2) use($model, $table, $alias) {
|
||||
|
||||
foreach (request()->input() as $code => $value) {
|
||||
$aliasTemp = $alias . $code;
|
||||
|
||||
$attribute = $this->attribute->findOneByField('code', $code);
|
||||
|
||||
if(!$attribute)
|
||||
continue;
|
||||
|
||||
$model = $model->leftJoin('product_attribute_values as ' . $aliasTemp, $table . '.id', '=', $aliasTemp . '.product_id');
|
||||
|
||||
$query2 = $this->applyChannelLocaleFilter($attribute, $query2, $aliasTemp);
|
||||
|
||||
$column = ProductAttributeValue::$attributeTypeFields[$attribute->type];
|
||||
|
||||
$temp = explode(',', $value);
|
||||
if($attribute->type != 'price') {
|
||||
$query2 = $query2->where($aliasTemp . '.attribute_id', $attribute->id);
|
||||
|
||||
$query2 = $query2->where(function($query3) use($aliasTemp, $column, $temp) {
|
||||
foreach($temp as $code => $filterValue) {
|
||||
$query3 = $query3->orWhere($aliasTemp . '.' . $column, $filterValue);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$query2 = $query2->where($aliasTemp . '.' . $column, '>=', current($temp))
|
||||
->where($aliasTemp . '.' . $column, '<=', end($temp))
|
||||
->where($aliasTemp . '.attribute_id', $attribute->id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Contracts\Criteria;
|
||||
|
||||
use Prettus\Repository\Contracts\CriteriaInterface;
|
||||
use Prettus\Repository\Contracts\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class MyCriteria.
|
||||
*
|
||||
* @package namespace App\Criteria;
|
||||
*/
|
||||
class FilterByCategoryCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $categoryId;
|
||||
|
||||
/**
|
||||
* @param integer $categoryId
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($categoryId)
|
||||
{
|
||||
$this->categoryId = $categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply criteria in query repository
|
||||
*
|
||||
* @param string $model
|
||||
* @param RepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($model, RepositoryInterface $repository)
|
||||
{
|
||||
$model = $model->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id')
|
||||
->where('product_categories.category_id', $this->categoryId);
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Contracts\Criteria;
|
||||
|
||||
use Prettus\Repository\Contracts\CriteriaInterface;
|
||||
use Prettus\Repository\Contracts\RepositoryInterface;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Product\AbstractProduct;
|
||||
|
||||
/**
|
||||
* Class MyCriteria.
|
||||
*
|
||||
* @package namespace App\Criteria;
|
||||
*/
|
||||
class SortCriteria extends AbstractProduct implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* @var AttributeRepository
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AttributeRepository $attribute)
|
||||
{
|
||||
$this->attribute = $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply criteria in query repository
|
||||
*
|
||||
* @param string $model
|
||||
* @param RepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($model, RepositoryInterface $repository)
|
||||
{
|
||||
$params = request()->input();
|
||||
|
||||
if(isset($params['sort'])) {
|
||||
if($params['sort'] == 'name' || $params['sort'] == 'price') {
|
||||
$attribute = $this->attribute->findOneByField('code', $params['sort']);
|
||||
|
||||
$alias = 'sort_' . $params['sort'];
|
||||
|
||||
$model = $model->leftJoin('product_attribute_values as ' . $alias, function($qb) use($attribute, $alias) {
|
||||
|
||||
$qb = $this->applyChannelLocaleFilter($attribute, $qb, $alias);
|
||||
|
||||
$qb->on('products.id', $alias . '.product_id')
|
||||
->where($alias . '.attribute_id', $attribute->id);
|
||||
});
|
||||
|
||||
$model = $model->addSelect($alias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $attribute->code);
|
||||
|
||||
$model = $model->orderBy($attribute->code, $params['order']);
|
||||
|
||||
} else {
|
||||
$model = $model->orderBy($params['sort'], $params['order']);
|
||||
}
|
||||
} else {
|
||||
$model = $model->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Database\Eloquent;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder as BaseBuilder;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
class Builder extends BaseBuilder
|
||||
{
|
||||
/**
|
||||
* Paginate the given query.
|
||||
*
|
||||
* @param int $perPage
|
||||
* @param array $columns
|
||||
* @param string $pageName
|
||||
* @param int|null $page
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
|
||||
{
|
||||
$page = $page ?: Paginator::resolveCurrentPage($pageName);
|
||||
|
||||
$perPage = $perPage ?: $this->model->getPerPage();
|
||||
|
||||
$results = ($total = $this->toBase()->getCountForPagination($columns))
|
||||
? $this->forPage($page, $perPage)->get($columns)
|
||||
: $this->model->newCollection();
|
||||
|
||||
return $this->paginator($results, $total, $perPage, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => $pageName,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ class Product extends Model
|
|||
*/
|
||||
public function up_sells()
|
||||
{
|
||||
return $this->belongsToMany(self::class, 'product_up_sells');
|
||||
return $this->belongsToMany(self::class, 'product_up_sells', 'parent_id', 'child_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,9 +139,9 @@ class Product extends Model
|
|||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($key)
|
||||
{
|
||||
{
|
||||
if (!method_exists(self::class, $key) && !in_array($key, ['parent_id', 'attribute_family_id']) && !isset($this->attributes[$key])) {
|
||||
if ($this->isCustomAttribute($key)) {
|
||||
if (isset($this->id) && $this->isCustomAttribute($key)) {
|
||||
$this->attributes[$key] = '';
|
||||
|
||||
$attributeModel = $this->attribute_family->custom_attributes()->where('attributes.code', $key)->first();
|
||||
|
|
@ -185,32 +185,46 @@ class Product extends Model
|
|||
|
||||
$hiddenAttributes = $this->getHidden();
|
||||
|
||||
$channel = request()->get('channel') ?: core()->getCurrentChannelCode();
|
||||
if(isset($this->id)) {
|
||||
$channel = request()->get('channel') ?: core()->getCurrentChannelCode();
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
||||
foreach ($this->attribute_family->custom_attributes as $attribute) {
|
||||
if (in_array($attribute->code, $hiddenAttributes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if($attribute->value_per_channel) {
|
||||
if($attribute->value_per_locale) {
|
||||
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
|
||||
} else {
|
||||
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('attribute_id', $attribute->id)->first();
|
||||
foreach ($this->attribute_family->custom_attributes as $attribute) {
|
||||
if (in_array($attribute->code, $hiddenAttributes)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if($attribute->value_per_locale) {
|
||||
$attributeValue = $this->attribute_values()->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
|
||||
} else {
|
||||
$attributeValue = $this->attribute_values()->where('attribute_id', $attribute->id)->first();
|
||||
}
|
||||
}
|
||||
|
||||
$attributes[$attribute->code] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]];
|
||||
if($attribute->value_per_channel) {
|
||||
if($attribute->value_per_locale) {
|
||||
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
|
||||
} else {
|
||||
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('attribute_id', $attribute->id)->first();
|
||||
}
|
||||
} else {
|
||||
if($attribute->value_per_locale) {
|
||||
$attributeValue = $this->attribute_values()->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
|
||||
} else {
|
||||
$attributeValue = $this->attribute_values()->where('attribute_id', $attribute->id)->first();
|
||||
}
|
||||
}
|
||||
|
||||
$attributes[$attribute->code] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]];
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default Eloquent query builder
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function newEloquentBuilder($query)
|
||||
{
|
||||
return new \Webkul\Product\Database\Eloquent\Builder($query);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,8 +3,17 @@
|
|||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Customer\Models\Customer;
|
||||
|
||||
class ProductReview extends Model
|
||||
{
|
||||
protected $fillable = [];
|
||||
protected $fillable = ['comment','title','rating','status','product_id','customer_id'];
|
||||
|
||||
/**
|
||||
* Get the product attribute family that owns the product.
|
||||
*/
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,30 +35,4 @@ abstract class AbstractProduct
|
|||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attributes to select
|
||||
*
|
||||
* @param QB $qb
|
||||
* @return QB
|
||||
*/
|
||||
public function addSelectAttributes($qb)
|
||||
{
|
||||
foreach ($this->attributeToSelect as $code) {
|
||||
$attribute = $this->attribute->findOneByField('code', $code);
|
||||
|
||||
$productValueAlias = 'pav_' . $attribute->code;
|
||||
|
||||
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function($leftJoin) use($attribute, $productValueAlias) {
|
||||
|
||||
$leftJoin->on('products.id', $productValueAlias . '.product_id');
|
||||
|
||||
$leftJoin = $this->applyChannelLocaleFilter($attribute, $leftJoin, $productValueAlias)->where($productValueAlias . '.attribute_id', $attribute->id);
|
||||
});
|
||||
|
||||
$qb->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Product;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||
|
||||
class Collection extends AbstractProduct
|
||||
{
|
||||
/**
|
||||
* ProductRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* AttributeRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* array object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributeToSelect = [
|
||||
'name',
|
||||
'description',
|
||||
'short_description',
|
||||
'price',
|
||||
'special_price',
|
||||
'special_price_from',
|
||||
'special_price_to'
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Product $product, Attribute $attribute)
|
||||
{
|
||||
$this->product = $product;
|
||||
|
||||
$this->attribute = $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attributes
|
||||
* @return Void
|
||||
*/
|
||||
public function addAttributesToSelect($attributes)
|
||||
{
|
||||
$this->attributeToSelect = array_unique(
|
||||
array_merge($this->attributeToSelect, $attributes)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $categoryId
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCollection($categoryId = null)
|
||||
{
|
||||
$qb = $this->product->getModel()
|
||||
->select('products.*')
|
||||
->join('product_categories', 'products.id', '=', 'product_categories.product_id')
|
||||
->where('product_categories.category_id', $categoryId);
|
||||
|
||||
$this->addSelectAttributes($qb);
|
||||
|
||||
// foreach (request()->input() as $code => $value) {
|
||||
// $filterAlias = 'filter_' . $code;
|
||||
|
||||
// $qb->leftJoin('product_attribute_values as ' . $filterAlias, 'products.id', '=', $filterAlias . '.product_id');
|
||||
|
||||
// $qb->where($filterAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type], $value);
|
||||
// }
|
||||
|
||||
// if(0) {
|
||||
// $qb->orderBy('id', 'desc');
|
||||
// }
|
||||
|
||||
return $qb->paginate(9);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Shop\Product;
|
||||
namespace Webkul\Product\Product;
|
||||
|
||||
class Review extends AbstractProduct
|
||||
{
|
||||
/**
|
||||
* Returns the product's avg rating
|
||||
*
|
||||
* @param Product $product
|
||||
* @return float
|
||||
*/
|
||||
public function getAverageRating($product)
|
||||
{
|
||||
return round($product->reviews->average('rating'));
|
||||
return round($product->reviews->where('status',1)->average('rating'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total review of the product
|
||||
*
|
||||
* @param Product $product
|
||||
* @return integer
|
||||
*/
|
||||
public function getTotalReviews($product)
|
||||
{
|
||||
return $product->reviews()->where('status',1)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formated created at date
|
||||
*
|
||||
* @param ProductReview $review
|
||||
* @return integer
|
||||
*/
|
||||
public function formatDate($reviewCreatedAt)
|
||||
{
|
||||
return core()->formatDate($reviewCreatedAt, 'd, M Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total rating of the product
|
||||
*
|
||||
* @param Product $product
|
||||
* @return integer
|
||||
*/
|
||||
public function getTotalRating($product)
|
||||
{
|
||||
return $product->reviews()->where('status',1)->sum('rating');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Percentage rating of the product
|
||||
*
|
||||
* @param Product $product
|
||||
* @return integer
|
||||
*/
|
||||
public function getPercentageRating($product)
|
||||
{
|
||||
$reviews['five'] = $product->reviews()->where('rating', 5)->where('status',1)->count();
|
||||
|
||||
$reviews['four'] = $product->reviews()->where('rating', 4)->where('status',1)->count();
|
||||
|
||||
$reviews['three'] = $product->reviews()->where('rating', 3)->where('status',1)->count();
|
||||
|
||||
$reviews['two'] = $product->reviews()->where('rating', 2)->where('status',1)->count();
|
||||
|
||||
$reviews['one'] = $product->reviews()->where('rating', 1)->where('status',1)->count();
|
||||
|
||||
foreach($reviews as $key=>$review){
|
||||
|
||||
if($this->getTotalReviews($product) == 0){
|
||||
$percentage[$key]=0;
|
||||
}else{
|
||||
$percentage[$key] = round(($review/$this->getTotalReviews($product))*100);
|
||||
}
|
||||
}
|
||||
|
||||
return $percentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the of the product
|
||||
*
|
||||
* @param Product $product
|
||||
* @return integer
|
||||
*/
|
||||
|
||||
public function loadMore($product)
|
||||
{
|
||||
$link = $_SERVER['PHP_SELF'];
|
||||
$link_array = explode('/',$link);
|
||||
$last=end($link_array);
|
||||
$itemPerPage = $last*5;
|
||||
return $product->reviews()->where('status',1)->paginate($itemPerPage);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Product;
|
||||
|
||||
class Toolbar extends AbstractProduct
|
||||
{
|
||||
/**
|
||||
* Returns available sort orders
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getAvailableOrders()
|
||||
{
|
||||
return [
|
||||
'name-asc' => 'from-a-z',
|
||||
'name-desc' => 'from-z-a',
|
||||
'created_at-desc' => 'newest-first',
|
||||
'created_at-asc' => 'oldest-first',
|
||||
'price-asc' => 'cheapest-first',
|
||||
'price-desc' => 'expansive-first'
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Returns available limits
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getAvailableLimits()
|
||||
{
|
||||
return [9, 15, 21, 28];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sort order url
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderUrl($key)
|
||||
{
|
||||
$keys = explode('-', $key);
|
||||
|
||||
return request()->fullUrlWithQuery([
|
||||
'sort' => current($keys),
|
||||
'order' => end($keys)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the limit url
|
||||
*
|
||||
* @param integer $limit
|
||||
* @return string
|
||||
*/
|
||||
public function getLimitUrl($limit)
|
||||
{
|
||||
return request()->fullUrlWithQuery([
|
||||
'limit' => $limit
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mode url
|
||||
*
|
||||
* @param string $mode
|
||||
* @return string
|
||||
*/
|
||||
public function getModeUrl($mode)
|
||||
{
|
||||
return request()->fullUrlWithQuery([
|
||||
'mode' => $mode
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if sort order is active
|
||||
*
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOrderCurrent($key)
|
||||
{
|
||||
$params = request()->input();
|
||||
|
||||
if(isset($params['sort']) && $key == $params['sort'] . '-' . $params['order'])
|
||||
return true;
|
||||
elseif(!isset($params['sort']) && $key == 'created_at-desc')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if limit is active
|
||||
*
|
||||
* @param integer $limit
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLimitCurrent($limit)
|
||||
{
|
||||
$params = request()->input();
|
||||
|
||||
if(isset($params['limit']) && $limit == $params['limit'])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if mode is active
|
||||
*
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function isModeActive($key)
|
||||
{
|
||||
$params = request()->input();
|
||||
|
||||
if(isset($params['mode']) && $key == $params['mode'])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mode
|
||||
*
|
||||
* @param string $mode
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentMode()
|
||||
{
|
||||
$params = request()->input();
|
||||
|
||||
if(isset($params['mode']))
|
||||
return $params['mode'];
|
||||
|
||||
return 'grid';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Product;
|
||||
|
||||
class View extends AbstractProduct
|
||||
{
|
||||
/**
|
||||
* Returns the visible custom attributes
|
||||
*
|
||||
* @param Product $product
|
||||
* @return integer
|
||||
*/
|
||||
public function getAdditionalData($product)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$attributes = $product->attribute_family->custom_attributes;
|
||||
|
||||
foreach($attributes as $attribute) {
|
||||
if($attribute->is_visible_on_front) {
|
||||
$data[] = [
|
||||
'code' => $attribute->code,
|
||||
'label' => $attribute->name,
|
||||
'value' => $product->{$attribute->code},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ class ProductAttributeValueRepository extends Repository
|
|||
*/
|
||||
public function isValueUnique($productId, $attributeId, $column, $value)
|
||||
{
|
||||
$result = $this->resetScope()->model->where($column, $value)->where('attribute_id', '!=', $attributeId)->where('product_id', '!=', $productId)->get();
|
||||
$result = $this->resetScope()->model->where($column, $value)->where('attribute_id', '=', $attributeId)->where('product_id', '!=', $productId)->get();
|
||||
|
||||
return $result->count() ? false : true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
|||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Contracts\Criteria\SortCriteria;
|
||||
use Webkul\Product\Contracts\Criteria\AttributeToSelectCriteria;
|
||||
use Webkul\Product\Contracts\Criteria\FilterByAttributesCriteria;
|
||||
use Webkul\Product\Contracts\Criteria\FilterByCategoryCriteria;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
/**
|
||||
* Product Repository
|
||||
|
|
@ -177,6 +182,8 @@ class ProductRepository extends Repository
|
|||
}
|
||||
}
|
||||
|
||||
$previousVariantIds = $product->variants->pluck('id');
|
||||
|
||||
if(isset($data['variants'])) {
|
||||
foreach ($data['variants'] as $variantId => $variantData) {
|
||||
if (str_contains($variantId, 'variant_')) {
|
||||
|
|
@ -187,13 +194,22 @@ class ProductRepository extends Repository
|
|||
|
||||
$this->createVariant($product, $permutation, $variantData);
|
||||
} else {
|
||||
if(is_numeric($index = $previousVariantIds->search($variantId))) {
|
||||
$previousVariantIds->forget($index);
|
||||
}
|
||||
|
||||
$variantData['channel'] = $data['channel'];
|
||||
$variantData['locale'] = $data['locale'];
|
||||
|
||||
$this->updateVariant($variantData, $variantId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($previousVariantIds as $variantId) {
|
||||
$this->delete($variantId);
|
||||
}
|
||||
|
||||
$this->productInventory->saveInventories($data, $product);
|
||||
|
||||
$this->productImage->uploadImages($data, $product);
|
||||
|
|
@ -358,4 +374,53 @@ class ProductRepository extends Repository
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $categoryId
|
||||
* @return Collection
|
||||
*/
|
||||
public function findAllByCategory($categoryId = null)
|
||||
{
|
||||
$this->pushCriteria(app(SortCriteria::class));
|
||||
$this->pushCriteria(app(FilterByAttributesCriteria::class));
|
||||
$this->pushCriteria(new FilterByCategoryCriteria($categoryId));
|
||||
$this->pushCriteria(app(AttributeToSelectCriteria::class)->addAttribueToSelect([
|
||||
'name',
|
||||
'description',
|
||||
'short_description',
|
||||
'price',
|
||||
'special_price',
|
||||
'special_price_from',
|
||||
'special_price_to'
|
||||
]));
|
||||
|
||||
$params = request()->input();
|
||||
|
||||
return $this->scopeQuery(function($query){
|
||||
return $query->distinct()->addSelect('products.*');
|
||||
})->paginate(isset($params['limit']) ? $params['limit'] : 9, ['products.id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive product from slug
|
||||
*
|
||||
* @param string $slug
|
||||
* @return mixed
|
||||
*/
|
||||
public function findBySlugOrFail($slug)
|
||||
{
|
||||
$attribute = $this->attribute->findOneByField('code', 'url_key');
|
||||
|
||||
$attributeValue = $this->attributeValue->findOneWhere([
|
||||
'attribute_id' => $attribute->id,
|
||||
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $slug
|
||||
]);
|
||||
|
||||
if($attributeValue && $attributeValue->product)
|
||||
return $attributeValue->product;
|
||||
|
||||
throw (new ModelNotFoundException)->setModel(
|
||||
get_class($this->model), $slug
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Repositories;
|
||||
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
/**
|
||||
* Product Review Reposotory
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class ProductReviewRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function model()
|
||||
{
|
||||
return 'Webkul\Product\Models\ProductReview';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Shop\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
|
||||
/**
|
||||
* Product controller
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class ProductController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* ProductRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Product $product)
|
||||
{
|
||||
$this->product = $product;
|
||||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index($slug)
|
||||
{
|
||||
$product = $this->product->findBySlugOrFail($slug);
|
||||
|
||||
return view($this->_config['view'], compact('product'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Shop\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
use Webkul\Product\Repositories\ProductReviewRepository as ProductReview;
|
||||
|
||||
/**
|
||||
* Review controller
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class ReviewController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* ProductRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* ProductReviewRepository object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $productReview;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @param Webkul\Product\Repositories\ProductReviewRepository $productReview
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Product $product, ProductReview $productReview)
|
||||
{
|
||||
$this->product = $product;
|
||||
|
||||
$this->productReview = $productReview;
|
||||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create($slug)
|
||||
{
|
||||
$product = $this->product->findBySlugOrFail($slug);
|
||||
|
||||
return view($this->_config['view'], compact('product'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request , $id)
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'comment' => 'required',
|
||||
'rating' => 'required',
|
||||
'title' => 'required',
|
||||
]);
|
||||
|
||||
$data=$request->all();
|
||||
|
||||
$customer_id = auth()->guard('customer')->user()->id;
|
||||
|
||||
$data['status']=0;
|
||||
$data['product_id']=$id;
|
||||
$data['customer_id']=$customer_id;
|
||||
|
||||
$this->productReview->create($data);
|
||||
|
||||
session()->flash('success', 'Review submitted successfully.');
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display reviews accroding to product.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
$product = $this->product->findBySlugOrFail($slug);
|
||||
|
||||
return view($this->_config['view'],compact('product'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$review = $this->productReview->find($id);
|
||||
|
||||
return view($this->_config['view'],compact('review'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
|
||||
$this->productReview->update(request()->all(), $id);
|
||||
|
||||
session()->flash('success', 'Review updated successfully.');
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ Route::group(['middleware' => ['web']], function () {
|
|||
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [
|
||||
'view' => 'shop::products.index'
|
||||
]);
|
||||
|
||||
|
||||
/* dummy routes */
|
||||
Route::view('/customer/order','shop::customers.account.orders.index');
|
||||
|
||||
|
|
@ -24,9 +24,33 @@ Route::group(['middleware' => ['web']], function () {
|
|||
Route::view('/customer/payment_complete','shop::customers.checkout.complete');
|
||||
/* dummy routes ends here */
|
||||
|
||||
|
||||
Route::get('/products/{slug}', 'Webkul\Shop\Http\Controllers\ProductController@index')->defaults('_config', [
|
||||
'view' => 'shop::products.view'
|
||||
])->name('shop.products.index');
|
||||
|
||||
|
||||
// Product Review routes
|
||||
Route::get('/reviews/{slug}/{id}', 'Webkul\Shop\Http\Controllers\ReviewController@show')->defaults('_config', [
|
||||
'view' => 'shop::products.reviews.index'
|
||||
])->name('shop.reviews.index');
|
||||
|
||||
Route::get('/product/{slug}/review', 'Webkul\Shop\Http\Controllers\ReviewController@create')->defaults('_config', [
|
||||
'view' => 'shop::products.reviews.create'
|
||||
])->name('shop.reviews.create');
|
||||
|
||||
Route::post('/product/{slug}/review', 'Webkul\Shop\Http\Controllers\ReviewController@store')->defaults('_config', [
|
||||
'redirect' => 'shop.reviews.index'
|
||||
])->name('shop.reviews.store');
|
||||
|
||||
// Route::post('/reviews/create/{slug}', 'Webkul\Core\Http\Controllers\ReviewController@store')->defaults('_config', [
|
||||
// 'redirect' => 'admin.reviews.index'
|
||||
// ])->name('admin.reviews.store');
|
||||
|
||||
|
||||
Route::view('/cart', 'shop::store.product.view.cart.index');
|
||||
|
||||
Route::view('/products/{slug}', 'shop::store.product.details.index');
|
||||
// Route::view('/products/{slug}', 'shop::products.view');
|
||||
|
||||
//customer routes starts here
|
||||
Route::prefix('customer')->group(function () {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//shop variables
|
||||
$font-color: #242424;
|
||||
$font-size-base: 16px;
|
||||
$font-name: "Montserrat", sans-serif;
|
||||
$background-color: #f2f2f2;
|
||||
$footer-back: #f2f2f2;
|
||||
|
|
@ -23,6 +25,7 @@ $horizontal-rule-color: #E8E8E8;
|
|||
//product
|
||||
$real-price:#A5A5A5;
|
||||
$product-font-color: #242424;
|
||||
$product-special-price-color: #FF6472;
|
||||
$product-price-color: #FF6472;
|
||||
$dark-blue-shade: #0031F0;
|
||||
$bar-color: #D8D8D8;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ body {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: $font-color;
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
* {
|
||||
|
|
@ -200,7 +201,7 @@ body {
|
|||
|
||||
.nav a {
|
||||
display:block;
|
||||
color: #242424;
|
||||
color: $font-color;
|
||||
text-decoration: none;
|
||||
padding: 0.8em 0.3em 0.8em 0.5em;
|
||||
text-transform: uppercase;
|
||||
|
|
@ -674,13 +675,13 @@ section.slider-block {
|
|||
.layered-filter-wrapper {
|
||||
width: 25%;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
padding-right: 20px;
|
||||
min-height: 1px;
|
||||
|
||||
.filter-title {
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
color: $font-color;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
|
|
@ -760,6 +761,7 @@ section.slider-block {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.main-container-wrapper {
|
||||
margin-left: 10%;
|
||||
margin-right: 10%;
|
||||
|
|
@ -769,6 +771,11 @@ section.slider-block {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: inline-block;
|
||||
width: 75%
|
||||
}
|
||||
|
||||
.product-grid {
|
||||
display: grid;
|
||||
grid-gap: 30px;
|
||||
|
|
@ -789,58 +796,129 @@ section.slider-block {
|
|||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.product-image img {
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
.product-card {
|
||||
|
||||
.product-image img {
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
color: $font-color;
|
||||
|
||||
a {
|
||||
color: $font-color;
|
||||
}
|
||||
}
|
||||
|
||||
.product-description {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.product-ratings {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.cart-fav-seg {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
.addtocart {
|
||||
border-radius: 0px;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-list {
|
||||
.product-card {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.product-image {
|
||||
float: left;
|
||||
width: 30%;
|
||||
height: 350px;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.product-name {
|
||||
.product-information {
|
||||
float: right;
|
||||
width: 70%;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-toolbar {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-bottom: 25px;
|
||||
|
||||
.page-info {
|
||||
float: left;
|
||||
color: $font-color;
|
||||
line-height: 45px;
|
||||
}
|
||||
|
||||
.pager {
|
||||
float: right;
|
||||
|
||||
label {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
select {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
color: $font-color;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.view-mode {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
|
||||
.regular-price {
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
text-decoration: line-through;
|
||||
margin-right: 10px;
|
||||
}
|
||||
a, span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
.special-price {
|
||||
font-size: 16px;
|
||||
color: #FF6472;
|
||||
&.grid-view {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-ratings {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
.sorter {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.cart-fav-seg {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
.addtocart {
|
||||
border-radius: 0px;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.limiter {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -920,6 +998,30 @@ section.slider-block {
|
|||
}
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
|
||||
.price-label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.regular-price {
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
text-decoration: line-through;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.special-price {
|
||||
font-size: 16px;
|
||||
color: #FF6472;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: $footer-back;
|
||||
padding-left: 10%;
|
||||
|
|
@ -1123,7 +1225,7 @@ section.slider-block {
|
|||
.section-head {
|
||||
.profile-heading {
|
||||
font-size: 28px;
|
||||
color: #242424;
|
||||
color: $font-color;
|
||||
text-transform: capitalize;
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -1230,24 +1332,16 @@ section.product-detail, section.product-review {
|
|||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.price {
|
||||
.product-price {
|
||||
margin-bottom: 14px;
|
||||
|
||||
.main-price {
|
||||
font-size: 24px;
|
||||
color: $product-price-color;
|
||||
}
|
||||
|
||||
.real-price {
|
||||
color: $real-price;
|
||||
text-decoration-line: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rating-reviews {
|
||||
margin-top: 30px;
|
||||
margin-top: 0px;
|
||||
width: 50%;
|
||||
margin-left: 20px;
|
||||
|
||||
.title-inline {
|
||||
display: inline-flex;
|
||||
|
|
@ -1298,14 +1392,11 @@ section.product-detail, section.product-review {
|
|||
background: $bar-color;
|
||||
|
||||
.line-value {
|
||||
height: 4px;
|
||||
width: 100px;
|
||||
background-color: $dark-blue-shade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.reviews {
|
||||
|
|
@ -1377,12 +1468,12 @@ section.product-detail, section.product-review {
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.price {
|
||||
.product-price {
|
||||
margin-bottom: 14px;
|
||||
font-size: 24px;
|
||||
|
||||
.main-price {
|
||||
.special-price {
|
||||
font-size: 24px;
|
||||
color: $product-price-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1394,9 +1485,21 @@ section.product-detail, section.product-review {
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
hr{
|
||||
border-top: 1px solid $horizontal-rule-color;
|
||||
margin-bottom: 17px;
|
||||
.full-specifications {
|
||||
td {
|
||||
padding: 10px 0;
|
||||
color: #5E5E5E;
|
||||
|
||||
&:first-child {
|
||||
padding-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accordian .accordian-header {
|
||||
font-size: 16px;
|
||||
padding-left: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.attributes {
|
||||
|
|
@ -1478,21 +1581,21 @@ section.product-detail, section.product-review {
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
.full-specification{
|
||||
|
||||
}
|
||||
|
||||
.rating-reviews {
|
||||
margin-top: 30px;
|
||||
|
||||
.title{
|
||||
.title {
|
||||
margin-bottom: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.overall {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.number{
|
||||
font-size: 34px;
|
||||
.review-info {
|
||||
.number {
|
||||
font-size: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
|
|
@ -1500,7 +1603,6 @@ section.product-detail, section.product-review {
|
|||
border-radius: 0px !important;
|
||||
}
|
||||
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.reviews {
|
||||
|
|
@ -1512,11 +1614,23 @@ section.product-detail, section.product-review {
|
|||
|
||||
.stars {
|
||||
margin-bottom: 15px;
|
||||
display: inline-block;
|
||||
|
||||
.icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.reviewer-details {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
}
|
||||
|
||||
.view-all {
|
||||
margin-top:15px;
|
||||
color: $logo-color;
|
||||
|
|
@ -1525,33 +1639,7 @@ section.product-detail, section.product-review {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// .related-products-wrapper {
|
||||
// margin-bottom: 80px;
|
||||
|
||||
// .title{
|
||||
// margin-bottom: 22px;
|
||||
// text-align: center;
|
||||
// }
|
||||
|
||||
// .horizontal-rule {
|
||||
// height: 1px;
|
||||
// background: $horizontal-rule-color;
|
||||
// width: 148px;
|
||||
// margin-bottom: 24px;
|
||||
// margin-left:auto;
|
||||
// margin-right:auto;
|
||||
// }
|
||||
|
||||
// .related-products {
|
||||
// display: grid;
|
||||
// grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
// grid-gap: 10px;
|
||||
// }
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
/* cart pages and elements css begins here */
|
||||
|
|
@ -1780,14 +1868,25 @@ section.cart {
|
|||
|
||||
}
|
||||
|
||||
.related-products-wrapper {
|
||||
.attached-products-wrapper {
|
||||
margin-bottom: 80px;
|
||||
|
||||
.title{
|
||||
margin-bottom: 22px;
|
||||
.title {
|
||||
margin-bottom: 40px;
|
||||
font-size: 18px;
|
||||
color: $product-font-color;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid rgba(162, 162, 162, 0.2);
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
margin-left: -50px;
|
||||
}
|
||||
}
|
||||
|
||||
.horizontal-rule {
|
||||
|
|
@ -1798,13 +1897,6 @@ section.cart {
|
|||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
|
||||
.related-products {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// order page css start here
|
||||
|
|
@ -3648,4 +3740,184 @@ section.cart {
|
|||
// complete page end here
|
||||
|
||||
|
||||
// review page start here
|
||||
|
||||
section.review {
|
||||
font-size: 16px;
|
||||
color: $product-font-color;
|
||||
|
||||
.category-breadcrumbs {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.review-layouter {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
margin-top: 20px;
|
||||
|
||||
.product-info {
|
||||
|
||||
.image {
|
||||
border:1px solid red;
|
||||
|
||||
img {
|
||||
height: 280px;
|
||||
width: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
margin-top: 20px;
|
||||
|
||||
span {
|
||||
font-size: 24px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.58px;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
margin-top: 10px;
|
||||
|
||||
.pro-price {
|
||||
font-size: 24px;
|
||||
color: #FF6472;
|
||||
letter-spacing: -0.58px;
|
||||
}
|
||||
|
||||
.pro-price-not {
|
||||
margin-left: 10px;
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
.offer {
|
||||
margin-left: 10px;
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.review-info {
|
||||
margin-left: 20px;
|
||||
width: 49%;
|
||||
|
||||
.heading {
|
||||
margin-top: 10px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
.btn.btn-primary.right {
|
||||
float: right;
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.rating {
|
||||
margin-top : 25px;
|
||||
font-size: 16px;
|
||||
color: #5E5E5E;
|
||||
letter-spacing: -0.12px;
|
||||
|
||||
span {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.stars {
|
||||
|
||||
width: 270px;
|
||||
display: inline-block;
|
||||
|
||||
label.star {
|
||||
font-size: 36px;
|
||||
color: #d4d4d4;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
label.star:before {
|
||||
content: '\2605';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.write-review {
|
||||
margin-top: 25px;
|
||||
|
||||
.control-group {
|
||||
margin-bottom: 0px;
|
||||
|
||||
textarea {
|
||||
margin-top: 5px;
|
||||
border: 2px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
width: 600px;
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
margin-top: 10px;
|
||||
|
||||
button {
|
||||
background: #0031F0;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: -0.26px;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
height: 38px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.review-detail{
|
||||
height: 150px;
|
||||
border: 1px solid firebrick;
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.rating-review {
|
||||
margin-top: 40px;
|
||||
margin-left: 20px;
|
||||
width: 48%;
|
||||
|
||||
.avg-rating-count{
|
||||
|
||||
span {
|
||||
font-size: 34px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.82px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rating-calculate {
|
||||
|
||||
.progress-only {
|
||||
width:20px;
|
||||
border: 1px solid blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// review page start here
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,23 @@
|
|||
display: inline-block;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.dropdown-right-icon{
|
||||
background-image:URL('../images/icon-dropdown-left.svg');
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-left:auto;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.grid-view-icon {
|
||||
background-image:URL('../images/icon-grid-view.svg');
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.list-view-icon {
|
||||
background-image:URL('../images/icon-list-view.svg');
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
|
@ -35,6 +35,20 @@ return [
|
|||
'products' => [
|
||||
'layered-nav-title' => 'Shop By',
|
||||
'price-label' => 'As low as',
|
||||
'remove-filter-link-title' => 'Clear All'
|
||||
'remove-filter-link-title' => 'Clear All',
|
||||
'sort-by' => 'Sort By',
|
||||
'from-a-z' => 'From A-Z',
|
||||
'from-z-a' => 'From Z-A',
|
||||
'newest-first' => 'Newest First',
|
||||
'oldest-first' => 'Oldest First',
|
||||
'cheapest-first' => 'Cheapest First',
|
||||
'expansive-first' => 'Expansive First',
|
||||
'show' => 'Show',
|
||||
'pager-info' => 'Showing :showing of :total Items',
|
||||
'description' => 'Description',
|
||||
'specification' => 'Specification',
|
||||
'total-reviews' => ':total Reviews',
|
||||
'by' => 'By :name',
|
||||
'up-sell-title' => 'We found other products you might like!'
|
||||
]
|
||||
];
|
||||
|
|
@ -1 +1 @@
|
|||
<button class="btn btn-md btn-primary addtocart">Add to Cart</button>
|
||||
<button class="btn btn-lg btn-primary addtocart">Add to Cart</button>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<div class="product-card">
|
||||
<div class="product-image">
|
||||
<img src="{{ bagisto_asset('images/gogs.png') }}" />
|
||||
</div>
|
||||
|
||||
<div class="product-name">
|
||||
<span>{{ $product->name }}</span>
|
||||
</div>
|
||||
|
||||
@include ('shop::products.price', ['product' => $product])
|
||||
|
||||
@if ($product->reviews->count())
|
||||
|
||||
@include ('shop::products.review', ['product' => $product])
|
||||
|
||||
@endif
|
||||
|
||||
@include ('shop::products.add-to', ['product' => $product])
|
||||
|
||||
</div>
|
||||
|
|
@ -2,24 +2,40 @@
|
|||
|
||||
@section('content-wrapper')
|
||||
|
||||
@include ('shop::products.layered-navigation')
|
||||
@include ('shop::products.list.layered-navigation')
|
||||
|
||||
<div class="main" style="display: inline-block">
|
||||
|
||||
<div class="product-grid max-3-col">
|
||||
@inject ('productRepository', 'Webkul\Product\Repositories\ProductRepository')
|
||||
|
||||
@inject ('productHelper', 'Webkul\Product\Product\Collection')
|
||||
|
||||
<?php $products = $productHelper->getCollection($category->id); ?>
|
||||
|
||||
@foreach ($products as $product)
|
||||
<?php $products = $productRepository->findAllByCategory($category->id); ?>
|
||||
|
||||
@include ('shop::products.card', ['product' => $product])
|
||||
@include ('shop::products.list.toolbar')
|
||||
|
||||
@endforeach
|
||||
@inject ('toolbarHelper', 'Webkul\Product\Product\Toolbar')
|
||||
|
||||
</div>
|
||||
@if ($toolbarHelper->getCurrentMode() == 'grid')
|
||||
<div class="product-grid max-3-col">
|
||||
|
||||
@foreach ($products as $product)
|
||||
|
||||
@include ('shop::products.list.card', ['product' => $product])
|
||||
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
@else
|
||||
<div class="product-list">
|
||||
|
||||
@foreach ($products as $product)
|
||||
|
||||
@include ('shop::products.list.card', ['product' => $product])
|
||||
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="bottom-toolbar">
|
||||
|
||||
{{ $products->appends(request()->input())->links() }}
|
||||
|
|
@ -28,8 +44,4 @@
|
|||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
@push('scripts')
|
||||
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<div class="product-card">
|
||||
<div class="product-image">
|
||||
<a href="{{ route('shop.products.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<img src="{{ bagisto_asset('images/gogs.png') }}" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="product-information">
|
||||
|
||||
<div class="product-name">
|
||||
|
||||
{{ $product->id }}
|
||||
|
||||
<a href="" title="{{ $product->name }}">
|
||||
<span>{{ $product->name }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="product-description">
|
||||
{{ $product->short_description }}
|
||||
</div>
|
||||
|
||||
@include ('shop::products.price', ['product' => $product])
|
||||
|
||||
@if ($product->reviews->count())
|
||||
|
||||
@include ('shop::products.review', ['product' => $product])
|
||||
|
||||
@endif
|
||||
|
||||
@include ('shop::products.add-to', ['product' => $product])
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
@inject ('attributeRepository', 'Webkul\Attribute\Repositories\AttributeRepository')
|
||||
|
||||
<div class="layered-filter-wrapper">
|
||||
|
||||
<layered-navigation></layered-navigation>
|
||||
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
|
|
@ -129,8 +131,8 @@
|
|||
|
||||
sliderConfig: {
|
||||
value: [
|
||||
100,
|
||||
250
|
||||
0,
|
||||
0
|
||||
],
|
||||
max: 500,
|
||||
processStyle: {
|
||||
|
|
@ -171,7 +173,7 @@
|
|||
|
||||
clearFilters () {
|
||||
if(this.attribute.type == 'price') {
|
||||
this.sliderConfig.value = [100, 250];
|
||||
this.sliderConfig.value = [0, 0];
|
||||
}
|
||||
|
||||
this.appliedFilters = [];
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
@inject ('toolbarHelper', 'Webkul\Product\Product\Toolbar')
|
||||
|
||||
<div class="top-toolbar">
|
||||
|
||||
<div class="page-info">
|
||||
{{ __('shop::app.products.pager-info', ['showing' => $products->firstItem() . '-' . $products->lastItem(), 'total' => $products->total()]) }}
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
|
||||
<div class="view-mode">
|
||||
@if ($toolbarHelper->isModeActive('grid'))
|
||||
<span class="grid-view">
|
||||
<i class="icon grid-view-icon"></i>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $toolbarHelper->getModeUrl('grid') }}" class="grid-view">
|
||||
<i class="icon grid-view-icon"></i>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($toolbarHelper->isModeActive('list'))
|
||||
<span class="list-view">
|
||||
<i class="icon list-view-icon"></i>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $toolbarHelper->getModeUrl('list') }}" class="list-view">
|
||||
<i class="icon list-view-icon"></i>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="sorter">
|
||||
<label>{{ __('shop::app.products.sort-by') }}</label>
|
||||
|
||||
<select onchange="window.location.href = this.value">
|
||||
|
||||
@foreach ($toolbarHelper->getAvailableOrders() as $key => $order)
|
||||
|
||||
<option value="{{ $toolbarHelper->getOrderUrl($key) }}" {{ $toolbarHelper->isOrderCurrent($key) ? 'selected' : '' }}>
|
||||
{{ __('shop::app.products.' . $order) }}
|
||||
</option>
|
||||
|
||||
@endforeach
|
||||
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="limiter">
|
||||
<label>{{ __('shop::app.products.show') }}</label>
|
||||
|
||||
<select onchange="window.location.href = this.value">
|
||||
|
||||
@foreach ($toolbarHelper->getAvailableLimits() as $limit)
|
||||
|
||||
<option value="{{ $toolbarHelper->getLimitUrl($limit) }}" {{ $toolbarHelper->isLimitCurrent($limit) ? 'selected' : '' }}>
|
||||
{{ $limit }}
|
||||
</option>
|
||||
|
||||
@endforeach
|
||||
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
@extends('shop::layouts.master')
|
||||
|
||||
@section('content-wrapper')
|
||||
<section class="review">
|
||||
|
||||
<div class="category-breadcrumbs">
|
||||
<span class="breadcrumb">Home</span> > <span class="breadcrumb">Men</span> > <span class="breadcrumb">Slit Open Jeans</span>
|
||||
</div>
|
||||
|
||||
<div class="review-layouter">
|
||||
|
||||
<div class="product-info">
|
||||
|
||||
<div class="image">
|
||||
<img src="{{ bagisto_asset('images/jeans_big.jpg') }}" />
|
||||
</div>
|
||||
|
||||
<div class="heading">
|
||||
<span>{{ $product->name }}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="price">
|
||||
|
||||
@inject ('priceHelper', 'Webkul\Product\Product\Price')
|
||||
|
||||
@if ($product->type == 'configurable')
|
||||
<span class="pro-price">{{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>
|
||||
@else
|
||||
@if ($priceHelper->haveSpecialPrice($product))
|
||||
<span class="pro-price">{{ core()->currency($priceHelper->getSpecialPrice($product)) }}</span>
|
||||
@else
|
||||
<span class="pro-price">{{ core()->currency($product->price) }}</span>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<span class="pro-price-not">
|
||||
<strike> $45.00 </strike>
|
||||
</span>
|
||||
|
||||
<span class="offer"> 10% Off </span>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="review-info">
|
||||
|
||||
<form method="POST" action="{{ route('shop.reviews.store', $product->id ) }}">
|
||||
@csrf
|
||||
|
||||
<div class="heading">
|
||||
<span> Write a review </span>
|
||||
</div>
|
||||
|
||||
<div class="rating">
|
||||
<span> {{ __('admin::app.customers.reviews.rating') }} </span>
|
||||
</div>
|
||||
<div class="stars">
|
||||
<label class="star star-5" for="star-5" onclick="calculateRating(id)" id="1"></label>
|
||||
<label class="star star-4" for="star-4" onclick="calculateRating(id)" id="2"></label>
|
||||
<label class="star star-3" for="star-3" onclick="calculateRating(id)" id="3"></label>
|
||||
<label class="star star-2" for="star-2" onclick="calculateRating(id)" id="4"></label>
|
||||
<label class="star star-1" for="star-1" onclick="calculateRating(id)" id="5"></label>
|
||||
|
||||
<input type="name" name="title" class="form-control" placeholder="title">
|
||||
|
||||
<input type="hidden" id="rating" name="rating">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="write-review">
|
||||
<div class="control-group">
|
||||
<label for="review">{{ __('admin::app.customers.reviews.comment') }}</label>
|
||||
<textarea name="comment">
|
||||
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit-button">
|
||||
<button type="submit" class="btn btn-lg btn-primary"> SUBMIT </button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
|
||||
@push('scripts')
|
||||
|
||||
<script>
|
||||
|
||||
function calculateRating(id){
|
||||
|
||||
var a=document.getElementById(id);
|
||||
document.getElementById("rating").value = id;
|
||||
|
||||
for (let i=1 ; i <= 5 ; i++){
|
||||
|
||||
if(id >= i){
|
||||
document.getElementById(i).style.color="#242424";
|
||||
}else{
|
||||
document.getElementById(i).style.color="#d4d4d4";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
@inject ('reviewHelper', 'Webkul\Product\Product\Review')
|
||||
@inject ('priceHelper', 'Webkul\Product\Product\Price')
|
||||
|
||||
@extends('shop::layouts.master')
|
||||
@section('content-wrapper')
|
||||
<section class="product-review">
|
||||
<div class="category-breadcrumbs">
|
||||
|
||||
<span class="breadcrumb">Home</span> > <span class="breadcrumb">Men</span> > <span class="breadcrumb">Slit Open Jeans</span>
|
||||
|
||||
</div>
|
||||
<div class="layouter">
|
||||
|
||||
<div class="mixed-group">
|
||||
|
||||
<div class="single-image">
|
||||
<img src="{{ bagisto_asset('images/jeans_big.jpg') }}" />
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
|
||||
<div class="product-name">
|
||||
{{ $product->name }}
|
||||
</div>
|
||||
|
||||
<div class="price">
|
||||
@if ($product->type == 'configurable')
|
||||
<span class="main-price">${{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>
|
||||
@else
|
||||
@if ($priceHelper->haveSpecialPrice($product))
|
||||
<span class="main-price">${{ core()->currency($priceHelper->getSpecialPrice($product)) }}</span>
|
||||
@else
|
||||
<span class="main-price">${{ core()->currency($product->price) }}</span>
|
||||
@endif
|
||||
@endif
|
||||
<span class="real-price">
|
||||
$25.00
|
||||
</span>
|
||||
<span class="discount">
|
||||
10% Off
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rating-reviews">
|
||||
|
||||
<div class="title-inline">
|
||||
<span>Ratings & {{ __('admin::app.customers.reviews.name') }}</span>
|
||||
<!-- <button class="btn btn-md btn-primary">Write Review</button> -->
|
||||
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary right">Write Review</a>
|
||||
</div>
|
||||
|
||||
<div class="overall">
|
||||
<div class="left-side">
|
||||
<span class="number">
|
||||
{{ $reviewHelper->getAverageRating($product) }}
|
||||
</span>
|
||||
|
||||
@for($i = 1; $i <= $reviewHelper->getAverageRating($product) ; $i++)
|
||||
<span class="stars">
|
||||
<span class="icon star-icon"></span>
|
||||
</span>
|
||||
@endfor
|
||||
|
||||
<div class="total-reviews">
|
||||
{{ $reviewHelper->getTotalRating($product) }} {{ __('admin::app.customers.reviews.rating') }} & {{ $reviewHelper->getTotalReviews($product) }} {{ __('admin::app.customers.reviews.name') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-side">
|
||||
@foreach($reviewHelper->getPercentageRating($product) as $key=>$count)
|
||||
<div class="rater 5star">
|
||||
<div class="star" id={{$key}}star> Star</div>
|
||||
<div class="line-bar" >
|
||||
<div class="line-value" id="{{ $key }}"></div>
|
||||
</div>
|
||||
<div class="percentage"> {{$count}}% </div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="reviews">
|
||||
@foreach($reviewHelper->loadMore($product) as $review)
|
||||
<div class="review">
|
||||
<div class="title">
|
||||
{{ $review->title }}
|
||||
</div>
|
||||
<div class="stars">
|
||||
@for ($i = 1; $i <= $review->rating ; $i++)
|
||||
<span class="icon star-icon"></span>
|
||||
@endfor
|
||||
</div>
|
||||
<div class="message">
|
||||
{{ $review->comment }}
|
||||
</div>
|
||||
<div class="reviewer-details">
|
||||
<span class="by">
|
||||
{{ __('shop::app.products.by', ['name' => $review->customer->name]) }}
|
||||
</span>
|
||||
<span class="when">
|
||||
{{ $reviewHelper->formatDate($review->created_at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<div class="view-all" onclick="loadMore()">Load More</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
|
||||
@push('scripts')
|
||||
|
||||
<script>
|
||||
|
||||
window.onload = (function(){
|
||||
|
||||
var percentage = {};
|
||||
<?php foreach ($reviewHelper->getPercentageRating($product) as $key=>$count) { ?>
|
||||
percentage.<?php echo $key; ?> = <?php echo "'$count';"; ?>
|
||||
<?php } ?>
|
||||
|
||||
var i=5;
|
||||
for(var key in percentage){
|
||||
width= percentage[key] * 1.58;
|
||||
let id =key + 'star';
|
||||
console.log(id);
|
||||
document.getElementById(key).style.width = width + "px";
|
||||
document.getElementById(key).style.height = 4 + "px";
|
||||
document.getElementById(id).innerHTML = i + '\xa0\xa0' + "star";
|
||||
i--;
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
function loadMore(){
|
||||
var segment_str = window.location.pathname;
|
||||
var segment_array = segment_str.split( '/' );
|
||||
var last_segment = segment_array[segment_array.length - 1];
|
||||
url = segment_str.slice(0, segment_str.lastIndexOf('/'));
|
||||
project = url + "/" + (parseInt(last_segment)+1) ;
|
||||
location.href = project;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@endpush
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
wevf bebv
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
@extends('shop::layouts.master')
|
||||
|
||||
@section('content-wrapper')
|
||||
<section class="product-detail">
|
||||
<div class="category-breadcrumbs">
|
||||
|
||||
<span class="breadcrumb">Home</span> > <span class="breadcrumb">Men</span> > <span class="breadcrumb">Slit Open Jeans</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="layouter">
|
||||
|
||||
@include ('shop::products.view.gallery')
|
||||
|
||||
<div class="details">
|
||||
|
||||
<div class="product-heading">
|
||||
<span>{{ $product->name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="rating">
|
||||
<img src="{{ bagisto_asset('images/5star.svg') }}" />
|
||||
75 Ratings & 11 Reviews
|
||||
</div>
|
||||
|
||||
@include ('shop::products.price', ['product' => $product])
|
||||
|
||||
@include ('shop::products.view.stock')
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="description">
|
||||
{{ $product->short_description }}
|
||||
</div>
|
||||
|
||||
@if ($product->type == 'configurable')
|
||||
|
||||
@include ('shop::products.view.configurable-options')
|
||||
|
||||
@endif
|
||||
|
||||
<accordian :title="{{ __('shop::app.products.description') }}" :active="true">
|
||||
<div slot="header">
|
||||
{{ __('shop::app.products.description') }}
|
||||
<i class="icon expand-icon right"></i>
|
||||
</div>
|
||||
|
||||
<div slot="body">
|
||||
<div class="full-description">
|
||||
{{ $product->description }}
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
@include ('shop::products.view.attributes')
|
||||
|
||||
@include ('shop::products.view.reviews')
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include ('shop::products.view.up-sells')
|
||||
|
||||
</section>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
@inject ('productViewHelper', 'Webkul\Product\Product\View')
|
||||
|
||||
<accordian :title="{{ __('shop::app.products.specification') }}" :active="false">
|
||||
<div slot="header">
|
||||
{{ __('shop::app.products.specification') }}
|
||||
<i class="icon expand-icon right"></i>
|
||||
</div>
|
||||
|
||||
<div slot="body">
|
||||
<table class="full-specifications">
|
||||
|
||||
@foreach ($productViewHelper->getAdditionalData($product) as $attribute)
|
||||
|
||||
<tr>
|
||||
<td>{{ $attribute['label'] }}</td>
|
||||
<td> - {{ $attribute['value'] }}</td>
|
||||
</tr>
|
||||
|
||||
@endforeach
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</accordian>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<div class="attributes">
|
||||
|
||||
<div class="attribute color">
|
||||
<div class="title">Color</div>
|
||||
|
||||
<div class="values">
|
||||
<div class="colors red"></div>
|
||||
<div class="colors blue"></div>
|
||||
<div class="colors green"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attribute size">
|
||||
<div class="title">Size</div>
|
||||
|
||||
<div class="values">
|
||||
<div class="size xl">XL</div>
|
||||
<div class="size xxl">XXL</div>
|
||||
<div class="size xxxl">XXXL</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attribute quantity">
|
||||
<div class="title">Quantity</div>
|
||||
|
||||
<div class="values">
|
||||
<div class="size">1</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<div class="product-image-group">
|
||||
|
||||
<div class="side-group">
|
||||
<img src="{{ bagisto_asset('images/jeans.jpg') }}" />
|
||||
<img src="{{ bagisto_asset('images/jeans.jpg') }}" />
|
||||
<img src="{{ bagisto_asset('images/jeans.jpg') }}" />
|
||||
<img src="{{ bagisto_asset('images/jeans.jpg') }}" />
|
||||
</div>
|
||||
|
||||
<div class="product-hero-image">
|
||||
<img src="{{ bagisto_asset('images/jeans_big.jpg') }}" />
|
||||
<img class="wishlist" src="{{ bagisto_asset('images/wish.svg') }}" />
|
||||
<img class="share" src="{{ bagisto_asset('images/icon-share.svg') }}" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
@inject ('reviewHelper', 'Webkul\Product\Product\Review')
|
||||
|
||||
@if ($total = $reviewHelper->getTotalReviews($product))
|
||||
<div class="rating-reviews">
|
||||
<div class="title">
|
||||
Ratings & Reviews
|
||||
</div>
|
||||
|
||||
<div class="overall">
|
||||
<div class="review-info">
|
||||
|
||||
<span class="number">
|
||||
{{ $reviewHelper->getAverageRating($product) }}
|
||||
</span>
|
||||
|
||||
<span class="stars">
|
||||
@for ($i = 1; $i <= $reviewHelper->getAverageRating($product); $i++)
|
||||
|
||||
<span class="icon star-icon"></span>
|
||||
|
||||
@endfor
|
||||
</span>
|
||||
|
||||
<div class="total-reviews">
|
||||
{{ __('shop::app.products.total-reviews', ['total' => $total]) }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary">Write Review</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="reviews">
|
||||
|
||||
@foreach ($product->reviews()->paginate(5) as $review)
|
||||
<div class="review">
|
||||
<div class="title">
|
||||
{{ $review->title }}
|
||||
</div>
|
||||
|
||||
<span class="stars">
|
||||
@for ($i = 1; $i <= $review->rating; $i++)
|
||||
|
||||
<span class="icon star-icon"></span>
|
||||
|
||||
@endfor
|
||||
</span>
|
||||
|
||||
<div class="message">
|
||||
{{ $review->comment }}
|
||||
</div>
|
||||
|
||||
<div class="reviewer-details">
|
||||
<span class="by">
|
||||
{{ __('shop::app.products.by', ['name' => $review->customer->name]) }},
|
||||
</span>
|
||||
|
||||
<span class="when">
|
||||
{{ $reviewHelper->formatDate($review->created_at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<a href="{{ route('shop.reviews.index', $product->url_key) }}" class="view-all">View All</a>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<div class="stock-status">
|
||||
InStock
|
||||
</div>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@if ($product->up_sells()->count())
|
||||
<div class="attached-products-wrapper">
|
||||
|
||||
<div class="title">
|
||||
{{ __('shop::app.products.up-sell-title') }}
|
||||
<span class="border-bottom"></span>
|
||||
</div>
|
||||
|
||||
<div class="product-grid max-4-col">
|
||||
|
||||
@foreach ($product->up_sells()->paginate(4) as $up_sell_product)
|
||||
|
||||
@include ('shop::products.list.card', ['product' => $up_sell_product])
|
||||
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon-Customers</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Icon-Customers" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g transform="translate(9.000000, 8.000000)" id="Combined-Shape" stroke="#8E8E8E" stroke-width="2">
|
||||
<path d="M0.0694092808,30.8793785 C0.789639214,23.4815617 7.02613841,17.6997284 14.6130571,17.6997284 C22.1999758,17.6997284 28.436475,23.4815617 29.156705,30.8793785 L0.0694092808,30.8793785 Z M14.5,13.6997284 C10.9101491,13.6997284 8,10.7895793 8,7.19972838 C8,3.60987751 10.9101491,0.699728384 14.5,0.699728384 C18.0898509,0.699728384 21,3.60987751 21,7.19972838 C21,10.7895793 18.0898509,13.6997284 14.5,13.6997284 Z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -1271,5 +1271,312 @@ h2 {
|
|||
margin-left: 31px;
|
||||
}
|
||||
|
||||
|
||||
// admin dashboard css ends here
|
||||
|
||||
|
||||
// customer order information for admin css start here
|
||||
|
||||
.order-information {
|
||||
|
||||
.order-info {
|
||||
|
||||
span{
|
||||
font-size: 18px;
|
||||
color: #8E8E8E;
|
||||
letter-spacing: -0.29px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
float :right;
|
||||
font-size: 16px;
|
||||
color: #0041FF;
|
||||
letter-spacing: -0.29px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.horizotal-rule {
|
||||
width:100%;
|
||||
border:1px solid #A2A2A2;
|
||||
opacity: 0.2;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.order-account{
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
margin-top: 20px;
|
||||
|
||||
.left-content {
|
||||
width: 200px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-content {
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account-information {
|
||||
margin-top: 30px;
|
||||
|
||||
.account-info {
|
||||
|
||||
span{
|
||||
font-size: 18px;
|
||||
color: #8E8E8E;
|
||||
letter-spacing: -0.29px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
float :right;
|
||||
font-size: 16px;
|
||||
color: #0041FF;
|
||||
letter-spacing: -0.29px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.horizotal-rule {
|
||||
width:100%;
|
||||
border:1px solid #A2A2A2;
|
||||
opacity: 0.2;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.order-account{
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
margin-top: 20px;
|
||||
|
||||
.left-content {
|
||||
width: 200px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.right-content {
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: #0041FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-information {
|
||||
|
||||
.address-name {
|
||||
|
||||
span{
|
||||
font-size: 18px;
|
||||
color: #8E8E8E;
|
||||
letter-spacing: -0.29px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
float :right;
|
||||
font-size: 16px;
|
||||
color: #0041FF;
|
||||
letter-spacing: -0.29px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.horizotal-rule {
|
||||
width:100%;
|
||||
border:1px solid #A2A2A2;
|
||||
opacity: 0.2;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.address-detail{
|
||||
margin-top: 10px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-information:last-child {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.payment-information {
|
||||
|
||||
.title {
|
||||
|
||||
span{
|
||||
font-size: 18px;
|
||||
color: #8E8E8E;
|
||||
letter-spacing: -0.29px;
|
||||
}
|
||||
}
|
||||
|
||||
.horizotal-rule {
|
||||
width:100%;
|
||||
border:1px solid #A2A2A2;
|
||||
opacity: 0.2;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.payment-info{
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
margin-top: 20px;
|
||||
|
||||
.left-content {
|
||||
width: 200px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-content {
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #3A3A3A;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payment-information:last-child {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.total {
|
||||
margin-top: 2%;
|
||||
height: 130px;
|
||||
|
||||
.calculate {
|
||||
margin-right: 8%;
|
||||
float: right;
|
||||
|
||||
.sub-total {
|
||||
|
||||
span {
|
||||
font-size: 14px; font-size: 14px;
|
||||
color: #3A3A3A;
|
||||
color: #3A3A3A;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 109px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.ship-handle {
|
||||
margin-top: 5px;
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #3A3A3A;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.discount {
|
||||
margin-top: 5px;
|
||||
|
||||
span {
|
||||
font-size: 14px; font-size: 14px;
|
||||
color: #3A3A3A;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 98px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.grand-total {
|
||||
margin-top: 5px;
|
||||
|
||||
span {
|
||||
font-size: 14px; font-size: 14px;
|
||||
color: #3A3A3A;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 87px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.due {
|
||||
margin-top: 5px;
|
||||
|
||||
span {
|
||||
font-size: 14px; font-size: 14px;
|
||||
color: #3A3A3A;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 101px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// customer order information for admin css end here
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
@extend %menu-properties;
|
||||
background-image: url("../images/Icon-Catalog.svg");
|
||||
}
|
||||
.customer-icon {
|
||||
@extend %menu-properties;
|
||||
background-image: url("../images/Icon-Customers.svg");
|
||||
}
|
||||
.configuration-icon {
|
||||
@extend %menu-properties;
|
||||
background-image: url("../images/Icon-Configure.svg");
|
||||
|
|
|
|||
|
|
@ -106,13 +106,17 @@
|
|||
<th class="grid_head" data-column-name="{{ $column->alias }}" data-column-label="{{ $column->label }}">{!! $column->sorting() !!}</th>
|
||||
@endif
|
||||
@endforeach
|
||||
@if(isset($attribute_columns))
|
||||
{{-- @if(isset($attribute_columns))
|
||||
@foreach($attribute_columns as $key => $value)
|
||||
<th>
|
||||
{{ $value }}
|
||||
<th class="grid_head"
|
||||
data-column-name="{{ $attributeAliases[$key] }}"
|
||||
data-column-label="{{ $attributeAliases[$key] }}"
|
||||
data-column-sort="asc"
|
||||
>
|
||||
{{ $value }}<span class="icon sort-down-icon"></span>
|
||||
</th>
|
||||
@endforeach
|
||||
@endif
|
||||
@endif --}}
|
||||
<th>
|
||||
Actions
|
||||
</th>
|
||||
|
|
@ -131,12 +135,11 @@
|
|||
@foreach ($columns as $column)
|
||||
<td class="">{!! $column->render($result) !!}</td>
|
||||
@endforeach
|
||||
|
||||
@if(isset($attribute_columns))
|
||||
{{-- @if(isset($attribute_columns))
|
||||
@foreach ($attribute_columns as $atc)
|
||||
<td>{{ $result->{$atc} }}</td>
|
||||
@endforeach
|
||||
@endif
|
||||
@endif --}}
|
||||
|
||||
<td class="action">
|
||||
@foreach($actions as $action)
|
||||
|
|
|
|||
|
|
@ -53,9 +53,13 @@ class AccountController extends Controller
|
|||
'email' => 'email|unique:admins,email,' . $user->id,
|
||||
'password' => 'nullable|confirmed'
|
||||
]);
|
||||
|
||||
|
||||
$user->update(request(['name', 'email', 'password']));
|
||||
$data = request()->all();
|
||||
|
||||
if(!$data['password'])
|
||||
unset($data['password']);
|
||||
|
||||
$user->update($data);
|
||||
|
||||
session()->flash('success', 'Account changes saved successfully.');
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,12 @@ class UserController extends Controller
|
|||
*/
|
||||
public function update(UserForm $request, $id)
|
||||
{
|
||||
$this->admin->update(request()->all(), $id);
|
||||
$data = request()->all();
|
||||
|
||||
if(!$data['password'])
|
||||
unset($data['password']);
|
||||
|
||||
$this->admin->update($data, $id);
|
||||
|
||||
session()->flash('success', 'User updated successfully.');
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,24 @@
|
|||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.grid-view-icon {
|
||||
background-image: URL("../images/icon-grid-view.svg");
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.list-view-icon {
|
||||
background-image: URL("../images/icon-list-view.svg");
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #242424;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
* {
|
||||
|
|
@ -710,7 +723,7 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
|
|||
.layered-filter-wrapper {
|
||||
width: 25%;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
padding-right: 20px;
|
||||
min-height: 1px;
|
||||
}
|
||||
|
||||
|
|
@ -802,6 +815,11 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.main-container-wrapper .main {
|
||||
display: inline-block;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid {
|
||||
display: grid;
|
||||
grid-gap: 30px;
|
||||
|
|
@ -832,49 +850,36 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-image img {
|
||||
.main-container-wrapper .product-card .product-image img {
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-name {
|
||||
.main-container-wrapper .product-card .product-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
color: #242424;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-price {
|
||||
.main-container-wrapper .product-card .product-name a {
|
||||
color: #242424;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-card .product-description {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-price .price-label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-price .regular-price {
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
text-decoration: line-through;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-price .special-price {
|
||||
font-size: 16px;
|
||||
color: #FF6472;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .product-ratings {
|
||||
.main-container-wrapper .product-card .product-ratings {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .cart-fav-seg {
|
||||
.main-container-wrapper .product-card .cart-fav-seg {
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
|
|
@ -884,12 +889,91 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-grid .product-card .cart-fav-seg .addtocart {
|
||||
.main-container-wrapper .product-card .cart-fav-seg .addtocart {
|
||||
border-radius: 0px;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-list .product-card {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-list .product-card .product-image {
|
||||
float: left;
|
||||
width: 30%;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-list .product-card .product-image img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-list .product-card .product-information {
|
||||
float: right;
|
||||
width: 70%;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-list .product-card:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .page-info {
|
||||
float: left;
|
||||
color: #242424;
|
||||
line-height: 45px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager label {
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager select {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager .view-mode {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager .view-mode a, .main-container-wrapper .top-toolbar .pager .view-mode span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager .view-mode a.grid-view, .main-container-wrapper .top-toolbar .pager .view-mode span.grid-view {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager .sorter {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .top-toolbar .pager .limiter {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.main-container-wrapper .bottom-toolbar {
|
||||
display: block;
|
||||
margin-top: 40px;
|
||||
|
|
@ -971,6 +1055,30 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.product-price .price-label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.product-price .regular-price {
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
text-decoration: line-through;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.product-price .special-price {
|
||||
font-size: 16px;
|
||||
color: #FF6472;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #f2f2f2;
|
||||
padding-left: 10%;
|
||||
|
|
@ -1293,23 +1401,14 @@ section.product-detail div.layouter .mixed-group .details .product-name, section
|
|||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .mixed-group .details .price, section.product-review div.layouter .mixed-group .details .price {
|
||||
section.product-detail div.layouter .mixed-group .details .product-price, section.product-review div.layouter .mixed-group .details .product-price {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .mixed-group .details .price .main-price, section.product-review div.layouter .mixed-group .details .price .main-price {
|
||||
font-size: 24px;
|
||||
color: #FF6472;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .mixed-group .details .price .real-price, section.product-review div.layouter .mixed-group .details .price .real-price {
|
||||
color: #A5A5A5;
|
||||
-webkit-text-decoration-line: line-through;
|
||||
text-decoration-line: line-through;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .rating-reviews, section.product-review div.layouter .rating-reviews {
|
||||
margin-top: 30px;
|
||||
margin-top: 0px;
|
||||
width: 50%;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .rating-reviews .title-inline, section.product-review div.layouter .rating-reviews .title-inline {
|
||||
|
|
@ -1384,8 +1483,6 @@ section.product-detail div.layouter .rating-reviews .overall .right-side .rater
|
|||
}
|
||||
|
||||
section.product-detail div.layouter .rating-reviews .overall .right-side .rater .line-bar .line-value, section.product-review div.layouter .rating-reviews .overall .right-side .rater .line-bar .line-value {
|
||||
height: 4px;
|
||||
width: 100px;
|
||||
background-color: #0031F0;
|
||||
}
|
||||
|
||||
|
|
@ -1469,13 +1566,13 @@ section.product-detail div.layouter .details .rating, section.product-review div
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .price, section.product-review div.layouter .details .price {
|
||||
section.product-detail div.layouter .details .product-price, section.product-review div.layouter .details .product-price {
|
||||
margin-bottom: 14px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .price .main-price, section.product-review div.layouter .details .price .main-price {
|
||||
section.product-detail div.layouter .details .product-price .special-price, section.product-review div.layouter .details .product-price .special-price {
|
||||
font-size: 24px;
|
||||
color: #FF6472;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .stock-status, section.product-review div.layouter .details .stock-status {
|
||||
|
|
@ -1486,9 +1583,19 @@ section.product-detail div.layouter .details .description, section.product-revie
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details hr, section.product-review div.layouter .details hr {
|
||||
border-top: 1px solid #E8E8E8;
|
||||
margin-bottom: 17px;
|
||||
section.product-detail div.layouter .details .full-specifications td, section.product-review div.layouter .details .full-specifications td {
|
||||
padding: 10px 0;
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .full-specifications td:first-child, section.product-review div.layouter .details .full-specifications td:first-child {
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .accordian .accordian-header, section.product-review div.layouter .details .accordian .accordian-header {
|
||||
font-size: 16px;
|
||||
padding-left: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .attributes, section.product-review div.layouter .details .attributes {
|
||||
|
|
@ -1576,13 +1683,14 @@ section.product-detail div.layouter .details .rating-reviews, section.product-re
|
|||
|
||||
section.product-detail div.layouter .details .rating-reviews .title, section.product-review div.layouter .details .rating-reviews .title {
|
||||
margin-bottom: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .overall, section.product-review div.layouter .details .rating-reviews .overall {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .overall .number, section.product-review div.layouter .details .rating-reviews .overall .number {
|
||||
section.product-detail div.layouter .details .rating-reviews .overall .review-info .number, section.product-review div.layouter .details .rating-reviews .overall .review-info .number {
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
|
|
@ -1602,12 +1710,22 @@ section.product-detail div.layouter .details .rating-reviews .reviews .review, s
|
|||
|
||||
section.product-detail div.layouter .details .rating-reviews .reviews .review .stars, section.product-review div.layouter .details .rating-reviews .reviews .review .stars {
|
||||
margin-bottom: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .reviews .review .stars .icon, section.product-review div.layouter .details .rating-reviews .reviews .review .stars .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .reviews .review .message, section.product-review div.layouter .details .rating-reviews .reviews .review .message {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .reviews .review .reviewer-details, section.product-review div.layouter .details .rating-reviews .reviews .review .reviewer-details {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
section.product-detail div.layouter .details .rating-reviews .reviews .view-all, section.product-review div.layouter .details .rating-reviews .reviews .view-all {
|
||||
margin-top: 15px;
|
||||
color: #0031f0;
|
||||
|
|
@ -1847,18 +1965,29 @@ section.cart .cart-content .right-side .coupon-section .after-coupon-amount .amo
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.related-products-wrapper {
|
||||
.attached-products-wrapper {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.related-products-wrapper .title {
|
||||
margin-bottom: 22px;
|
||||
.attached-products-wrapper .title {
|
||||
margin-bottom: 40px;
|
||||
font-size: 18px;
|
||||
color: #242424;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.related-products-wrapper .horizontal-rule {
|
||||
.attached-products-wrapper .title .border-bottom {
|
||||
border-bottom: 1px solid rgba(162, 162, 162, 0.2);
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
margin-left: -50px;
|
||||
}
|
||||
|
||||
.attached-products-wrapper .horizontal-rule {
|
||||
height: 1px;
|
||||
background: #E8E8E8;
|
||||
width: 148px;
|
||||
|
|
@ -1867,12 +1996,6 @@ section.cart .cart-content .right-side .coupon-section .after-coupon-amount .amo
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
.related-products-wrapper .related-products {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.order {
|
||||
margin-left: 5.5%;
|
||||
margin-top: 1%;
|
||||
|
|
@ -3543,3 +3666,175 @@ section.cart .cart-content .right-side .coupon-section .after-coupon-amount .amo
|
|||
text-align: center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
section.review {
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
}
|
||||
|
||||
section.review .category-breadcrumbs {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
section.review .review-layouter {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-flow: row;
|
||||
flex-flow: row;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .image {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .image img {
|
||||
height: 280px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .heading {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .heading span {
|
||||
font-size: 24px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.58px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .price {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .price .pro-price {
|
||||
font-size: 24px;
|
||||
color: #FF6472;
|
||||
letter-spacing: -0.58px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .price .pro-price-not {
|
||||
margin-left: 10px;
|
||||
font-size: 16px;
|
||||
color: #A5A5A5;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .product-info .price .offer {
|
||||
margin-left: 10px;
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info {
|
||||
margin-left: 20px;
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .heading {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .heading span {
|
||||
font-size: 16px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.26px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .heading .btn.btn-primary.right {
|
||||
float: right;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .rating {
|
||||
margin-top: 25px;
|
||||
font-size: 16px;
|
||||
color: #5E5E5E;
|
||||
letter-spacing: -0.12px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .rating span {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .stars {
|
||||
width: 270px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .stars label.star {
|
||||
font-size: 36px;
|
||||
color: #d4d4d4;
|
||||
-webkit-transition: all .2s;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .stars label.star:before {
|
||||
content: '\2605';
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .write-review {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .write-review .control-group {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .write-review .control-group textarea {
|
||||
margin-top: 5px;
|
||||
border: 2px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
width: 600px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .submit-button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .submit-button button {
|
||||
background: #0031F0;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: -0.26px;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
height: 38px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .review-detail {
|
||||
height: 150px;
|
||||
border: 1px solid firebrick;
|
||||
margin-top: 30px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .review-detail .rating-review {
|
||||
margin-top: 40px;
|
||||
margin-left: 20px;
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .review-detail .rating-review .avg-rating-count span {
|
||||
font-size: 34px;
|
||||
color: #242424;
|
||||
letter-spacing: -0.82px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section.review .review-layouter .review-info .review-detail .rating-calculate .progress-only {
|
||||
width: 20px;
|
||||
border: 1px solid blue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue