init
This commit is contained in:
parent
5e552c572e
commit
5880fbaa0a
|
|
@ -0,0 +1,2 @@
|
|||
#*
|
||||
#!default
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.index" />
|
||||
|
||||
<div class="row">
|
||||
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
@if (\Session::has('success'))
|
||||
<div class="alert alert-success">
|
||||
<ul>
|
||||
<li>{!! \Session::get('success') !!}</li>
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
@if (0)
|
||||
<div class="card mb-4 account-card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.index') }}</h5>
|
||||
<a href="{{ shop_route('account.edit.index') }}" class="text-muted">{{ __('shop/account.revise_info') }}</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-nowrap card-items py-2">
|
||||
<a href="{{ shop_route('account.wishlist.index') }}" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted">{{ __('shop/account.collect') }}</span></a>
|
||||
<a href="http://" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted">{{ __('shop/account.coupon') }}</span></a>
|
||||
<a href="http://" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted">{{ __('shop/account.coupon') }}</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card account-card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.my_order') }}</h5>
|
||||
<a href="{{ shop_route('account.order.index') }}" class="text-muted">{{ __('shop/account.orders') }}</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-nowrap card-items mb-4 py-3">
|
||||
<a href="{{ shop_route('account.order.index', ['status' => 'unpaid']) }}" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted text-center">{{ __('shop/account.pending_payment') }}</span></a>
|
||||
<a href="{{ shop_route('account.order.index', ['status' => 'paid']) }}" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted text-center">{{ __('shop/account.pending_send') }}</span></a>
|
||||
<a href="{{ shop_route('account.order.index', ['status' => 'shipped']) }}" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted text-center">{{ __('shop/account.pending_receipt') }}</span></a>
|
||||
<a href="{{ shop_route('account.rma.index') }}" class="d-flex flex-column align-items-center"><i class="iconfont"></i><span
|
||||
class="text-muted text-center">{{ __('shop/account.after_sales') }}</span></a>
|
||||
</div>
|
||||
<div class="order-wrap">
|
||||
@if (!count($latest_orders))
|
||||
<div class="no-order d-flex flex-column align-items-center">
|
||||
<div class="icon mb-2"><i class="iconfont"></i></div>
|
||||
<div class="text mb-3 text-muted">{{ __('shop/account.no_order') }}<a href="">{{ __('shop/account.to_buy') }}</a></div>
|
||||
</div>
|
||||
@else
|
||||
{{-- <p class="text-muted">近期订单</p> --}}
|
||||
<ul class="list-unstyled orders-list table-responsive">
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
@foreach ($latest_orders as $order)
|
||||
<tr class="align-middle">
|
||||
<td style="width: 62px">
|
||||
<div class="img border wh-60 d-flex justify-content-between align-items-center">
|
||||
<img src="{{ $order->orderProducts[0]->image ?? '' }}" class="img-fluid">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="mb-2">{{ __('shop/account.order_number') }}:<span style="width: 110px;display: inline-block;">{{ $order->number }}</span> <span class="vr lh-1 me-2 bg-secondary"></span> {{ __('shop/account.all') }} {{ count($order->orderProducts) }} {{ __('shop/account.items') }}</div>
|
||||
<div class="text-muted">{{ __('shop/account.order_time') }}:{{ $order->created_at }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="ms-4 d-inline-block">{{ __('shop/account.state') }}:{{ $order->status_format }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="ms-3 d-inline-block">{{ __('shop/account.amount') }}:{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}"
|
||||
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.check_details') }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-address')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="address-app">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.addresses.index" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.addresses.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body h-600">
|
||||
<button v-if="addresses.length" class="btn btn-dark mb-3" @click="editAddress"><i class="bi bi-plus-square-dotted me-1"></i>
|
||||
{{ __('shop/account.addresses.add_address') }}</button>
|
||||
<div class="addresses-wrap" v-cloak>
|
||||
<div class="row" v-if="addresses.length">
|
||||
<div class="col-6" v-for="address, index in addresses" :key="index">
|
||||
<div class="item">
|
||||
<div class="name-wrap">
|
||||
<span class="name">@{{ address.name }}</span>
|
||||
<span class="phone">@{{ address.phone }}</span>
|
||||
</div>
|
||||
<div class="zipcode">@{{ address.zipcode }}</div>
|
||||
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
|
||||
@{{ address.address_1 }}</div>
|
||||
<div class="address-bottom">
|
||||
<div><span class="badge bg-success"
|
||||
v-if="address.default">{{ __('shop/account.addresses.default_address') }}</span></div>
|
||||
<div>
|
||||
<a class="me-2" @click.stop="deleteAddress(index)">{{ __('shop/account.addresses.delete') }}</a>
|
||||
<a href="javascript:void(0)" @click.stop="editAddress(index)">{{ __('shop/account.addresses.edit') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-center">
|
||||
<x-shop-no-data />
|
||||
<button class="btn btn-dark mb-3" @click="editAddress"><i class="bi bi-plus-square-dotted me-1"></i>
|
||||
{{ __('shop/account.addresses.add_address') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<address-dialog ref="address-dialog" @change="onAddressDialogChange"></address-dialog>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
@include('shared.address-form')
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#address-app',
|
||||
|
||||
data: {
|
||||
editIndex: null,
|
||||
addresses: @json($addresses ?? []),
|
||||
},
|
||||
|
||||
// 实例被挂载后调用
|
||||
mounted() {},
|
||||
|
||||
methods: {
|
||||
editAddress(index) {
|
||||
let addresses = null
|
||||
|
||||
if (typeof index == 'number') {
|
||||
this.editIndex = index;
|
||||
|
||||
addresses = JSON.parse(JSON.stringify(this.addresses[index]))
|
||||
}
|
||||
|
||||
this.$refs['address-dialog'].editAddress(addresses)
|
||||
},
|
||||
|
||||
deleteAddress(index) {
|
||||
this.$confirm('{{ __('shop/account.addresses.confirm_delete') }}',
|
||||
'{{ __('shop/account.addresses.hint') }}', {
|
||||
confirmButtonText: '{{ __('common.confirm') }}',
|
||||
cancelButtonText: '{{ __('common.cancel') }}',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.delete('/account/addresses/' + this.addresses[index].id).then((res) => {
|
||||
this.$message.success(res.message);
|
||||
this.addresses.splice(index, 1)
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
onAddressDialogChange(form) {
|
||||
const type = form.id ? 'put' : 'post';
|
||||
const url = `/account/addresses${type == 'put' ? '/' + form.id : ''}`;
|
||||
|
||||
$http[type](url, form).then((res) => {
|
||||
if (res.data.default) {
|
||||
this.addresses.map(e => e.default = false)
|
||||
}
|
||||
|
||||
if (this.addresses.find(e => e.id == res.data.id)) {
|
||||
this.addresses[this.editIndex] = res.data
|
||||
} else {
|
||||
this.addresses.push(res.data)
|
||||
}
|
||||
this.editIndex = null;
|
||||
this.$forceUpdate()
|
||||
this.$refs['address-dialog'].closeAddressDialog()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-edit')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/cropper/cropper.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/cropper/cropper.min.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="address-app">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.edit.index" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.edit.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body h-600">
|
||||
<form novalidate class="needs-validation" action="{{ shop_route('account.edit.update') }}" method="POST">
|
||||
@csrf
|
||||
{{ method_field('put') }}
|
||||
|
||||
@if (session('success'))
|
||||
<x-shop-alert type="success" msg="{{ session('success') }}" class="mt-4" />
|
||||
@endif
|
||||
|
||||
<div class="bg-light rounded-3 p-4 mb-4" style="background: #f6f9fc;">
|
||||
<div class="d-flex align-items-center">
|
||||
<img class="rounded-3" id="avatar" src="{{ image_resize($customer->avatar, 200, 200) }}"
|
||||
width="90">
|
||||
<div class="ps-3">
|
||||
<label class="btn btn-light shadow-sm bg-body mb-2" data-toggle="tooltip" title="Change your avatar">
|
||||
<i class="bi bi-arrow-repeat"></i> {{ __('shop/account.edit.modify_avatar') }}
|
||||
<input type="file" class="d-none" id="update-btn" name="" accept="image/*">
|
||||
<input type="hidden" id="avatar-input" name="avatar" value="{{ $customer->avatar }}">
|
||||
</label>
|
||||
<div class="p mb-0 fs-ms text-muted">{{ __('shop/account.edit.suggest') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gx-4 gy-3">
|
||||
<div class="col-sm-6">
|
||||
<label class="form-label">{{ __('shop/account.edit.name') }}</label>
|
||||
<input class="form-control {{ $errors->has('name') ? 'is-invalid' : '' }}" type="text" name="name"
|
||||
value="{{ old('name', $customer->name ?? '') }}" required>
|
||||
<span class="invalid-feedback"
|
||||
role="alert">{{ $errors->has('name') ? $errors->first('name') : __('common.error_required', ['name' => __('shop/account.edit.name')]) }}</span>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label class="form-label">{{ __('shop/account.edit.email') }}</label>
|
||||
<input class="form-control {{ $errors->has('email') ? 'is-invalid' : '' }}" type="email"
|
||||
name="email" value="{{ old('email', $customer->email ?? '') }}" required>
|
||||
<span class="invalid-feedback"
|
||||
role="alert">{{ $errors->has('email') ? $errors->first('email') : __('common.error_required', ['name' => __('shop/account.edit.email')]) }}</span>
|
||||
</div>
|
||||
<div class="col-12 mt-4">
|
||||
<button class="btn btn-primary mt-sm-0" type="submit">{{ __('common.submit') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="modal" tabindex="-1" data-bs-backdrop="static" aria-labelledby="exampleModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">{{ __('shop/account.edit.crop') }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="img-container">
|
||||
<img id="cropper-image" src="{{ image_resize('/') }}" class="img-fluid">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ __('shop/common.cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary cropper-crop">{{ __('shop/common.confirm') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var avatar = document.getElementById('avatar');
|
||||
var image = document.getElementById('cropper-image');
|
||||
var cropper;
|
||||
var $modal = $('#modal');
|
||||
|
||||
$(document).on('change', '#update-btn', function(e) {
|
||||
var files = e.target.files;
|
||||
var done = function(url) {
|
||||
$(this).val('');
|
||||
image.src = url;
|
||||
$('#modal').modal('show');
|
||||
};
|
||||
var reader;
|
||||
var file;
|
||||
var url;
|
||||
|
||||
if (files && files.length > 0) {
|
||||
file = files[0];
|
||||
|
||||
$('#update-btn').remove()
|
||||
$('#avatar-input').before('<input type="file" class="d-none" id="update-btn" name="" accept="image/*">');
|
||||
|
||||
if (URL) {
|
||||
done(URL.createObjectURL(file));
|
||||
} else if (FileReader) {
|
||||
reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
done(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$modal.on('shown.bs.modal', function() {
|
||||
cropper = new Cropper(image, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 3,
|
||||
});
|
||||
}).on('hidden.bs.modal', function() {
|
||||
cropper.destroy();
|
||||
cropper = null;
|
||||
});
|
||||
|
||||
$('.cropper-crop').click(function(event) {
|
||||
var initialAvatarURL;
|
||||
var canvas;
|
||||
|
||||
$modal.modal('hide');
|
||||
|
||||
if (cropper) {
|
||||
canvas = cropper.getCroppedCanvas({
|
||||
width: 200,
|
||||
height: 200,
|
||||
});
|
||||
initialAvatarURL = avatar.src;
|
||||
// avatar.src = canvas.toDataURL();
|
||||
canvas.toBlob(function(blob) {
|
||||
var formData = new FormData();
|
||||
|
||||
formData.append('file', blob, 'avatar.png');
|
||||
formData.append('type', 'avatar');
|
||||
$http.post('{{ shop_route('file.store') }}', formData).then(res => {
|
||||
$('#avatar').attr('src', res.data.url);
|
||||
$('#avatar-input').val(res.data.value)
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-forgotten')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||
@endpush
|
||||
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="page-forgotten" v-cloak>
|
||||
|
||||
<x-shop-breadcrumb type="static" value="forgotten.index" />
|
||||
|
||||
<div class="row my-5 justify-content-md-center">
|
||||
<div class="col-lg-5 col-xxl-4">
|
||||
<div class="card">
|
||||
<el-form ref="form" :model="form" :rules="rules">
|
||||
<div class="card-body p-0">
|
||||
<h4 class="fw-bold">{{ __('shop/forgotten.follow_prompt') }}</h4>
|
||||
<p class="text-muted" v-if="!isCode">{{ __('shop/forgotten.email_forCode') }}</p>
|
||||
<p class="text-muted" v-else>{{ __('shop/forgotten.enter_password') }}</p>
|
||||
|
||||
<el-form-item label="{{ __('shop/forgotten.email') }}" prop="email" v-if="!isCode">
|
||||
<el-input v-model="form.email" placeholder="{{ __('shop/forgotten.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/forgotten.verification_code') }}" prop="code" class="mb-3" v-if="isCode">
|
||||
<el-input v-model="form.code" placeholder="{{ __('shop/forgotten.verification_code') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/forgotten.password') }}" prop="password" class="mb-3" v-if="isCode">
|
||||
<el-input type="password" v-model="form.password" placeholder="{{ __('shop/forgotten.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/forgotten.confirm_password') }}" prop="password_confirmation" v-if="isCode">
|
||||
<el-input type="password" v-model="form.password_confirmation" placeholder="{{ __('shop/forgotten.confirm_password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<div class="mt-5 mb-3 d-flex justify-content-between">
|
||||
<button type="button" @click="submitForm('form')" class="btn w-50 btn-dark">
|
||||
{{-- @{{ !isCode ? '发送验证码' : '提交' }} --}}
|
||||
<template v-if="!isCode">{{ __('shop/forgotten.send_code') }}</template>
|
||||
<template v-else>{{ __('common.submit') }}</template>
|
||||
</button>
|
||||
</div>
|
||||
<a href="javascript:void(0)" v-if="isCode" @click="isCode = false" class="text-muted">{{ __('shop/forgotten.to_back') }}</a>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
callback(new Error('{{ __('shop/forgotten.enter_password') }}'));
|
||||
} else {
|
||||
if (value !== '') {
|
||||
app.$refs.form.validateField('password_confirmation');
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
var validatePass2 = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
callback(new Error('{{ __('shop/forgotten.please_confirm') }}'));
|
||||
} else if (value !== app.form.password) {
|
||||
callback(new Error('{{ __('shop/forgotten.password_err') }}'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
let app = new Vue({
|
||||
el: '#page-forgotten',
|
||||
|
||||
data: {
|
||||
form: {
|
||||
email: bk.getQueryString('email', ''),
|
||||
code: bk.getQueryString('code', ''),
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
},
|
||||
|
||||
isCode: !!bk.getQueryString('code'),
|
||||
|
||||
rules: {
|
||||
email: [
|
||||
{required: true, message: '{{ __('shop/forgotten.enter_email') }}', trigger: 'blur'},
|
||||
{type: 'email', message: '{{ __('shop/forgotten.email_err') }}', trigger: 'blur'},
|
||||
],
|
||||
code: [
|
||||
{required: true, message: '{{ __('shop/forgotten.enter_code') }}', trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{required: true, validator: validatePass, trigger: 'blur'}
|
||||
],
|
||||
password_confirmation: [
|
||||
{required: true, validator: validatePass2, trigger: 'blur'}
|
||||
]
|
||||
},
|
||||
},
|
||||
|
||||
mounted () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
submitForm(form) {
|
||||
let _data = this.form, url = 'forgotten/password'
|
||||
|
||||
if (!this.isCode) {
|
||||
url = 'forgotten/send_code'
|
||||
}
|
||||
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http.post(url, this.form).then((res) => {
|
||||
if (this.isCode) {
|
||||
layer.msg(res.message)
|
||||
} else {
|
||||
this.$alert(res.message, '{{ __('common.text_hint') }}');
|
||||
}
|
||||
|
||||
this.$refs[form].clearValidate();
|
||||
|
||||
if (this.isCode) {
|
||||
location = "{{ shop_route('login.index') }}"
|
||||
}
|
||||
this.isCode = true
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-login')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||
@endpush
|
||||
|
||||
|
||||
@section('content')
|
||||
<div class="{{ request('iframe') ? 'container-fluid form-iframe mt-5' : 'container' }}" id="page-login" v-cloak>
|
||||
@if (!request('iframe'))
|
||||
<x-shop-breadcrumb type="static" value="login.index" />
|
||||
<div class="hero-content pb-5 text-center"><h1 class="hero-heading">{{ __('shop/login.index') }}</h1></div>
|
||||
@endif
|
||||
|
||||
<div class="login-wrap">
|
||||
<div class="card">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" :inline-message="true">
|
||||
<div class="login-item-header card-header">
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.login') }}</h6>
|
||||
</div>
|
||||
<div class="card-body px-md-2">
|
||||
@hookwrapper('account.login.email')
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" v-model="loginForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('account.login.password')
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" type="password" v-model="loginForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
@endhookwrapper
|
||||
|
||||
@hook('account.login.password.after')
|
||||
|
||||
@if (!request('iframe'))
|
||||
<a class="text-muted forgotten-link" href="{{ shop_route('forgotten.index') }}"><i class="bi bi-question-circle"></i> {{ __('shop/login.forget_password') }}</a>
|
||||
@endif
|
||||
|
||||
<div class="mt-4 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('loginForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-box-arrow-in-right"></i> {{ __('shop/login.login') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
@if($social_buttons)
|
||||
<div class="social-wrap px-2">
|
||||
<div class="title mb-4"><span>{{ __('shop/login.third_party_logins') }}</span></div>
|
||||
@foreach($social_buttons as $button)
|
||||
{!! $button !!}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="d-flex vr-wrap">
|
||||
<div class="vr bg-secondary"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="login-item-header card-header">
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.new') }}</h6>
|
||||
</div>
|
||||
<div class="card-body px-md-2">
|
||||
<el-form ref="registerForm" :model="registerForm" :rules="registeRules">
|
||||
@hookwrapper('account.login.new.email')
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" v-model="registerForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('account.login.new.password')
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('account.login.new.confirm_password')
|
||||
<el-form-item label="{{ __('shop/login.confirm_password') }}" prop="password_confirmation">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password_confirmation" placeholder="{{ __('shop/login.confirm_password') }}"></el-input>
|
||||
</el-form-item>
|
||||
@endhookwrapper
|
||||
|
||||
@hook('account.login.new.confirm_password.bottom')
|
||||
|
||||
<div class="mt-5 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('registerForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-person"></i> {{ __('shop/login.register') }}</button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
callback(new Error('{{ __('shop/login.enter_password') }}'));
|
||||
} else {
|
||||
if (value !== '') {
|
||||
app.$refs.registerForm.validateField('password_confirmation');
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
var validatePass2 = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
callback(new Error('{{ __('shop/login.please_confirm') }}'));
|
||||
} else if (value !== app.registerForm.password) {
|
||||
callback(new Error('{{ __('shop/login.password_err') }}'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
let app = new Vue({
|
||||
el: '#page-login',
|
||||
|
||||
data: {
|
||||
loginForm: {
|
||||
email: '',
|
||||
password: '',
|
||||
},
|
||||
|
||||
registerForm: {
|
||||
email: '',
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
},
|
||||
|
||||
loginRules: {
|
||||
email: [
|
||||
{required: true, message: '{{ __('shop/login.enter_email') }}', trigger: 'change'},
|
||||
{type: 'email', message: '{{ __('shop/login.email_err') }}', trigger: 'change'},
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '{{ __('shop/login.enter_password')}}', trigger: 'change'}
|
||||
]
|
||||
},
|
||||
|
||||
registeRules: {
|
||||
email: [
|
||||
{required: true, message: '{{ __('shop/login.enter_email') }}', trigger: 'change'},
|
||||
{type: 'email', message: '{{ __('shop/login.email_err') }}', trigger: 'change'},
|
||||
],
|
||||
password: [
|
||||
{required: true, trigger: 'change'}
|
||||
],
|
||||
password_confirmation: [
|
||||
{required: true, validator: validatePass2, trigger: 'change'}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
beforeMount () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
checkedBtnLogin(form) {
|
||||
let _data = this.loginForm, url = '/login'
|
||||
|
||||
if (form == 'registerForm') {
|
||||
_data = this.registerForm, url = '/register'
|
||||
}
|
||||
|
||||
this.$refs['loginForm'].clearValidate();
|
||||
this.$refs['registerForm'].clearValidate();
|
||||
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (!valid) {
|
||||
layer.msg('{{ __('shop/login.check_form') }}', () => {})
|
||||
return;
|
||||
}
|
||||
|
||||
$http.post(url, _data).then((res) => {
|
||||
layer.msg(res.message)
|
||||
@if (!request('iframe'))
|
||||
location = "{{ shop_route('account.index') }}"
|
||||
@else
|
||||
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
|
||||
setTimeout(() => {
|
||||
parent.layer.close(index); //再执行关闭
|
||||
parent.window.location.reload()
|
||||
}, 400);
|
||||
@endif
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@hook('account.login.form.js.after')
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-order-list')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.order.index" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card mb-4 account-card order-wrap">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.order.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('shop/account.order.order_details') }}</th>
|
||||
<th width="160px">{{ __('shop/account.order.amount') }}</th>
|
||||
<th width="100px">{{ __('shop/account.order.state') }}</th>
|
||||
<th width="100px" class="text-end">{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@if (count($orders))
|
||||
@foreach ($orders as $order)
|
||||
<tbody>
|
||||
<tr class="sep-row">
|
||||
<td colspan="4"></td>
|
||||
</tr>
|
||||
<tr class="head-tr">
|
||||
<td colspan="4">
|
||||
<span class="order-created me-4">{{ $order->created_at }}</span>
|
||||
<span
|
||||
class="order-number">{{ __('shop/account.order.order_number') }}:{{ $order->number }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@foreach ($order->orderProducts as $product)
|
||||
<tr class="{{ $loop->first ? 'first-tr' : '' }}">
|
||||
<td>
|
||||
<div class="product-info">
|
||||
<div class="img border d-flex justify-content-between align-items-center"><img src="{{ $product->image }}" class="img-fluid"></div>
|
||||
<div class="name">
|
||||
<a class="text-dark"
|
||||
href="{{ shop_route('products.show', ['product' => $product->product_id]) }}">{{ $product->name }}</a>
|
||||
<div class="quantity mt-1 text-secondary">x {{ $product->quantity }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@if ($loop->first)
|
||||
<td rowspan="{{ $loop->count }}">
|
||||
{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
|
||||
<td rowspan="{{ $loop->count }}">{{ __("common.order.{$order->status}") }}</td>
|
||||
<td rowspan="{{ $loop->count }}" class="text-end">
|
||||
<a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}"
|
||||
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.order.check') }}</a>
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
@endforeach
|
||||
@else
|
||||
<tbody>
|
||||
<tr><td colspan="4" class="border-0"><x-shop-no-data /></td></tr>
|
||||
</tbody>
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-order-info')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="order" value="{{ $order->number }}" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
|
||||
@if ($errors->any())
|
||||
@foreach ($errors->all() as $error)
|
||||
<x-shop-alert type="danger" msg="{{ $error }}" class="mt-4" />
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
<div class="card mb-4 order-head">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<h6 class="card-title">{{ __('shop/account.order.order_info.order_details') }}</h6>
|
||||
<div>
|
||||
@if ($order->status == 'unpaid')
|
||||
<a href="{{ shop_route('orders.pay', $order->number) }}" class="btn btn-primary btn-sm nowrap">{{ __('shop/account.order.order_info.to_pay') }}</a>
|
||||
<button class="btn btn-outline-secondary btn-sm cancel-order" type="button">{{ __('shop/account.order.order_info.cancel') }}</button>
|
||||
@endif
|
||||
@if ($order->status == 'shipped')
|
||||
<button class="btn btn-primary btn-sm shipped-ed" type="button">{{ __('shop/account.order.order_info.confirm_receipt') }}</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="bg-light p-2 table-responsive">
|
||||
<table class="table table-borderless mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('shop/account.order.order_info.order_number') }}</th>
|
||||
<th class="nowrap">{{ __('shop/account.order.order_info.order_date') }}</th>
|
||||
<th>{{ __('shop/account.order.order_info.state') }}</th>
|
||||
<th>{{ __('shop/account.order.order_info.order_amount') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ $order->number }}</td>
|
||||
<td>{{ $order->created_at }}</td>
|
||||
<td>
|
||||
{{ __("common.order.{$order->status}") }}
|
||||
</td>
|
||||
<td>{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><h6 class="card-title">{{ __('order.address_info') }}</h6></div>
|
||||
<div class="card-body">
|
||||
<table class="table ">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th>{{ __('order.shipping_address') }}</th>
|
||||
<th>{{ __('order.payment_address') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div>{{ __('address.name') }}:{{ $order->shipping_customer_name }} ({{ $order->shipping_telephone }})</div>
|
||||
<div>
|
||||
{{ __('address.address') }}:
|
||||
{{ $order->shipping_address_1 }}
|
||||
{{ $order->shipping_address_2 }}
|
||||
{{ $order->shipping_city }}
|
||||
{{ $order->shipping_zone }}
|
||||
{{ $order->shipping_country }}
|
||||
</div>
|
||||
<div>{{ __('address.post_code') }}:{{ $order->shipping_zipcode }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>{{ __('address.name') }}:{{ $order->payment_customer_name }} ({{ $order->payment_telephone }})</div>
|
||||
<div>
|
||||
{{ __('address.address') }}:
|
||||
{{ $order->payment_address_1 }}
|
||||
{{ $order->payment_address_2 }}
|
||||
{{ $order->payment_city }}
|
||||
{{ $order->payment_zone }}
|
||||
{{ $order->payment_country }}
|
||||
</div>
|
||||
<div>{{ __('address.post_code') }}:{{ $order->payment_zipcode }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h6 class="card-title">{{ __('shop/account.order.order_info.order_items') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@foreach ($order->orderProducts as $product)
|
||||
<div class="product-list">
|
||||
<div class="d-flex">
|
||||
<div class="left border d-flex justify-content-between align-items-center"><img src="{{ $product->image }}" class="img-fluid"></div>
|
||||
<div class="right">
|
||||
<div class="name">
|
||||
<a class="text-dark" href="{{ shop_route('products.show', ['product' => $product->product_id]) }}">{{ $product->name }}</a>
|
||||
</div>
|
||||
<div class="price">
|
||||
{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}
|
||||
x {{ $product->quantity }}
|
||||
= {{ currency_format($product->price * $product->quantity, $order->currency_code, $order->currency_value) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if ($order->status == 'completed')
|
||||
<a href="{{ shop_route('account.rma.create', [$product->id]) }}" style="white-space: nowrap;"
|
||||
class="btn btn-outline-primary btn-sm">{{ __('shop/account.order.order_info.apply_after_sales') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h6 class="card-title">{{ __('shop/account.order.order_info.order_total') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-bordered border">
|
||||
<tbody>
|
||||
@foreach (array_chunk($order->orderTotals->all(), 2) as $totals)
|
||||
<tr>
|
||||
@foreach ($totals as $total)
|
||||
<td class="bg-light wp-200">{{ $total->title }}</td>
|
||||
<td><strong>{{ currency_format($total->value, $order->currency_code, $order->currency_value) }}</strong></td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@foreach ($html_items as $item)
|
||||
{!! $item !!}
|
||||
@endforeach
|
||||
|
||||
@if (0)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h6 class="card-title">{{ __('shop/account.order.order_info.logistics_status') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($order->orderShipments->count())
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><h6 class="card-title">{{ __('order.order_shipments') }}</h6></div>
|
||||
<div class="card-body">
|
||||
<div class="table-push">
|
||||
<table class="table ">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th>{{ __('order.express_company') }}</th>
|
||||
<th>{{ __('order.express_number') }}</th>
|
||||
<th>{{ __('order.history_created_at') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($order->orderShipments as $ship)
|
||||
<tr>
|
||||
<td>{{ $ship->express_company }}</td>
|
||||
<td>{{ $ship->express_number }}</td>
|
||||
<td>{{ $ship->created_at }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($order->orderHistories->count())
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h6 class="card-title">{{ __('shop/account.order.order_info.order_status') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table ">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th>{{ __('shop/account.order.order_info.state') }}</th>
|
||||
<th>{{ __('shop/account.order.order_info.remark') }}</th>
|
||||
<th>{{ __('shop/account.order.order_info.update_time') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($order->orderHistories as $orderHistory)
|
||||
<tr>
|
||||
<td>{{ $orderHistory->status_format }}</td>
|
||||
<td><span class="fw-bold">{{ $orderHistory->comment }}</span></td>
|
||||
<td><span class="fw-bold">{{ $orderHistory->created_at }}</span></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
$('.shipped-ed').click(function(event) {
|
||||
$http.post('orders/{{ $order->number }}/complete').then((res) => {
|
||||
layer.msg(res.message)
|
||||
window.location.reload()
|
||||
})
|
||||
});
|
||||
|
||||
$('.cancel-order').click(function(event) {
|
||||
$http.post('orders/{{ $order->number }}/cancel').then((res) => {
|
||||
layer.msg(res.message)
|
||||
window.location.reload()
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-order-success')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
{{-- <x-shop-breadcrumb type="static" value="account.order.index" /> --}}
|
||||
|
||||
<div class="row mt-5 justify-content-center mb-5">
|
||||
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 3])</div>
|
||||
</div>
|
||||
|
||||
<div class="card order-wrap border">
|
||||
<div class="card-body main-body">
|
||||
<div class="order-top border-bottom">
|
||||
<div class="left">
|
||||
<i class="bi bi-check2-circle"></i>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3 class="order-title">{{ __('shop/account.order.order_success.order_success') }}</h3>
|
||||
<div class="order-info">
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ __('shop/account.order.order_success.order_number') }}:<span class="fw-bold">{{ $order['number'] }}</span></td>
|
||||
<td>{{ __('shop/account.order.order_success.amounts_payable') }}:<span class="fw-bold">{{ currency_format($order['total']) }}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ __('shop/account.order.order_success.payment_method') }}:<span class="fw-bold">{{ $order['payment_method_name'] }}</span></td>
|
||||
@if (current_customer())
|
||||
<td><a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}">{{ __('shop/account.order.order_success.view_order') }}</a></td>
|
||||
@endif
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="{{ shop_route('orders.pay', [$order['number']]) }}" class="btn btn-primary">{{ __('shop/account.order.order_success.pay_now') }}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="text-muted mt-4">{{ __('shop/account.order.order_success.kind_tips') }}</div>
|
||||
<div class="mt-3">{{ __('shop/account.order.order_success.also') }}:<a href="/">{{ __('shop/account.order.order_success.continue_purchase') }}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-bottom">
|
||||
<div class="text-muted">{{ __('shop/account.order.order_success.contact_customer_service') }}:</div>
|
||||
<div>{{ __('shop/account.order.order_success.emaill') }}: {{ system_setting('base.email', '') }}</div>
|
||||
<div>{{ __('shop/account.order.order_success.service_hotline') }}: {{ system_setting('base.telephone', '') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@push('add-scripts')
|
||||
<script></script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Register</h1>
|
||||
<form action="{{ route('shop.register.store') }}" method="post">
|
||||
@csrf
|
||||
|
||||
@hookwrapper('account.register.email')
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="email">邮箱</span>
|
||||
</div>
|
||||
<input type="text" name="register[email]" class="form-control" value="{{ old('register.email') }}"
|
||||
placeholder="邮箱地址">
|
||||
</div>
|
||||
@error('register.email')
|
||||
<x-admin::form.error :message="$message"/>
|
||||
@enderror
|
||||
</div>
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('account.register.password')
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="password">密码</span>
|
||||
</div>
|
||||
<input type="password" name="register[password]" class="form-control" placeholder="密码">
|
||||
</div>
|
||||
@error('register.password')
|
||||
<x-admin::form.error :message="$message"/>
|
||||
@enderror
|
||||
</div>
|
||||
@endhookwrapper
|
||||
|
||||
@hook('account.register.email.after')
|
||||
|
||||
@if (session('error'))
|
||||
<div class="alert alert-success">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-block mb-4">登录</button>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-rmas')
|
||||
|
||||
@push('header')
|
||||
{{-- <script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script> --}}
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="address-app">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.rma.index" />
|
||||
|
||||
{{-- <nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Library</li>
|
||||
</ol>
|
||||
</nav> --}}
|
||||
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar/>
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.rma.rma_form.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body h-min-600">
|
||||
<div class="bg-light rounded-3 p-3 mb-4" style="background: #f6f9fc;">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="left wh-70">
|
||||
<img src="{{ $orderProduct->image }}" class="img-fluid">
|
||||
</div>
|
||||
<div class="right ms-3">
|
||||
<div class="name mb-2 fw-bold fs-5">{{ $orderProduct->name }}</div>
|
||||
<div class="price">{{ $orderProduct->price }} x {{ $orderProduct->quantity }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="{{ shop_route('account.rma.store') }}" method="POST">
|
||||
@csrf
|
||||
{{-- {{ method_field('put') }} --}}
|
||||
|
||||
@if (session('success'))
|
||||
<x-shop-alert type="success" msg="{{ session('success') }}" class="mt-4"/>
|
||||
@endif
|
||||
|
||||
<input type="hidden" name="order_product_id" value="{{ $orderProduct->id }}">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.service_type') }}</label>
|
||||
<select class="form-select" name="type">
|
||||
@foreach ($types as $key => $item)
|
||||
<option value="{{ $key }}" {{ $key == old('type', '') ? 'selected': '' }}>{{ $item }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.return_quantity') }}</label>
|
||||
<input class="form-control {{ $errors->has('quantity') ? 'is-invalid' : '' }}" type="text" name="quantity" value="{{ old('quantity', $orderProduct->quantity ?? '1') }}">
|
||||
@if ($errors->has('quantity'))
|
||||
<span class="invalid-feedback" role="alert">{{ $errors->first('quantity') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.unpacked') }}</label>
|
||||
<select class="form-select" name="opened">
|
||||
<option selected value="0">{{ __('common.no') }}</option>
|
||||
<option value="1">{{ __('common.yes') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.return_reason') }}</label>
|
||||
<select class="form-select {{ $errors->has('rma_reason_id') ? 'is-invalid' : '' }}" name="rma_reason_id">
|
||||
@foreach ($reasons as $item)
|
||||
<option value="{{ $item['id'] }}" {{ $item['id'] == old('opened', '') ? 'selected': '' }}>{{ $item['name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
@if ($errors->has('rma_reason_id'))
|
||||
<span class="invalid-feedback" role="alert">{{ $errors->first('rma_reason_id') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="col-12 "></div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.remark') }}</label>
|
||||
<textarea rows="4" type="text" name="comment" class="form-control">{{ old('comment', '') }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
<button class="btn btn-primary mt-sm-0" type="submit">{{ __('shop/common.submit') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-rmas')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="account.rma.index" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card mb-4 account-card order-wrap h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.rma.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('shop/account.rma.commodity') }}</th>
|
||||
<th>{{ __('shop/account.rma.quantity') }}</th>
|
||||
<th>{{ __('shop/account.rma.service_type') }}</th>
|
||||
<th>{{ __('shop/account.rma.return_reason') }}</th>
|
||||
<th>{{ __('shop/account.rma.creation_time') }}</th>
|
||||
{{-- <th>状态</th> --}}
|
||||
<th class="text-end">{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (count($rmas))
|
||||
@foreach ($rmas as $rma)
|
||||
<tr>
|
||||
<td>{{ sub_string($rma['product_name'], 80) }}</td>
|
||||
<td>{{ $rma['quantity'] }}</td>
|
||||
<td>{{ $rma['type'] }}</td>
|
||||
<td>{{ $rma['reason'] }}</td>
|
||||
<td>{{ $rma['created_at'] }}</td>
|
||||
<td class="text-end"><a href="{{ shop_route('account.rma.show', [$rma['id']]) }}"
|
||||
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.rma.check') }}</a> </td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="6" class="border-0">
|
||||
<x-shop-no-data />
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{-- {{ $rmas->links('shared/pagination/bootstrap-4') }} --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-rmas')
|
||||
|
||||
@push('header')
|
||||
{{-- <script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script> --}}
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="address-app">
|
||||
|
||||
<x-shop-breadcrumb type="rma" value="{{ $rma->id }}" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.rma.rma_info.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body h-600">
|
||||
<div class="bg-light rounded-3 p-3 mb-4" style="background: #f6f9fc;">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="left wh-70">
|
||||
<img src="{{ $orderProduct->image }}" class="img-fluid">
|
||||
</div>
|
||||
<div class="right ms-3">
|
||||
<div class="name mb-2 fw-bold fs-5">{{ $orderProduct->name }}</div>
|
||||
<div class="price">{{ $orderProduct->price }} x {{ $orderProduct->quantity }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.service_type') }}</label>
|
||||
@foreach ($types as $key => $item)
|
||||
@if ($key == $rma->type)
|
||||
<div>{{ $item}}</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.return_quantity') }}</label>
|
||||
<div>{{ $rma->quantity }}</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('common.status') }}</label>
|
||||
<div>{{ $rma->status }}</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.unpacked') }}</label>
|
||||
<div>
|
||||
@if ($rma->opened)
|
||||
{{ __('common.yes') }}
|
||||
@else
|
||||
{{ __('common.no') }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.creation_time') }}</label>
|
||||
<div>
|
||||
{{ $rma->created_at }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.return_reason') }}</label>
|
||||
<div>
|
||||
@foreach ($reasons as $item)
|
||||
@if ($rma->rma_reason_id == $item['id'])
|
||||
{{$item['name']}}
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 mb-4">
|
||||
<label class="form-label">{{ __('shop/account.rma.rma_form.remark') }}</label>
|
||||
<div>{{$rma->comment}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-account-wishlist')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="static" value="account.wishlist.index" />
|
||||
|
||||
<div class="row">
|
||||
<x-shop-sidebar />
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="card mb-4 h-min-600">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('shop/account.wishlist.index') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="90px"></th>
|
||||
<th>{{ __('shop/account.wishlist.product') }}</th>
|
||||
<th>{{ __('shop/account.wishlist.price') }}</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (count($wishlist))
|
||||
@foreach ($wishlist as $item)
|
||||
<tr data-id="{{ $item['id'] }}">
|
||||
<td>
|
||||
<div class="wh-70 border d-flex justify-content-between align-items-center"><img src="{{ $item['image'] }}" class="img-fluid"></div>
|
||||
</td>
|
||||
<td>{{ $item['product_name'] }}</td>
|
||||
<td>{{ $item['price'] }}</td>
|
||||
<td class="text-end">
|
||||
<div class="">
|
||||
<a class="btn btn-dark btn-sm add-cart"
|
||||
href="{{ shop_route('products.show', $item['product_id']) }}">{{ __('shop/account.wishlist.check_details') }}</a>
|
||||
<button class="btn btn-danger btn-sm remove-wishlist"><i class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="4" class="border-0">
|
||||
<x-shop-no-data />
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.remove-wishlist').click(function() {
|
||||
const product_id = $(this).closest('tr').data('id');
|
||||
|
||||
$http.delete('account/wishlist/' + product_id).then((res) => {
|
||||
if (res.status == 'success') {
|
||||
$(this).closest('tr').fadeOut(function() {
|
||||
$(this).remove();
|
||||
if ($('.remove-wishlist').length == 0) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories')
|
||||
@section('title', $brand->name)
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="brand" :value="$brand" />
|
||||
|
||||
<div class="row">
|
||||
@foreach ($products_format as $product)
|
||||
<div class="col-6 col-md-3">@include('shared.product')</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{ $products->links('shared/pagination/bootstrap-4') }}
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-brands')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="brands.index" />
|
||||
<p class="fw-bold fs-3 d-flex justify-content-center mb-4">{{ __('shop/brands.index') }}</p>
|
||||
|
||||
<ul class="list-group list-group-horizontal mb-5 curser-list">
|
||||
@foreach ($brands as $brand)
|
||||
<li class="list-group-item p-0 flex-grow-1">
|
||||
<a href="brands#{{ $brand['0']['first'] }}" class="py-2 px-3 text-center fw-bold d-block">{{ $brand['0']['first'] }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
<ul class="brand-list ps-0">
|
||||
@foreach ($brands as $brand)
|
||||
<li class="d-flex border-top py-3">
|
||||
<p class="px-2 fs-5 mt-4 fw-bold py-5" id="{{ $brand['0']['first'] }}">{{ $brand['0']['first'] }}</p>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($brand as $item)
|
||||
<div class="text-center col-6 col-md-4 col-lg-2 mt-2">
|
||||
<a href="{{ type_route('brand', $item['id']) }}">
|
||||
<div class="brand-item">
|
||||
<img src="{{ $item['logo'] }}" class="img-fluid" alt="{{ $item['name'] }}">
|
||||
</div>
|
||||
<p class="mb-0 mt-1 ">{{ $item['name'] }}</p>
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-cart')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="app-cart" v-cloak>
|
||||
|
||||
<x-shop-breadcrumb type="static" value="carts.index" />
|
||||
|
||||
<div class="row mt-1 justify-content-center mb-2">
|
||||
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 1])</div>
|
||||
</div>
|
||||
|
||||
@if ($errors->has('error'))
|
||||
<x-shop-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
|
||||
@endif
|
||||
|
||||
<div class="row mt-5" v-if="products.length">
|
||||
<div class="col-12 col-md-9 left-column">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-lg-4">
|
||||
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.commodity') }}</h4></div>
|
||||
<div class="cart-products-wrap table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="130">
|
||||
<input class="form-check-input" type="checkbox" value="" id="check-all" v-model="allSelected">
|
||||
<label class="form-check-label ms-1" for="check-all">
|
||||
{{ __('shop/carts.select_all') }}
|
||||
</label>
|
||||
</th>
|
||||
<th width="40%">{{ __('shop/carts.index') }}</th>
|
||||
<th width="170">{{ __('shop/carts.commodity') }}</th>
|
||||
<th width="170">{{ __('shop/carts.subtotal') }}</th>
|
||||
<th width="100" class="text-end">{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="product, index in products" :key="index" :class="product.selected ? 'active' : ''">
|
||||
<td>
|
||||
<div class="d-flex align-items-center p-image">
|
||||
<input class="form-check-input" type="checkbox" @change="checkedCartTr(index)" v-model="product.selected">
|
||||
<div class="border d-flex align-items-center justify-content-between wh-80 ms-3"><img :src="product.image" class="img-fluid"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="name text-truncate-2 mb-1 fw-bold" v-text="product.name"></div>
|
||||
<div class="text-size-min text-muted mb-1">@{{ product.variant_labels }}</div>
|
||||
<div class="price text-muted">@{{ product.price_format }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="quantity-wrap">
|
||||
<input type="text" class="form-control" @input="quantityChange(product.quantity, product.cart_id, product.sku_id)" onkeyup="this.value=this.value.replace(/\D/g,'')" v-model.number="product.quantity" name="quantity" minimum="1">
|
||||
<div class="right">
|
||||
<i class="bi bi-chevron-up"></i>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>@{{ product.subtotal_format }}</td>
|
||||
<td class="text-end">
|
||||
<button type="button" class="btn text-danger btn-sm px-0" @click.stop="checkedBtnDelete(product.cart_id)">
|
||||
<i class="bi bi-x-lg"></i> {{ __('common.delete') }}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@hook('carts.products.after')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-3 right-column">
|
||||
<div class="card shadow-sm x-fixed-top">
|
||||
<div class="card-body p-lg-4">
|
||||
<div class="card total-wrap">
|
||||
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.product_total') }}</h4></div>
|
||||
<div class="card-body p-lg-0">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><span>{{ __('shop/carts.all') }}</span><span>@{{ allProduct }}</span></li>
|
||||
<li class="list-group-item"><span>{{ __('shop/carts.selected') }}</span><span>@{{ total_quantity }}</span></li>
|
||||
<li class="list-group-item border-bottom-0"><span>{{ __('shop/carts.product_total') }}</span><span class="total-price">@{{ amount_format }}</span></li>
|
||||
<li class="list-group-item d-grid gap-2 mt-3 border-bottom-0">
|
||||
<button type="button" class="btn btn-primary fs-5 fw-bold" @click="checkedBtnToCheckout">{{ __('shop/carts.to_checkout') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="d-flex justify-content-center align-items-center flex-column">
|
||||
<div class="empty-cart-wrap text-center mt-5">
|
||||
<div class="empty-cart-icon mb-3">
|
||||
<i class="bi bi-cart fs-1"></i>
|
||||
</div>
|
||||
<div class="empty-cart-text mb-3">
|
||||
<h5>{{ __('shop/carts.cart_empty') }}</h5>
|
||||
<p class="text-muted">{{ __('shop/carts.go_buy') }}</p>
|
||||
</div>
|
||||
<div class="empty-cart-action">
|
||||
<a href="{{ shop_route('home.index') }}" class="btn btn-primary">{{ __('shop/carts.go_shopping') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: "#app-cart",
|
||||
data: {
|
||||
products: @json($data['carts']),
|
||||
total_quantity: @json($data['quantity']),
|
||||
amount: @json($data['amount']),
|
||||
amount_format: @json($data['amount_format']),
|
||||
},
|
||||
// components: {},
|
||||
// 计算属性
|
||||
computed: {
|
||||
allSelected: {
|
||||
get() {
|
||||
return !this.products.length ? false : this.products.every(s => s.selected)
|
||||
},
|
||||
set(val) {
|
||||
// return
|
||||
this.products.map(e => e.selected = val)
|
||||
this.selectedBtnSelected()
|
||||
}
|
||||
},
|
||||
|
||||
allProduct() {
|
||||
return this.products.map(e => e.quantity).reduce((n,m) => n + m);
|
||||
},
|
||||
},
|
||||
// 侦听器
|
||||
watch: {},
|
||||
// 组件方法
|
||||
methods: {
|
||||
checkedBtnToCheckout() {
|
||||
if (!this.products.some(e => e.selected)) {
|
||||
layer.msg('{{ __('shop/carts.empty_selected_products') }}', ()=>{})
|
||||
return
|
||||
}
|
||||
|
||||
location = '{{ shop_route("checkout.index") }}'
|
||||
},
|
||||
|
||||
quantityChange(quantity, cart_id, sku_id) {
|
||||
const self = this;
|
||||
$http.put(`/carts/${cart_id}`, {quantity: quantity, sku_id}, {hload: true}).then((res) => {
|
||||
this.setUpdateData(res);
|
||||
})
|
||||
},
|
||||
|
||||
checkedBtnDelete(cart_id) {
|
||||
const self = this;
|
||||
|
||||
$http.delete(`/carts/${cart_id}`).then((res) => {
|
||||
this.setUpdateData(res);
|
||||
})
|
||||
},
|
||||
|
||||
checkedCartTr(index) {
|
||||
// this.products[index].selected = !this.products[index].selected;
|
||||
this.selectedBtnSelected();
|
||||
},
|
||||
|
||||
selectedBtnSelected() {
|
||||
const self = this;
|
||||
const cart_ids = this.products.filter(e => e.selected).map(x => x.cart_id)
|
||||
|
||||
$http.post(`/carts/select`, {cart_ids: cart_ids}, {hload: true}).then((res) => {
|
||||
this.setUpdateData(res);
|
||||
})
|
||||
},
|
||||
|
||||
setUpdateData(res) {
|
||||
this.products = res.data.carts
|
||||
this.amount_format = res.data.amount_format
|
||||
this.total_quantity = res.data.quantity
|
||||
bk.getCarts()
|
||||
}
|
||||
},
|
||||
// 实例被挂载后调用
|
||||
mounted () {
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<div class="offcanvas-header">
|
||||
<h5 id="offcanvasRightLabel" class="mx-auto mb-0">{{ __('shop/carts.mini') }}</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body pt-0">
|
||||
@php $check = 0 @endphp
|
||||
|
||||
@if ($carts)
|
||||
<div class="offcanvas-right-products">
|
||||
@foreach ($carts as $cart)
|
||||
@if ($cart['selected']) @php $check = $check + 1 @endphp @endif
|
||||
<div class="product-list d-flex align-items-center">
|
||||
<div class="select-wrap">
|
||||
<i class="bi {{ $cart['selected'] ? 'bi-check-circle-fill' : 'bi-circle' }}" data-id="{{ $cart['cart_id'] }}"></i>
|
||||
</div>
|
||||
<div class="product-info d-flex align-items-center">
|
||||
<div class="left"><a href="{{ shop_route('products.show', $cart['product_id']) }}" class="d-flex justify-content-between align-items-center h-100"><img src="{{ $cart['image'] }}" class="img-fluid"></a></div>
|
||||
<div class="right flex-grow-1">
|
||||
<a href="{{ shop_route('products.show', $cart['product_id']) }}" class="name fs-sm fw-bold mb-2 text-dark text-truncate-2" title="{{ $cart['name'] }}">{{ $cart['name'] }}</a>
|
||||
<div class="text-muted mb-1 text-size-min">{{ $cart['variant_labels'] }}</div>
|
||||
<div class="product-bottom d-flex justify-content-between align-items-center">
|
||||
<div class="price d-flex align-items-center">
|
||||
{{ $cart['price_format'] }} x
|
||||
<input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
|
||||
data-id="{{ $cart['cart_id'] }}" data-sku="{{ $cart['sku_id'] }}" class="form-control p-1" value="{{ $cart['quantity'] }}">
|
||||
</div>
|
||||
<span class="offcanvas-products-delete" data-id="{{ $cart['cart_id'] }}"><i class="bi bi-x-lg"></i>
|
||||
{{ __('common.delete') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="d-flex justify-content-center align-items-center flex-column">
|
||||
<div class="empty-cart-wrap text-center mt-5">
|
||||
<div class="empty-cart-icon mb-3">
|
||||
<i class="bi bi-cart fs-1"></i>
|
||||
</div>
|
||||
<div class="empty-cart-text mb-3">
|
||||
<h5>{{ __('shop/carts.cart_empty') }}</h5>
|
||||
<p class="text-muted">{{ __('shop/carts.go_buy') }}</p>
|
||||
</div>
|
||||
<div class="empty-cart-action">
|
||||
<a href="{{ shop_route('home.index') }}" class="btn btn-primary">{{ __('shop/carts.go_shopping') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($carts)
|
||||
<div class="offcanvas-footer">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2 p-3 bg-light top-footer">
|
||||
<div class="select-wrap all-select d-flex align-items-center">
|
||||
<i class="bi {{ $check == count($carts) ? 'bi-check-circle-fill' : 'bi-circle' }}"></i>
|
||||
<span class="ms-1 text-secondary">{{ __('common.select_all') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-secondary">{{ __('shop/carts.product_total') }}</span><strong>(<span class="offcanvas-right-cart-count">{{ $quantity }}</span>)</strong>
|
||||
<strong class="ms-auto offcanvas-right-cart-amount">{{ $amount_format }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<a href="{{ shop_route('checkout.index') }}" class="btn w-100 fw-bold btn-dark to-checkout {{ !$check ? 'disabled' : '' }}">{{ __('shop/carts.to_checkout') }}</a>
|
||||
<a href="{{ shop_route('carts.index') }}" class="btn w-100 fw-bold btn-outline-dark mt-2">{{ __('shop/carts.check_cart') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories')
|
||||
@section('title', $category->description->meta_title ?: system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') .' - '. $category->description->name)
|
||||
@section('keywords', $category->description->meta_keywords ?: system_setting('base.meta_keyword'))
|
||||
@section('description', $category->description->meta_description ?: system_setting('base.meta_description'))
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="category" :value="$category" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-3 pe-lg-4 left-column d-none d-lg-block">
|
||||
<div class="x-fixed-top">@include('shared.filter_sidebar_block')</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-9 right-column">
|
||||
<div class="filter-value-wrap mb-2 d-none">
|
||||
<ul class="list-group list-group-horizontal">
|
||||
@foreach ($filter_data['attr'] as $index => $attr)
|
||||
@foreach ($attr['values'] as $value_index => $value)
|
||||
@if ($value['selected'])
|
||||
<li class="list-group-item me-1 mb-1" data-attr="{{ $index }}" data-attrval="{{ $value_index }}">
|
||||
{{ $attr['name'] }}: {{ $value['name'] }} <i class="bi bi-x-lg ms-1"></i>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endforeach
|
||||
<li class="list-group-item me-1 mb-1 delete-all">{{ __('common.delete_all') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@if (count($products_format))
|
||||
@include('shared.filter_bar_block')
|
||||
@if ($children)
|
||||
<div class="children-wrap me-2 mb-3 mt-n3">
|
||||
<span class="text-secondary">{{ __('category.children') }}:</span>
|
||||
@foreach ($children as $item)
|
||||
<a href="{{ $item['url'] }}">{{ $item['name'] }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<div class="row {{ request('style_list') == 'list' ? 'product-list-wrap' : ''}}">
|
||||
@foreach ($products_format as $product)
|
||||
<div class="{{ !request('style_list') || request('style_list') == 'grid' ? 'col-6 col-md-4' : 'col-12'}}">
|
||||
@include('shared.product')
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<x-shop-no-data />
|
||||
@endif
|
||||
|
||||
{{ $products->links('shared/pagination/bootstrap-4') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
let filterAttr = @json($filter_data['attr'] ?? []);
|
||||
|
||||
$('.filter-value-wrap li').click(function(event) {
|
||||
let [attr, val] = [$(this).data('attr'),$(this).data('attrval')];
|
||||
if ($(this).hasClass('delete-all')) {
|
||||
return deleteFilterAll();
|
||||
}
|
||||
|
||||
filterAttr[attr].values[val].selected = false;
|
||||
filterProductData();
|
||||
});
|
||||
|
||||
if ($('.filter-value-wrap li').length > 1) {
|
||||
$('.filter-value-wrap').removeClass('d-none')
|
||||
}
|
||||
|
||||
$('.child-category').each(function(index, el) {
|
||||
if ($(this).hasClass('active')) {
|
||||
$(this).parent('ul').addClass('show').siblings('button').removeClass('collapsed')
|
||||
$(this).parents('li').addClass('active')
|
||||
}
|
||||
});
|
||||
|
||||
$('.attr-value-check').change(function(event) {
|
||||
let [attr, val] = [$(this).data('attr'),$(this).data('attrval')];
|
||||
filterAttr[attr].values[val].selected = $(this).is(":checked");
|
||||
filterProductData();
|
||||
});
|
||||
|
||||
$('.form-select, input[name="style_list"]').change(function(event) {
|
||||
filterProductData();
|
||||
});
|
||||
|
||||
function filterProductData() {
|
||||
let url = bk.removeURLParameters(window.location.href, 'attr', 'price', 'sort', 'order');
|
||||
let [psMin, psMax, pMin, pMax] = [$('.price-select-min').val(), $('.price-select-max').val(), $('.price-min').val(), $('.price-max').val()];
|
||||
let order = $('.order-select').val();
|
||||
let perpage = $('.perpage-select').val();
|
||||
let styleList = $('input[name="style_list"]:checked').val();
|
||||
|
||||
layer.load(2, {shade: [0.3,'#fff'] })
|
||||
|
||||
if (filterAttrChecked(filterAttr)) {
|
||||
url = bk.updateQueryStringParameter(url, 'attr', filterAttrChecked(filterAttr));
|
||||
}
|
||||
|
||||
if ((psMin != pMin) || (psMax != pMax)) {
|
||||
url = bk.updateQueryStringParameter(url, 'price', `${psMin}-${psMax}`);
|
||||
}
|
||||
|
||||
if (order) {
|
||||
let orderKeys = order.split('|');
|
||||
url = bk.updateQueryStringParameter(url, 'sort', orderKeys[0]);
|
||||
url = bk.updateQueryStringParameter(url, 'order', orderKeys[1]);
|
||||
}
|
||||
|
||||
if (perpage) {
|
||||
url = bk.updateQueryStringParameter(url, 'per_page', perpage);
|
||||
}
|
||||
|
||||
if (styleList) {
|
||||
url = bk.updateQueryStringParameter(url, 'style_list', styleList);
|
||||
}
|
||||
|
||||
location = url;
|
||||
}
|
||||
|
||||
function filterAttrChecked(data) {
|
||||
let filterAtKey = [];
|
||||
data.forEach((item) => {
|
||||
let checkedAtValues = [];
|
||||
item.values.forEach((val) => val.selected ? checkedAtValues.push(val.id) : '')
|
||||
if (checkedAtValues.length) {
|
||||
filterAtKey.push(`${item.id}:${checkedAtValues.join('/')}`)
|
||||
}
|
||||
})
|
||||
|
||||
return filterAtKey.join('|')
|
||||
}
|
||||
|
||||
function deleteFilterAll() {
|
||||
let url = bk.removeURLParameters(window.location.href, 'attr', 'price');
|
||||
location = url;
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-checkout')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
|
||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="checkout.index" />
|
||||
|
||||
<div class="row mt-1 justify-content-center">
|
||||
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 2])</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-5">
|
||||
<div class="col-12 col-md-8 left-column">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-lg-4">
|
||||
@include('checkout._address')
|
||||
|
||||
<div class="checkout-black">
|
||||
<h5 class="checkout-title">{{ __('shop/checkout.payment_method') }}</h5>
|
||||
<div class="radio-line-wrap">
|
||||
@foreach ($payment_methods as $payment)
|
||||
<div class="radio-line-item {{ $payment['code'] == $current['payment_method_code'] ? 'active' : '' }}" data-key="payment_method_code" data-value="{{ $payment['code'] }}">
|
||||
<div class="left">
|
||||
<span class="radio"></span>
|
||||
<img src="{{ $payment['icon'] }}" class="img-fluid">
|
||||
</div>
|
||||
<div class="right ms-2">
|
||||
<div class="title">{{ $payment['name'] }}</div>
|
||||
<div class="sub-title">{!! $payment['description'] !!}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="checkout-black">
|
||||
<h5 class="checkout-title">{{ __('shop/checkout.delivery_method') }}</h5>
|
||||
<div class="radio-line-wrap">
|
||||
@foreach ($shipping_methods as $methods)
|
||||
@foreach ($methods['quotes'] as $shipping)
|
||||
<div class="radio-line-item {{ $shipping['code'] == $current['shipping_method_code'] ? 'active':'' }}" data-key="shipping_method_code" data-value="{{ $shipping['code'] }}">
|
||||
<div class="left">
|
||||
<span class="radio"></span>
|
||||
<img src="{{ $shipping['icon'] }}" class="img-fluid">
|
||||
</div>
|
||||
<div class="right ms-2">
|
||||
<div class="title">{{ $shipping['name'] }}</div>
|
||||
<div class="sub-title">{!! $shipping['description'] !!}</div>
|
||||
<div class="mt-2">{!! $shipping['html'] ?? '' !!}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4 right-column">
|
||||
<div class="x-fixed-top">
|
||||
@if (!current_customer())
|
||||
<div class="card total-wrap mb-4 p-lg-4 shadow-sm">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">{{ __('shop/login.login_and_sign') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<button class="btn btn-outline-dark guest-checkout-login"><i class="bi bi-box-arrow-in-right me-2"></i>{{ __('shop/login.login_and_sign') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card total-wrap p-lg-4 shadow-sm">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<h5 class="mb-0">{{ __('shop/checkout.cart_totals') }}</h5>
|
||||
<span class="rounded-circle bg-primary">{{ $carts['quantity'] }}</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="products-wrap">
|
||||
@foreach ($carts['carts'] as $cart)
|
||||
<div class="item">
|
||||
<div class="image">
|
||||
<img src="{{ $cart['image'] }}" class="img-fluid">
|
||||
<div class="name">
|
||||
<div title="{{ $cart['name'] }}" class="text-truncate-2">{{ $cart['name'] }}</div>
|
||||
@if ($cart['variant_labels'])
|
||||
<div class="text-muted mt-1">{{ $cart['variant_labels'] }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="price text-end">
|
||||
<div>{{ $cart['price_format'] }}</div>
|
||||
<div class="quantity">x {{ $cart['quantity'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<ul class="totals">
|
||||
@foreach ($totals as $total)
|
||||
<li><span>{{ $total['title'] }}</span><span>{{ $total['amount_format'] }}</span></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="d-grid gap-2 mt-3">
|
||||
<button class="btn btn-primary fw-bold fs-5" type="button" id="submit-checkout">{{ __('shop/checkout.submit_order') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.radio-line-item').click(function(event) {
|
||||
const key = $(this).data('key');
|
||||
const value = $(this).data('value');
|
||||
let html = '';
|
||||
|
||||
$http.put('/checkout', {[key]: value}).then((res) => {
|
||||
$(this).addClass('active').siblings().removeClass('active')
|
||||
res.totals.forEach((item) => {
|
||||
html += `<li><span>${item.title}</span><span>${item.amount_format}</span></li>`
|
||||
})
|
||||
|
||||
$('ul.totals').html(html);
|
||||
})
|
||||
});
|
||||
|
||||
$('#submit-checkout').click(function(event) {
|
||||
if (!config.isLogin && checkoutAddressApp.source.guest_shipping_address === null) {
|
||||
layer.msg('{{ __('shop/checkout.error_payment_address') }}', ()=>{})
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.isLogin && !checkoutAddressApp.form.payment_address_id) {
|
||||
layer.msg('{{ __('shop/checkout.error_payment_address') }}', ()=>{})
|
||||
return;
|
||||
}
|
||||
|
||||
$http.post('/checkout/confirm').then((res) => {
|
||||
location = 'orders/' + res.number + '/success?type=create'
|
||||
})
|
||||
});
|
||||
|
||||
$('.guest-checkout-login').click(function(event) {
|
||||
bk.openLogin();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
<div id="checkout-address-app" v-cloak>
|
||||
<div class="checkout-black">
|
||||
<div class="checkout-title">
|
||||
<div class="d-flex">
|
||||
<h5 class="mb-0 me-4">{{ __('shop/checkout.address') }}</h5>
|
||||
<el-checkbox v-model="same_as_shipping_address" v-if="source.addresses.length || source.guest_shipping_address">{{ __('shop/checkout.same_as_shipping_address') }}
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<button class="btn btn-sm icon" v-if="isAllAddress" @click="isAllAddress = false"><i
|
||||
class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
<div class="addresses-wrap">
|
||||
<div class="row">
|
||||
<template v-if="source.isLogin">
|
||||
<div class="col-6" v-for="address, index in source.addresses" :key="index"
|
||||
v-if="source.addresses.length &&( address.id == form.shipping_address_id || isAllAddress)">
|
||||
<div :class="['item', address.id == form.shipping_address_id ? 'active' : '']"
|
||||
@click="updateCheckout(address.id, 'shipping_address_id')">
|
||||
<div class="name-wrap">
|
||||
<span class="name">@{{ address.name }}</span>
|
||||
<span class="phone">@{{ address.phone }}</span>
|
||||
</div>
|
||||
<div class="zipcode">@{{ address.zipcode }}</div>
|
||||
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
|
||||
@{{ address.address_1 }}</div>
|
||||
<div class="address-bottom">
|
||||
<div>
|
||||
<span class="badge bg-success"
|
||||
v-if="form.shipping_address_id == address.id">{{ __('shop/checkout.chosen') }}</span>
|
||||
</div>
|
||||
<a href="javascript:void(0)" class=""
|
||||
@click.stop="editAddress(index, 'shipping_address_id')">{{ __('shop/checkout.edit') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6" v-if="!isAllAddress">
|
||||
<div class="item address-right">
|
||||
<button class="btn btn-outline-dark w-100 mb-3" v-if="source.addresses.length > 1"
|
||||
@click="isAllAddress = true">{{ __('shop/checkout.choose_another_address') }}</button>
|
||||
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'shipping_address_id')"><i
|
||||
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="col-6" v-if="source.guest_shipping_address">
|
||||
<div class="item active">
|
||||
<div class="name-wrap">
|
||||
<span class="name">@{{ source.guest_shipping_address.name }}</span>
|
||||
<span class="phone">@{{ source.guest_shipping_address.phone }}</span>
|
||||
</div>
|
||||
<div class="zipcode">
|
||||
<span>@{{ source.guest_shipping_address.zipcode }}</span>
|
||||
<span class="ms-1">@{{ source.guest_shipping_address.email }}</span>
|
||||
</div>
|
||||
<div class="address-info">@{{ source.guest_shipping_address.country }} @{{ source.guest_shipping_address.zone }} @{{ source.guest_shipping_address.city }}
|
||||
@{{ source.guest_shipping_address.address_1 }}</div>
|
||||
<div class="address-bottom">
|
||||
<div>
|
||||
<span class="badge bg-success">{{ __('shop/checkout.chosen') }}</span>
|
||||
</div>
|
||||
<a class="javascript:void(0)"
|
||||
@click.stop="editAddress(null, 'guest_shipping_address')">{{ __('shop/checkout.edit') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6" v-if="!source.guest_shipping_address">
|
||||
<div class="item address-right">
|
||||
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'guest_shipping_address')"><i
|
||||
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="checkout-black" v-if='!same_as_shipping_address'>
|
||||
<div class="checkout-title">
|
||||
<div class="d-flex">
|
||||
<h5 class="mb-0 me-4">{{ __('shop/checkout.payment_address') }}</h5>
|
||||
</div>
|
||||
<button class="btn btn-sm icon" v-if="isAllAddressPayment" @click="isAllAddressPayment = false"><i
|
||||
class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
<div class="addresses-wrap">
|
||||
<div class="row">
|
||||
<template v-if="source.isLogin">
|
||||
<div class="col-6" v-for="address, index in source.addresses" :key="index"
|
||||
v-if="source.addresses.length && (form.payment_address_id == '' || address.id == form.payment_address_id || isAllAddressPayment)">
|
||||
<div :class="['item', address.id == form.payment_address_id ? 'active' : '']"
|
||||
@click="updateCheckout(address.id, 'payment_address_id')">
|
||||
<div class="name-wrap">
|
||||
<span class="name">@{{ address.name }}</span>
|
||||
<span class="phone">@{{ address.phone }}</span>
|
||||
</div>
|
||||
<div class="zipcode">@{{ address.zipcode }}</div>
|
||||
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
|
||||
@{{ address.address_1 }}</div>
|
||||
<div class="address-bottom">
|
||||
<div>
|
||||
<span class="badge bg-success"
|
||||
v-if="form.payment_address_id == address.id">{{ __('shop/checkout.chosen') }}</span>
|
||||
</div>
|
||||
<a class="javascript:void(0)"
|
||||
@click.stop="editAddress(index, 'payment_address_id')">{{ __('shop/checkout.edit') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6" v-if="!isAllAddressPayment">
|
||||
<div class="item address-right">
|
||||
<button class="btn btn-outline-dark w-100 mb-3" v-if="source.addresses.length > 1"
|
||||
@click="isAllAddressPayment = true">{{ __('shop/checkout.choose_another_address') }}</button>
|
||||
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'payment_address_id')"><i
|
||||
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="col-6" v-if="source.guest_payment_address">
|
||||
<div class="item active">
|
||||
<div class="name-wrap">
|
||||
<span class="name">@{{ source.guest_payment_address.name }}</span>
|
||||
<span class="phone">@{{ source.guest_payment_address.phone }}</span>
|
||||
</div>
|
||||
<div class="zipcode">@{{ source.guest_payment_address.zipcode }}</div>
|
||||
<div class="address-info">@{{ source.guest_payment_address.country }} @{{ source.guest_payment_address.zone }} @{{ source.guest_payment_address.city }}
|
||||
@{{ source.guest_payment_address.address_1 }}</div>
|
||||
<div class="address-bottom">
|
||||
<div>
|
||||
<span class="badge bg-success">{{ __('shop/checkout.chosen') }}</span>
|
||||
</div>
|
||||
<a class="javascript:void(0)"
|
||||
@click.stop="editAddress(null, 'guest_payment_address')">{{ __('shop/checkout.edit') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6" v-if="!source.guest_payment_address">
|
||||
<div class="item address-right">
|
||||
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'guest_payment_address')"><i
|
||||
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<address-dialog ref="address-dialog" @change="onAddressDialogChange"></address-dialog>
|
||||
</div>
|
||||
@push('add-scripts')
|
||||
@include('shared.address-form')
|
||||
<script>
|
||||
var checkoutAddressApp = new Vue({
|
||||
el: '#checkout-address-app',
|
||||
|
||||
data: {
|
||||
form: {
|
||||
shipping_address_id: @json($current['shipping_address_id']),
|
||||
payment_address_id: @json($current['payment_address_id']),
|
||||
},
|
||||
|
||||
isAllAddress: false,
|
||||
isAllAddressPayment: false,
|
||||
|
||||
source: {
|
||||
addresses: @json($addresses ?? []),
|
||||
guest_shipping_address: @json($current['guest_shipping_address'] ?? null),
|
||||
guest_payment_address: @json($current['guest_payment_address'] ?? null),
|
||||
isLogin: config.isLogin,
|
||||
},
|
||||
|
||||
dialogAddress: {
|
||||
index: null,
|
||||
type: 'shipping_address_id',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
same_as_shipping_address: {
|
||||
get() {
|
||||
if (!this.source.isLogin) {
|
||||
return JSON.stringify(this.source.guest_shipping_address) === JSON.stringify(this.source.guest_payment_address);
|
||||
}
|
||||
|
||||
return this.form.shipping_address_id === this.form.payment_address_id
|
||||
},
|
||||
|
||||
set(e) {
|
||||
if (e) {
|
||||
if (!this.source.isLogin) {
|
||||
$http.put('/checkout', {guest_payment_address: this.source.guest_shipping_address}).then((res) => {
|
||||
this.source.guest_payment_address = res.current.guest_payment_address;
|
||||
})
|
||||
} else {
|
||||
this.form.payment_address_id = this.form.shipping_address_id
|
||||
this.updateCheckout(this.form.payment_address_id, 'same_as_shipping_address')
|
||||
}
|
||||
} else {
|
||||
this.form.payment_address_id = '';
|
||||
this.source.guest_payment_address = null
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
editAddress(index, type) {
|
||||
let addresses = null
|
||||
|
||||
if (typeof index == 'number') {
|
||||
this.dialogAddress.index = index;
|
||||
addresses = JSON.parse(JSON.stringify(this.source.addresses[index]))
|
||||
}
|
||||
|
||||
// 游客结账
|
||||
if ((type == 'guest_shipping_address' || type == 'guest_payment_address') && this.source[type]) {
|
||||
addresses = JSON.parse(JSON.stringify(this.source[type]))
|
||||
}
|
||||
|
||||
this.dialogAddress.type = type
|
||||
this.$refs['address-dialog'].editAddress(addresses, this.dialogAddress.type)
|
||||
},
|
||||
|
||||
onAddressDialogChange(form) {
|
||||
const type = form.id ? 'put' : 'post';
|
||||
const url = `/account/addresses${type == 'put' ? '/' + form.id : ''}`;
|
||||
|
||||
if (!this.source.isLogin) {
|
||||
let data = {[this.dialogAddress.type]: form}
|
||||
|
||||
if (this.source.guest_payment_address === null && this.source.guest_shipping_address === null) {
|
||||
data = {
|
||||
guest_shipping_address: form,
|
||||
guest_payment_address: form
|
||||
}
|
||||
}
|
||||
|
||||
$http.put('/checkout', data).then((res) => {
|
||||
if (this.source.guest_payment_address === null && this.source.guest_shipping_address === null) {
|
||||
this.source.guest_shipping_address = res.current.guest_shipping_address;
|
||||
this.source.guest_payment_address = res.current.guest_payment_address;
|
||||
} else {
|
||||
this.source[this.dialogAddress.type] = res.current[this.dialogAddress.type];
|
||||
}
|
||||
this.$message.success('{{ __('common.edit_success') }}');
|
||||
this.$refs['address-dialog'].closeAddressDialog()
|
||||
})
|
||||
} else {
|
||||
$http[type](url, form).then((res) => {
|
||||
this.$message.success(res.message);
|
||||
if (this.source.addresses.find(e => e.id == res.data.id)) {
|
||||
this.source.addresses[this.dialogAddress.index] = res.data
|
||||
} else {
|
||||
this.source.addresses.push(res.data)
|
||||
this.updateCheckout(res.data.id, this.dialogAddress.type)
|
||||
this.form[this.dialogAddress.type] = res.data.id
|
||||
}
|
||||
|
||||
this.dialogAddress.index = null;
|
||||
this.$forceUpdate()
|
||||
this.$refs['address-dialog'].closeAddressDialog()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
updateCheckout(id, key) {
|
||||
if (this.form[key] === id && key != 'same_as_shipping_address') {
|
||||
return
|
||||
}
|
||||
|
||||
if (key == 'shipping_address_id' && this.same_as_shipping_address) {
|
||||
this.form.payment_address_id = id
|
||||
}
|
||||
|
||||
this.form[key] = id
|
||||
|
||||
$http.put('/checkout', this.form).then((res) => {
|
||||
this.form = res.current
|
||||
this.source.totals = res.totals
|
||||
|
||||
this.isAllAddress = false
|
||||
this.isAllAddressPayment = false
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
@extends('layout.master')
|
||||
|
||||
@section('body-class', 'page-payment')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row mt-5 mb-5 justify-content-center">
|
||||
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 4])</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card order-wrap border">
|
||||
<div class="card-body main-body">
|
||||
<div class="order-top">
|
||||
<div class="left">
|
||||
<i class="bi bi-credit-card-2-back"></i>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3 class="order-title">{{ __('shop/checkout.payment.please_pay') }}</h3>
|
||||
<div class="order-info mb-4">
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ __('shop/checkout.payment.order_number') }}:<span class="fw-bold">{{ $order['number'] }}</span></td>
|
||||
<td>{{ __('shop/checkout.payment.amounts_payable') }}:<span class="fw-bold">{{ $order['total_format'] }}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ __('shop/checkout.payment.payment_method') }}:<span class="fw-bold">{{ $order['payment_method_name'] }}</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{!! $payment !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<div class="col-12 col-md-3">
|
||||
<div class="account-sides-info">
|
||||
<div class="head">
|
||||
<div class="portrait"><img src="{{ image_resize($customer->avatar, 200, 200) }}" class="img-fluid"></div>
|
||||
<div class="account-name">{{ $customer->name }}</div>
|
||||
<div class="account-email">{{ $customer->email }}</div>
|
||||
</div>
|
||||
|
||||
<nav class="list-group account-links">
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.index') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.index') }}">
|
||||
<span>{{ __('shop/account.index') }}</span></a>
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.edit.index') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.edit.index') }}">
|
||||
<span>{{ __('shop/account.edit.index') }}</span></a>
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.order.index') || equal_route('shop.account.order.show') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.order.index') }}">
|
||||
<span>{{ __('shop/account.order.index') }}</span></a>
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.addresses.index') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.addresses.index') }}">
|
||||
<span>{{ __('shop/account.addresses.index') }}</span></a>
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.wishlist.index') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.wishlist.index') }}">
|
||||
<span>{{ __('shop/account.wishlist.index') }}</span></a>
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.rma.index') || equal_route('shop.account.rma.show') ? 'active' : '' }}"
|
||||
href="{{ shop_route('account.rma.index') }}">
|
||||
<span>{{ __('shop/account.rma.index') }}</span></a>
|
||||
|
||||
@hook('account.sidebar.before.logout')
|
||||
|
||||
<a class="list-group-item d-flex justify-content-between align-items-center" href="{{ shop_route('logout') }}">
|
||||
<span>{{ __('common.sign_out') }}</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<div class="alert alert-{{ $type }} alert-dismissible">
|
||||
<i class="bi bi-check-circle-fill"></i>
|
||||
{{ $msg }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
@unless ($breadcrumbs->isEmpty())
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
@foreach ($breadcrumbs as $breadcrumb)
|
||||
|
||||
@if (isset($breadcrumb['url']) && $breadcrumb['url'])
|
||||
<li class="breadcrumb-item"><a href="{{ $breadcrumb['url'] }}">{{ $breadcrumb['title'] }}</a></li>
|
||||
@else
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ $breadcrumb['title'] }}</li>
|
||||
@endif
|
||||
|
||||
@endforeach
|
||||
</ol>
|
||||
</nav>
|
||||
@endunless
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<div class="d-flex flex-column align-center align-items-center mb-4">
|
||||
<img src="{{ asset('image/no-data.svg') }}" class="img-fluid wp-400">
|
||||
<div class="text-secondary fs-4 mb-3">{{ $text }}</div>
|
||||
@if ($link)
|
||||
<a href="{{ $link }}" class="btn btn-primary"><i class="bi bi-box-arrow-left"></i> {{ $btn }}</a>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
@if ($design)
|
||||
<div class="module-edit">
|
||||
<div class="edit-wrap">
|
||||
<div class="down" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('admin/builder.move_down') }}"><i class="bi bi-chevron-down"></i></div>
|
||||
<div class="up" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('admin/builder.move_up') }}"><i class="bi bi-chevron-up"></i></div>
|
||||
<div class="delete" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('common.delete') }}"><i class="bi bi-x-lg"></i></div>
|
||||
<div class="edit" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('common.edit') }}"><i class="bi bi-pencil-square"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info module-brand mb-3 mb-md-5">
|
||||
<div class="module-title">{{ $content['title'] }}</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($content['brands'] as $brand)
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<a href="{{ $brand['url'] }}" class="text-decoration-none">
|
||||
<div class="brand-item">
|
||||
<img src="{{ $brand['logo'] ?? asset('image/default/banner-1.png') }}" class="img-fluid">
|
||||
</div>
|
||||
<p class="text-center text-dark mb-4">{{ $brand['name'] }}</p>
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@if ($content['brands'])
|
||||
<div class="d-flex justify-content-center mt-4">
|
||||
<a class="btn btn-outline-secondary btn-lg" href="{{ shop_route('brands.index') }}">{{ __('common.show_all') }}</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info mb-3 mb-md-5">
|
||||
@if ($content['title'])
|
||||
<div class="module-title">{{ $content['title'] }}</div>
|
||||
@endif
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($content['images'] as $image)
|
||||
<div class="col-6 col-md-4 col-lg-2">
|
||||
<a href="{{ $image['link'] ?: 'javascript:void(0)' }}" class="text-decoration-none">
|
||||
<div class="image-item d-flex justify-content-center mb-3">
|
||||
<img src="{{ $image['image'] }}" class="img-fluid">
|
||||
</div>
|
||||
@if ($image['text'])
|
||||
<p class="text-center text-dark mb-2 mt-2 fs-5">{{ $image['text'] }}</p>
|
||||
@endif
|
||||
@if ($image['sub_text'])
|
||||
<p class="text-center text-secondary my-2">{{ $image['sub_text'] }}</p>
|
||||
@endif
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-image-banner module-info {{ !$content['full'] ? 'container' : '' }} mb-3 mb-md-5 d-flex justify-content-center">
|
||||
<div class="container{{ $content['full'] ? '-fluid' : '' }} d-flex justify-content-center">
|
||||
<a href="{{ $content['images'][0]['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $content['images'][0]['image'] }}" class="img-fluid"></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-image-banner module-info mb-3 mb-md-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($content['images'] as $item)
|
||||
<div class="col-12 col-md-6 mb-2 mb-xl-0"><a href="{{ $item['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $item['image'] }}" class="img-fluid"></a></div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-image-banner module-info mb-3 mb-md-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($content['images'] as $item)
|
||||
<div class="col-12 col-md-4"><a href="{{ $item['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $item['image'] }}" class="img-fluid"></a></div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-image-plus module-info mb-3 mb-md-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-12 mb-3 mb-md-0">
|
||||
<a href="{{ $content['images'][0]['link']['link'] ?? '' }}"><img src="{{ $content['images'][0]['image'] }}" class="img-fluid"></a>
|
||||
</div>
|
||||
<div class="col-md-6 col-12">
|
||||
<div class="module-image-plus-top">
|
||||
<a href="{{ $content['images'][1]['link']['link'] ?? '' }}"><img src="{{ $content['images'][1]['image'] }}" class="img-fluid"></a>
|
||||
<a href="{{ $content['images'][2]['link']['link'] ?? '' }}" class="right"><img src="{{ $content['images'][2]['image'] }}" class="img-fluid"></a>
|
||||
</div>
|
||||
<div class="module-image-plus-bottom"><a href="{{ $content['images'][3]['link']['link'] ?? '' }}"><img src="{{ $content['images'][3]['image'] }}" class="img-fluid"></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info module-product mb-3 mb-md-5 swiper-style-plus">
|
||||
<div class="container position-relative">
|
||||
<div class="module-title">{{ $content['title'] }}</div>
|
||||
@if ($content['products'])
|
||||
<div class="swiper module-product-{{ $module_id }} module-slideshow">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($content['products'] as $product)
|
||||
<div class="swiper-slide">
|
||||
@include('shared.product')
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination rectangle module-product-{{ $module_id }}-pagination"></div>
|
||||
<div class="swiper-button-prev product-prev"></div>
|
||||
<div class="swiper-button-next product-next"></div>
|
||||
@elseif (!$content['products'] and $design)
|
||||
<div class="row">
|
||||
@for ($s = 0; $s < 4; $s++)
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<div class="product-wrap">
|
||||
<div class="image"><a href="javascript:void(0)"><img src="{{ asset('catalog/placeholder.png') }}" class="img-fluid"></a></div>
|
||||
<div class="product-name">请配置商品</div>
|
||||
<div class="product-price">
|
||||
<span class="price-new">66.66</span>
|
||||
<span class="price-lod">99.99</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endfor
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Swiper ('.module-product-{{ $module_id }}', {
|
||||
watchSlidesProgress: true,
|
||||
breakpoints:{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
slidesPerGroup: 2,
|
||||
spaceBetween: 10,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
slidesPerGroup: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
},
|
||||
spaceBetween: 30,
|
||||
// 如果需要分页器
|
||||
pagination: {
|
||||
el: '.module-product-{{ $module_id }}-pagination',
|
||||
clickable: true,
|
||||
},
|
||||
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.product-next',
|
||||
prevEl: '.product-prev',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info mb-3 mb-md-5">
|
||||
{!! $content['data'] !!}
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
@push('header')
|
||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||
@endpush
|
||||
|
||||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info mb-3 mb-md-5 {{ !$content['full'] ? 'container' : '' }}">
|
||||
<div class="swiper module-swiper-{{ $module_id }} module-slideshow">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach($content['images'] as $image)
|
||||
<div class="swiper-slide">
|
||||
<a href="{{ $image['link']['link'] ?: 'javascript:void(0)' }}" class="d-flex justify-content-center"><img src="{{ $image['image'] }}" class="img-fluid"></a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="swiper-pagination slideshow-pagination-{{ $module_id }}"></div>
|
||||
<div class="swiper-button-prev slideshow-btnprev-{{ $module_id }}"></div>
|
||||
<div class="swiper-button-next slideshow-btnnext-{{ $module_id }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Swiper ('.module-swiper-{{ $module_id }}', {
|
||||
loop: '{{ count($content['images']) > 1 ? true : false }}', // 循环模式选项
|
||||
autoplay: true,
|
||||
pauseOnMouseEnter: true,
|
||||
clickable :true,
|
||||
|
||||
// 如果需要分页器
|
||||
pagination: {
|
||||
el: '.slideshow-pagination-{{ $module_id }}',
|
||||
clickable :true
|
||||
},
|
||||
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.slideshow-btnnext-{{ $module_id }}',
|
||||
prevEl: '.slideshow-btnprev-{{ $module_id }}',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
|
||||
@include('design._partial._module_tool')
|
||||
|
||||
<div class="module-info module-tab-product">
|
||||
<div class="module-title">{{ $content['title'] }}</div>
|
||||
<div class="container">
|
||||
@if ($content['tabs'])
|
||||
<div class="nav justify-content-center mb-3">
|
||||
@foreach ($content['tabs'] as $key => $tabs)
|
||||
<a class="nav-link {{ $loop->first ? 'active' : '' }}" href="#tab-product-{{ $loop->index }}" data-bs-toggle="tab">{{ $tabs['title'] }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
@foreach ($content['tabs'] as $products)
|
||||
<div class="tab-pane fade show {{ $loop->first ? 'active' : '' }}" id="tab-product-{{ $loop->index }}">
|
||||
<div class="row">
|
||||
@if ($products['products'])
|
||||
@foreach ($products['products'] as $product)
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
@include('shared.product')
|
||||
</div>
|
||||
@endforeach
|
||||
@elseif (!$products['products'] and $design)
|
||||
@for ($s = 0; $s < 8; $s++)
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<div class="product-wrap">
|
||||
<div class="image"><a href="javascript:void(0)"><img src="{{ asset('catalog/placeholder.png') }}" class="img-fluid"></a></div>
|
||||
<div class="product-name">请配置商品</div>
|
||||
<div class="product-price">
|
||||
<span class="price-new">66.66</span>
|
||||
<span class="price-lod">99.99</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endfor
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Unauthorized'))
|
||||
@section('code', '401')
|
||||
@section('message', __('Unauthorized'))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Forbidden'))
|
||||
@section('code', '403')
|
||||
@section('message', __($exception->getMessage() ?: 'Forbidden'))
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@extends('errors.layout')
|
||||
@section('title', __('common.error_page'))
|
||||
|
||||
@section('content')
|
||||
<x-shop-no-data
|
||||
text="{{ __('common.error_page') }}"
|
||||
link="{{ request()->headers->get('referer') ? 'javascript:history.go(-1)' : '/' }}"
|
||||
btn="{{ __('common.error_page_btn') }}" />
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Page Expired'))
|
||||
@section('code', '419')
|
||||
@section('message', __('Page Expired'))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Too Many Requests'))
|
||||
@section('code', '429')
|
||||
@section('message', __('Too Many Requests'))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Server Error'))
|
||||
@section('code', '500')
|
||||
@section('message', __('Server Error'))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Service Unavailable'))
|
||||
@section('code', '503')
|
||||
@section('message', __('Service Unavailable'))
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title')</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('/build/beike/shop/default/css/bootstrap.css') }}">
|
||||
</head>
|
||||
|
||||
<body class="page-400">
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
@yield('content')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,17 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-home')
|
||||
@section('content')
|
||||
|
||||
<div class="modules-box">
|
||||
|
||||
@hook('footer.modules.before')
|
||||
|
||||
@foreach($modules as $module)
|
||||
@include($module['view_path'], $module)
|
||||
@endforeach
|
||||
|
||||
@hook('footer.modules.after')
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<footer>
|
||||
@php
|
||||
$locale = locale();
|
||||
@endphp
|
||||
|
||||
@hook('footer.services.before')
|
||||
|
||||
@if ($footer_content['services']['enable'])
|
||||
<div class="services-wrap">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach ($footer_content['services']['items'] as $item)
|
||||
<div class="col-lg-3 col-md-6 col-12">
|
||||
<div class="service-item my-1">
|
||||
<div class="icon"><img src="{{ image_resize($item['image'], 80, 80) }}" class="img-fluid"></div>
|
||||
<div class="text">
|
||||
<p class="title">{{ $item['title'][locale()] ?? '' }}</p>
|
||||
<p class="sub-title">{{ $item['sub_title'][locale()] ?? '' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@hook('footer.services.after')
|
||||
|
||||
<div class="container">
|
||||
<div class="footer-content">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-3">
|
||||
<div class="footer-content-left">
|
||||
<div class="logo"><a href="http://"><img
|
||||
src="{{ image_origin($footer_content['content']['intro']['logo']) }}" class="img-fluid"></a></div>
|
||||
<div class="text tinymce-format-p">{!! $footer_content['content']['intro']['text'][$locale] ?? '' !!}</div>
|
||||
</div>
|
||||
</div>
|
||||
@for ($i = 1; $i <= 3; $i++)
|
||||
@php
|
||||
$link = $footer_content['content']['link' . $i];
|
||||
@endphp
|
||||
<div class="col-6 col-sm footer-content-link{{ $i }}">
|
||||
<h6 class="text-uppercase text-dark mb-3">{{ $link['title'][$locale] ?? '' }}</h6>
|
||||
<ul class="list-unstyled">
|
||||
@foreach ($link['links'] as $item)
|
||||
@if ($item['link'])
|
||||
<li class="lh-lg mb-2">
|
||||
<a href="{{ $item['link'] }}" @if (isset($item['new_window']) && $item['new_window']) target="_blank" @endif>
|
||||
{{ $item['text'] }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endfor
|
||||
|
||||
@hook('footer.contact.before')
|
||||
@hookwrapper('footer.contact')
|
||||
<div class="col-12 col-md-3 footer-content-contact">
|
||||
<h6 class="text-uppercase text-dark mb-3">{{ __('common.contact_us') }}</h6>
|
||||
<ul class="list-unstyled">
|
||||
@if ($footer_content['content']['contact']['email'])
|
||||
<li class="lh-lg mb-2"><i class="bi bi-envelope-fill"></i> {{ $footer_content['content']['contact']['email'] }}</li>
|
||||
@endif
|
||||
@if ($footer_content['content']['contact']['telephone'])
|
||||
<li class="lh-lg mb-2"><i class="bi bi-telephone-fill"></i> {{ $footer_content['content']['contact']['telephone'] }}</li>
|
||||
@endif
|
||||
@if ($footer_content['content']['contact']['address'][$locale] ?? '')
|
||||
<li class="lh-lg mb-2"><i class="bi bi-geo-alt-fill"></i> {{ $footer_content['content']['contact']['address'][$locale] ?? '' }}</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
@hook('footer.contact.after')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@hookwrapper('footer.copyright')
|
||||
<div class="footer-bottom">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<div class="d-flex">
|
||||
Powered By
|
||||
{!! $footer_content['bottom']['copyright'][$locale] ?? '' !!}
|
||||
</div>
|
||||
</div>
|
||||
@if (isset($footer_content['bottom']['image']) && $footer_content['bottom']['image'])
|
||||
<div class="col-auto right-img">
|
||||
<img src="{{ image_origin($footer_content['bottom']['image']) }}" class="img-fluid">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
|
||||
</footer>
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
<header>
|
||||
<div class="top-wrap">
|
||||
<div class="container d-flex justify-content-between align-items-center">
|
||||
<div class="left d-flex align-items-center">
|
||||
@hookwrapper('header.top.currency')
|
||||
@if (currencies()->count() > 1)
|
||||
<div class="dropdown">
|
||||
<a class="btn dropdown-toggle ps-0" href="javascript:void(0)" role="button" id="currency-dropdown" data-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
@foreach (currencies() as $currency)
|
||||
@if ($currency->code == current_currency_code())
|
||||
@if ($currency->symbol_left)
|
||||
{{ $currency->symbol_left }}
|
||||
@endif
|
||||
{{ $currency->name }}
|
||||
@if ($currency->symbol_right)
|
||||
{{ $currency->symbol_right }}
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu" aria-labelledby="currency-dropdown">
|
||||
@foreach (currencies() as $currency)
|
||||
<a class="dropdown-item"
|
||||
href="{{ shop_route('currency.switch', [$currency->code]) }}">
|
||||
@if ($currency->symbol_left)
|
||||
{{ $currency->symbol_left }}
|
||||
@endif
|
||||
{{ $currency->name }}
|
||||
@if ($currency->symbol_right)
|
||||
{{ $currency->symbol_right }}
|
||||
@endif
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('header.top.language')
|
||||
@if (count($languages) > 1)
|
||||
<div class="dropdown">
|
||||
<a class="btn dropdown-toggle" href="javascript:void(0)" role="button" id="language-dropdown" data-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{{ current_language()->name }}
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu" aria-labelledby="language-dropdown">
|
||||
@foreach ($languages as $language)
|
||||
<a class="dropdown-item" href="{{ shop_route('lang.switch', [$language->code]) }}">
|
||||
{{ $language->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endhookwrapper
|
||||
</div>
|
||||
|
||||
@if (system_setting('base.telephone', ''))
|
||||
<div class="right nav">
|
||||
@hookwrapper('header.top.telephone')
|
||||
<span class="px-2"><i class="bi bi-telephone-forward me-2"></i> {{ system_setting('base.telephone') }}</span>
|
||||
@endhookwrapper
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-content d-none d-lg-block py-3">
|
||||
<div class="container navbar-expand-lg">
|
||||
@hookwrapper('header.menu.logo')
|
||||
<div class="logo"><a href="{{ shop_route('home.index') }}">
|
||||
<img src="{{ image_origin(system_setting('base.logo')) }}" class="img-fluid"></a>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
<div class="menu-wrap">
|
||||
@if (!is_mobile())
|
||||
@include('shared.menu-pc')
|
||||
@endif
|
||||
</div>
|
||||
<div class="right-btn">
|
||||
<ul class="navbar-nav flex-row">
|
||||
@hookwrapper('header.menu.icon')
|
||||
<li class="nav-item"><a href="#offcanvas-search-top" data-bs-toggle="offcanvas"
|
||||
aria-controls="offcanvasExample" class="nav-link"><i class="iconfont"></i></a></li>
|
||||
<li class="nav-item"><a href="{{ shop_route('account.wishlist.index') }}" class="nav-link"><i
|
||||
class="iconfont"></i></a></li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="{{ shop_route('account.index') }}" class="nav-link"><i class="iconfont"></i></a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
@auth('web_shop')
|
||||
<li class="dropdown-item">
|
||||
<h6 class="mb-0">{{ current_customer()->name }}</h6>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="dropdown-divider opacity-100">
|
||||
</li>
|
||||
<li><a href="{{ shop_route('account.index') }}" class="dropdown-item"><i class="bi bi-person me-1"></i>
|
||||
{{ __('shop/account.index') }}</a></li>
|
||||
<li><a href="{{ shop_route('account.order.index') }}" class="dropdown-item"><i
|
||||
class="bi bi-clipboard-check me-1"></i> {{ __('shop/account.order.index') }}</a></li>
|
||||
<li><a href="{{ shop_route('account.wishlist.index') }}" class="dropdown-item"><i
|
||||
class="bi bi-heart me-1"></i> {{ __('shop/account.wishlist.index') }}</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider opacity-100">
|
||||
</li>
|
||||
<li><a href="{{ shop_route('logout') }}" class="dropdown-item"><i class="bi bi-box-arrow-left me-1"></i>
|
||||
{{ __('common.sign_out') }}</a></li>
|
||||
@else
|
||||
<li><a href="{{ shop_route('login.index') }}" class="dropdown-item"><i
|
||||
class="bi bi-box-arrow-right me-1"></i>{{ __('shop/login.login_and_sign') }}</a></li>
|
||||
@endauth
|
||||
</ul>
|
||||
</li>
|
||||
@endhookwrapper
|
||||
<li class="nav-item">
|
||||
<a class="nav-link position-relative" {{ !equal_route('shop.carts.index') ? 'data-bs-toggle=offcanvas' : '' }}
|
||||
href="{{ !equal_route('shop.carts.index') ? '#offcanvas-right-cart' : 'javascript:void(0);' }}" role="button"
|
||||
aria-controls="offcanvasExample">
|
||||
<i class="iconfont"></i>
|
||||
<span class="cart-badge-quantity"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-mobile d-lg-none">
|
||||
<div class="mobile-content">
|
||||
<div class="left">
|
||||
<div class="mobile-open-menu"><i class="bi bi-list"></i></div>
|
||||
<div class="mobile-open-search" href="#offcanvas-search-top" data-bs-toggle="offcanvas" aria-controls="offcanvasExample">
|
||||
<i class="iconfont"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center"><a href="{{ shop_route('home.index') }}">
|
||||
<img src="{{ image_origin(system_setting('base.logo')) }}" class="img-fluid"></a>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a href="{{ shop_route('account.index') }}" class="nav-link"><i class="iconfont"></i></a>
|
||||
<a href="{{ shop_route('carts.index') }}" class="nav-link ms-3"><i class="iconfont"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas-mobile-menu">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasWithBothOptionsLabel">{{ __('common.menu') }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body mobile-menu-wrap">
|
||||
@if (is_mobile())
|
||||
@include('shared.menu-mobile')
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!equal_route('shop.carts.index'))
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-right-cart" aria-labelledby="offcanvasRightLabel"></div>
|
||||
@endif
|
||||
|
||||
<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvas-search-top" aria-labelledby="offcanvasTopLabel">
|
||||
<div class="offcanvas-header">
|
||||
<input type="text" class="form-control input-group-lg border-0 fs-4" focus
|
||||
placeholder="{{ __('common.input') }}" aria-label="Type your search here" aria-describedby="button-addon2">
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<div align="center">
|
||||
<div class="" style="margin-left: 8px; margin-top: 8px; margin-bottom: 8px; margin-right: 8px;">
|
||||
<div style="word-break: break-all;box-sizing:border-box;text-align:center;min-width:320px; max-width:660px; border:1px solid #f6f6f6; background-color:#f7f8fa; margin:auto; padding:20px 0 30px; font-family:'helvetica neue',PingFangSC-Light,arial,'hiragino sans gb','microsoft yahei ui','microsoft yahei',simsun,sans-serif">
|
||||
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse">
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3%;max-width:30px;"></td>
|
||||
<td style="max-width:600px;">
|
||||
<div style="height: 35px;display: block;max-width: 200px;">
|
||||
<a href="{{ shop_route('home.index') }}" style="display: block;height: 35px;display: block;max-width: 200px;">
|
||||
<img border="0" src="{{ image_origin(system_setting('base.logo')) }}" style="max-width:100%; max-height: 100%;display">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p style="height:2px;background-color: #fd560f;border: 0;font-size:0;padding:0;width:100%;margin-top:10px;"></p>
|
||||
<div style="background-color:#fff; padding:23px 0 20px;box-shadow: 0px 1px 1px 0px rgba(122, 55, 55, 0.2);text-align:left;">
|
||||
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse;text-align:left;">
|
||||
@yield('content')
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px; text-align:center; font-size:12px; line-height:18px; color:#999">
|
||||
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse">
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
<td style="max-width:540px;">
|
||||
<p style="max-width: 100%; margin:auto;font-size:12px;color:#999;text-align:center;line-height:22px;">
|
||||
{{ config('app.name') }} © {{ date('Y') }} All Rights Reserved
|
||||
</p>
|
||||
</td>
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:3%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<!doctype html>
|
||||
<html lang="{{ locale() }}">
|
||||
<head>
|
||||
<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=AW-11146062373"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'AW-11146062373'); </script>
|
||||
<!-- Event snippet for Website sale conversion page --> <script> gtag('event', 'conversion', { 'send_to': 'AW-11146062373/ilbpCKSvzZkYEKXU7cIp', 'transaction_id': '' }); </script>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>@yield('title', system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') )</title><!-- . ' Powered By BeikeShop' -->
|
||||
<meta name="keywords" content="@yield('keywords', system_setting('base.meta_keywords'))">
|
||||
<meta name="description" content="@yield('description', system_setting('base.meta_description'))">
|
||||
<meta name="generator" content="BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }})">
|
||||
<base href="{{ $shop_base_url }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/css/bootstrap.css') }}">
|
||||
<script src="{{ asset('vendor/jquery/jquery-3.6.0.min.js') }}"></script>
|
||||
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
|
||||
<link rel="shortcut icon" href="{{ image_origin(system_setting('base.favicon')) }}">
|
||||
<script src="{{ asset('vendor/bootstrap/5.1.3/js/bootstrap.bundle.min.js') }}"></script>
|
||||
<script src="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/js/app.js') }}"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/css/app.css') }}">
|
||||
@if (system_setting('base.head_code'))
|
||||
{!! system_setting('base.head_code') !!}
|
||||
@endif
|
||||
@stack('header')
|
||||
</head>
|
||||
<body class="@yield('body-class')">
|
||||
@if (!request('iframe'))
|
||||
@include('layout.header')
|
||||
@endif
|
||||
|
||||
@yield('content')
|
||||
|
||||
@if (!request('iframe'))
|
||||
@include('layout.footer')
|
||||
@endif
|
||||
|
||||
<script>
|
||||
const config = {
|
||||
isLogin: !!{{ current_customer()->id ?? 'null' }},
|
||||
guestCheckout: !!{{ system_setting('base.guest_checkout', 1) }}
|
||||
}
|
||||
|
||||
// 如果页面使用了ElementUI,且当前语言不是中文,则加载对应的语言包
|
||||
@if (locale() != 'zh_cn')
|
||||
if (typeof ELEMENT !== 'undefined') {
|
||||
const elLocale = '{{ asset('vendor/element-ui/language/'.locale().'.js') }}';
|
||||
document.write("<script src='" + elLocale + "'><\/script>")
|
||||
|
||||
$(function () {
|
||||
setTimeout(() => {
|
||||
ELEMENT.locale(ELEMENT.lang['{{ locale() }}'])
|
||||
}, 0);
|
||||
})
|
||||
}
|
||||
@endif
|
||||
</script>
|
||||
|
||||
@stack('add-scripts')
|
||||
</body>
|
||||
<!-- BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }}) -->
|
||||
</html>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<div class="product-wrap">
|
||||
<div class="image"><img src="{{ $product['image'] }}" class="img-fluid"></div>
|
||||
<div class="product-name">{{ $product['name'] }}</div>
|
||||
<div class="product-price">
|
||||
<span class="price-new">$55.00</span>
|
||||
<span class="price-lod">$125.00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
@extends('layout.mail')
|
||||
|
||||
@section('content')
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
<td style="max-width:480px;text-align:left;">
|
||||
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
|
||||
{{ __('mail.retrieve_password_title') }}
|
||||
</h1>
|
||||
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
|
||||
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.retrieve_password_text') }}
|
||||
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
|
||||
</span>
|
||||
</p>
|
||||
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
|
||||
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('shop/forgotten.verification_code') }}:
|
||||
<span style="font-weight: bold;">{{ $code }}</span>
|
||||
</span>
|
||||
</p>
|
||||
<p style="font-size: 14px; color: rgb(51, 51, 51); line-height: 24px; margin: 6px 0px 0px; word-wrap: break-word; word-break: break-all;">
|
||||
<a href="{{ $is_admin ? admin_route('forgotten.index') : shop_route('forgotten.index') }}?code={{ $code }}&email={{ $email }}" title="" style="font-size: 16px; line-height: 45px; display: block; background-color: #fd560f; color: rgb(255, 255, 255); text-align: center; text-decoration: none; margin-top: 20px; border-radius: 3px;">
|
||||
{{ __('mail.retrieve_password_btn') }}
|
||||
</a>
|
||||
</p>
|
||||
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
|
||||
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
|
||||
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
|
||||
{{ __('mail.sincerely') }}
|
||||
<br>
|
||||
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
@extends('layout.mail')
|
||||
|
||||
@section('content')
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
<td style="max-width:480px;text-align:left;">
|
||||
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
|
||||
{{ __('mail.order_success') }}
|
||||
</h1>
|
||||
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
|
||||
{{ __('mail.customer_name', ['name' => $order->customer_name]) }}!
|
||||
</p>
|
||||
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
|
||||
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.order_success') }}
|
||||
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
|
||||
</span>
|
||||
</p>
|
||||
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_details') }}:</p>
|
||||
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; background-color:#f8f9fa">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_number') }}</td>
|
||||
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_date') }}</td>
|
||||
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.state') }}</td>
|
||||
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_amount') }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding:7px;font-size:13px;">{{ $order->number }}</td>
|
||||
<td style="padding:7px;font-size:13px;">{{ $order->created_at }}</td>
|
||||
<td style="padding:7px;font-size:13px;">
|
||||
{{ __("common.order.{$order->status}") }}
|
||||
</td>
|
||||
<td style="padding:7px;font-size:13px;">{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_items') }}:</p>
|
||||
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px;width: 80px;text-align:center">{{ __('product.image') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.name') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.product_quantity') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.price') }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($order->orderProducts as $product)
|
||||
<tr>
|
||||
<td style="border: 1px solid #eee;padding:4px;text-align:center"><img style="width: 60px; height: 60px;" src="{{ image_origin($product->image) }}"></td>
|
||||
<td style="font-size:12px; border: 1px solid #eee; width: 50%;padding:4px;">{{ $product->name }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $product->quantity }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_total') }}:</p>
|
||||
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse;border:1px solid #eee;">
|
||||
<tbody>
|
||||
@foreach ($order->orderTotals as $total)
|
||||
<tr>
|
||||
<td style="border: 1px solid #eee;padding:4px; background-color: #f8f9fa;font-size:13px;padding: 7px;width: 30%">{{ $total->title }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size:13px;padding: 7px"><strong>{{ currency_format($total->value, $order->currency_code, $order->currency_value) }}</strong></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
|
||||
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
|
||||
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
|
||||
{{ __('mail.sincerely') }}
|
||||
<br>
|
||||
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
@extends('layout.mail')
|
||||
|
||||
@section('content')
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
<td style="max-width:480px;text-align:left;">
|
||||
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
|
||||
{{ __('mail.order_update') }}
|
||||
</h1>
|
||||
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
|
||||
{{ __('mail.customer_name', ['name' => $order->customer_name]) }}
|
||||
</p>
|
||||
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
|
||||
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.order_update_status', ['number' => $order->number]) }}:
|
||||
<span style="font-weight: bold;">{{ __("common.order.{$order->status}") }}</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_items') }}:</p>
|
||||
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px;width: 80px;text-align:center">{{ __('product.image') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.name') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.product_quantity') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.price') }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($order->orderProducts as $product)
|
||||
<tr>
|
||||
<td style="border: 1px solid #eee;padding:4px;text-align:center"><img style="width: 60px; height: 60px;" src="{{ image_origin($product->image) }}"></td>
|
||||
<td style="font-size:12px; border: 1px solid #eee; width: 50%;padding:4px;">{{ $product->name }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $product->quantity }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@if ($order->orderShipments->count())
|
||||
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('order.order_shipments') }}</p>
|
||||
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.express_company') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.express_number') }}</td>
|
||||
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.history_created_at') }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($order->orderShipments as $ship)
|
||||
<tr>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->express_company }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->express_number }}</td>
|
||||
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->created_at }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
|
||||
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
|
||||
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
|
||||
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
|
||||
{{ __('mail.sincerely') }}
|
||||
<br>
|
||||
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
@extends('layout.mail')
|
||||
|
||||
@section('content')
|
||||
<tbody>
|
||||
<tr style="font-weight:300">
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
<td style="max-width:480px;text-align:left;">
|
||||
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
|
||||
{{ __('mail.welcome_register') }} {{ config('app.name') }}
|
||||
</h1>
|
||||
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
|
||||
{{ __('mail.customer_name', ['name' => $customer->name]) }}
|
||||
</p>
|
||||
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
|
||||
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.register_end') }}
|
||||
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
|
||||
</span>
|
||||
</p>
|
||||
<p style="font-size: 14px; color: rgb(51, 51, 51); line-height: 24px; margin: 6px 0px 0px; word-wrap: break-word; word-break: break-all;">
|
||||
<a href="{{ config('app.url') }}" title="" style="font-size: 16px; line-height: 45px; display: block; background-color: #fd560f; color: rgb(255, 255, 255); text-align: center; text-decoration: none; margin-top: 20px; border-radius: 3px;">
|
||||
{{ __('mail.btn_buy_now') }}
|
||||
</a>
|
||||
</p>
|
||||
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
|
||||
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
|
||||
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
|
||||
{{ __('mail.sincerely') }}
|
||||
<br>
|
||||
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
<td style="width:3.2%;max-width:30px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories-home')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
{{ $breadcrumb->render() }}
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-12">
|
||||
<div class="card mb-4 shadow-sm p-3 h-min-600">
|
||||
<div class="card-body">
|
||||
@foreach ($active_pages as $page)
|
||||
<div>
|
||||
<h5 class="card-title mb-2"><a class="text-black" href="{{ shop_route('pages.show', [$page->id]) }}">{{ $page->description->title }}</a></h5>
|
||||
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
|
||||
@if ($page->description->summary)
|
||||
<p class="card-text mb-3">{{ $page->description->summary ?? '' }}</p>
|
||||
@endif
|
||||
<div class="text-danger"><a href="{{ shop_route('pages.show', [$page->id]) }}">{{ __('shop/account.check_details') }}<i class="bi bi-arrow-right-short"></i></a></div>
|
||||
</div>
|
||||
|
||||
@if (!$loop->last)
|
||||
<hr class="my-4">
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($active_page_categories)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories-home')
|
||||
@section('title', $category->description->meta_title ?: system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 -
|
||||
BeikeShop官网') . ' - ' . $category->description->name)
|
||||
@section('keywords', $category->description->meta_keywords ?: system_setting('base.meta_keyword'))
|
||||
@section('description', $category->description->meta_description ?: system_setting('base.meta_description'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page_category" :value="$category['id']" />
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-12">
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h3>{{ $category->description->title }}</h3>
|
||||
<div>{{ $category->description->summary }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body">
|
||||
@if ($category_pages->count() > 0)
|
||||
@foreach ($category_pages as $page)
|
||||
<div>
|
||||
<h5 class="card-title mb-2"><a class="text-black"
|
||||
href="{{ type_route('page', $page) }}">{{ $page->description->title }}</a></h5>
|
||||
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
|
||||
@if ($page->description->summary)
|
||||
<p class="card-text mb-4">{{ $page->description->summary ?? '' }}</p>
|
||||
@endif
|
||||
<div class="text-danger"><a
|
||||
href="{{ type_route('page', $page) }}">{{ __('shop/account.check_details') }}<i
|
||||
class="bi bi-arrow-right-short"></i></a></div>
|
||||
</div>
|
||||
|
||||
@if (!$loop->last)
|
||||
<hr class="my-4">
|
||||
@endif
|
||||
@endforeach
|
||||
@else
|
||||
<x-shop-no-data />
|
||||
@endif
|
||||
|
||||
{{ $category_pages->links('shared/pagination/bootstrap-4') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($active_page_categories)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ type_route('page_category', $category) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-pages')
|
||||
@section('title', $page->description->meta_title ?: $page->description->title)
|
||||
@section('keywords', $page->description->meta_keywords)
|
||||
@section('description', $page->description->meta_description)
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page" :value="$page['id']" />
|
||||
<div class="row">
|
||||
<div class="{{ $page->category ? "col-lg-9 col-12" : 'col-12' }}">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body h-min-600 p-lg-4">
|
||||
<h2 class="mb-3">{{ $page->description->title }}</h2>
|
||||
<div class="text-secondary opacity-75 mb-4">
|
||||
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg> {{ __('page_category.author') }}: {{ $page->author }}</span>
|
||||
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> {{ __('page_category.created_at') }}: {{ $page->created_at }}</span>
|
||||
<span><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg> {{ __('page_category.views') }}: {{ $page->views }}</span>
|
||||
</div>
|
||||
{!! $page_format['content'] !!}
|
||||
|
||||
|
||||
@if ($products)
|
||||
<div class="relations-wrap mt-5">
|
||||
<div class="container position-relative">
|
||||
<div class="title text-center fs-4 mb-4">{{ __('admin/product.product_relations') }}</div>
|
||||
<div class="product swiper-style-plus">
|
||||
<div class="swiper relations-swiper">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($products as $item)
|
||||
<div class="swiper-slide">
|
||||
@include('shared.product', ['product' => $item])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination relations-pagination"></div>
|
||||
<div class="swiper-button-prev relations-swiper-prev"></div>
|
||||
<div class="swiper-button-next relations-swiper-next"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($page->category)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var relationsSwiper = new Swiper ('.relations-swiper', {
|
||||
watchSlidesProgress: true,
|
||||
breakpoints:{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 10,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
},
|
||||
spaceBetween: 30,
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.relations-swiper-next',
|
||||
prevEl: '.relations-swiper-prev',
|
||||
},
|
||||
|
||||
// 如果需要分页器
|
||||
pagination: {
|
||||
el: '.relations-pagination',
|
||||
clickable: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-pages')
|
||||
@section('title', $page['meta_title'] ?: $page['title'])
|
||||
@section('keywords', $page['meta_keywords'])
|
||||
@section('description', $page['meta_description'])
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page" :value="$page['id']" />
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
{!! $page_format['content'] !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-product')
|
||||
@section('title', $product['meta_title'] ?: $product['name'])
|
||||
@section('keywords', $product['meta_keywords'] ?: system_setting('base.meta_keyword'))
|
||||
@section('description', $product['meta_description'] ?: system_setting('base.meta_description'))
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container" id="product-app" v-cloak>
|
||||
<x-shop-breadcrumb type="product" :value="$product['id']" />
|
||||
|
||||
<div class="row mb-5 mt-3 mt-md-0" id="product-top">
|
||||
<div class="col-12 col-lg-6 mb-3">
|
||||
<div class="product-image d-flex align-items-start">
|
||||
@if(!is_mobile())
|
||||
<div class="left" v-if="images.length">
|
||||
<div class="swiper" id="swiper">
|
||||
<div class="swiper-wrapper">
|
||||
<div class="swiper-slide" :class="!index ? 'active' : ''" v-for="image, index in images">
|
||||
<a href="javascript:;" :data-image="image.preview" :data-zoom-image="image.popup">
|
||||
<img :src="image.thumb" class="img-fluid">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pager">
|
||||
<div class="swiper-button-next new-feature-slideshow-next"></div>
|
||||
<div class="swiper-button-prev new-feature-slideshow-prev"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right" id="zoom">
|
||||
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
||||
</div>
|
||||
@else
|
||||
<div class="swiper" id="swiper-mobile">
|
||||
<div class="swiper-wrapper">
|
||||
<div class="swiper-slide" v-for="image, index in images">
|
||||
<img :src="image.preview" class="img-fluid">
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination mobile-pagination"></div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="peoduct-info">
|
||||
@hookwrapper('product.detail.name')
|
||||
<h1 class="mb-4 product-name">{{ $product['name'] }}</h1>
|
||||
@endhookwrapper
|
||||
<div class="price-wrap d-flex align-items-end">
|
||||
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}@{{ price_setting }}</div>
|
||||
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||
@{{ product.origin_price_format }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stock-and-sku mb-4">
|
||||
@hookwrapper('product.detail.quantity')
|
||||
<div class="d-flex">
|
||||
<span class="title text-muted">{{ __('product.quantity') }}:</span>
|
||||
<div :class="product.quantity > 0 ? 'text-success' : 'text-secondary'">
|
||||
<template v-if="product.quantity > 0">{{ __('shop/products.in_stock') }}</template>
|
||||
<template v-else>{{ __('shop/products.out_stock') }}</template>
|
||||
</div>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
|
||||
@if ($product['brand_id'])
|
||||
@hookwrapper('product.detail.brand')
|
||||
<div class="d-flex">
|
||||
<span class="title text-muted">{{ __('product.brand') }}:</span>
|
||||
<a href="{{ shop_route('brands.show', $product['brand_id']) }}">{{ $product['brand_name'] }}</a>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
@endif
|
||||
|
||||
@hookwrapper('product.detail.sku')
|
||||
<div class="d-flex"><span class="title text-muted">SKU:</span>@{{ product.sku }}</div>
|
||||
@endhookwrapper
|
||||
|
||||
@hookwrapper('product.detail.model')
|
||||
<div class="d-flex" v-if="product.model"><span class="title text-muted">{{ __('shop/products.model') }}:</span> @{{ product.model }}</div>
|
||||
@endhookwrapper
|
||||
</div>
|
||||
@if (0)
|
||||
<div class="rating-wrap d-flex">
|
||||
<div class="rating">
|
||||
@for ($i = 0; $i < 5; $i++)
|
||||
<i class="iconfont"></i>
|
||||
@endfor
|
||||
</div>
|
||||
<span class="text-muted">132 reviews</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="variables-wrap mb-4" v-if="source.variables.length">
|
||||
<div class="variable-group mb-2" v-for="variable, variable_index in source.variables" :key="variable_index">
|
||||
<p class="mb-2">@{{ variable.name }}</p>
|
||||
<div class="variable-info">
|
||||
<div
|
||||
v-for="value, value_index in variable.values"
|
||||
@click="checkedVariableValue(variable_index, value_index, value)"
|
||||
:key="value_index"
|
||||
:class="[value.selected ? 'selected' : '', value.disabled ? 'disabled' : '']">
|
||||
<span class="image" v-if="value.image"><img :src="value.image" class="img-fluid"></span>
|
||||
@{{ value.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($product['active'])
|
||||
<div class="quantity-btns">
|
||||
@hook('product.detail.buy.before')
|
||||
<div class="quantity-wrap">
|
||||
<input type="text" class="form-control" :disabled="!product.quantity" onkeyup="this.value=this.value.replace(/\D/g,'')" v-model="quantity" name="quantity">
|
||||
<div class="right">
|
||||
<i class="bi bi-chevron-up"></i>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-outline-dark ms-md-3 add-cart fw-bold"
|
||||
:disabled="!product.quantity"
|
||||
@click="addCart(false, this)"
|
||||
><i class="bi bi-cart-fill me-1"></i>{{ __('shop/products.add_to_cart') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark ms-3 fw-bold"
|
||||
:disabled="!product.quantity"
|
||||
@click="addCart(true, this)"
|
||||
><i class="bi bi-bag-fill me-1"></i>{{ __('shop/products.buy_now') }}
|
||||
</button>
|
||||
@hook('product.detail.buy.after')
|
||||
</div>
|
||||
<div class="add-wishlist">
|
||||
<button class="btn btn-link ps-0 text-secondary" data-in-wishlist="{{ $product['in_wishlist'] }}" onclick="bk.addWishlist('{{ $product['id'] }}', this)">
|
||||
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }} me-1"></i> {{ __('shop/products.add_to_favorites') }}
|
||||
</button>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-danger"><i class="bi bi-exclamation-circle-fill"></i> {{ __('product.has_been_inactive') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="product-description">
|
||||
<div class="nav nav-tabs nav-overflow justify-content-start justify-content-md-center border-bottom mb-3">
|
||||
<a class="nav-link fw-bold active fs-5" data-bs-toggle="tab" href="#product-description">
|
||||
{{ __('shop/products.product_details') }}
|
||||
</a>
|
||||
@if ($product['attributes'])
|
||||
<a class="nav-link fw-bold fs-5" data-bs-toggle="tab" href="#product-attributes">
|
||||
{{ __('admin/attribute.index') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="product-description" role="tabpanel">
|
||||
{!! $product['description'] !!}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="product-attributes" role="tabpanel">
|
||||
<table class="table table-bordered attribute-table">
|
||||
@foreach ($product['attributes'] as $group)
|
||||
<thead class="table-light">
|
||||
<tr><td colspan="2"><strong>{{ $group['attribute_group_name'] }}</strong></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($group['attributes'] as $item)
|
||||
<tr>
|
||||
<td>{{ $item['attribute'] }}</td>
|
||||
<td>{{ $item['attribute_value'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($relations)
|
||||
<div class="relations-wrap mt-5">
|
||||
<div class="container position-relative">
|
||||
<div class="title text-center fs-1 mb-4">{{ __('admin/product.product_relations') }}</div>
|
||||
<div class="product swiper-style-plus">
|
||||
<div class="swiper relations-swiper">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($relations as $item)
|
||||
<div class="swiper-slide">
|
||||
@include('shared.product', ['product' => $item])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination relations-pagination"></div>
|
||||
<div class="swiper-button-prev relations-swiper-prev"></div>
|
||||
<div class="swiper-button-next relations-swiper-next"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
let swiperMobile = null;
|
||||
|
||||
let app = new Vue({
|
||||
el: '#product-app',
|
||||
|
||||
data: {
|
||||
selectedVariantsIndex: [], // 选中的变量索引
|
||||
images: [],
|
||||
product: {
|
||||
id: 0,
|
||||
images: "",
|
||||
model: "",
|
||||
origin_price: 0,
|
||||
origin_price_format: "",
|
||||
position: 0,
|
||||
price: 0,
|
||||
price_format: "",
|
||||
quantity: 0,
|
||||
sku: "",
|
||||
},
|
||||
quantity: 1,
|
||||
source: {
|
||||
skus: @json($product['skus']),
|
||||
variables: @json($product['variables'] ?? []),
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
beforeMount () {
|
||||
const skus = JSON.parse(JSON.stringify(this.source.skus));
|
||||
const skuDefault = skus.find(e => e.is_default)
|
||||
this.selectedVariantsIndex = skuDefault.variants
|
||||
|
||||
// 为 variables 里面每一个 values 的值添加 selected、disabled 字段
|
||||
if (this.source.variables.length) {
|
||||
this.source.variables.forEach(variable => {
|
||||
variable.values.forEach(value => {
|
||||
this.$set(value, 'selected', false)
|
||||
this.$set(value, 'disabled', false)
|
||||
})
|
||||
})
|
||||
|
||||
this.checkedVariants()
|
||||
this.getSelectedSku();
|
||||
this.updateSelectedVariantsStatus()
|
||||
} else {
|
||||
// 如果没有默认的sku,则取第一个sku的第一个变量的第一个值
|
||||
this.product = skus[0];
|
||||
this.images = @json($product['images'] ?? []);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
checkedVariableValue(variable_idnex, value_index, value) {
|
||||
$('.product-image .swiper .swiper-slide').eq(0).addClass('active').siblings().removeClass('active');
|
||||
this.source.variables[variable_idnex].values.forEach((v, i) => {
|
||||
v.selected = i == value_index
|
||||
})
|
||||
|
||||
this.updateSelectedVariantsIndex();
|
||||
this.getSelectedSku();
|
||||
this.updateSelectedVariantsStatus()
|
||||
},
|
||||
|
||||
// 把对应 selectedVariantsIndex 下标选中 variables -> values 的 selected 字段为 true
|
||||
checkedVariants() {
|
||||
this.source.variables.forEach((variable, index) => {
|
||||
variable.values[this.selectedVariantsIndex[index]].selected = true
|
||||
})
|
||||
},
|
||||
|
||||
getSelectedSku() {
|
||||
// 通过 selectedVariantsIndex 的值比对 skus 的 variables
|
||||
const sku = this.source.skus.find(sku => sku.variants.toString() == this.selectedVariantsIndex.toString())
|
||||
const spuImages = @json($product['images'] ?? []);
|
||||
this.images = [...sku.images, ...spuImages]
|
||||
this.product = sku;
|
||||
if (swiperMobile) {
|
||||
swiperMobile.slideTo(0, 0, false)
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
$('#zoom img').attr('src', $('#swiper a').attr('data-image'));
|
||||
$('#zoom').trigger('zoom.destroy');
|
||||
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
||||
})
|
||||
},
|
||||
|
||||
addCart(isBuyNow = false) {
|
||||
bk.addCart({sku_id: this.product.id, quantity: this.quantity, isBuyNow});
|
||||
},
|
||||
|
||||
updateSelectedVariantsIndex() {
|
||||
// 获取选中的 variables 内 value的 下标 index 填充到 selectedVariantsIndex 中
|
||||
this.source.variables.forEach((variable, index) => {
|
||||
variable.values.forEach((value, value_index) => {
|
||||
if (value.selected) {
|
||||
this.selectedVariantsIndex[index] = value_index
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateSelectedVariantsStatus() {
|
||||
// skus 里面 quantity 不为 0 的 sku.variants
|
||||
const skus = this.source.skus.filter(sku => sku.quantity > 0).map(sku => sku.variants);
|
||||
this.source.variables.forEach((variable, index) => {
|
||||
variable.values.forEach((value, value_index) => {
|
||||
const selectedVariantsIndex = this.selectedVariantsIndex.slice(0);
|
||||
|
||||
selectedVariantsIndex[index] = value_index;
|
||||
const selectedSku = skus.find(sku => sku.toString() == selectedVariantsIndex.toString());
|
||||
if (selectedSku) {
|
||||
value.disabled = false;
|
||||
} else {
|
||||
value.disabled = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("mouseover", ".product-image #swiper .swiper-slide a", function() {
|
||||
$(this).parent().addClass('active').siblings().removeClass('active');
|
||||
$('#zoom').trigger('zoom.destroy');
|
||||
$('#zoom img').attr('src', $(this).attr('data-image'));
|
||||
$('#zoom').zoom({url: $(this).attr('data-zoom-image')});
|
||||
});
|
||||
|
||||
var swiper = new Swiper("#swiper", {
|
||||
direction: "vertical",
|
||||
slidesPerView: 1,
|
||||
spaceBetween:3,
|
||||
breakpoints:{
|
||||
375:{
|
||||
slidesPerView: 3,
|
||||
spaceBetween:3,
|
||||
},
|
||||
480:{
|
||||
slidesPerView: 4,
|
||||
spaceBetween:27,
|
||||
},
|
||||
768:{
|
||||
slidesPerView: 6,
|
||||
spaceBetween:3,
|
||||
},
|
||||
},
|
||||
navigation: {
|
||||
nextEl: '.new-feature-slideshow-next',
|
||||
prevEl: '.new-feature-slideshow-prev',
|
||||
},
|
||||
observer: true,
|
||||
observeParents: true
|
||||
});
|
||||
|
||||
var relationsSwiper = new Swiper ('.relations-swiper', {
|
||||
watchSlidesProgress: true,
|
||||
breakpoints:{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 10,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
},
|
||||
spaceBetween: 30,
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.relations-swiper-next',
|
||||
prevEl: '.relations-swiper-prev',
|
||||
},
|
||||
|
||||
// 如果需要分页器
|
||||
pagination: {
|
||||
el: '.relations-pagination',
|
||||
clickable: true,
|
||||
},
|
||||
})
|
||||
|
||||
@if (is_mobile())
|
||||
swiperMobile = new Swiper("#swiper-mobile", {
|
||||
slidesPerView: 1,
|
||||
pagination: {
|
||||
el: ".mobile-pagination",
|
||||
},
|
||||
observer: true,
|
||||
observeParents: true
|
||||
});
|
||||
@endif
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#zoom').trigger('zoom.destroy');
|
||||
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
||||
<x-shop-breadcrumb type="static" value="products.search" />
|
||||
|
||||
<div class="row">
|
||||
@if (count($items))
|
||||
@foreach ($items as $product)
|
||||
<div class="col-6 col-md-3">@include('shared.product')</div>
|
||||
@endforeach
|
||||
@else
|
||||
<x-shop-no-data />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{ $products->links('shared/pagination/bootstrap-4') }}
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
<template id="address-dialog">
|
||||
<div>
|
||||
<el-dialog custom-class="mobileWidth" title="{{ __('address.index') }}" :visible.sync="editShow" @close="closeAddressDialog('addressForm')" :close-on-click-modal="false">
|
||||
<el-form ref="addressForm" :rules="rules" :model="form" label-width="100px">
|
||||
<el-form-item label="{{ __('address.name') }}" prop="name">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
@if (!current_customer())
|
||||
<el-form-item label="{{ __('common.email') }}" prop="email" v-if="type == 'guest_shipping_address'">
|
||||
<el-input v-model="form.email"></el-input>
|
||||
</el-form-item>
|
||||
@endif
|
||||
<el-form-item label="{{ __('address.phone') }}" prop="phone">
|
||||
<el-input maxlength="11" v-model="form.phone" type="number"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('address.address') }}" required>
|
||||
<div class="row dialog-address">
|
||||
<div class="col-4">
|
||||
<el-form-item>
|
||||
<el-select v-model="form.country_id" filterable placeholder="{{ __('address.country_id') }}" @change="countryChange">
|
||||
<el-option v-for="item in source.countries" :key="item.id" :label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="col-4 mt-2 mt-sm-0">
|
||||
<el-form-item prop="zone_id">
|
||||
<el-select v-model="form.zone_id" filterable placeholder="{{ __('address.zone') }}">
|
||||
<el-option v-for="item in source.zones" :key="item.id" :label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="col-4 mt-2 mt-sm-0">
|
||||
<el-form-item prop="city">
|
||||
<el-input v-model="form.city" placeholder="{{ __('shop/account.addresses.enter_city') }}"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('address.post_code') }}" prop="zipcode">
|
||||
<el-input v-model="form.zipcode"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('address.address_1') }}" prop="address_1">
|
||||
<el-input v-model="form.address_1"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('address.address_2') }}">
|
||||
<el-input v-model="form.address_2"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('address.default') }}" v-if="source.isLogin">
|
||||
<el-switch
|
||||
v-model="form.default"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="addressFormSubmit('addressForm')">{{ __('common.save') }}</el-button>
|
||||
<el-button @click="closeAddressDialog('addressForm')">{{ __('common.cancel') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
Vue.component('address-dialog', {
|
||||
template: '#address-dialog',
|
||||
props: {
|
||||
value: {
|
||||
default: null
|
||||
},
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
editShow: false,
|
||||
index: null,
|
||||
type: 'shipping_address_id',
|
||||
form: {
|
||||
name: '',
|
||||
phone: '',
|
||||
country_id: @json((int) system_setting('base.country_id')),
|
||||
zipcode: '',
|
||||
zone_id: @json((int) system_setting('base.zone_id')),
|
||||
city: '',
|
||||
address_1: '',
|
||||
address_2: '',
|
||||
default: false,
|
||||
},
|
||||
|
||||
rules: {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '{{ __('shop/account.addresses.enter_name') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
email: [{
|
||||
required: true,
|
||||
type: 'email',
|
||||
message: '{{ __('shop/login.enter_email') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '{{ __('shop/account.addresses.enter_phone') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
address_1: [{
|
||||
required: true,
|
||||
message: ' {{ __('shop/account.addresses.enter_address') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
zone_id: [{
|
||||
required: true,
|
||||
message: '{{ __('shop/account.addresses.select_province') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
city: [{
|
||||
required: true,
|
||||
message: '{{ __('shop/account.addresses.enter_city') }}',
|
||||
trigger: 'blur'
|
||||
}, ],
|
||||
},
|
||||
|
||||
source: {
|
||||
countries: @json($countries ?? []),
|
||||
zones: [],
|
||||
isLogin: config.isLogin,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
this.countryChange(this.form.country_id);
|
||||
},
|
||||
|
||||
methods: {
|
||||
editAddress(addresses, type) {
|
||||
this.type = type
|
||||
if (addresses) {
|
||||
this.form = addresses
|
||||
}
|
||||
|
||||
this.countryChange(this.form.country_id);
|
||||
this.editShow = true
|
||||
},
|
||||
|
||||
addressFormSubmit(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (!valid) {
|
||||
this.$message.error('{{ __('shop/checkout.check_form') }}');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$emit('change', this.form)
|
||||
// const type = this.form.id ? 'put' : 'post';
|
||||
|
||||
// const url = `/account/addresses${type == 'put' ? '/' + this.form.id : ''}`;
|
||||
|
||||
// $http[type](url, this.form).then((res) => {
|
||||
// this.$message.success(res.message);
|
||||
// this.$emit('change', res.data)
|
||||
// this.editShow = false
|
||||
// })
|
||||
});
|
||||
},
|
||||
|
||||
closeAddressDialog() {
|
||||
this.$refs['addressForm'].resetFields();
|
||||
this.editShow = false
|
||||
|
||||
Object.keys(this.form).forEach(key => this.form[key] = '')
|
||||
this.form.country_id = @json((int) system_setting('base.country_id'));
|
||||
this.form.default = false;
|
||||
},
|
||||
|
||||
countryChange(e) {
|
||||
const self = this;
|
||||
|
||||
$http.get(`/countries/${e}/zones`, null, {
|
||||
hload: true
|
||||
}).then((res) => {
|
||||
this.source.zones = res.data.zones;
|
||||
|
||||
if (!res.data.zones.some(e => e.id == this.form.zone_id)) {
|
||||
this.form.zone_id = '';
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<div class="product-tool d-flex justify-content-between align-items-center mb-4">
|
||||
@if (!is_mobile())
|
||||
<div class="style-wrap d-flex align-items-center">
|
||||
<label class="{{ !request('style_list') || request('style_list') == 'grid' ? 'active' : ''}} grid"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('common.text_grid') }}"
|
||||
>
|
||||
<svg viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg" width="18" height="18"><rect width="5" height="5"></rect><rect x="7" width="5" height="5"></rect><rect x="14" width="5" height="5"></rect><rect y="7" width="5" height="5"></rect><rect x="7" y="7" width="5" height="5"></rect><rect x="14" y="7" width="5" height="5"></rect><rect y="14" width="5" height="5"></rect><rect x="7" y="14" width="5" height="5"></rect><rect x="14" y="14" width="5" height="5"></rect></svg>
|
||||
<input class="d-none" value="grid" type="radio" name="style_list">
|
||||
</label>
|
||||
<label class="ms-1 {{ request('style_list') == 'list' ? 'active' : '' }} list"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('common.text_list') }}"
|
||||
>
|
||||
<svg viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg" width="18" height="18"><rect width="5" height="5"></rect><rect x="7" height="5" width="12"></rect><rect y="7" width="5" height="5"></rect><rect x="7" y="7" height="5" width="12"></rect><rect y="14" width="5" height="5"></rect><rect x="7" y="14" height="5" width="12"></rect></svg>
|
||||
<input class="d-none" value="list" type="radio" name="style_list">
|
||||
</label>
|
||||
</div>
|
||||
@endif
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-nowrap text-secondary">
|
||||
{{ __('common.showing_page', ['per_page' => request('per_page'), 'total' => $products->total()]) }}
|
||||
</div>
|
||||
|
||||
<select class="form-select perpage-select ms-3">
|
||||
@foreach ($per_pages as $val)
|
||||
<option value="{{ $val }}" {{ request('per_page') == $val ? 'selected' : '' }}>{{ $val }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="form-select order-select ms-2">
|
||||
<option value="">{{ __('common.default') }}</option>
|
||||
<option value="products.sales|asc" {{ request('sort') == 'products.sales' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('common.sales') }} ({{ __('common.low') . '-' . __('common.high')}})</option>
|
||||
<option value="products.sales|desc" {{ request('sort') == 'products.sales' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('common.sales') }} ({{ __('common.high') . '-' . __('common.low')}})</option>
|
||||
<option value="pd.name|asc" {{ request('sort') == 'pd.name' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('common.name') }} (A - Z)</option>
|
||||
<option value="pd.name|desc" {{ request('sort') == 'pd.name' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('common.name') }} (Z - A)</option>
|
||||
<option value="product_skus.price|asc" {{ request('sort') == 'product_skus.price' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('product.price') }} ({{ __('common.low') . '-' . __('common.high')}})</option>
|
||||
<option value="product_skus.price|desc" {{ request('sort') == 'product_skus.price' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('product.price') }} ({{ __('common.high') . '-' . __('common.low')}})</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<div class="mb-4 module-category-wrap">
|
||||
<h4 class="mb-3"><span>{{ __('product.category') }}</span></h4>
|
||||
<ul class="sidebar-widget mb-0" id="category-one">
|
||||
@foreach ($all_categories as $key_a => $category_all)
|
||||
<li class="{{ $category_all['id'] == $category->id ? 'active' : ''}}">
|
||||
<a href="{{ shop_route('categories.show', [$category_all['id']]) }}" title="{{ $category_all['name'] }}" class="category-href">{{ $category_all['name'] }}</a>
|
||||
@if ($category_all['children'])
|
||||
<button class="toggle-icon btn {{ $category_all['id'] == $category->id ? '' : 'collapsed'}}" data-bs-toggle="collapse" href="#category-{{ $key_a }}"><i class="bi bi-chevron-up"></i></button>
|
||||
<ul id="category-{{ $key_a }}" class="accordion-collapse collapse {{ $category_all['id'] == $category->id ? 'show' : ''}}" data-bs-parent="#category-one">
|
||||
@foreach ($category_all['children'] as $key_b => $child)
|
||||
<li class="{{ $child['id'] == $category->id ? 'active' : ''}} child-category">
|
||||
<a href="{{ shop_route('categories.show', [$child['id']]) }}" title="{{ $child['name'] }}">{{ $child['name'] }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="filter-box">
|
||||
@if ($filter_data['price']['min'] != $filter_data['price']['max'])
|
||||
@hookwrapper('category.filter.sidebar.price')
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/jquery/jquery-ui/jquery-ui.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/jquery/jquery-ui/jquery-ui.min.css') }}">
|
||||
@endpush
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header p-0">
|
||||
<h4 class="mb-3">{{ __('product.price') }}</h4>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div id="price-slider" class="mb-2"><div class="slider-bg"></div></div>
|
||||
<div class="text-secondary price-range d-flex justify-content-between">
|
||||
<div>
|
||||
{{ __('common.text_form') }}
|
||||
<span class="min">{{ currency_format($filter_data['price']['select_min'], current_currency_code()) }}</span>
|
||||
</div>
|
||||
<div>
|
||||
{{ __('common.text_to') }}
|
||||
<span class="max">{{ currency_format($filter_data['price']['select_max'], current_currency_code()) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<input value="{{ $filter_data['price']['select_min'] }}" class="price-select-min d-none">
|
||||
<input value="{{ $filter_data['price']['select_max'] }}" class="price-select-max d-none">
|
||||
<input value="{{ $filter_data['price']['min'] }}" class="price-min d-none">
|
||||
<input value="{{ $filter_data['price']['max'] }}" class="price-max d-none">
|
||||
</div>
|
||||
</div>
|
||||
@endhookwrapper
|
||||
@endif
|
||||
|
||||
@hookwrapper('category.filter.sidebar.attr')
|
||||
@foreach ($filter_data['attr'] as $index => $attr)
|
||||
<div class="card">
|
||||
<div class="card-header fw-bold p-0">
|
||||
<h4 class="mb-3">{{ $attr['name'] }}</h4>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush attribute-item" data-attribute-id="{{ $attr['id'] }}">
|
||||
@foreach ($attr['values'] as $value_index => $value)
|
||||
<li class="list-group-item border-0 px-0">
|
||||
<label class="form-check-label d-block">
|
||||
<input class="form-check-input attr-value-check me-2" data-attr="{{ $index }}" data-attrval="{{ $value_index }}" {{ $value['selected'] ? 'checked' : '' }} name="6" type="checkbox" value="{{ $value['id'] }}">{{ $value['name'] }}
|
||||
</label>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endforeach
|
||||
@endhookwrapper
|
||||
</div>
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
const currencyRate = {{ current_currency_rate() }};
|
||||
$(document).ready(function() {
|
||||
if (!$('#price-slider').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
$("#price-slider").slider({
|
||||
range: true,
|
||||
step: 0.01,
|
||||
min: {{ $filter_data['price']['min'] ?? 0 }},
|
||||
max: {{ $filter_data['price']['max'] ?? 0 }},
|
||||
values: [{{ $filter_data['price']['select_min'] }}, {{ $filter_data['price']['select_max'] }}],
|
||||
change: function(event, ui) {
|
||||
$('input.price-select-min').val(ui.values[0])
|
||||
$('input.price-select-max').val(ui.values[1])
|
||||
filterProductData();
|
||||
},
|
||||
slide: function(event, ui) {
|
||||
let min = $('.price-range .min').html();
|
||||
let max = $('.price-range .max').html();
|
||||
$('.price-range .min').html(min.replace(min.replace(/[^0-9.,]/g, ''), (ui.values[0] * currencyRate).toFixed(2)));
|
||||
$('.price-range .max').html(max.replace(max.replace(/[^0-9.,]/g, ''), (ui.values[1] * currencyRate).toFixed(2)));
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<div class="alert alert-success alert-dismissible">
|
||||
<i class="bi bi-check-circle-fill"></i>
|
||||
{{ $msg }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<div class="accordion accordion-flush" id="menu-accordion">
|
||||
@foreach ($menu_content as $key => $menu)
|
||||
@if ($menu['name'])
|
||||
<div class="accordion-item">
|
||||
<div class="nav-item-text">
|
||||
<a class="nav-link" target="{{ isset($menu['new_window']) && $menu['new_window'] ? '_blank' : '_self' }}" href="{{ $menu['link'] ?? '' }}">
|
||||
{{ $menu['name'] }}
|
||||
@if (isset($menu['badge']) && $menu['badge']['name'])
|
||||
<span class="badge" style="background-color: {{ $menu['badge']['bg_color'] }}; color: {{ $menu['badge']['text_color'] }}; border-color: {{ $menu['badge']['bg_color'] }}">
|
||||
{{ $menu['badge']['name'] }}
|
||||
</span>
|
||||
@endif
|
||||
</a>
|
||||
@if (isset($menu['children_group']) && $menu['children_group'])
|
||||
<span class="collapsed" data-bs-toggle="collapse" data-bs-target="#flush-menu-{{ $key }}"><i class="bi bi-chevron-down"></i></span>
|
||||
@endif
|
||||
</div>
|
||||
@if (isset($menu['children_group']) && $menu['children_group'])
|
||||
<div class="accordion-collapse collapse" id="flush-menu-{{ $key }}" data-bs-parent="#menu-accordion">
|
||||
@forelse ($menu['children_group'] as $group)
|
||||
<div class="children-group mb-3">
|
||||
@if ($group['name'])
|
||||
<div class="group-name">{{ $group['name'] }}</div>
|
||||
@endif
|
||||
@if ($group['type'] == 'image')
|
||||
<a target="{{ isset($group['image']['link']['new_window']) && $group['image']['link']['new_window'] ? '_blank' : '_self' }}" href="{{ $group['image']['link'] }}"><img src="{{ $group['image']['image'] }}" class="img-fluid"></a>
|
||||
@else
|
||||
<ul class="nav flex-column ul-children">
|
||||
@foreach ($group['children'] as $children)
|
||||
@if (!is_array($children['link']['text']) && $children['link']['text'])
|
||||
<li class="nav-item">
|
||||
<a target="{{ isset($children['link']['new_window']) && $children['link']['new_window'] ? '_blank' : '_self' }}" class="nav-link px-0" href="{{ $children['link']['link'] }}">{{ $children['link']['text'] }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<ul class="navbar-nav mx-auto">
|
||||
@hook('header.menu.before')
|
||||
@foreach ($menu_content as $menu)
|
||||
@if ($menu['name'])
|
||||
<li
|
||||
class="nav-item {{ isset($menu['children_group']) ? 'dropdown' : '' }} {{ isset($menu['isFull']) && $menu['isFull'] ? 'position-static' : '' }}">
|
||||
<a class="nav-link fw-bold {{ isset($menu['children_group']) ? 'dropdown-toggle' : '' }}"
|
||||
target="{{ isset($menu['new_window']) && $menu['new_window'] ? '_blank' : '_self' }}"
|
||||
href="{{ $menu['link'] ?: 'javascript:void(0)' }}">
|
||||
{{ $menu['name'] }}
|
||||
@if (isset($menu['badge']) && $menu['badge']['name'])
|
||||
<span class="badge"
|
||||
style="background-color: {{ $menu['badge']['bg_color'] }}; color: {{ $menu['badge']['text_color'] }}; border-color: {{ $menu['badge']['bg_color'] }}">
|
||||
{{ $menu['badge']['name'] }}
|
||||
</span>
|
||||
@endif
|
||||
</a>
|
||||
@if (isset($menu['children_group']) && $menu['children_group'])
|
||||
<div class="dropdown-menu {{ $menu['isFull'] ? 'w-100' : '' }}"
|
||||
style="min-width: {{ count($menu['children_group']) * 240 }}px">
|
||||
<div class="card card-lg">
|
||||
<div class="card-body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@forelse ($menu['children_group'] as $group)
|
||||
<div class="col-6 col-md">
|
||||
@if ($group['name'])
|
||||
<div class="mb-3 fw-bold group-name">{{ $group['name'] }}</div>
|
||||
@endif
|
||||
@if ($group['type'] == 'image')
|
||||
<a
|
||||
target="{{ isset($group['image']['link']['new_window']) && $group['image']['link']['new_window'] ? '_blank' : '_self' }}"
|
||||
href="{{ $group['image']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $group['image']['image'] }}"
|
||||
class="img-fluid"></a>
|
||||
@else
|
||||
<ul class="nav flex-column ul-children">
|
||||
@foreach ($group['children'] as $children)
|
||||
@if (!is_array($children['link']['text']) && $children['link']['text'])
|
||||
<li class="nav-item">
|
||||
<a
|
||||
target="{{ isset($children['link']['new_window']) && $children['link']['new_window'] ? '_blank' : '_self' }}"
|
||||
class="nav-link px-0"
|
||||
href="{{ $children['link']['link'] ?: 'javascript:void(0)' }}">{{ $children['link']['text'] }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
@hook('header.menu.after')
|
||||
</ul>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav class="d-flex justify-content-center">
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
|
||||
@endif
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
|
||||
@else
|
||||
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li>
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
|
||||
@else
|
||||
<li><a href="{{ $url }}">{{ $page }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li>
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
@if ($paginator->hasPages())
|
||||
<div class="ui pagination menu" role="navigation">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
|
||||
@else
|
||||
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
|
||||
@else
|
||||
<a class="item" href="{{ $url }}">{{ $page }}</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
|
||||
@else
|
||||
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.previous')</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.next')</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
|
||||
@else
|
||||
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
|
||||
@else
|
||||
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.next') !!}
|
||||
</a>
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
|
||||
<div class="flex justify-between flex-1 sm:hidden">
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.next') !!}
|
||||
</a>
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-700 leading-5">
|
||||
{!! __('Showing') !!}
|
||||
@if ($paginator->firstItem())
|
||||
<span class="font-medium">{{ $paginator->firstItem() }}</span>
|
||||
{!! __('to') !!}
|
||||
<span class="font-medium">{{ $paginator->lastItem() }}</span>
|
||||
@else
|
||||
{{ $paginator->count() }}
|
||||
@endif
|
||||
{!! __('of') !!}
|
||||
<span class="font-medium">{{ $paginator->total() }}</span>
|
||||
{!! __('results') !!}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="relative z-0 inline-flex shadow-sm rounded-md">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<span aria-disabled="true">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">{{ $element }}</span>
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<span aria-current="page">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5">{{ $page }}</span>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $url }}" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
|
||||
{{ $page }}
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@else
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<div class="product-wrap {{ request('style_list') ?? '' }}">
|
||||
<div class="image">
|
||||
<a href="{{ $product['url'] }}">
|
||||
<div class="image-old">
|
||||
<img src="{{ $product['images'][0] ?? image_resize('', 400, 400) }}" class="img-fluid">
|
||||
</div>
|
||||
</a>
|
||||
@if (!request('style_list') || request('style_list') == 'grid')
|
||||
<div class="button-wrap">
|
||||
<button
|
||||
class="btn btn-dark text-light mx-1 rounded-3"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('shop/products.add_to_favorites') }}"
|
||||
data-in-wishlist="{{ $product['in_wishlist'] }}"
|
||||
onclick="bk.addWishlist('{{ $product['id'] }}', this)">
|
||||
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }}"></i>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark text-light mx-1 rounded-3"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('shop/products.add_to_cart') }}"
|
||||
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
|
||||
<i class="bi bi-cart"></i>
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="product-bottom-info">
|
||||
<div class="product-name">{{ $product['name_format'] }}</div>
|
||||
<div class="product-price">
|
||||
<span class="price-new">{{ $product['price_format'] }}</span>
|
||||
<span>-</span>
|
||||
@if ($product['price'] != $product['origin_price'] && $product['origin_price'] > 0)
|
||||
<span class="price-new">{{ $product['origin_price_format'] }}</span>
|
||||
@endif
|
||||
<span style="color:#aaa">/pieces</span>
|
||||
</div>
|
||||
<!--yt修改-->
|
||||
<div class="product-price">
|
||||
<span class="price-new">1 pieces</span>
|
||||
<span style="color:#aaa;margin-left:4px">(Min Order)</span>
|
||||
</div>
|
||||
|
||||
@if (request('style_list') == 'list')
|
||||
<div class="button-wrap mt-3">
|
||||
<button
|
||||
class="btn btn-dark text-light"
|
||||
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
|
||||
<i class="bi bi-cart"></i>
|
||||
{{ __('shop/products.add_to_cart') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-link ps-0 text-secondary" data-in-wishlist="{{ $product['in_wishlist'] }}" onclick="bk.addWishlist('{{ $product['id'] }}', this)">
|
||||
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }} me-1"></i> {{ __('shop/products.add_to_favorites') }}
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<div class="quantity-wrap">
|
||||
<input type="text" class="form-control" onkeyup="this.value=this.value.replace(/\D/g,'')" value="{{ isset($quantity) ? $quantity : 1 }}" name="quantity" minimum="{{ isset($minimum) ? $minimum : 1 }}">
|
||||
<div class="right">
|
||||
<i class="bi bi-chevron-up"></i>
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<div class="steps-wrap">
|
||||
<div class="{{ $steps == 1 || $steps == 2 || $steps == 3 || $steps == 4 ? 'active':'' }}">
|
||||
<div class="number-wrap"><span class="number">1</span></div>
|
||||
<span class="title">{{ __('shop/steps.cart') }}</span>
|
||||
</div>
|
||||
<div class="{{ $steps == 2 || $steps == 3 || $steps == 4 ? 'active':'' }}">
|
||||
<div class="number-wrap"><span class="number">2</span></div>
|
||||
<span class="title">{{ __('shop/steps.checkout') }}</span>
|
||||
</div>
|
||||
<div class="{{ $steps == 3 || $steps == 4 ? 'active':'' }}">
|
||||
<div class="number-wrap"><span class="number">3</span></div>
|
||||
<span class="title">{{ __('shop/steps.submitted_successfully') }}</span>
|
||||
</div>
|
||||
<div class="{{ $steps == 4 ? 'active':'' }}">
|
||||
<div class="number-wrap"><span class="number">4</span></div>
|
||||
<span class="title">{{ __('shop/steps.payment') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Reference in New Issue