somewhere

This commit is contained in:
Swift
2023-08-17 13:05:51 +03:30
parent 30c7eb0e7b
commit 53843207cc
429 changed files with 117489 additions and 1 deletions
@@ -0,0 +1,19 @@
<template>
<div class="pwa_dialog">
<div class="dialog-wrapper">
<div class="txt">
<p>با نصب برنامه تحت وب آسان سرویس سریع تر به پنل کاربری خود دسترسی داشته باشید!</p>
</div>
<div class="btns">
<button id="installPWA" class="btn btn-secondary secondary-reverse">نصب کن</button>
<button id="closePwaDialog" class="btn btn-secondary cancel">فعلا نه!</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'PwaDialog'
}
</script>
+23
View File
@@ -0,0 +1,23 @@
<template>
<div class="hero">
<div class="bg">
<div class="container">
<h2>{{ title }}</h2>
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'HeroComponent',
props: {
title: {
required: true,
type: String,
default: ''
}
}
}
</script>
@@ -0,0 +1,118 @@
<template>
<div class="lottery">
<div
v-if="!lotteryPopUpBtn || lotteryPopUpBtn.visible"
class="lottery-popup-button"
:style="[buttonStyle, { transform: btnScale }]"
@click="showPopup"
></div>
<div class="lottery-popup">
<div class="relatevePos">
<div class="bg" @click="closePopup"></div>
<div class="content" :style="[popUpStyle]">
<div class="relativePos">
<i class="closeBtn far fa-times-circle" @click="closePopup"></i>
<div class="btnBox" @click="closePopup">
<nuxt-link
v-if="lastLottery && lastLottery.expired"
:to="{ name: 'lottery', query: { mode: 'result' } }"
class="btn btn-primary"
>مشاهده نتایج قرعه کشی</nuxt-link
>
<nuxt-link v-else :to="{ name: 'lottery', query: { mode: 'enroll' } }" class="btn btn-primary"
>شرکت در قرعه کشی</nuxt-link
>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'LotteryPopUp',
data() {
return {
lotteryPopUpBtn: null,
lastLottery: null,
btnScale: 'scale(0)',
isPopupOpen: false
}
},
computed: {
buttonStyle() {
const btn = this.lotteryPopUpBtn
const data = {
bottom: btn?.y.toString().concat('px') || 0,
left: btn?.x.toString().concat('px') || 0,
width: btn?.w.toString().concat('px') || 0,
height: btn?.h.toString().concat('px') || 0
}
if (btn) data.backgroundImage = `url(${btn?.bgImg})`
return data
},
popUpStyle() {
const popup = this.lastLottery
const data = {}
if (popup) {
if (!popup.expired) {
data.backgroundImage = `url(${popup?.entryBgImg})`
data.width = popup.entryWidth.toString().concat('px')
data.height = popup.entryHeight.toString().concat('px')
} else {
data.backgroundImage = `url(${popup?.resultBgImg})`
data.width = popup.resultWidth.toString().concat('px')
data.height = popup.resultHeight.toString().concat('px')
}
}
return data
}
},
watch: {
buttonStyle(neVal, oldVal) {
setTimeout(() => (this.btnScale = 'scale(1)'), 1 * 1000)
}
},
async mounted() {
// attach esc key to window
$(document).keyup(e => {
if (e.key === 'Escape' && this.isPopupOpen) this.closePopup()
})
// fetch data
try {
const lotteryPopUpBtn = await this.$axios.get('/api/public/lotteryPopUp')
if (lotteryPopUpBtn.data.visible) {
const lastLottery = await this.$axios.get('/api/public/lastLottery')
this.lastLottery = lastLottery.data
}
setTimeout(() => (this.lotteryPopUpBtn = lotteryPopUpBtn.data), 2 * 1000)
} catch (e) {
console.log('LotteryPopUp button fetch problem ---- ', e.response.data)
}
},
methods: {
showPopup() {
this.$gsap
.timeline({
onComplete: () => (this.isPopupOpen = true)
})
.to($('.lottery-popup'), { autoAlpha: 1, duration: 0.04 })
.to($('.lottery-popup .content'), { opacity: 1, scale: 1, duration: 0.2, ease: 'power3.out' })
},
closePopup() {
this.$gsap
.timeline({
onComplete: () => (this.isPopupOpen = false)
})
.to($('.lottery-popup .content'), { opacity: 0, scale: 0, duration: 0.1 })
.to($('.lottery-popup'), { autoAlpha: 0, duration: 0.04 })
}
}
}
</script>
@@ -0,0 +1,3 @@
<template>
<p class="notice">*برای مشاهده ادامه جدول افقی اسکرول کنید.</p>
</template>
+21
View File
@@ -0,0 +1,21 @@
<template>
<CSubheader
class="custom-subheader px-3"
:class="[sidebarShow ? null : 'sideBarClose', sidebarMinimize ? 'sideBarMinimized' : 'sideBarFull']"
>
<slot />
</CSubheader>
</template>
<script>
export default {
computed: {
sidebarShow() {
return this.$store.state.admin.sidebarShow
},
sidebarMinimize() {
return this.$store.state.admin.sidebarMinimize
}
}
}
</script>
+21
View File
@@ -0,0 +1,21 @@
import Vue from 'vue'
Vue.component('RenderString', {
props: {
// eslint-disable-next-line vue/require-prop-types
string: {
required: true
}
},
render(h) {
const render = {
template: '<div>' + this.string + '</div>',
methods: {
markComplete() {
console.log('the method called')
}
}
}
return h(render)
}
})
+14
View File
@@ -0,0 +1,14 @@
<template>
<CFooter :fixed="false">
<div class="mfs-auto">
<span class="mr-1" target="_blank">Powered by</span>
<a href="https://negarehagency.com/" target="_blank" class="copy-right">Negareh Agency</a>
</div>
</CFooter>
</template>
<script>
export default {
name: 'TheFooter'
}
</script>
+42
View File
@@ -0,0 +1,42 @@
<template>
<CHeader fixed with-subheader light>
<CToggler in-header class="ml-3 d-lg-none" @click="$store.commit('admin/toggleSidebarMobile')" />
<CToggler in-header class="ml-3 d-md-down-none" @click="$store.commit('admin/toggleSidebarDesktop')" />
<!-- <CHeaderBrand class="mx-auto d-lg-none" to="/">-->
<!-- <CIcon name="logo" height="48" alt="Logo"/>-->
<!-- </CHeaderBrand>-->
<!-- <CHeaderNav class="d-md-down-none mr-auto">-->
<!-- <CHeaderNavItem class="px-3">-->
<!-- <CHeaderNavLink :to="{name: 'admin'}">-->
<!-- صفحه اصلی-->
<!-- </CHeaderNavLink>-->
<!-- </CHeaderNavItem>-->
<!-- </CHeaderNav>-->
<CHeaderNav class="mr-4 mr-auto">
<TheHeaderDropdownAccnt />
</CHeaderNav>
</CHeader>
</template>
<script>
export default {
name: 'TheHeader',
data() {
return {
breadcrumb: [
{
text: 'صفحه اصلی',
to: '/admin'
},
{
text: 'لیست دانلود ها',
to: { name: 'admin-downloads' }
},
{
text: 'This is a span'
}
]
}
}
}
</script>
@@ -0,0 +1,64 @@
<template>
<CDropdown in-nav class="c-header-nav-items" placement="bottom-end" add-menu-classes="pt-0">
<template #toggler>
<CHeaderNavLink>
<div class="c-avatar">
<img src="/img/avatars/avatar.png" class="c-avatar-img" alt="" title="حساب کاربری" />
</div>
</CHeaderNavLink>
</template>
<CDropdownHeader tag="div" class="text-center" color="light">
<strong v-if="$auth.loggedIn">{{ $auth.user.first_name }}</strong>
</CDropdownHeader>
<!-- <CDropdownItem :to="{name: 'admin-users'}">-->
<!-- <CIcon name="cil-user"/>-->
<!-- <span>پروفایل</span>-->
<!-- </CDropdownItem>-->
<CDropdownItem @click="logOut">
<CIcon name="cil-lock-locked" />
<span>خروج از حساب</span>
</CDropdownItem>
</CDropdown>
</template>
<script>
export default {
name: 'TheHeaderDropdownAccnt',
data() {
return {
itemsCount: 42
}
},
methods: {
logOut() {
this.$confirm('میخواهید از حساب کاربری خارج شوید؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
})
.then(async () => {
try {
await this.$auth.logout()
window.location.href = '/'
} catch (e) {
console.log(e.response.data)
}
})
.catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
}
}
}
</script>
<style scoped>
.c-icon {
margin-right: 0.3rem;
}
</style>
+331
View File
@@ -0,0 +1,331 @@
<template>
<CSidebar
fixed
:minimize="minimize"
:show="show"
@update:show="value => $store.commit('admin/set', ['sidebarShow', value])"
>
<CSidebarBrand class="d-md-down-none">
<a href="/" target="_blank">
<logo class="c-sidebar-brand-full" size="custom-size" :height="40" name="logo" />
<img
src="assets/img/favicon_white.png"
alt="logo"
class="c-sidebar-brand-minimized"
size="custom-size"
:height="35"
name="logo"
/>
</a>
</CSidebarBrand>
<!-- <CRenderFunction flat :content-to-render="$options.nav"/>-->
<!-- sidebar content -->
<CSidebarNav>
<CSidebarNavItem name="صفحه اصلی" :to="{ name: 'admin' }" icon="cil-speedometer" />
<CSidebarNavDropdown
:show="getDropdownState('adminS_WebsiteM_Dropdown')"
name="مدیریت وبسایت"
font-icon="fas fa-folder"
@update:show="val => setDropdownState('adminS_WebsiteM_Dropdown', val)"
>
<CSidebarNavItem
v-if="hasPermission('downloads')"
name="لیست دانلود ها"
:to="{ name: 'admin-downloads-page', params: { page: 1 } }"
font-icon="fal fa-arrow-alt-to-bottom"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('download-categories')"
name="دسته بندی دانلود"
:to="{ name: 'admin-download-categories' }"
font-icon="fal fa-arrow-alt-to-bottom"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('learning')"
name="آموزش ها"
:to="{ name: 'admin-learning-page', params: { page: 1 } }"
icon="cil-chart-pie"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('warranty-terms')"
name="شرایط گارانتی"
:to="{ name: 'admin-warranty-terms-page', params: { page: 1 } }"
font-icon="fal fa-file-alt"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('faq')"
name="سوالات متداول"
:to="{ name: 'admin-faq' }"
font-icon="fal fa-file-alt"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('help')"
name="راهنمای ثبت گارانتی"
:to="{ name: 'admin-help' }"
font-icon="fal fa-file-alt"
exact
/>
</CSidebarNavDropdown>
<CSidebarNavDropdown
v-if="hasPermission('downloads')"
:show="getDropdownState('adminS_CustomerM_Dropdown')"
name="مدیریت مشتریان"
font-icon="fas fa-folder"
@update:show="val => setDropdownState('adminS_CustomerM_Dropdown', val)"
>
<CSidebarNavItem
v-if="hasPermission('contact-us')"
name="پیام های صفحه تماس با ما"
:to="{ name: 'admin-contact-us' }"
font-icon="fal fa-envelope"
:exact="false"
:badge="unreadCuMsgs ? { text: unreadCuMsgs, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('customers')"
name="لیست مشتریان"
:to="{ name: 'admin-customers', query: { filter: 'all' } }"
font-icon="fal fa-list"
:exact="false"
:badge="newCustomers ? { text: newCustomers, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('tickets')"
name="تیکت های مشتریان"
:to="{ name: 'admin-tickets' }"
font-icon="fal fa-comment-alt-dots"
:exact="false"
:badge="unreadTickets ? { text: unreadTickets, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('tickets')"
name="ایجاد تیکت برای مشتری"
:to="{ name: 'admin-add-tickets' }"
font-icon="fal fa-plus"
exact
/>
</CSidebarNavDropdown>
<CSidebarNavDropdown
:show="getDropdownState('adminS_AgentM_Dropdown')"
name="مدیریت نمایندگان"
font-icon="fas fa-folder"
@update:show="val => setDropdownState('adminS_AgentM_Dropdown', val)"
>
<CSidebarNavItem
v-if="hasPermission('representations')"
name="درخواست های نمایندگی"
:to="{ name: 'admin-representations', query: { status: 'registered' } }"
font-icon="fas fa-handshake"
:exact="false"
:badge="newRepresentations ? { text: newRepresentations, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('agents')"
name="لیست نمایندگان"
:to="{ name: 'admin-agents', query: { agent: true } }"
font-icon="fas fa-list"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('agents')"
name="نمایندگان صلب امتیاز شده"
:to="{ name: 'admin-agents', query: { revoked: true } }"
font-icon="fas fa-list"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('agentsInbox')"
name="صندوق ورودی نمایندگان"
:to="{ name: 'admin-agentsInbox', query: { status: 'all' } }"
font-icon="fas fa-inbox"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('piece-requests')"
name="درخواست های قطعه"
:to="{ name: 'admin-piece-requests', query: { status: 'sent' } }"
font-icon="fas fa-wrench"
:exact="false"
:badge="newPieceRequests ? { text: newPieceRequests, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('op-requests')"
name="درخواست های قطعه داغی"
:to="{ name: 'admin-op-requests', query: { status: 'sent' } }"
font-icon="fas fa-backpack"
:exact="false"
:badge="newOldPieceRequests ? { text: newOldPieceRequests, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('buffer-requests')"
name="درخواست های کالای بافر"
:to="{ name: 'admin-buffer-requests', query: { status: 'sent' } }"
font-icon="fab fa-buffer"
:exact="false"
:badge="newBufferRequests ? { text: newBufferRequests, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('guarantee-reports')"
name="فرم های عملکرد گارانتی"
:to="{ name: 'admin-guarantee-reports' }"
font-icon="fas fa-file-chart-line"
:exact="false"
:badge="newGuaranteeReports ? { text: newGuaranteeReports, color: 'danger' } : null"
/>
<CSidebarNavItem
v-if="hasPermission('agentReports')"
name="گزارشات"
:to="{ name: 'admin-agentReports' }"
font-icon="fas fa-file-chart-pie"
:exact="false"
/>
</CSidebarNavDropdown>
<CSidebarNavDropdown
v-if="hasPermission('admins')"
:show="getDropdownState('adminS_AdminsM_Dropdown')"
name="مدیریت ادمین ها"
font-icon="fas fa-folder"
@update:show="val => setDropdownState('adminS_AdminsM_Dropdown', val)"
>
<CSidebarNavItem
v-if="hasPermission('admins')"
name="افزودن ادمین"
:to="{ name: 'admin-admins-admin', params: { admin: 'new' } }"
font-icon="fal fa-user"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('admins')"
name="لیست ادمین ها"
:to="{ name: 'admin-admins' }"
font-icon="fal fa-list"
:exact="false"
/>
</CSidebarNavDropdown>
<CSidebarNavDropdown
:show="getDropdownState('adminS_AppM_Dropdown')"
name="مدیریت اپلیکیشن"
font-icon="fas fa-folder"
@update:show="val => setDropdownState('adminS_AppM_Dropdown', val)"
>
<CSidebarNavItem
v-if="hasPermission('announcements')"
name="اعلانات مشتریان"
:to="{ name: 'admin-announcements', query: { user: true } }"
font-icon="fal fa-bell"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('announcements')"
name="اطلاعیه های نمایندگان"
:to="{ name: 'admin-announcements', query: { agent: true } }"
font-icon="fal fa-bullhorn"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('sms')"
name="ارسال پیامک"
:to="{ name: 'admin-sms' }"
font-icon="fas fa-sms"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('serials-exel')"
name="فایل اکسل شماره سریال گارانتی"
:to="{ name: 'admin-serials-exel', query: { type: 'guaranteeSerial' } }"
font-icon="fal fa-file-excel"
exact
/>
<CSidebarNavItem
v-if="hasPermission('serials-exel')"
name="فایل اکسل شماره سریال کالا"
:to="{ name: 'admin-serials-exel', query: { type: 'orginality' } }"
font-icon="fal fa-file-excel"
exact
/>
<CSidebarNavItem
v-if="hasPermission('lotteryPopUp')"
name="دکمه قرعه کشی"
:to="{ name: 'admin-lotteryPopUp' }"
font-icon="fal fa-hand-pointer"
exact
/>
<CSidebarNavItem
v-if="hasPermission('lottery')"
name="قرعه کشی"
:to="{ name: 'admin-lottery' }"
font-icon="fal fa-calendar-check"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('surveys')"
name="نظرسنجی"
:to="{ name: 'admin-surveys' }"
font-icon="fal fa-chart-bar"
:exact="false"
/>
<CSidebarNavItem
v-if="hasPermission('pieces')"
name="لیست قطعات"
:to="{ name: 'admin-pieces' }"
font-icon="fas fa-wrench"
:exact="false"
/>
</CSidebarNavDropdown>
</CSidebarNav>
<!-- sidebar content -->
<CSidebarMinimizer
class="d-md-down-none"
@click.native="$store.commit('admin/set', ['sidebarMinimize', !minimize])"
/>
</CSidebar>
</template>
<script>
// import nav from './_nav'
import { mapState } from 'vuex'
export default {
name: 'TheSidebar',
// nav,
computed: {
...mapState({
show: state => state.admin.sidebarShow,
minimize: state => state.admin.sidebarMinimize,
unreadCuMsgs: state => state.admin.unreadCuMsgs,
unreadTickets: state => state.admin.unreadTickets,
newCustomers: state => state.admin.newCustomers,
newRepresentations: state => state.admin.newRepresentations,
newPieceRequests: state => state.admin.newPieceRequests,
newOldPieceRequests: state => state.admin.newOldPieceRequests,
newBufferRequests: state => state.admin.newBufferRequests,
newGuaranteeReports: state => state.admin.newGuaranteeReports
})
},
methods: {
hasPermission(permission) {
if (this.$auth.loggedIn) return this.$auth.user.permissions.includes(permission)
else return false
},
setDropdownState(id, state) {
localStorage.setItem(id, state)
},
getDropdownState(id) {
return localStorage.getItem(id) === 'true'
}
}
}
</script>
+66
View File
@@ -0,0 +1,66 @@
export default [
{
_name: 'CSidebarNav',
_children: [
{
_name: 'CSidebarNavItem',
name: 'صفحه اصلی',
to: { name: 'admin' },
icon: 'cil-speedometer'
},
// {
// _name: 'CSidebarNavTitle',
// _children: ['مدیریت صفحات داینامیک']
// },
{
_name: 'CSidebarNavDropdown',
name: 'دانلود ها',
// route: {name: 'admin-download'},
fontIcon: 'fal fa-arrow-alt-to-bottom',
items: [
{
name: 'لیست',
to: { name: 'admin-downloads-page', params: { page: 1 } },
exact: false
},
{
name: 'دسته بندی ها',
to: { name: 'admin-download-categories' }
}
]
},
{
_name: 'CSidebarNavItem',
name: 'آموزش ها',
to: { name: 'admin-learning-page', params: { page: 1 } },
exact: false,
icon: 'cil-chart-pie'
},
{
_name: 'CSidebarNavItem',
name: 'شرایط گارانتی',
to: { name: 'admin-warranty-terms-page', params: { page: 1 } },
exact: false,
fontIcon: 'fal fa-file-alt'
},
{
_name: 'CSidebarNavItem',
name: 'سوالات متداول',
to: { name: 'admin-FAQ' },
exact: false,
fontIcon: 'fal fa-graduation-cap'
},
{
_name: 'CSidebarNavItem',
name: 'پیام های صفحه تماس با ما',
to: { name: 'admin-contact-us' },
exact: false,
badge: {
color: 'primary'
// text: this.computed.unreadMessages
},
fontIcon: 'fal fa-id-card-alt'
}
]
}
]
@@ -0,0 +1,20 @@
<template>
<CChartBar :datasets="defaultDatasets" labels="months" />
</template>
<script>
export default {
name: 'CChartBarExample',
computed: {
defaultDatasets() {
return [
{
label: 'GitHub Commits',
backgroundColor: '#f87979',
data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11]
}
]
}
}
}
</script>
@@ -0,0 +1,78 @@
/* eslint-disable vue/require-default-prop */
<template>
<CChartBar :datasets="computedDatasets" :options="computedOptions" :labels="labels" />
</template>
<script>
import CoreUtils from '~/mixins/CoreUtils'
export default {
name: 'CChartBarSimple',
mixins: [CoreUtils],
props: {
// eslint-disable-next-line vue/require-default-prop
datasets: Array,
// eslint-disable-next-line vue/require-default-prop
labels: [Array, String],
// eslint-disable-next-line vue/require-default-prop
options: Object,
// eslint-disable-next-line vue/require-default-prop
plugins: Array,
backgroundColor: {
type: String,
default: 'rgba(0,0,0,.2)'
},
// eslint-disable-next-line vue/require-default-prop
pointHoverBackgroundColor: String,
dataPoints: {
type: Array,
default: () => [10, 22, 34, 46, 58, 70, 46, 23, 45, 78, 34, 12]
},
label: {
type: String,
default: 'Sales'
},
pointed: Boolean
},
computed: {
defaultDatasets() {
return [
{
data: this.dataPoints,
backgroundColor: this.getColor(this.backgroundColor),
pointHoverBackgroundColor: this.getColor(this.pointHoverBackgroundColor),
label: this.label,
barPercentage: 0.5,
categoryPercentage: 1
}
]
},
defaultOptions() {
return {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
display: false
}
],
yAxes: [
{
display: false
}
]
}
}
},
computedDatasets() {
return this.deepObjectsMerge(this.defaultDatasets, this.datasets || {})
},
computedOptions() {
return this.deepObjectsMerge(this.defaultOptions, this.options || {})
}
}
}
</script>
@@ -0,0 +1,19 @@
<template>
<CChartDoughnut :datasets="defaultDatasets" :labels="['VueJs', 'EmberJs', 'ReactJs', 'AngularJs']" />
</template>
<script>
export default {
name: 'CChartDoughnutExample',
computed: {
defaultDatasets() {
return [
{
backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'],
data: [40, 20, 80, 10]
}
]
}
}
}
</script>
@@ -0,0 +1,25 @@
<template>
<CChartLine :datasets="defaultDatasets" labels="months" />
</template>
<script>
export default {
name: 'CChartLineExample',
computed: {
defaultDatasets() {
return [
{
label: 'Data One',
backgroundColor: 'rgb(228,102,81,0.9)',
data: [30, 39, 10, 50, 30, 70, 35]
},
{
label: 'Data Two',
backgroundColor: 'rgb(0,216,255,0.9)',
data: [39, 80, 40, 35, 40, 20, 45]
}
]
}
}
}
</script>
@@ -0,0 +1,145 @@
/* eslint-disable vue/require-default-prop */
<template>
<CChartLine :datasets="computedDatasets" :options="computedOptions" :labels="labels" />
</template>
<script>
import CoreUtils from '~/mixins/CoreUtils'
export default {
name: 'CChartLineSimple',
mixins: [CoreUtils],
props: {
// eslint-disable-next-line vue/require-default-prop
datasets: Array,
// eslint-disable-next-line vue/require-default-prop
labels: [Array, String],
// eslint-disable-next-line vue/require-default-prop
options: Object,
// eslint-disable-next-line vue/require-default-prop
plugins: Array,
borderColor: {
type: String,
default: 'rgba(255,255,255,.55)'
},
backgroundColor: {
type: String,
default: 'transparent'
},
dataPoints: {
type: Array,
default: () => [10, 22, 34, 46, 58, 70, 46, 23, 45, 78, 34, 12]
},
label: {
type: String,
default: 'Sales'
},
pointed: Boolean,
// eslint-disable-next-line vue/require-default-prop
pointHoverBackgroundColor: String
},
computed: {
pointHoverColor() {
if (this.pointHoverBackgroundColor) {
return this.pointHoverBackgroundColor
} else if (this.backgroundColor !== 'transparent') {
return this.backgroundColor
}
return this.borderColor
},
defaultDatasets() {
return [
{
data: this.dataPoints,
borderColor: this.getColor(this.borderColor),
backgroundColor: this.getColor(this.backgroundColor),
pointBackgroundColor: this.getColor(this.pointHoverColor),
pointHoverBackgroundColor: this.getColor(this.pointHoverColor),
label: this.label
}
]
},
pointedOptions() {
return {
scales: {
xAxes: [
{
offset: true,
gridLines: {
color: 'transparent',
zeroLineColor: 'transparent'
},
ticks: {
fontSize: 2,
fontColor: 'transparent'
}
}
],
yAxes: [
{
display: false,
ticks: {
display: false,
min: Math.min.apply(Math, this.dataPoints) - 5,
max: Math.max.apply(Math, this.dataPoints) + 5
}
}
]
},
elements: {
line: {
borderWidth: 1
},
point: {
radius: 4,
hitRadius: 10,
hoverRadius: 4
}
}
}
},
straightOptions() {
return {
scales: {
xAxes: [
{
display: false
}
],
yAxes: [
{
display: false
}
]
},
elements: {
line: {
borderWidth: 2
},
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4
}
}
}
},
defaultOptions() {
const options = this.pointed ? this.pointedOptions : this.straightOptions
return Object.assign({}, options, {
maintainAspectRatio: false,
legend: {
display: false
}
})
},
computedDatasets() {
return this.deepObjectsMerge(this.defaultDatasets, this.datasets || {})
},
computedOptions() {
return this.deepObjectsMerge(this.defaultOptions, this.options || {})
}
}
}
</script>
@@ -0,0 +1,19 @@
<template>
<CChartPie :datasets="defaultDatasets" :labels="['VueJs', 'EmberJs', 'ReactJs', 'AngularJs']" />
</template>
<script>
export default {
name: 'CChartPieExample',
computed: {
defaultDatasets() {
return [
{
backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'],
data: [40, 20, 80, 10]
}
]
}
}
}
</script>
@@ -0,0 +1,42 @@
<template>
<CChartPolarArea
:datasets="defaultDatasets"
:options="defaultOptions"
:labels="['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running']"
/>
</template>
<script>
export default {
name: 'CChartPolarAreaExample',
computed: {
defaultDatasets() {
return [
{
label: 'My First dataset',
backgroundColor: 'rgba(179,181,198,0.2)',
pointBackgroundColor: 'rgba(179,181,198,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: 'rgba(179,181,198,1)',
pointHoverBorderColor: 'rgba(179,181,198,1)',
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: 'My Second dataset',
backgroundColor: 'rgba(255,99,132,0.2)',
pointBackgroundColor: 'rgba(255,99,132,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: 'rgba(255,99,132,1)',
pointHoverBorderColor: 'rgba(255,99,132,1)',
data: [28, 48, 40, 19, 96, 27, 100]
}
]
},
defaultOptions() {
return {
aspectRatio: 1.5
}
}
}
}
</script>
@@ -0,0 +1,46 @@
<template>
<CChartRadar
:datasets="defaultDatasets"
:options="defaultOptions"
:labels="['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running']"
/>
</template>
<script>
export default {
name: 'CChartRadarExample',
computed: {
defaultDatasets() {
return [
{
label: '2019',
backgroundColor: 'rgba(179,181,198,0.2)',
borderColor: 'rgba(179,181,198,1)',
pointBackgroundColor: 'rgba(179,181,198,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(179,181,198,1)',
tooltipLabelColor: 'rgba(179,181,198,1)',
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: '2020',
backgroundColor: 'rgba(255,99,132,0.2)',
borderColor: 'rgba(255,99,132,1)',
pointBackgroundColor: 'rgba(255,99,132,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(255,99,132,1)',
tooltipLabelColor: 'rgba(255,99,132,1)',
data: [28, 48, 40, 19, 96, 27, 100]
}
]
},
defaultOptions() {
return {
aspectRatio: 1.5
}
}
}
}
</script>
@@ -0,0 +1,135 @@
<template>
<CChartLine
:datasets="defaultDatasets"
:options="defaultOptions"
:labels="[
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su',
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su',
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su',
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su'
]"
/>
</template>
<script>
// import { CChartLine } from '@coreui/vue-chartjs'
// import { getStyle, hexToRgba } from '@coreui/utils/src'
import CoreUtils from '~/mixins/CoreUtils'
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
export default {
name: 'MainChartExample',
mixins: [CoreUtils],
layout: 'admin',
computed: {
defaultDatasets() {
const brandSuccess = this.getStyle('success2') || '#4dbd74'
const brandInfo = this.getStyle('info') || '#20a8d8'
const brandDanger = this.getStyle('danger') || '#f86c6b'
const elements = 27
const data1 = []
const data2 = []
const data3 = []
for (let i = 0; i <= elements; i++) {
data1.push(random(50, 200))
data2.push(random(80, 100))
data3.push(65)
}
return [
{
label: 'My First dataset',
backgroundColor: this.hexToRgba(brandInfo, 10),
borderColor: brandInfo,
pointHoverBackgroundColor: brandInfo,
borderWidth: 2,
data: data1
},
{
label: 'My Second dataset',
backgroundColor: 'transparent',
borderColor: brandSuccess,
pointHoverBackgroundColor: brandSuccess,
borderWidth: 2,
data: data2
},
{
label: 'My Third dataset',
backgroundColor: 'transparent',
borderColor: brandDanger,
pointHoverBackgroundColor: brandDanger,
borderWidth: 1,
borderDash: [8, 5],
data: data3
}
]
},
defaultOptions() {
return {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
gridLines: {
drawOnChartArea: false
}
}
],
yAxes: [
{
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
stepSize: Math.ceil(250 / 5),
max: 250
},
gridLines: {
display: true
}
}
]
},
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4,
hoverBorderWidth: 3
}
}
}
}
}
}
</script>
+118
View File
@@ -0,0 +1,118 @@
<template>
<CRow>
<template v-if="!noCharts">
<CCol md="3" sm="6">
<CWidgetBrand color="facebook" right-header="89k" right-footer="friends" left-header="459" left-footer="feeds">
<CIcon name="cib-facebook" height="52" class="my-4" />
<CChartLineSimple
class="c-chart-brand"
background-color="rgba(255,255,255,.1)"
:data-points="[65, 59, 84, 84, 51, 55, 40]"
label="Friends"
labels="months"
/>
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand
color="twitter"
right-header="973k"
right-footer="followers"
left-header="1.792"
left-footer="tweets"
>
<CIcon name="cib-twitter" height="52" class="my-4" />
<CChartLineSimple
class="c-chart-brand"
background-color="rgba(255,255,255,.1)"
:data-points="[1, 13, 9, 17, 34, 41, 38]"
label="Followers"
labels="months"
/>
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand
color="linkedin"
right-header="500+"
right-footer="contracts"
left-header="292"
left-footer="feeds"
>
<CIcon name="cib-linkedin" height="52" class="my-4" />
<CChartLineSimple
class="c-chart-brand"
background-color="rgba(255,255,255,.1)"
:data-points="[78, 81, 80, 45, 34, 12, 40]"
label="Contracts"
labels="months"
/>
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand right-header="12" right-footer="events" left-header="4" left-footer="meetings" color="warning">
<CIcon name="cil-calendar" height="52" class="my-4" />
<CChartLineSimple
class="c-chart-brand"
background-color="rgba(255,255,255,.1)"
:data-points="[35, 23, 56, 22, 97, 23, 64]"
label="Followers"
labels="months"
/>
</CWidgetBrand>
</CCol>
</template>
<template v-else>
<CCol md="3" sm="6">
<CWidgetBrand color="facebook" right-header="89k" right-footer="friends" left-header="459" left-footer="feeds">
<CIcon name="cib-facebook" height="56" class="my-4" />
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand
color="twitter"
right-header="973k"
right-footer="followers"
left-header="1.792"
left-footer="tweets"
>
<CIcon name="cib-twitter" height="56" class="my-4" />
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand
color="linkedin"
right-header="500+"
right-footer="contracts"
left-header="292"
left-footer="feeds"
>
<CIcon name="cib-linkedin" height="56" class="my-4" />
</CWidgetBrand>
</CCol>
<CCol md="3" sm="6">
<CWidgetBrand right-header="12" right-footer="events" left-header="4" left-footer="meetings" color="warning">
<CIcon name="cil-calendar" height="56" class="my-4" />
</CWidgetBrand>
</CCol>
</template>
</CRow>
</template>
<script>
export default {
name: 'WidgetsBrand',
layout: 'admin',
props: {
noCharts: Boolean
}
}
</script>
<style scoped>
.c-chart-brand {
position: absolute;
width: 100%;
height: 100px;
}
</style>
@@ -0,0 +1,115 @@
<template>
<CRow>
<CCol sm="6" lg="3">
<CWidgetDropdown color="primary" header="9.823" text="Members online">
<template #default>
<CDropdown color="transparent p-0" placement="bottom-end">
<template #toggler-content>
<CIcon name="cil-settings" />
</template>
<CDropdownItem>Action</CDropdownItem>
<CDropdownItem>Another action</CDropdownItem>
<CDropdownItem>Something else here...</CDropdownItem>
<CDropdownItem disabled>Disabled action</CDropdownItem>
</CDropdown>
</template>
<template #footer>
<CChartLineSimple
pointed
class="mt-3 mx-3"
style="height: 70px"
:data-points="[65, 59, 84, 84, 51, 55, 40]"
point-hover-background-color="primary"
label="Members"
labels="months"
/>
</template>
</CWidgetDropdown>
</CCol>
<CCol sm="6" lg="3">
<CWidgetDropdown color="info" header="9.823" text="Members online">
<template #default>
<CDropdown color="transparent p-0" placement="bottom-end" :caret="false">
<template #toggler-content>
<CIcon name="cil-location-pin" />
</template>
<CDropdownItem>Action</CDropdownItem>
<CDropdownItem>Another action</CDropdownItem>
<CDropdownItem>Something else here...</CDropdownItem>
<CDropdownItem disabled>Disabled action</CDropdownItem>
</CDropdown>
</template>
<template #footer>
<CChartLineSimple
pointed
class="mt-3 mx-3"
style="height: 70px"
:data-points="[1, 18, 9, 17, 34, 22, 11]"
point-hover-background-color="info"
:options="{ elements: { line: { tension: 0.00001 } } }"
label="Members"
labels="months"
/>
</template>
</CWidgetDropdown>
</CCol>
<CCol sm="6" lg="3">
<CWidgetDropdown color="warning" header="9.823" text="Members online">
<template #default>
<CDropdown color="transparent p-0" placement="bottom-end">
<template #toggler-content>
<CIcon name="cil-settings" />
</template>
<CDropdownItem>Action</CDropdownItem>
<CDropdownItem>Another action</CDropdownItem>
<CDropdownItem>Something else here...</CDropdownItem>
<CDropdownItem disabled>Disabled action</CDropdownItem>
</CDropdown>
</template>
<template #footer>
<CChartLineSimple
class="mt-3"
style="height: 70px"
background-color="rgba(255,255,255,.2)"
:data-points="[78, 81, 80, 45, 34, 12, 40]"
:options="{ elements: { line: { borderWidth: 2.5 } } }"
point-hover-background-color="warning"
label="Members"
labels="months"
/>
</template>
</CWidgetDropdown>
</CCol>
<CCol sm="6" lg="3">
<CWidgetDropdown color="danger" header="9.823" text="Members online">
<template #default>
<CDropdown color="transparent p-0" placement="bottom-end">
<template #toggler-content>
<CIcon name="cil-settings" />
</template>
<CDropdownItem>Action</CDropdownItem>
<CDropdownItem>Another action</CDropdownItem>
<CDropdownItem>Something else here...</CDropdownItem>
<CDropdownItem disabled>Disabled action</CDropdownItem>
</CDropdown>
</template>
<template #footer>
<CChartBarSimple
class="mt-3 mx-3"
style="height: 70px"
background-color="rgb(250, 152, 152)"
label="Members"
labels="months"
/>
</template>
</CWidgetDropdown>
</CCol>
</CRow>
</template>
<script>
export default {
name: 'WidgetsDropdown',
layout: 'admin'
}
</script>
+97
View File
@@ -0,0 +1,97 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div class="agentDetailsModal">
<el-form label-position="top" :model="agent">
<el-form-item label="نوع نماینده">
<el-input v-if="agent.representation_type === 'both'" disabled value="نماینده هر دو نوع لوازم"/>
<el-input v-if="agent.representation_type === 'verity'" disabled value="نماینده لوازم جانبی کامپیوتر و موبایل"/>
<el-input v-if="agent.representation_type === 'panatech'" disabled value="نماینده لوازم صوتی تصویری خودرو"/>
</el-form-item>
<el-form-item label="نام فروشگاه">
<el-input disabled :value="agent.store_name"></el-input>
</el-form-item>
<el-form-item label="کد نماینده">
<el-input disabled :value="agent.agent_code"></el-input>
</el-form-item>
<el-form-item label="نام و نام خانوادگی">
<el-input disabled :value="agent.full_name"></el-input>
</el-form-item>
<el-form-item label="شماره تلفن ثابت">
<el-input disabled :value="agent.tel_number"></el-input>
</el-form-item>
<el-form-item label="شماره فکس">
<el-input disabled :value="agent.fax_number || '-'"></el-input>
</el-form-item>
<el-form-item label="شماره موبایل">
<el-input disabled :value="agent.mobile_number"></el-input>
</el-form-item>
<el-form-item label="ایمیل">
<el-input disabled :value="agent.email"></el-input>
</el-form-item>
<el-form-item label="استان">
<el-input disabled :value="agent.province_name"></el-input>
</el-form-item>
<el-form-item label="شهر">
<el-input disabled :value="agent.city_name"></el-input>
</el-form-item>
<el-form-item label="آدرس" :title="agent.address">
<el-input disabled :value="agent.address"></el-input>
</el-form-item>
<el-form-item label="کد پستی">
<el-input disabled :value="agent.postal_code"></el-input>
</el-form-item>
</el-form>
<div class="btnRow" style="text-align: center">
<a class="btn btn-primary mb-1" :href="`tel: ${agent.mobile_number}`">تماس به همراه</a>
<a class="btn btn-primary mb-1" :href="`tel: ${agent.tel_number}`">تماس به تلفن ثابت</a>
<a class="btn btn-primary mb-1" :href="`mailto: ${agent.email}`">ایمیل</a>
<el-button class="btn btn-primary mb-1" @click="showModal = false">بستن</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AgentDetailsModal',
props: {
show: {
type: Boolean,
default: false
},
agent: {
requred: true,
type: Object,
default: null
}
},
data() {
return {}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
return 'اطلاعات تماس نماینده'
}
}
}
</script>
+136
View File
@@ -0,0 +1,136 @@
<template>
<el-dialog title="پیگیری وضعیت درخواست" :visible.sync="showModal">
<div v-if="!$auth.loggedIn || !$auth.hasScope('user')" class="panel not-logged-in">
<h3>
<span> برای بررسی درخواست نمایندگی باید </span>
<nuxt-link :to="{ name: 'auth-login-register', query: { path: 'representation' } }">وارد حساب کاربری</nuxt-link>
<span>خود شوید.</span>
</h3>
</div>
<div v-else class="checkUploadModalContent">
<div class="repCheckBox">
<form class="form form_3" @submit.prevent="checkRepCode">
<div class="formRow" :class="validation.representation_code && 'err'">
<input
id="repCodeInput"
v-model="repCodeInput"
type="text"
placeholder="کد پیگیری درخواست خود را وارد کنید"
/>
<p v-if="validation.representation_code">{{ validation.representation_code.msg }}</p>
</div>
<div class="formRow">
<button type="submit" class="btn btn-primary">بررسی</button>
</div>
</form>
</div>
<div class="resultBox">
<div class="repInfo" :class="repInfo.status">
<p>
<span>تاریخ ثبت درخواست:</span>
<b> {{ $jDate(repInfo.created_at) }} </b>
</p>
<p>
<span>وضعیت درخواست: </span>
<b v-if="repInfo.status === 'registered'"> ثبت شده در سیستم </b>
<b v-if="repInfo.status === 'ongoing'"> در دست اقدام </b>
<b v-if="repInfo.status === 'verification'"> احراز هویت و بررسی مدارک </b>
<b v-if="repInfo.status === 'accepted'"> تایید شده </b>
<b v-if="repInfo.status === 'rejected'"> رد شده </b>
</p>
<p v-if="repInfo.status !== 'rejected'">
<span>دسترسی برای آپلود مدارک: </span>
<b v-if="repInfo.upload"> دارید </b>
<b v-else> ندارید </b>
</p>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'CheckRepAndUploadDocs',
props: {
show: {
type: Boolean,
default: false
}
},
data() {
return {
checkingRepCode: false,
repCodeInput: '',
repInfo: {},
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
}
},
watch: {
showModal(newVal, oldVal) {
if (newVal) setTimeout(() => $('#repCodeInput').focus(), 300)
}
},
methods: {
showResult() {
const _DU = 0.3
this.$gsap
.timeline({ onCompleted: () => console.log('hiiiiiiiiiiii') })
.to(
$('.checkUploadModalContent'),
{ height: $('.checkUploadModalContent .resultBox').height() + 32, duration: _DU },
0
)
.set($('.checkUploadModalContent .repCheckBox'), { position: 'absolute', left: 0, top: 0 }, 0)
.to($('.checkUploadModalContent .repCheckBox'), { top: '-100%', opacity: 0, duration: _DU }, 0)
.to($('.checkUploadModalContent .resultBox'), { top: 0, opacity: 1, duration: _DU }, 0.05)
.set($('.checkUploadModalContent .resultBox'), { position: 'static' })
.set($('.checkUploadModalContent'), { height: 'auto' })
},
checkRepCode() {
this.validation = {}
this.$axios
.post('/api/user/checkRepresentation', { representation_code: this.repCodeInput?.trim() })
.then(res => {
this.repInfo = res.data
setTimeout(() => this.showResult(), 300)
})
.catch(err => {
if (err.response.status === 422) this.validation = err.response.data.validation
else {
const title = 'خطا'
this.$alert(err.response.data.message, title, {
confirmButtonText: 'بستن'
})
}
})
}
}
}
</script>
@@ -0,0 +1,97 @@
<template>
<div class="panel upload-assets">
<div class="title">
<h3>
<span>درخواست نمایندگی شما با کد</span>
<b>{{ user.representation_code }}</b>
<span>ثبت شده است.</span>
</h3>
</div>
<el-skeleton v-if="loading" class="mt-5" :rows="6" />
<template v-else>
<template v-if="lastRepresentation.upload">
<div class="level-description">
<h3>مرحله دوم ثبت درخواست:</h3>
<p>اطلاعات شما تا این مرجله در سیستم ثبت شده است، لطفا از طریق این صفحه اقدام به بارگذاری مدارک خود کنید.</p>
<p>
تا زمانی که درخواست شما تعیین وضعیت نشده است در هر زمانی میتوانید با مراجعه به همین صفحه مدارک بیشتری
بارگذاری کنید یا مدارک قبلی را ویرایش کنید.
</p>
</div>
<div class="upload-description">
<h3>نکاتی درباره بارگذاری مدارک:</h3>
<ul>
<li>
<span>در هر بخش تصاویر مدارک مربوطه را بارگذاری نمایید.</span>
</li>
<li>
<span>فیلدهای بارگذاری عکس در این صفحه هیچ کدام اجباری نیست.</span>
</li>
<li>
<span>فرمت مجاز تصاور jpeg میباشد.</span>
</li>
<li>
<span>نهایت حجم مجاز برای هر تصویر 2 مگابایت میباشد.</span>
</li>
</ul>
</div>
<div class="upload">
<section v-for="item in agentAssetCategories" :key="item.title">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
<RepresentationImageUploader
:name="item.fieldName"
:files-list="lastRepresentation[item.fieldName] || []"
:representation_code="lastRepresentation.representation_code"
/>
</section>
</div>
</template>
<div v-else class="mt-5" style="text-align: center; color: red">
<h1>شما دسترسی آپلود مدارک ندارید</h1>
</div>
</template>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'EnrollRepresentationAssets',
data() {
return {
lastRepresentation: {},
loading: true
}
},
head() {
return {
title: 'آسان سرویس | آپلود مدارک'
}
},
computed: {
...mapGetters({
agentAssetCategories: 'front/agentAssetCategories'
}),
user() {
return this.$auth.user
},
userFullName() {
return this.user.first_name + ' ' + this.user.last_name
}
},
async mounted() {
try {
const lastRep = await this.$axios.$get(`/api/user/representation/${this.user.representation_code}`)
this.lastRepresentation = lastRep
} catch (err) {
console.log('err', err)
}
this.loading = false
}
}
</script>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
<template>
<div>
<el-upload
:action="uploadUrl"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="handleAvatarSuccess"
:before-upload="validateFile"
:headers="requestHeaders"
:file-list="files"
:before-remove="beforeRemove"
:disabled="disabled"
multiple
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</div>
</template>
<script>
export default {
name: 'RepresentationImageUploader',
props: {
name: {
type: String,
required: true,
default: ''
},
filesList: {
type: Array,
required: true,
default: () => []
},
representation_code: {
type: String,
required: true,
default: ''
},
disabled: {
type: Boolean,
required: false,
default: false
},
isAdmin: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
dialogImageUrl: '',
dialogVisible: false,
requestHeaders: {
authorization: this.$auth?.$storage?._state?.['_token.local'] || ''
}
}
},
computed: {
files() {
return this.filesList.map(item => {
return { id: item._id, name: item.name, url: item.url }
})
},
uploadUrl() {
const adminUrl = `/api/admin/representationImages/admin/${this.representation_code}?name=${this.name}`
const userUrl = `/api/user/representationImages/${this.representation_code}?name=${this.name}`
return this.isAdmin ? adminUrl : userUrl
}
},
methods: {
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw)
},
validateFile(file) {
const isJPG = file.type === 'image/jpeg'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('فقط فرمت jpg قایل قبول است')
}
if (!isLt2M) {
this.$message.error('تصویر نباید بیشتر از 2 مگابایت باشد')
}
return isJPG && isLt2M
},
handleRemove(file, fileList) {
if (!file.raw) {
const adminUrl = `/api/admin/representationImages/admin/${this.representation_code}/${file.id}?name=${this.name}`
const userUrl = `/api/user/representationImages/${this.representation_code}/${file.id}?name=${this.name}`
this.$axios.delete(this.isAdmin ? adminUrl : userUrl)
}
},
beforeRemove(file) {
if (file.raw && !this.validateFile(file.raw)) {
return true
}
const title = 'هشدار'
const msg = 'شما در حال حذف این فایل هستید، ادامه میدهید؟'
return this.$confirm(msg, title, {
confirmButtonText: 'ادامه',
cancelButtonText: 'لغو',
type: 'warning'
})
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
}
}
}
</script>
+244
View File
@@ -0,0 +1,244 @@
<template>
<footer class="site--footer">
<div class="container">
<div class="row">
<section class="col-12 r1">
<a :href="`tel: ${config.supportTel}`">
<span>شماره تماس پشتیبانی: </span>
<b> {{ config.supportTel }} </b>
</a>
<i class="d-none d-md-inline-block"> | </i>
<br class="d-md-none" />
<a :href="`mailto: ${config.supportEmail}`">
<span>ایمیل پشتیبانی: </span>
<b> {{ config.supportEmail }} </b>
</a>
</section>
<section class="col-12 r2">
<ul>
<li>
<img src="/assets/img/footer/guarantee.svg" alt="icon" />
<p>ضمانت بلند مدت</p>
</li>
<li>
<img src="/assets/img/footer/service.svg" alt="icon" />
<p>خدمات با کیفیت</p>
</li>
<li>
<img src="/assets/img/footer/repair.svg" alt="icon" />
<p>نیروی حرفه ای</p>
</li>
<li>
<img src="/assets/img/footer/learning.svg" alt="icon" />
<p>آموزش کاربردی</p>
</li>
<li>
<img src="/assets/img/footer/software.svg" alt="icon" />
<p>نرم افزار به روز</p>
</li>
<li>
<img src="/assets/img/footer/support.svg" alt="icon" />
<p>پشتیبانی آنلاین</p>
</li>
</ul>
</section>
<div class="col-12">
<el-divider></el-divider>
</div>
<section class="col-12 r3">
<nav class="row">
<div class="col-12 col-sm-4 mb-5 mb-sm-0 r3-1">
<h3>صفحات اصلی</h3>
<ul>
<li>
<nuxt-link :to="{ name: 'learning', query: { page: 1 } }">آموزش</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'download', query: { category: 'all', page: 1 } }">دانلود</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'agents' }">لیست نمایندگان</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'representation' }">اخذ نمایندگی</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'contact' }">ارتباط با ما</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'about' }">درباره ما</nuxt-link>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 mb-5 mb-sm-0 r3-2">
<h3>خدمات مشتریان</h3>
<ul>
<li v-if="help && help.helpId">
<nuxt-link :to="{ name: 'learning-post+', params: { post: help.helpId.title } }"
>راهنمای ثبت گارانتی</nuxt-link
>
</li>
<li>
<nuxt-link :to="{ name: 'index' }">استعلام گارانتی</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'warranty-terms', query: { page: 1 } }">شرایط گارانتی</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'FAQ' }">سوالات متداول</nuxt-link>
</li>
<li>
<nuxt-link :to="{ name: 'account-post' }">ارسال کالا برای گارانتی</nuxt-link>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 mb-5 mb-sm-0 r3-3">
<h3>با ما همراه باشید</h3>
<ul>
<li>
<a :href="config.whatsApp" target="_blank">
<img src="/assets/img/footer/whatsapp.svg" alt="icon" />
</a>
</li>
<li>
<a :href="config.instagram" target="_blank">
<img src="/assets/img/footer/instagram.svg" alt="icon" />
</a>
</li>
<li>
<a :href="config.aparat" target="_blank">
<img src="/assets/img/footer/aparat.svg" alt="icon" />
</a>
</li>
</ul>
<div class="newsletter">
<h3>از اخبار مطلع شوید</h3>
<div class="inputBox">
<input v-model="newsletter" type="text" placeholder="ایمیل خودرا وارد کنید" />
<button :disabled="!newsletter.length" @click="registerNewsletter">ثبت</button>
</div>
</div>
</div>
</nav>
</section>
<section class="col-12 apps">
<div class="btns">
<button id="showPwaDialog">
<img src="/assets/img/footer/pwaApp.png" alt="icon" />
</button>
<button>
<a :href="config.andoridAppURL" target="_blank">
<img src="/assets/img/footer/androidApp.png" alt="icon" />
</a>
</button>
</div>
</section>
<section class="col-12 r4">
<div class="bg">
<div class="container-fluid">
<div class="row">
<div class="col-12 col-md-6 logo">
<nuxt-link id="footerTitle" :to="{ name: 'index' }">
<Logo />
</nuxt-link>
</div>
<div class="col-12 col-md-6 companies">
<ul>
<li>
<img src="/assets/img/footer/sony.png" alt="logo" />
</li>
<li>
<img src="/assets/img/footer/apple.png" alt="logo" />
</li>
<li>
<img src="/assets/img/footer/panatech.png" alt="logo" />
</li>
<li>
<img src="/assets/img/footer/verity.png" alt="logo" />
</li>
<li>
<img src="/assets/img/footer/nintendo.png" alt="logo" />
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<section class="col-12 r5">
<h3>آسان سرویس اجرا کننده خدمات پس از فروش</h3>
<p>
امروزه یکی از ارکان اصلی شرکت های تولیدی صنعتی و برندهای تجاری ارائه خدمات پس از فروش است و رضایتمندی
مشتریان از نحوه رسیدگی به هنگام و آگاهی از روند انجام خدمات پس از فروش نقش بسزایی در روند توسعه برندهای
تجاری دارد . آسان سرویس به عنوان بازوی اجرایی خدمات پس از فروش شرکت تولیدی صنعتی پخش صبا درصدد است با به
کارگیری صحیح از منابع انسانی متخصص و نیز مدیریت واحدهای مختلف دپارتمان خدمات پس از فروش ، رضایت مشتریان
گرامی را از لحظه ورود محصول تا انجام خدمت به صورت مطلوب تامین نماید .
</p>
<div class="btns">
<nuxt-link :to="{ name: 'about' }">
<span>بیشتر بخوانید</span>
<i class="fas fa-angle-left"></i>
</nuxt-link>
</div>
</section>
</div>
</div>
<div class="container-fluid">
<div class="row">
<section class="col-12 r6">
<a id="copyright" :href="config.copyrightURL" target="_blank">
Designed and Developed in {{ config.copyrightName }}
</a>
</section>
</div>
</div>
</footer>
</template>
<script>
export default {
data() {
return {
newsletter: '',
help: null
}
},
computed: {
config() {
return this.$config
}
},
mounted() {
// fetch help page info
this.$axios.get('/api/public/help?front=true').then(res => (this.help = res.data))
// split text
const copyright = new this.$ATextSplitter({ rtl: false, letterSpace: 3, wordSpace: 7 })
copyright.injectToElement('copyright')
// animate text
this.$gsap
.timeline({ repeat: -1 })
.from($('#copyright .tsLetters'), { opacity: 0.2, duration: 0.7, stagger: 0.08 })
.to($('#copyright .tsLetters'), { opacity: 0.2, duration: 0.7, stagger: 0.08 }, 0.4)
},
methods: {
registerNewsletter() {
this.newsletter = ''
return this.$message({
type: 'warning',
message: 'مشکلی در ثبت اطلاعات پیش آمده'
})
}
}
}
</script>
+143
View File
@@ -0,0 +1,143 @@
<template>
<aside class="mobile-menu">
<nav class="body">
<ul>
<nuxt-link :to="{ name: 'index' }" exact tag="li">
<a>استعلام گارانتی</a>
</nuxt-link>
<nuxt-link :to="{ name: 'warranty-terms', query: { page: 1 } }" tag="li">
<a>شرایط گارانتی</a>
</nuxt-link>
<nuxt-link :to="{ name: 'download', query: { category: 'all', page: 1 } }" tag="li">
<a>دانلود</a>
</nuxt-link>
<nuxt-link :to="{ name: 'about' }" tag="li">
<a>درباره ما</a>
</nuxt-link>
<nuxt-link :to="{ name: 'contact' }" tag="li">
<a>ارتباط با ما</a>
</nuxt-link>
</ul>
<div class="title">
<!-- <span>نمایندگی</span>-->
</div>
<ul>
<nuxt-link :to="{ name: 'agents' }" tag="li">
<a>لیست نمایندگان</a>
</nuxt-link>
<nuxt-link :to="{ name: 'agent-benefits' }" tag="li">
<a>مزایای نمایندگی</a>
</nuxt-link>
<nuxt-link :to="{ name: 'representation' }" tag="li">
<a>اخذ نمایندگی</a>
</nuxt-link>
</ul>
<div class="title">
<!-- <span>راهنما</span>-->
</div>
<ul>
<nuxt-link :to="{ name: 'learning', query: { page: 1 } }" tag="li">
<a>آموزش</a>
</nuxt-link>
<nuxt-link :to="{ name: 'FAQ' }" tag="li">
<a>سوالات متداول</a>
</nuxt-link>
</ul>
<div class="title">
<!-- <span>حساب کاربری</span>-->
</div>
<ul>
<nuxt-link :to="isUser ? { name: 'account' } : { name: 'auth-login-register' }" tag="li">
<a>
<span v-if="isUser">{{ $auth.user.first_name + ' ' + $auth.user.last_name }}</span>
<span v-else>ورود</span>
<!-- user icon -->
<i v-if="isUser && userHasNotification" class="notificationAnim fas fa-bell"></i>
<i v-else class="fal fa-user"></i>
</a>
</nuxt-link>
</ul>
</nav>
<div class="bg" @click="menu(false)"></div>
</aside>
</template>
<script>
export default {
computed: {
mobileMenu() {
return this.$store.state.front.mobileMenu
},
isUser() {
return this.$auth.loggedIn && this.$auth.user.scope.includes('user')
},
userHasNotification() {
return this.$store.state.front.unreadTickets + this.$store.state.front.agentInbox
}
},
mounted() {
$('#menu').click(() => {
this.menu(!this.mobileMenu)
})
$('.mobile-menu ul li').click(() => {
this.menu(false)
})
},
methods: {
menu(action) {
const _DU = 0.5
const _EASE = 'power4.inOut'
this.$gsap
.timeline({
onComplete: () => {
if (!action) $('.mobile-menu').css({ display: 'none' })
}
})
.set($('.mobile-menu'), { display: 'block' })
.fromTo(
$('.mobile-menu .body'),
{ left: action ? -250 : 0 },
{ left: action ? 0 : -250, duration: _DU, ease: _EASE }
)
.fromTo(
$('.mobile-menu .body li'),
{
x: action ? -30 : 0,
opacity: action ? 0 : 1
},
{
x: action ? 0 : -30,
opacity: action ? 1 : 0,
duration: _DU,
ease: _EASE
},
'-=0.4'
)
.fromTo(
$('.mobile-menu .bg'),
{
opacity: action ? 0 : 1
},
{
opacity: action ? 1 : 0,
duration: _DU
},
0
)
.to(
$('#menu'),
{
opacity: 0,
scale: 0.9,
duration: _DU / 2,
onComplete: () => {
this.$store.commit('front/toggleMobileMenu')
}
},
0
)
.to($('#menu'), { opacity: 1, scale: 1, duration: _DU / 2 }, _DU / 2)
}
}
}
</script>
+124
View File
@@ -0,0 +1,124 @@
<template>
<header class="site--header">
<div class="container-fluid">
<div class="row">
<nav class="col-6 col-lg-2 logo">
<nuxt-link :to="{ name: 'index' }">
<logo />
</nuxt-link>
</nav>
<nav class="col-8 d-none d-lg-block">
<ul class="links">
<li
class="dropDown-container help"
:class="helpDropDownActiveClass && 'active'"
@mouseenter="openDrop('help')"
@mouseleave="closeDrop('help')"
>
<a>
<span>راهنما</span>
<i class="fas fa-angle-down"></i>
</a>
<div class="drop-down">
<nuxt-link
:to="{ name: 'learning', query: { page: 1 } }"
:class="$route.name.includes('learning') && 'active'"
>آموزش</nuxt-link
>
<nuxt-link :to="{ name: 'FAQ' }">سوالات متداول</nuxt-link>
</div>
</li>
<nuxt-link :to="{ name: 'index' }" exact tag="li">
<a>استعلام گارانتی</a>
</nuxt-link>
<nuxt-link :to="{ name: 'warranty-terms', query: { page: 1 } }" tag="li">
<a>شرایط گارانتی</a>
</nuxt-link>
<li
class="dropDown-container agents"
:class="agentsDropDownActiveClass && 'active'"
@mouseenter="openDrop('agents')"
@mouseleave="closeDrop('agents')"
>
<a>
<span>نمایندگان</span>
<i class="fas fa-angle-down"></i>
</a>
<div class="drop-down">
<nuxt-link :to="{ name: 'agents' }">لیست نمایندگان</nuxt-link>
<nuxt-link :to="{ name: 'agent-benefits' }">مزایای نمایندگی</nuxt-link>
<nuxt-link :to="{ name: 'representation' }" :exact="false">اخذ نمایندگی</nuxt-link>
</div>
</li>
<nuxt-link
:to="{ name: 'download', query: { category: 'all', page: 1 } }"
:class="$route.name.includes('download') && 'active'"
tag="li"
>
<a>دانلود</a>
</nuxt-link>
<nuxt-link :to="{ name: 'about' }" tag="li">
<a>درباره ما</a>
</nuxt-link>
<nuxt-link :to="{ name: 'contact' }" tag="li">
<a>ارتباط با ما</a>
</nuxt-link>
</ul>
</nav>
<nav class="col-2 d-none d-lg-flex account">
<nuxt-link :to="isUser ? { name: 'account' } : { name: 'auth-login-register' }">
<span v-if="isUser" class="singleLineTxt" :title="fullName">{{ fullName }}</span>
<span v-else>ورود</span>
<i v-if="isUser && userHasNotification" class="notificationAnim fas fa-bell"></i>
<i v-else class="fal fa-user"></i>
</nuxt-link>
</nav>
<div class="col-6 d-flex d-lg-none align-items-center justify-content-end menu">
<i id="menu" class="far" :class="!mobileMenu ? 'fa-bars' : 'fa-chevron-left'"></i>
</div>
</div>
</div>
</header>
</template>
<script>
import WS_User from '@/mixins/WS_User'
import WS_Agent from '@/mixins/WS_Agent'
export default {
mixins: [WS_User, WS_Agent],
data() {
return {}
},
computed: {
mobileMenu() {
return this.$store.state.front.mobileMenu
},
isUser() {
return this.$auth.loggedIn && this.$auth.user.scope.includes('user')
},
userHasNotification() {
const store = this.$store.state.front
return store.unreadTickets + store.agentInbox + store.newUserAnnosCount + store.newAgentAnnosCount
},
helpDropDownActiveClass() {
return this.$route.name === 'learning' || this.$route.name === 'learning-post+' || this.$route.name === 'FAQ'
},
agentsDropDownActiveClass() {
return this.$route.name === 'representation' || this.$route.name === 'agent-benefits'
},
fullName() {
return this.$auth.user.first_name + ' ' + this.$auth.user.last_name
}
},
methods: {
openDrop(name) {
$(`.dropDown-container.${name}`).addClass('d-active')
},
closeDrop(name) {
$(`.dropDown-container.${name}`).removeClass('d-active')
}
}
}
</script>
+94
View File
@@ -0,0 +1,94 @@
<template>
<svg viewBox="0 0 71 71" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<path
fill="#1b3545"
opacity="1.00"
d=" M 28.74 0.00 L 34.10 0.00 C 33.02 1.52 31.05 1.66 29.38 1.27 L 28.92 0.70 L 28.74 0.00 Z"
/>
<path
fill="#1b3545"
opacity="1.00"
d=" M 37.63 0.00 L 41.28 0.00 L 42.04 0.62 L 42.15 1.17 C 40.55 1.93 38.66 1.44 37.63 0.00 Z"
/>
<path
fill="#1b3545"
opacity="1.00"
d=" M 9.85 47.79 C 14.44 46.13 19.29 44.70 24.15 44.52 C 25.20 48.92 26.58 53.31 28.31 57.47 C 29.25 61.59 30.93 65.54 32.03 69.64 L 32.29 70.57 C 21.00 69.86 10.49 62.90 4.92 53.16 C 5.93 50.87 7.87 49.22 9.85 47.79 Z"
/>
<path
fill="#1b3545"
opacity="1.00"
d=" M 42.78 59.43 C 44.99 54.66 46.11 49.39 47.83 44.41 C 50.42 44.20 52.74 45.64 55.31 45.49 C 59.61 46.45 64.66 48.21 66.27 52.74 C 60.98 62.37 50.84 69.47 39.79 70.42 C 40.31 66.62 42.12 63.17 42.78 59.43 Z"
/>
</g>
<g>
<path
fill="#0c0a0b"
opacity="1.00"
d=" M 34.10 0.00 L 37.63 0.00 C 38.66 1.44 40.55 1.93 42.15 1.17 C 45.42 2.46 49.09 4.05 50.63 7.46 C 52.37 11.28 52.33 15.63 51.92 19.73 C 51.30 21.29 50.24 22.60 49.42 24.05 C 50.53 21.21 47.36 19.64 46.64 17.17 C 45.60 14.50 42.90 13.14 40.20 12.75 C 36.54 13.46 34.02 17.60 30.00 16.49 C 27.73 16.57 25.95 13.82 23.76 14.65 C 23.73 17.83 22.10 20.69 22.47 23.92 C 21.86 22.67 21.15 21.47 20.40 20.30 C 19.93 16.41 18.50 12.24 20.49 8.53 C 21.61 4.52 25.71 2.43 29.38 1.27 C 31.05 1.66 33.02 1.52 34.10 0.00 Z"
/>
</g>
<g>
<path
fill="#f6f6f6"
opacity="1.00"
d=" M 8.62 12.65 C 13.68 6.38 21.11 2.39 28.92 0.70 L 29.38 1.27 C 25.71 2.43 21.61 4.52 20.49 8.53 C 18.50 12.24 19.93 16.41 20.40 20.30 C 17.05 21.21 18.70 24.97 20.22 26.81 C 23.04 29.84 25.07 33.48 27.17 37.03 C 27.22 38.22 27.27 39.42 27.33 40.62 C 22.69 45.53 14.62 43.30 9.85 47.79 C 7.87 49.22 5.93 50.87 4.92 53.16 C 1.70 47.94 0.38 41.81 0.00 35.75 L 0.00 35.21 C 0.32 27.05 3.07 18.77 8.62 12.65 Z"
/>
<path
fill="#f6f6f6"
opacity="1.00"
d=" M 42.15 1.17 L 42.04 0.62 C 49.81 2.46 57.33 6.30 62.34 12.65 C 67.92 18.77 70.67 27.06 71.00 35.24 L 71.00 35.78 C 70.60 41.66 69.39 47.65 66.27 52.74 C 64.66 48.21 59.61 46.45 55.31 45.49 C 51.91 43.24 47.19 44.11 44.36 40.82 C 44.34 40.01 44.30 38.38 44.28 37.57 C 46.52 33.85 48.46 29.74 51.86 26.90 C 53.69 25.00 54.69 21.33 51.92 19.73 C 52.33 15.63 52.37 11.28 50.63 7.46 C 49.09 4.05 45.42 2.46 42.15 1.17 Z"
/>
<path
fill="#f6f6f6"
opacity="1.00"
d=" M 28.31 57.47 C 29.92 56.62 31.53 55.76 32.97 54.63 C 34.69 59.48 32.23 64.65 32.03 69.64 C 30.93 65.54 29.25 61.59 28.31 57.47 Z"
/>
<path
fill="#f6f6f6"
opacity="1.00"
d=" M 38.86 54.55 C 40.46 55.93 42.88 56.93 42.78 59.43 C 42.12 63.17 40.31 66.62 39.79 70.42 L 39.79 70.42 C 39.77 65.14 37.00 59.70 38.86 54.55 Z"
/>
</g>
<g>
<path
fill="#edcaa8"
opacity="1.00"
d=" M 30.00 16.49 C 34.02 17.60 36.54 13.46 40.20 12.75 C 42.90 13.14 45.60 14.50 46.64 17.17 C 47.36 19.64 50.53 21.21 49.42 24.05 C 50.24 22.60 51.30 21.29 51.92 19.73 C 54.69 21.33 53.69 25.00 51.86 26.90 C 48.46 29.74 46.52 33.85 44.28 37.57 C 41.40 39.03 38.76 41.82 35.30 41.50 C 32.73 40.79 30.63 39.01 28.23 37.92 C 28.09 38.71 27.81 40.27 27.68 41.06 L 27.33 40.62 C 27.27 39.42 27.22 38.22 27.17 37.03 C 25.07 33.48 23.04 29.84 20.22 26.81 C 18.70 24.97 17.05 21.21 20.40 20.30 C 21.15 21.47 21.86 22.67 22.47 23.92 C 22.10 20.69 23.73 17.83 23.76 14.65 C 25.95 13.82 27.73 16.57 30.00 16.49 Z"
/>
</g>
<g>
<path
fill="#e1ac88"
opacity="1.00"
d=" M 28.23 37.92 C 30.63 39.01 32.73 40.79 35.30 41.50 C 38.76 41.82 41.40 39.03 44.28 37.57 C 44.30 38.38 44.34 40.01 44.36 40.82 C 41.47 44.64 38.17 48.31 36.29 52.77 C 36.09 52.73 35.69 52.64 35.49 52.60 C 33.48 48.39 30.45 44.78 27.68 41.06 C 27.81 40.27 28.09 38.71 28.23 37.92 Z"
/>
</g>
<g>
<path
fill="#cbcbcb"
opacity="1.00"
d=" M 9.85 47.79 C 14.62 43.30 22.69 45.53 27.33 40.62 L 27.68 41.06 C 30.45 44.78 33.48 48.39 35.49 52.60 C 34.66 53.28 33.82 53.96 32.97 54.63 C 31.53 55.76 29.92 56.62 28.31 57.47 C 26.58 53.31 25.20 48.92 24.15 44.52 C 19.29 44.70 14.44 46.13 9.85 47.79 Z"
/>
<path
fill="#cbcbcb"
opacity="1.00"
d=" M 44.36 40.82 C 47.19 44.11 51.91 43.24 55.31 45.49 C 52.74 45.64 50.42 44.20 47.83 44.41 C 46.11 49.39 44.99 54.66 42.78 59.43 C 42.88 56.93 40.46 55.93 38.86 54.55 C 38.04 53.91 37.18 53.32 36.29 52.77 C 38.17 48.31 41.47 44.64 44.36 40.82 Z"
/>
</g>
<g>
<path
fill="#ac0101"
opacity="1.00"
d=" M 32.97 54.63 C 33.82 53.96 34.66 53.28 35.49 52.60 C 35.69 52.64 36.09 52.73 36.29 52.77 C 37.18 53.32 38.04 53.91 38.86 54.55 C 37.00 59.70 39.77 65.14 39.79 70.42 C 38.44 70.62 37.10 70.81 35.75 71.00 L 34.54 71.00 C 33.97 70.89 32.85 70.68 32.29 70.57 L 32.03 69.64 C 32.23 64.65 34.69 59.48 32.97 54.63 Z"
/>
</g>
</svg>
</template>
<script>
export default {
name: 'UserIconSVG'
}
</script>
+148
View File
@@ -0,0 +1,148 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 178.678 47.133">
<g transform="translate(111.26 -6.5)">
<g transform="translate(-129.36 -45)">
<path
d="M31.039,152.2l-2.864,10.174H26.792l-2.173-8.4-2.272,8.4H20.964L18.1,152.2h1.087l2.469,8.89,2.469-8.89h.988l2.371,8.89,2.568-8.89Z"
transform="translate(0 -70.408)"
fill="#ffe"
/>
<path
d="M40.8,162.4h-.988v-1.383a3.128,3.128,0,0,1-2.963,1.58,3.874,3.874,0,0,1-1.778-.4,4.451,4.451,0,0,1-1.383-.988A3.7,3.7,0,0,1,33,160.034a3.963,3.963,0,0,1-.3-1.482,3.155,3.155,0,0,1,.3-1.383,5.6,5.6,0,0,1,.79-1.284A3.758,3.758,0,0,1,35.071,155a4.613,4.613,0,0,1,1.679-.3,3.874,3.874,0,0,1,1.778.4,2.745,2.745,0,0,1,1.185,1.185V154.8H40.7l.1,7.606Zm-.988-3.753a2.69,2.69,0,0,0-.889-2.074,2.843,2.843,0,0,0-2.074-.889,3.064,3.064,0,0,0-2.173.889,2.843,2.843,0,0,0-.889,2.074,2.69,2.69,0,0,0,.889,2.074,3.064,3.064,0,0,0,2.173.889,2.843,2.843,0,0,0,2.074-.889,2.69,2.69,0,0,0,.889-2.074"
transform="translate(-0.179 -70.438)"
fill="#ffe"
/>
<path
d="M46.662,155.688a2.08,2.08,0,0,0-1.284.494,1.576,1.576,0,0,0-.691.889,2.135,2.135,0,0,0-.1,1.087V162.4H43.6V154.9h.988v1.086a2.162,2.162,0,0,1,.889-.988,3.155,3.155,0,0,1,1.383-.3Z"
transform="translate(-0.313 -70.438)"
fill="#ffe"
/>
<path
d="M51.662,155.688a2.08,2.08,0,0,0-1.284.494,1.576,1.576,0,0,0-.691.889,2.135,2.135,0,0,0-.1,1.087V162.4H48.6V154.9h.988v1.086a2.162,2.162,0,0,1,.889-.988,3.155,3.155,0,0,1,1.383-.3Z"
transform="translate(-0.374 -70.438)"
fill="#ffe"
/>
<path
d="M61.2,162.4h-.988v-1.383a3.128,3.128,0,0,1-2.963,1.58,3.874,3.874,0,0,1-1.778-.4,4.451,4.451,0,0,1-1.383-.988,3.7,3.7,0,0,1-.691-1.185,3.963,3.963,0,0,1-.3-1.482,3.155,3.155,0,0,1,.3-1.383A4.439,4.439,0,0,1,55.471,155a4.613,4.613,0,0,1,1.679-.3,3.874,3.874,0,0,1,1.778.4,2.745,2.745,0,0,1,1.185,1.185V154.8H61.1l.1,7.606Zm-.988-3.753a2.69,2.69,0,0,0-.889-2.074,2.843,2.843,0,0,0-2.074-.889,3.064,3.064,0,0,0-2.173.889,2.843,2.843,0,0,0-.889,2.074,2.69,2.69,0,0,0,.889,2.074,3.064,3.064,0,0,0,2.173.889,2.843,2.843,0,0,0,2.074-.889,2.4,2.4,0,0,0,.889-2.074"
transform="translate(-0.43 -70.438)"
fill="#ffe"
/>
<path
d="M70.617,162.4h-.988v-3.951a3.7,3.7,0,0,0-.1-1.087,2.05,2.05,0,0,0-.593-.988,1.809,1.809,0,0,0-1.679-.593,4.2,4.2,0,0,0-1.086.2,5.473,5.473,0,0,0-.79.593,1.985,1.985,0,0,0-.4.79,4.052,4.052,0,0,0-.1,1.087V162.4H63.9V154.9h.988v1.086a2.779,2.779,0,0,1,2.371-1.284,3.963,3.963,0,0,1,1.482.3,3.407,3.407,0,0,1,1.185.889,2.253,2.253,0,0,1,.593,1.185,3.288,3.288,0,0,1,.1,1.383Z"
transform="translate(-0.562 -70.438)"
fill="#ffe"
/>
<path
d="M76.946,155.756H75.168v6.618H74.18v-6.618H72.6v-.889h1.58V152.2h.988v2.667h1.778Z"
transform="translate(-0.669 -70.408)"
fill="#ffe"
/>
<path
d="M85.31,154.9l-4.445,10.174h-.988l1.185-2.864L78.1,154.9h1.087l2.469,5.926,2.469-5.926Z"
transform="translate(-0.736 -70.441)"
fill="#ffe"
/>
<path
d="M98.323,159.6a2.69,2.69,0,0,1-.889,2.074,3.064,3.064,0,0,1-2.173.889,3.3,3.3,0,0,1-2.272-.889,2.7,2.7,0,0,1-.889-2.173h1.086a2.178,2.178,0,0,0,.593,1.482,2.074,2.074,0,0,0,3.556-1.482,1.861,1.861,0,0,0-.2-.79,1.772,1.772,0,0,0-.494-.691,1.593,1.593,0,0,0-.691-.4c-.3-.1-.691-.2-.988-.3a6.137,6.137,0,0,1-.988-.3,3.468,3.468,0,0,1-.79-.494,1.537,1.537,0,0,1-.593-.79,1.954,1.954,0,0,1-.2-1.087,2.487,2.487,0,0,1,.889-1.975,3.187,3.187,0,0,1,2.074-.79,2.936,2.936,0,0,1,1.975.79,2.758,2.758,0,0,1,.79,1.975H97.038a1.878,1.878,0,0,0-.494-1.284,2.36,2.36,0,0,0-1.383-.494,2.081,2.081,0,0,0-1.284.494,1.878,1.878,0,0,0-.494,1.284,1.485,1.485,0,0,0,.4,1.087,2.6,2.6,0,0,0,1.482.691,11.743,11.743,0,0,0,1.383.4,3.548,3.548,0,0,1,.988.691,3.48,3.48,0,0,1,.691,2.074"
transform="translate(-0.908 -70.404)"
fill="#ffe"
/>
<path
d="M108,159.045h-6.815a2.112,2.112,0,0,0,.889,1.778,2.937,2.937,0,0,0,1.975.79,2.985,2.985,0,0,0,1.58-.494,2.513,2.513,0,0,0,1.087-1.185H107.8a3.967,3.967,0,1,1-7.507-2.568,3.866,3.866,0,0,1,.988-1.58,3.738,3.738,0,0,1,2.766-1.185,3.956,3.956,0,0,1,2.864,1.185,5,5,0,0,1,1.086,3.26m-.988-.988a2.668,2.668,0,0,0-.988-1.679,2.892,2.892,0,0,0-3.753,0,2.908,2.908,0,0,0-.988,1.778h5.729Z"
transform="translate(-1.006 -70.437)"
fill="#ffe"
/>
<path
d="M113.462,155.688a1.878,1.878,0,0,0-1.284.494,1.97,1.97,0,0,0-.79,1.975V162.4H110.4V154.9h.988v1.086a2.162,2.162,0,0,1,.889-.988,3.155,3.155,0,0,1,1.383-.3Z"
transform="translate(-1.132 -70.438)"
fill="#ffe"
/>
<path
d="M122.008,154.9l-3.161,7.507h-1.087L114.6,154.9h1.087l2.667,6.223,2.568-6.223Z"
transform="translate(-1.184 -70.441)"
fill="#ffe"
/>
<path
d="M135.1,157.168h-1.185a2.869,2.869,0,0,0-1.087-1.087,2.787,2.787,0,0,0-1.482-.4,3.452,3.452,0,0,0-2.173.79,2.69,2.69,0,0,0-.889,2.074,2.91,2.91,0,0,0,2.963,2.963,2.787,2.787,0,0,0,1.482-.4,3.14,3.14,0,0,0,1.185-1.087H135a4.228,4.228,0,0,1-1.482,1.778,3.459,3.459,0,0,1-2.173.593,4.56,4.56,0,0,1-2.963-1.086,3.476,3.476,0,0,1-1.185-2.864,3.587,3.587,0,0,1,1.185-2.766,3.517,3.517,0,0,1,2.864-1.086,3.843,3.843,0,0,1,2.272.691,3.633,3.633,0,0,1,1.58,1.877"
transform="translate(-1.339 -70.437)"
fill="#ffe"
/>
<path
d="M145,159.047h-6.815a2.112,2.112,0,0,0,.889,1.778,2.937,2.937,0,0,0,1.975.79,2.985,2.985,0,0,0,1.58-.494,2.513,2.513,0,0,0,1.087-1.185H144.8a4.281,4.281,0,0,1-3.753,2.667,3.88,3.88,0,0,1-2.766-1.087,3.737,3.737,0,0,1-1.185-2.766,3.587,3.587,0,0,1,1.185-2.766,3.738,3.738,0,0,1,2.766-1.185,3.956,3.956,0,0,1,2.864,1.185A3.809,3.809,0,0,1,145,159.047m-.988-.988a2.669,2.669,0,0,0-.988-1.679,2.893,2.893,0,0,0-3.753,0,2.908,2.908,0,0,0-.988,1.778h5.729Z"
transform="translate(-1.46 -70.439)"
fill="#ffe"
/>
<rect width="3.26" height="10.667" transform="translate(140.282 62.137)" fill="#ffe" />
<rect width="4.346" height="1.58" transform="translate(139.788 59.075)" fill="#ffe" />
<path
d="M60.6,136.944a6.1,6.1,0,0,0,5.926,6.025H68.5v.988a.556.556,0,0,1-.691.593H66.329v3.161a6,6,0,0,0,5.433-5.926V132.4H65.045a4.577,4.577,0,0,0-4.445,4.544m8,2.667H64.748a.885.885,0,0,1-.889-.889h0V136.45a.885.885,0,0,1,.889-.889H68.6Z"
transform="translate(-0.522 -70.165)"
fill="#ffe"
/>
<path
d="M124.26,138.781V129.2H121v7.7a5.986,5.986,0,0,0,6.025,6.025h12.84v-3.26H125.148a.885.885,0,0,1-.889-.889"
transform="translate(-1.262 -70.125)"
fill="#ffe"
/>
<path
d="M78.433,139.215V132.4h-3.26v11.655a.661.661,0,0,1-.593.691H73v3.161a5.935,5.935,0,0,0,5.433-5.531,3.9,3.9,0,0,0,2.766.691H96.31v-3.26H79.025c-.3-.1-.593-.3-.593-.593"
transform="translate(-0.674 -70.165)"
fill="#ffe"
/>
<path
d="M115.907,143.561a.885.885,0,0,1-.889.889H103.66V132.4H100.4v15.31h13.927a4.848,4.848,0,0,0,4.84-4.84h0V132.4h-3.259Z"
transform="translate(-1.01 -70.165)"
fill="#ffe"
/>
<path
d="M109.88,132.361a1.58,1.58,0,1,0-1.58-1.58h0a1.56,1.56,0,0,0,1.58,1.58"
transform="translate(-1.107 -70.125)"
fill="#ffe"
/>
<path
d="M55.98,144.9a1.58,1.58,0,1,0,1.58,1.58h0a1.56,1.56,0,0,0-1.58-1.58"
transform="translate(-0.445 -70.318)"
fill="#ffe"
/>
<path
d="M52.68,144.9a1.58,1.58,0,1,0,1.58,1.58h0a1.56,1.56,0,0,0-1.58-1.58h0"
transform="translate(-0.405 -70.318)"
fill="#ffe"
/>
<path
d="M54.65,132.4v6.618a.661.661,0,0,1-.593.691h-16.1a.556.556,0,0,1-.593-.691V132.4H34.1v11.161a.885.885,0,0,1-.889.889H21.66V132.4H18.4v15.31H31.339c3.951,0,5.729-2.074,5.926-5.334a4.086,4.086,0,0,0,1.877.494H52.773c3.062-.1,5.136-2.864,5.136-5.926V132.4Z"
transform="translate(-0.004 -70.165)"
fill="#ffe"
/>
<path
d="M124.988,153.882H124V152.4h.988Zm0,8.494H124v-7.507h.988Z"
transform="translate(-1.3 -70.41)"
fill="#ffe"
/>
</g>
<g>
<path
d="M46.766,6.5A23.566,23.566,0,1,0,70.333,30.066,23.553,23.553,0,0,0,46.766,6.5m0,45.119a21.553,21.553,0,1,1,21.6-21.553,21.532,21.532,0,0,1-21.6,21.553"
transform="translate(-2.915)"
fill="#ffe"
/>
<path
d="M75.868,20.943V38.253a1.977,1.977,0,0,1-.857,1.671L68.584,44.38h0l-6.427-4.413A2.033,2.033,0,0,1,61.3,38.3V20.943a17.97,17.97,0,0,1,14.568,0"
transform="translate(-24.689 -7.373)"
fill="#ffe"
/>
<path
d="M54.139,60.793A18.041,18.041,0,0,1,42.827,28.7V45.239a2.733,2.733,0,0,0,1.2,2.314l8.741,6.042a2.53,2.53,0,0,0,2.785,0l8.784-6.042a2.733,2.733,0,0,0,1.2-2.314v-16.5a18.057,18.057,0,0,1-11.4,32.05"
transform="translate(-10.287 -12.688)"
fill="#ffe"
/>
</g>
</g>
</svg>
</template>
<script>
export default {
name: 'AsanServiceLogoSVG'
}
</script>
@@ -0,0 +1,167 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div v-loading="fetchingBuffers" class="addPtoPrModal">
<el-form label-position="top" :model="formData">
<el-form-item label="نام کالا" :class="validation.ItemName && 'err'">
<el-select v-model="selectedItem" filterable style="width: 100%">
<el-option-group label="لوازم جانبی کامپیوتر و موبایل">
<el-option
v-for="item in verityProducts"
:key="item.ItemID + '_V'"
:value="item.ItemID + '__v'"
:label="item.ItemName"
></el-option>
</el-option-group>
<el-option-group label="لوازم صوتی و تصویری خودرو">
<el-option
v-for="item in panatechProducts"
:key="item.ItemID + '_P'"
:value="item.ItemID + '__p'"
:label="item.ItemName"
></el-option>
</el-option-group>
</el-select>
<p v-if="validation.ItemName" class="errMsg">{{ validation.ItemName.msg }}</p>
</el-form-item>
<el-form-item label="تعداد درخواستی" :class="validation.bufferQuantity && 'err'">
<el-input
v-model="formData.bufferQuantity"
placeholder="تعداد را وارد کنید"
@input="normalizeQuantityInput"
></el-input>
<p v-if="validation.bufferQuantity" class="errMsg">{{ validation.bufferQuantity.msg }}</p>
</el-form-item>
</el-form>
<div class="btnRow">
<el-button class="btn btn-primary custom-el-button" :loading="postingForm" @click="add">افزودن</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddBuffersToBufferRequest',
props: {
show: {
type: Boolean,
default: false
},
brId: {
requred: true,
type: String,
default: null
}
},
data() {
return {
fetchingBuffers: false,
postingForm: false,
selectedItem: '',
formData: {
ItemName: '',
ItemID: '',
ItemCode: '',
bufferQuantity: ''
},
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
return 'افزودن کالای بافر به فرم'
},
bufferQuantity() {
return this.formData.bufferQuantity
},
verityProducts() {
return this.$store.state.front.verityProducts
},
panatechProducts() {
return this.$store.state.front.panatechProducts
}
},
watch: {
selectedItem() {
const selectedItem = this.selectedItem
let ItemID, db_name
if (selectedItem.includes('__v')) {
ItemID = selectedItem.replace('__v', '')
db_name = 'verity'
} else if (selectedItem.includes('__p')) {
ItemID = selectedItem.replace('__p', '')
db_name = 'panatech'
} else {
return this.$message({
type: 'error',
message: 'Invalid Value'
})
}
// find product
let products
if (db_name === 'verity') products = this.verityProducts
if (db_name === 'panatech') products = this.panatechProducts
const item = products.find(item => item.ItemID === ItemID)
this.formData.ItemName = item?.ItemName
this.formData.ItemID = item?.ItemID
this.formData.ItemCode = item?.ItemCode
}
},
methods: {
normalizeQuantityInput() {
this.formData.bufferQuantity = this.formData.bufferQuantity.toString().replace(/[^0-9]/g, '')
if (
this.formData.bufferQuantity === '' ||
this.formData.bufferQuantity === null ||
this.formData.bufferQuantity < 1
) {
this.formData.bufferQuantity = 1
}
},
add() {
this.validation = {}
this.postingForm = true
const data = this.formData
this.$axios
.put(`/api/agent/addBrItems/${this.brId}`, data)
.then(res => {
this.postingForm = false
this.showModal = false
this.$message({
type: 'success',
message: 'کالای بافر درخواستی به فرم افزوده شد'
})
this.$nuxt.refresh()
})
.catch(err => {
this.postingForm = false
if (err.response.status === 422) {
this.$message({
type: 'warning',
message: 'پارامترها رو بررسی و دوباره تلاش کنید'
})
this.validation = err.response.data.validation
} else {
this.$message({
type: 'error',
message: err.response?.data?.message
})
}
})
}
}
}
</script>
@@ -0,0 +1,207 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div v-loading="fetchingPieces" class="addPtoPrModal">
<el-form label-position="top" :model="formData">
<h3 class="mb-3">مشخصات کالا:</h3>
<el-form-item label="تاریخ پذیرش" :class="validation.ItemReceptionTransDate && 'err'">
<div class="datePickerWrapper">
<persian-date-picker
v-model="formData.ItemReceptionTransDate"
display-format="jYYYY/jMM/jDD"
format="YYYY-MM-DD HH:mm:ss"
placeholder="تاریخ را انتخاب کنید"
color="#065495"
/>
</div>
<p v-if="validation.ItemReceptionTransDate" class="errMsg">{{ validation.ItemReceptionTransDate.msg }}</p>
</el-form-item>
<el-form-item label="نام کالا" :class="validation.ItemName && 'err'">
<el-select v-model="selectedItem" filterable style="width: 100%">
<el-option-group label="لوازم جانبی کامپیوتر و موبایل">
<el-option
v-for="item in verityProducts"
:key="item.ItemID + '_V'"
:value="item.ItemID + '__v'"
:label="item.ItemName"
></el-option>
</el-option-group>
<el-option-group label="لوازم صوتی و تصویری خودرو">
<el-option
v-for="item in panatechProducts"
:key="item.ItemID + '_P'"
:value="item.ItemID + '__p'"
:label="item.ItemName"
></el-option>
</el-option-group>
</el-select>
<p v-if="validation.ItemName" class="errMsg">{{ validation.ItemName.msg }}</p>
</el-form-item>
<el-form-item label="سریال">
<el-input v-model="formData.SerialNo1" placeholder="اختیاری"></el-input>
</el-form-item>
<h3 class="mb-3">مشخصات قطعه درخواستی:</h3>
<el-form-item label="نام قطعه" :class="validation.pieceName && 'err'">
<el-select v-model="selectedPiece" filterable style="width: 100%">
<el-option
v-for="item in pieces"
:key="item._id"
:value="item._id"
:label="item.name + ` ( کد: ${item.code} ) `"
></el-option>
</el-select>
<p v-if="validation.pieceName" class="errMsg">{{ validation.pieceName.msg }}</p>
</el-form-item>
</el-form>
<div class="btnRow">
<el-button class="btn btn-primary custom-el-button" :loading="postingForm" @click="add">افزودن</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddOldPiecesToOldPieceRequest',
props: {
show: {
type: Boolean,
default: false
},
oprId: {
requred: true,
type: String,
default: null
}
},
data() {
return {
fetchingPieces: false,
postingForm: false,
pieces: [],
selectedItem: '',
selectedPiece: '',
formData: {
ItemReceptionTransDate: '',
ItemName: '',
SerialNo1: '',
ItemID: '',
ItemCode: '',
// piece info
pieceName: '',
pieceCode: '',
pieceId: ''
},
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
return 'افزودن قطعه داغی به فرم'
},
verityProducts() {
return this.$store.state.front.verityProducts
},
panatechProducts() {
return this.$store.state.front.panatechProducts
}
},
watch: {
showModal(newVal, oldVal) {
if (newVal) {
this.fetchingPieces = true
this.$axios
.get('/api/agent/pieces')
.then(res => {
this.fetchingPieces = false
this.pieces = res.data
})
.catch(err => {
console.log(err)
})
}
},
selectedItem() {
const selectedItem = this.selectedItem
let ItemID, db_name
if (selectedItem.includes('__v')) {
ItemID = selectedItem.replace('__v', '')
db_name = 'verity'
} else if (selectedItem.includes('__p')) {
ItemID = selectedItem.replace('__p', '')
db_name = 'panatech'
} else {
return this.$message({
type: 'error',
message: 'Invalid Value'
})
}
// find product
let products
if (db_name === 'verity') products = this.verityProducts
if (db_name === 'panatech') products = this.panatechProducts
const item = products.find(item => item.ItemID === ItemID)
this.formData.ItemName = item?.ItemName
this.formData.ItemID = item?.ItemID
this.formData.ItemCode = item?.ItemCode
},
selectedPiece() {
const item = this.pieces.find(item => item._id === this.selectedPiece)
this.formData.pieceId = item?._id
this.formData.pieceName = item?.name
this.formData.pieceCode = item?.code
}
},
methods: {
add() {
this.validation = {}
this.postingForm = true
const data = this.formData
this.$axios
.put(`/api/agent/addOprItems/${this.oprId}`, data)
.then(res => {
this.postingForm = false
this.showModal = false
this.$message({
type: 'success',
message: 'قطعه داغی درخواستی به فرم افزوده شد'
})
this.$nuxt.refresh()
})
.catch(err => {
this.postingForm = false
if (err.response.status === 422) {
this.$message({
type: 'warning',
message: 'پارامترها رو بررسی و دوباره تلاش کنید'
})
this.validation = err.response.data.validation
} else {
this.$message({
type: 'error',
message: err.response?.data?.message
})
}
})
}
}
}
</script>
@@ -0,0 +1,239 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div v-loading="fetchingPieces" class="addPtoPrModal">
<el-form label-position="top" :model="formData">
<h3 class="mb-3">مشخصات کالا:</h3>
<el-form-item label="تاریخ پذیرش" :class="validation.ItemReceptionTransDate && 'err'">
<div class="datePickerWrapper">
<persian-date-picker
v-model="formData.ItemReceptionTransDate"
display-format="jYYYY/jMM/jDD"
format="YYYY-MM-DD HH:mm:ss"
placeholder="تاریخ را انتخاب کنید"
color="#065495"
/>
</div>
<p v-if="validation.ItemReceptionTransDate" class="errMsg">{{ validation.ItemReceptionTransDate.msg }}</p>
</el-form-item>
<el-form-item label="نام کالا" :class="validation.ItemName && 'err'">
<el-select v-model="selectedItem" filterable style="width: 100%">
<el-option-group label="لوازم جانبی کامپیوتر و موبایل">
<el-option
v-for="item in verityProducts"
:key="item.ItemID + '_V'"
:value="item.ItemID + '__v'"
:label="item.ItemName"
></el-option>
</el-option-group>
<el-option-group label="لوازم صوتی و تصویری خودرو">
<el-option
v-for="item in panatechProducts"
:key="item.ItemID + '_P'"
:value="item.ItemID + '__p'"
:label="item.ItemName"
></el-option>
</el-option-group>
</el-select>
<p v-if="validation.ItemName" class="errMsg">{{ validation.ItemName.msg }}</p>
</el-form-item>
<el-form-item label="سریال">
<el-input v-model="formData.SerialNo1" placeholder="اختیاری"></el-input>
</el-form-item>
<el-form-item label="وضعیت گارانتی" :class="validation.gStatus && 'err'">
<el-select v-model="formData.gStatus" style="width: 100%">
<el-option :value="true" label="دارد"></el-option>
<el-option :value="false" label="ندارد"></el-option>
</el-select>
<p v-if="validation.gStatus" class="errMsg">{{ validation.gStatus.msg }}</p>
</el-form-item>
<h3 class="mb-3">مشخصات قطعه درخواستی:</h3>
<el-form-item label="نام قطعه" :class="validation.pieceName && 'err'">
<el-select v-model="selectedPiece" filterable style="width: 100%">
<el-option
v-for="item in pieces"
:key="item._id"
:value="item._id"
:label="item.name + ` ( کد: ${item.code} ) `"
></el-option>
</el-select>
<p v-if="validation.pieceName" class="errMsg">{{ validation.pieceName.msg }}</p>
</el-form-item>
<el-form-item label="تعداد درخواستی" :class="validation.pieceQuantity && 'err'">
<el-input
v-model="formData.pieceQuantity"
placeholder="تعداد را وارد کنید"
@input="normalizeQuantityInput"
></el-input>
<p v-if="validation.pieceQuantity" class="errMsg">{{ validation.pieceQuantity.msg }}</p>
</el-form-item>
</el-form>
<div class="btnRow">
<el-button class="btn btn-primary custom-el-button" :loading="postingForm" @click="add">افزودن</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddPiecesToPieceRequest',
props: {
show: {
type: Boolean,
default: false
},
prId: {
requred: true,
type: String,
default: null
}
},
data() {
return {
fetchingPieces: false,
postingForm: false,
pieces: [],
selectedItem: '',
selectedPiece: '',
formData: {
ItemReceptionTransDate: '',
ItemName: '',
SerialNo1: '',
ItemID: '',
ItemCode: '',
gStatus: '',
// piece info
pieceName: '',
pieceCode: '',
pieceQuantity: '',
pieceId: ''
},
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
return 'افزودن قطعه به فرم'
},
pieceQuantity() {
return this.formData.pieceQuantity
},
verityProducts() {
return this.$store.state.front.verityProducts
},
panatechProducts() {
return this.$store.state.front.panatechProducts
}
},
watch: {
showModal(newVal, oldVal) {
if (newVal) {
this.fetchingPieces = true
this.$axios
.get('/api/agent/pieces')
.then(res => {
this.fetchingPieces = false
this.pieces = res.data
})
.catch(err => {
console.log(err)
})
}
},
selectedItem() {
const selectedItem = this.selectedItem
let ItemID, db_name
if (selectedItem.includes('__v')) {
ItemID = selectedItem.replace('__v', '')
db_name = 'verity'
} else if (selectedItem.includes('__p')) {
ItemID = selectedItem.replace('__p', '')
db_name = 'panatech'
} else {
return this.$message({
type: 'error',
message: 'Invalid Value'
})
}
// find product
let products
if (db_name === 'verity') products = this.verityProducts
if (db_name === 'panatech') products = this.panatechProducts
const item = products.find(item => item.ItemID === ItemID)
this.formData.ItemName = item?.ItemName
this.formData.ItemID = item?.ItemID
this.formData.ItemCode = item?.ItemCode
},
selectedPiece() {
const item = this.pieces.find(item => item._id === this.selectedPiece)
this.formData.pieceId = item?._id
this.formData.pieceName = item?.name
this.formData.pieceCode = item?.code
}
},
methods: {
normalizeQuantityInput() {
this.formData.pieceQuantity = this.formData.pieceQuantity.toString().replace(/[^0-9]/g, '')
if (
this.formData.pieceQuantity === '' ||
this.formData.pieceQuantity === null ||
this.formData.pieceQuantity < 1
) {
this.formData.pieceQuantity = 1
}
},
add() {
this.validation = {}
this.postingForm = true
const data = this.formData
this.$axios
.put(`/api/agent/addPrItems/${this.prId}`, data)
.then(res => {
this.postingForm = false
this.showModal = false
this.$message({
type: 'success',
message: 'قطعه درخواستی به فرم افزوده شد'
})
this.$nuxt.refresh()
})
.catch(err => {
this.postingForm = false
if (err.response.status === 422) {
this.$message({
type: 'warning',
message: 'پارامترها رو بررسی و دوباره تلاش کنید'
})
this.validation = err.response.data.validation
} else {
this.$message({
type: 'error',
message: err.response?.data?.message
})
}
})
}
}
}
</script>
@@ -0,0 +1,223 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div class="addPtoPrModal reportModal">
<el-form label-position="top" :model="formData">
<el-form-item label="نام و نام خانوادگی مشتری" :class="validation.customerName && 'err'">
<el-input v-model="formData.customerName" placeholder="نام را وارد کنید"></el-input>
<p v-if="validation.customerName" class="errMsg">{{ validation.customerName.msg }}</p>
</el-form-item>
<el-form-item label="شماره تماس مشتری" :class="validation.customerTel && 'err'">
<el-input v-model="formData.customerTel" placeholder="شماره را وارد کنید"></el-input>
<p v-if="validation.customerTel" class="errMsg">{{ validation.customerTel.msg }}</p>
</el-form-item>
<el-form-item label="مدل کالا" :class="validation.ItemName && 'err'">
<el-select v-model="selectedItem" filterable style="width: 100%">
<el-option-group label="لوازم جانبی کامپیوتر و موبایل">
<el-option
v-for="item in verityProducts"
:key="item.ItemID + '_V'"
:value="item.ItemID + '__v'"
:label="item.ItemName"
></el-option>
</el-option-group>
<el-option-group label="لوازم صوتی و تصویری خودرو">
<el-option
v-for="item in panatechProducts"
:key="item.ItemID + '_P'"
:value="item.ItemID + '__p'"
:label="item.ItemName"
></el-option>
</el-option-group>
</el-select>
<p v-if="validation.ItemName" class="errMsg">{{ validation.ItemName.msg }}</p>
</el-form-item>
<el-form-item label="سریال">
<el-input v-model="formData.SerialNo1" placeholder="اختیاری"></el-input>
</el-form-item>
<el-form-item label="ایراد کالا" :class="validation.productIssue && 'err'">
<el-input
v-model="formData.productIssue"
type="textarea"
:rows="5"
placeholder="شرح ایرادات کالا را بنویسید"
></el-input>
<p v-if="validation.productIssue" class="errMsg">{{ validation.productIssue.msg }}</p>
</el-form-item>
<el-form-item label="قطعات مصرفی" :class="validation.usedPieces && 'err'">
<el-input
v-model="formData.usedPieces"
type="textarea"
:rows="5"
placeholder="شرح قطقات مصرفی را بنویسید"
></el-input>
<p v-if="validation.usedPieces" class="errMsg">{{ validation.usedPieces.msg }}</p>
</el-form-item>
<el-form-item label="تاریخ دریافت از مشتی" :class="validation.recieveDate && 'err'">
<div class="datePickerWrapper">
<persian-date-picker
v-model="formData.recieveDate"
display-format="jYYYY/jMM/jDD"
format="YYYY-MM-DD HH:mm:ss"
placeholder="تاریخ را انتخاب کنید"
color="#065495"
/>
</div>
<p v-if="validation.recieveDate" class="errMsg">{{ validation.recieveDate.msg }}</p>
</el-form-item>
<el-form-item label="تاریخ تحویل به مشتری" :class="validation.deliverDate && 'err'">
<div class="datePickerWrapper">
<persian-date-picker
v-model="formData.deliverDate"
display-format="jYYYY/jMM/jDD"
format="YYYY-MM-DD HH:mm:ss"
:min="formData.recieveDate"
placeholder="تاریخ را انتخاب کنید"
color="#065495"
/>
</div>
<p v-if="validation.deliverDate" class="errMsg">{{ validation.deliverDate.msg }}</p>
</el-form-item>
</el-form>
<div class="btnRow">
<el-button class="btn btn-primary custom-el-button" :loading="postingForm" @click="add">افزودن</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddReportToGuaranteeReportForm',
props: {
show: {
type: Boolean,
default: false
},
grId: {
requred: true,
type: String,
default: null
}
},
data() {
return {
postingForm: false,
selectedItem: '',
formData: {
customerName: '',
customerTel: '',
// product info
ItemName: '',
SerialNo1: '',
ItemID: '',
ItemCode: '',
// product issue
productIssue: '',
usedPieces: '',
// dates
recieveDate: '',
deliverDate: ''
},
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
return 'افزودن گزارش به فرم'
},
verityProducts() {
return this.$store.state.front.verityProducts
},
panatechProducts() {
return this.$store.state.front.panatechProducts
},
recieveDate() {
return this.formData.recieveDate
}
},
watch: {
recieveDate(newVal, oldVal) {
this.formData.deliverDate = ''
},
selectedItem() {
const selectedItem = this.selectedItem
let ItemID, db_name
if (selectedItem.includes('__v')) {
ItemID = selectedItem.replace('__v', '')
db_name = 'verity'
} else if (selectedItem.includes('__p')) {
ItemID = selectedItem.replace('__p', '')
db_name = 'panatech'
} else {
return this.$message({
type: 'error',
message: 'Invalid Value'
})
}
// find product
let products
if (db_name === 'verity') products = this.verityProducts
if (db_name === 'panatech') products = this.panatechProducts
const item = products.find(item => item.ItemID === ItemID)
this.formData.ItemName = item?.ItemName
this.formData.ItemID = item?.ItemID
this.formData.ItemCode = item?.ItemCode
}
},
methods: {
add() {
this.validation = {}
this.postingForm = true
const data = this.formData
this.$axios
.put(`/api/agent/addGrItems/${this.grId}`, data)
.then(res => {
this.postingForm = false
this.showModal = false
this.$message({
type: 'success',
message: 'گزارش به فرم افزوده شد'
})
this.$nuxt.refresh()
})
.catch(err => {
this.postingForm = false
if (err.response.status === 422) {
this.$message({
type: 'warning',
message: 'پارامترها رو بررسی و دوباره تلاش کنید'
})
this.validation = err.response.data.validation
} else {
this.$message({
type: 'error',
message: err.response?.data?.message
})
}
})
}
}
}
</script>
+300
View File
@@ -0,0 +1,300 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div>
<form v-loading="fetchingSerials" class="form form_3 stuffModal" @submit.prevent="addStuff">
<div class="formRow">
<el-select
v-if="!currentItem.name"
ref="productSelector"
v-model="currentItem.item"
filterable
:placeholder="productsPlaceholder"
>
<el-option v-for="item in products" :key="item.ItemID" :label="item.ItemName" :value="item.ItemID">
</el-option>
</el-select>
<p v-else>
<b>نام کالا: </b>
<span>{{ currentItem.name }}</span>
<span style="margin: 0 5px"> - </span>
<i style="color: blue; font-weight: bold; cursor: pointer" @click="changeProduct">تغییر کالا</i>
</p>
</div>
<div
v-if="currentItem.item && !serials.length && !fetchingSerials"
class="formRow"
:class="validation.quantity ? 'err' : null"
>
<p style="user-select: none">
<b style="margin-left: 10px">تعداد: </b>
<i
style="color: #bf6060; cursor: pointer"
class="fas fa-minus-circle"
@click="changeQuantity('decrease')"
></i>
<!-- <span style="font-weight: bold;margin: 0 5px">{{ currentItem.quantity }}</span> -->
<input
ref="quantityInput"
v-model="currentItem.quantity"
type="text"
style="
width: 50px;
display: inline-block;
border-radius: 50px;
padding: 5px;
direction: ltr;
text-align: center;
"
@input="normalizeQuantityInput"
/>
<i
style="color: #658865; cursor: pointer"
class="fas fa-plus-circle"
@click="changeQuantity('increase')"
></i>
</p>
</div>
<div v-if="serials.length" class="formRow" :class="serialInput.length && !isValid ? 'err' : null">
<el-input
v-if="!currentItem.SerialNo1"
ref="serialInput"
v-model="serialInput"
:disabled="isValid"
placeholder="شماره سریال را به صورت کامل وارد کنید"
@input="checkSerial"
>
<template v-if="serialInput.length">
<i v-if="isValid" slot="prefix" style="color: green" class="el-input__icon fas fa-check-circle"></i>
<i v-else slot="prefix" style="color: red" class="el-input__icon fas fa-exclamation-circle"></i>
</template>
</el-input>
<p v-else>
<b>شماره سریال: </b>
<span>{{ currentItem.SerialNo1 }}</span>
<span style="margin: 0 5px"> - </span>
<i v-if="isValid" style="color: blue; font-weight: bold; cursor: pointer" @click="changeSerial">
تغییر شماره سریال
</i>
</p>
</div>
<div v-if="addBtnVisible" class="formRow">
<button id="addBtn" ref="addBtn" type="submit" class="btn btn-primary">افزودن</button>
</div>
</form>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddStuffModal',
props: {
show: {
type: Boolean,
default: false
},
db_name: {
type: String,
required: true
}
},
data() {
return {
serials: [],
fetchingSerials: false,
currentItem: {
name: null,
item: null,
quantity: 1,
SerialNo1: '',
GStartDate: '',
GEndDate: ''
},
isValid: false,
serialInput: '',
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
if (this.db_name === 'panatech') return 'افزودن کالاهای صوتی تصویری به فرم'
if (this.db_name === 'verity') return 'افزودن کالاهای لوازم جانبی به فرم'
else return ''
},
products() {
if (this.db_name === 'verity') return this.$store.state.front.verityProducts
else if (this.db_name === 'panatech') return this.$store.state.front.panatechProducts
else return []
},
productsPlaceholder() {
return this.products ? 'نام کالا را جستجو کنید' : 'درحال بارگیری اطلاعات...'
},
selectedItem() {
return this.currentItem.item
},
selectedSerial() {
return this.currentItem.SerialNo1
},
addBtnVisible() {
if (this.serials.length) {
return this.currentItem.item && this.currentItem.SerialNo1
} else {
return this.currentItem.item && !this.fetchingSerials
}
}
},
watch: {
addBtnVisible(newVal, oldVal) {
if (newVal) {
if (this.serials.length) setTimeout(() => this.$refs.addBtn?.focus(), 300)
else setTimeout(() => this.$refs.quantityInput?.focus(), 300)
}
},
async selectedSerial(newVal, oldVal) {
if (newVal) {
const serialObject = await this.serials.filter(item => item.SerialNo1 === newVal)[0]
this.currentItem.GStartDate = serialObject.GStartDate
this.currentItem.GEndDate = serialObject.GEndDate
} else {
this.currentItem.GStartDate = ''
this.currentItem.GEndDate = ''
}
},
async selectedItem(newVal, oldVal) {
if (newVal) {
try {
this.fetchingSerials = true
this.currentItem.SerialNo1 = ''
this.serials = []
this.currentItem.name = null
const item = await this.products.filter(item => item.ItemID === newVal)[0]
this.currentItem.name = item.ItemName
const serialsData = {
url: `/api/GetSerials?ItemCode=${item.ItemCode}&QtyStatus=1`,
db: this.db_name
}
const serials = await this.$axios.post('/api/cross/getRouteManager', serialsData, {
progress: false
})
this.serials = serials.data.data
this.fetchingSerials = false
setTimeout(() => this.$refs.serialInput?.focus(), 300)
} catch (e) {
this.currentItem = {
item: '',
quantity: 1,
SerialNo1: '',
GStartDate: '',
GEndDate: ''
}
console.log(e)
return this.$message({
type: 'error',
message: 'مشکلی در دریافت اطلاعات پیش آمده، لطفا نام کالا را دوباره انتخاب کنید.'
})
}
} else {
this.serials = []
}
},
serials(newVal, oldVal) {
this.currentItem.quantity = 1
},
showModal(newVal, oldVal) {
if (newVal) {
this.$nextTick(() => {
this.$refs?.productSelector?.focus()
})
}
}
},
methods: {
changeProduct() {
this.currentItem.item = this.currentItem.name = null
this.isValid = false
this.serialInput = ''
},
changeSerial() {
this.currentItem.SerialNo1 = ''
this.isValid = false
this.serialInput = ''
setTimeout(() => this.$refs.serialInput?.focus(), 300)
},
checkSerial(serial) {
const SerialNo1 = this.serials.find(item => item.SerialNo1.toLowerCase() === serial.toLowerCase())
if (SerialNo1) {
this.isValid = true
this.currentItem.SerialNo1 = SerialNo1.SerialNo1
} else this.isValid = false
},
changeQuantity(mode) {
if (mode === 'increase') this.currentItem.quantity++
else if (mode === 'decrease' && this.currentItem.quantity > 1) this.currentItem.quantity--
},
addStuff() {
if (this.serials.length && !this.currentItem.SerialNo1) {
return this.$message({
type: 'warning',
message: 'شماره سریال معتبر وارد کنید'
})
}
this.fetchingSerials = true
const currentItem = this.currentItem
const selectedItem = this.products.filter(item => item.ItemID === currentItem.item)[0]
const item = {
ItemID: selectedItem.ItemID,
ItemCode: selectedItem.ItemCode,
MjQty: Number(currentItem.quantity),
SerialNo1: currentItem.SerialNo1,
GStartDate: currentItem.GStartDate,
GEndDate: currentItem.GEndDate
}
this.$axios
.put(`/api/user/transactionDraftItemAdd/${this.$route.params.draftID}`, item, { progress: false })
.then(res => {
this.fetchingSerials = false
this.$message({
type: 'success',
message: res.data.message
})
this.showModal = false
this.$nuxt.refresh()
})
.catch(err => {
this.fetchingSerials = false
if (err.response.status === 406) {
return this.$message({
type: 'warning',
message: err.response.data.message
})
} else {
return this.$message({
type: 'error',
message: 'مشکلی در ثبت اطلاعات پیش آمده، لطفا دوباره امتحان کنید'
})
}
})
},
normalizeQuantityInput() {
this.currentItem.quantity = this.currentItem.quantity.toString().replace(/[^0-9]/g, '')
if (this.currentItem.quantity === '' || this.currentItem.quantity === null || this.currentItem.quantity < 1) {
this.currentItem.quantity = 1
}
}
}
}
</script>
@@ -0,0 +1,233 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div v-loading="fetchingDrafts">
<template v-if="!addingStuff">
<h3 class="mb-3">پیشنویس مورد نظر جهت افزودن اقلام انتخاب شده را انتخاب کنید:</h3>
<div class="tableBox">
<table class="drafts-modal">
<thead>
<tr>
<th class="index">ردیف</th>
<th class="description">توضیحات</th>
<th class="brand">نوع</th>
<th class="quantity">تعداد کالاها</th>
<th class="details">افزودن</th>
</tr>
</thead>
<tbody>
<template v-if="filteredDrafts.length">
<tr v-for="(item, index) in filteredDrafts" :key="item._id" :title="item.description">
<td class="index">
<span>{{ index + 1 }}</span>
</td>
<td class="description">
<span v-if="item.description" class="singleLineTxt">{{ item.description }}</span>
<span v-else style="color: gray">بدون توضیحات</span>
</td>
<td class="brand">
<!-- <img src="/assets/img/verity-small.png" alt="verity" v-if="item.db_name === 'verity'" />
<img src="/assets/img/panatech-small.png" alt="panatech" v-if="item.db_name === 'panatech'" /> -->
<i
v-if="item.db_name === 'verity'"
class="fas fa-phone-laptop"
title="لوازم جانبی کامپیوتر و موبایل"
></i>
<i
v-if="item.db_name === 'panatech'"
class="fas fa-photo-video"
title="لوازم صوتی و تصویری خودرو"
></i>
</td>
<td class="quantity">
<span>{{ totalItemsCount(item) }}</span>
</td>
<td class="details">
<button class="btn btn-primary" @click="addStuffToDraft(item._id)">
<i class="fas fa-link"></i>
</button>
</td>
</tr>
</template>
<tr v-else>
<td class="noItem">
<span>هیچ اطلاعاتی وجود ندارد</span>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template v-else>
<el-progress
class="mb-3"
:text-inside="true"
:stroke-width="20"
:percentage="addProgress"
:status="addProgressStatus"
></el-progress>
<div class="tableBox">
<table class="drafts-modal">
<thead>
<tr>
<th class="index">ردیف</th>
<th class="name">نام</th>
<th class="quantity">تعداد کالاها</th>
<th class="brand">شماره سریال</th>
<th class="addStatus">وضعیت</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in addedStuff" :key="index + '_addedStuff_modal_itemStatus'">
<td class="index">
<span>{{ index + 1 }}</span>
</td>
<td class="name">
<span class="singleLineTxt" :title="getItemName(item.ItemID)">{{ getItemName(item.ItemID) }}</span>
</td>
<td class="quantity">
<span>{{ item.MjQty }}</span>
</td>
<td class="brand">
<span> {{ item.SerialNo1 || '-' }} </span>
</td>
<td class="addStatus">
<i
v-if="item.status"
class="el-icon-success"
style="color: rgb(19, 206, 102)"
:title="item.statusTxt"
></i>
<i v-else class="el-icon-info" style="color: orange" :title="item.statusTxt"></i>
</td>
</tr>
</tbody>
</table>
</div>
</template>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'AddUserItemsToAgentDraft',
props: {
show: {
type: Boolean,
default: false
},
db_name: {
type: String,
required: true
},
items: {
type: Array,
required: true
}
},
data() {
return {
fetchingDrafts: false,
addingStuff: false,
addProgress: 0,
addProgressStatus: 'success',
transactionDrafts: [],
addedStuff: [],
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
if (this.db_name === 'panatech') return 'افزودن کالاهای صوتی تصویری به فرم'
if (this.db_name === 'verity') return 'افزودن کالاهای لوازم جانبی به فرم'
else return ''
},
filteredDrafts() {
return this.transactionDrafts.filter(item => item.db_name === this.db_name)
},
products() {
if (this.db_name === 'verity') return this.$store.state.front.verityProducts
else if (this.db_name === 'panatech') return this.$store.state.front.panatechProducts
else return []
}
},
watch: {
showModal(newVal, oldVal) {
if (newVal) {
this.fetchingDrafts = true
this.$axios
.get('/api/user/transactionDrafts')
.then(res => {
this.transactionDrafts = res.data
this.fetchingDrafts = false
})
.catch(() => {
this.$message({
type: 'error',
message: 'مشکلی در دریافت اطلاعات پیش آمده'
})
this.showModal = false
})
}
}
},
methods: {
totalItemsCount(draft) {
const items = draft.items
let count = 0
items.forEach(item => (count += item.MjQty))
return count
},
getItemName(ItemID) {
return this.products.find(item => item.ItemID === ItemID)?.ItemName
},
async addStuffToDraft(draftId) {
this.addingStuff = true
try {
let index = 1
for await (const item of this.items) {
this.addProgress = Number(((index * 100) / this.items.length).toFixed(0))
await new Promise((resolve, reject) => {
index++
this.$axios
.put(`/api/user/transactionDraftItemAdd/${draftId}`, item, { progress: false })
.then(res => {
this.addedStuff.push({ ...item, status: true, statusTxt: res.data.message })
resolve()
})
.catch(err => {
this.addedStuff.push({ ...item, status: false, statusTxt: err.response.data.message })
this.addProgressStatus = 'warning'
resolve()
})
})
}
} catch (e) {
this.$message({
type: 'error',
message: 'مشکلی در ثبت اطلاعات پیش آمده'
})
}
}
}
}
</script>
+99
View File
@@ -0,0 +1,99 @@
<template>
<el-dialog :title="title" :visible.sync="showModal">
<div>
<form class="form form_3 stuffModal" @submit.prevent="change">
<div class="formRow" :class="[validation.email && 'err', validation.mobile && 'err']">
<el-input v-model="input" :placeholder="inputPlaceholder"> </el-input>
<p v-if="validation.email">{{ validation.email.msg }}</p>
<p v-if="validation.mobile">{{ validation.mobile.msg }}</p>
</div>
<div class="formRow">
<el-button
class="btn btn-primary custom-el-button"
type="primary"
native-type="submit"
:loading="posting"
:disabled="input.length < 1"
>
تغییر
</el-button>
</div>
</form>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'ChangeEmailOrMobileModal',
props: {
show: {
type: Boolean,
default: false
},
type: {
required: true,
type: String
}
},
data() {
return {
input: '',
posting: false,
validation: {}
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
title() {
if (this.type === 'mobile') return 'تغییر شماره موبایل'
if (this.type === 'email') return 'تغییر ایمیل'
else return ''
},
inputPlaceholder() {
if (this.type === 'mobile') return 'شماره موبایل خود را وارد کنید'
if (this.type === 'email') return 'ایمیل خود را وارد کنید'
else return ''
}
},
methods: {
async change() {
try {
this.posting = true
this.validation = {}
let res
if (this.type === 'email') {
res = await this.$axios.put('/api/user/changeEmail', { email: this.input })
}
if (this.type === 'mobile') {
res = await this.$axios.put('/api/user/changeMobile', { mobile: this.input })
}
this.posting = false
this.$message({
type: 'success',
message: res.data.message
})
this.$auth.fetchUser()
this.showModal = false
} catch (err) {
this.posting = false
if (err.response.status === 422) this.validation = err.response.data.validation
else {
this.$message({
type: 'error',
message: 'مشکلی در بروزرسانی اطلاعات پیش آمده'
})
}
}
}
}
}
</script>
+230
View File
@@ -0,0 +1,230 @@
<template>
<el-dialog title="انتخاب نمایندگی و ارسال فرم" :visible.sync="showModal">
<div v-loading="fetchingAgents" class="terms">
<h2>تعهدنامه:</h2>
<p class="mb-5">
کاربر محترم درخواست کننده خدمت با تایید این متن هرگونه ادعایی خارج از پروتکل های اعلامی این شرکت را از خود سلب
مینماید و تشخیص و سنجش کارشناسان واحد خدمات پس از فروش آسان سرویس ملاک عمل خواهد بود .دریافت کننده خدمات با
تایید این متن تصدیق مینماید موارد خارج از شمول گارانتی اعلامی توسط آسان سرویس را میپذیرد .در صورتیکه کالایی فاقد
شرایط گارانتی باشد نخست جهت تعمیر به درخواست کننده خدمت در این سامانه اطلاع رسانی میگردد و در صورت عدم اعلام نظر
توسط کاربر جهت ثبت درخواست تعمیر ،کالای مذکور به نشانی کاربر عودت خواهد گردید.
</p>
<h4>موارد خارج از شمول گارانتی :</h4>
<ol>
<li>
<p>دستکاری توسط افراد غیر مجاز</p>
</li>
<li>
<p>مغایرت محصول با پک و یا نداشتن پک</p>
</li>
<li>
<p>شکستگی، ضربه خوردگی، آبخوردگی</p>
</li>
<li>
<p>مخدوش بودن سریال کالا با کارت گارانتی و پکیج محصول</p>
</li>
<li>
<p>کسورات لوازم جانبی و قطعات محصول در پک</p>
</li>
</ol>
<div class="form form_2">
<div class="formRow">
<label for="accept">
<input id="accept" v-model="termsOfUse" type="checkbox" />
<span>قوانین را میپذیرم</span>
</label>
</div>
<div class="formRow agents">
<el-select
v-model="agent"
:disabled="!termsOfUse || user.isAgent"
filterable
placeholder="نماینگی نزدیک خودرا انتخاب کنید"
>
<el-option label="شرکت آسان سرویس (تهران)" value="main"></el-option>
<el-option
v-for="item in filteredAgents"
:key="item._id"
:label="agentName(item)"
:title="agentName(item)"
:value="item._id"
>
</el-option>
</el-select>
<el-button
class="btn btn-primary custom-el-button"
:disabled="!termsOfUse"
:loading="postingForm"
@click="sendForm"
>
ارسال
</el-button>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'SelectAgentModal',
props: {
show: {
type: Boolean,
default: false
},
draft: {
required: true,
type: Object
}
},
data() {
return {
termsOfUse: false,
fetchingAgents: true,
postingForm: false,
agents: [],
agent: ''
}
},
computed: {
showModal: {
get() {
return this.show
},
set(value) {
this.$emit('closeModal')
}
},
user() {
return this.$auth.user
},
userAddress() {
const user = this.user
return user.province_name + '، ' + user.city_name + '، ' + user.address + '،کد پستی: ' + user.postal_code
},
filteredAgents() {
return this.agents.filter(item => {
if (this.draft.db_name === 'verity')
return item.representation_type === 'verity' || item.representation_type === 'both'
else if (this.draft.db_name === 'panatech')
return item.representation_type === 'panatech' || item.representation_type === 'both'
else return false
})
}
},
watch: {
show(newVal, oldVal) {
if (newVal) {
this.$axios
.get('/api/public/agents')
.then(res => {
this.agents = res.data
this.fetchingAgents = false
})
.catch(() => {
this.$message({
type: 'error',
message: 'در دریافت لیست نمایندگان مشکلی پیش آمده'
})
this.showModal = false
})
}
}
},
mounted() {
if (this.user.isAgent) this.agent = 'main'
},
methods: {
agentName(item) {
return (
'نمایندگی ' +
item.city_name +
' کد ' +
item.agent_code +
' ' +
'(' +
item.province_name +
', ' +
item.city_name +
', ' +
item.address +
')'
)
},
sendForm() {
// validations
if (this.postingForm) return
if (!this.termsOfUse)
return this.$message({
type: 'warning',
message: 'با قوانین و مقررات موافقت نکرده اید.'
})
if (!this.agent)
return this.$message({
type: 'warning',
message: 'نماینده مورد نظر را انتخاب کنید'
})
// set postingForm true
this.postingForm = true
const businessID = () => {
if (this.draft.db_name === 'panatech') return this.user.panatech_businessID
else if (this.draft.db_name === 'verity') return this.user.verity_businessID
else return ''
}
const agent = () => {
if (this.user.isAgent) return 'main'
else return this.agent
}
const data = {
BusinessID: businessID(),
Description: this.draft.description,
cAddress1: this.userAddress,
TransCCustom1: this.user.first_name + ' ' + this.user.last_name,
cTel1: this.user.mobile_number,
items: this.draft.items,
termsOfUse: this.termsOfUse,
draftId: this.draft._id,
db_name: this.draft.db_name,
agent: agent()
}
this.$axios
.post('/api/user/transaction', data)
.then(res => {
this.$message({
type: 'success',
message: 'فرم شما با موفقیت ارسال شد'
})
this.postingForm = false
this.$router.push({
name: 'account-guarantee-receipt',
query: { ttn: res.data.transNumber, host: res.data.host, db_name: this.draft.db_name }
})
})
.catch(e => {
this.postingForm = false
if (e.response.status === 422) {
this.$message({
type: 'error',
message: 'اطلاعات را بررسی و دوباره تلاش کنید'
})
} else if (e.response.status === 406) {
this.$message({
type: 'error',
message: e.response.data.message
})
} else {
this.$arpaError()
console.log(e)
}
})
}
}
}
</script>
+237
View File
@@ -0,0 +1,237 @@
<template>
<div class="user-aside">
<ul>
<template v-if="userContactConfirmed && user.isAgent">
<div class="seprator">
<div class="txt">
<span>امکانات نمایندگی</span>
</div>
<div class="line"></div>
</div>
<nuxt-link
:to="{ name: 'account-agents-inbox', query: { type: 'ttl' } }"
tag="li"
:class="$route.name.includes('account-agents-inbox') && 'active'"
>
<a>
<b v-if="agentInbox" class="badge">{{ agentInbox }}</b>
<i v-else class="fal fa-inbox"></i>
<span>صندوق ورودی</span>
</a>
</nuxt-link>
<nuxt-link
:to="{ name: 'account-agents-pieces', query: { type: 'temp' } }"
tag="li"
:class="$route.name.includes('account-agents-pieces') && 'active'"
>
<a>
<i class="fas fa-wrench"></i>
<span>درخواست قطعه</span>
</a>
</nuxt-link>
<nuxt-link
:to="{ name: 'account-agents-ops', query: { type: 'temp' } }"
tag="li"
:class="$route.name.includes('account-agents-ops') && 'active'"
>
<a>
<i class="fas fa-backpack"></i>
<span>درخواست قطعه داغی</span>
</a>
</nuxt-link>
<nuxt-link
:to="{ name: 'account-agents-buffer', query: { type: 'temp' } }"
tag="li"
:class="$route.name.includes('account-agents-buffer') && 'active'"
>
<a>
<i class="fab fa-buffer"></i>
<span>درخواست کالای بافر</span>
</a>
</nuxt-link>
<nuxt-link
:to="{ name: 'account-agents-guaranteeReports', query: { type: 'temp' } }"
tag="li"
:class="$route.name.includes('account-agents-guaranteeReports') && 'active'"
>
<a>
<i class="fas fa-file-chart-line"></i>
<span>ارسال گزارش عملکرد</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-agents-reports' }" tag="li">
<a>
<i class="fas fa-file-chart-pie"></i>
<span>گزارشات</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-agents-announcements' }" tag="li">
<a class="relativePos">
<b v-if="newAgentAnnosCount" class="badge">{{ newAgentAnnosCount }}</b>
<i v-else class="fas fa-bullhorn"></i>
<span>اطلاعیه ها</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-agents-edit-info' }" tag="li">
<a>
<i class="fas fa-edit"></i>
<span>ویرایش اطلاعات نمایندگی</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-agents-file-upload' }" tag="li">
<a>
<i class="fas fa-edit"></i>
<span>ویرایش مدارک نمایندگی</span>
</a>
</nuxt-link>
<div class="seprator">
<div class="txt">
<span>امکانات کاربری</span>
</div>
<div class="line"></div>
</div>
</template>
<nuxt-link :to="{ name: 'account' }" tag="li" exact class="username">
<a>
<i class="fas fa-user"></i>
<span class="singleLineTxt" :title="fullName">{{ fullName }}</span>
</a>
</nuxt-link>
<template v-if="userContactConfirmed">
<nuxt-link :to="{ name: 'account-post' }" tag="li">
<a>
<i class="fas fa-shipping-fast"></i>
<span>ارسال کالا</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-drafts' }" tag="li">
<a>
<b v-if="draftsCount" class="badge">{{ draftsCount }}</b>
<i v-else class="fas fa-mail-bulk"></i>
<span>پیش نویس ها</span>
</a>
</nuxt-link>
<nuxt-link
:to="{ name: 'account-guarantee', query: { type: 'ttl' } }"
tag="li"
:class="$route.name.includes('account-guarantee') && 'active'"
>
<a>
<i class="fal fa-list"></i>
<span>لیست گارانتی</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-history' }" tag="li">
<a>
<i class="fal fa-book"></i>
<span>مانده معین مشتری</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-addTicket' }" tag="li" exact>
<a>
<i class="fal fa-plus"></i>
<span>افزودن تیکت</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-tickets' }" tag="li">
<a class="relativePos">
<b v-if="unreadTickets" class="badge">{{ unreadTickets }}</b>
<i v-else class="fal fa-envelope"></i>
<span>تیکت ها</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-announcements' }" tag="li">
<a class="relativePos">
<b v-if="newUserAnnosCount" class="badge">{{ newUserAnnosCount }}</b>
<i v-else class="fas fa-bell"></i>
<span>اعلانات</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-survey' }" tag="li">
<a>
<i class="fas fa-chart-bar"></i>
<span>نظر سنجی</span>
</a>
</nuxt-link>
<nuxt-link :to="{ name: 'account-profile' }" tag="li">
<a>
<i class="fal fa-user-edit"></i>
<span>ویرایش پروفایل</span>
</a>
</nuxt-link>
</template>
<nuxt-link v-if="!user.email_confirmed || !user.mobile_confirmed" :to="{ name: 'account-verify' }" tag="li">
<a>
<i class="fas fa-badge-check"></i>
<span>تایید اطلاعات</span>
</a>
</nuxt-link>
<li>
<a @click="logOut">
<i class="fal fa-sign-out-alt"></i>
<span>خروج</span>
</a>
</li>
</ul>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
unreadTickets: state => state.front.unreadTickets,
draftsCount: state => state.front.draftsCount,
agentInbox: state => state.front.agentInbox,
newUserAnnosCount: state => state.front.newUserAnnosCount,
newAgentAnnosCount: state => state.front.newAgentAnnosCount
}),
user() {
return this.$auth.user
},
fullName() {
return this.user.first_name + ' ' + this.user.last_name
},
userContactConfirmed() {
return this.user.email_confirmed
}
},
methods: {
logOut() {
this.$confirm('میخواهید از حساب کاربری خارج شوید؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
})
.then(async () => {
try {
await this.$auth.logout()
location.reload()
} catch (e) {
console.log(e.response.data)
}
})
.catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
}
}
}
</script>
@@ -0,0 +1,34 @@
<template>
<div class="user-dashboard page" :class="pageClass">
<slot name="body" />
<div class="container">
<div class="row">
<div class="col-12">
<div class="panel">
<div class="panel-title">
<p class="singleLineTxt" :title="panelTitle">{{ panelTitle }}</p>
</div>
<slot />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
pageClass: {
required: false,
type: String,
default: null
},
panelTitle: {
required: false,
type: String,
default: null
}
}
}
</script>