31/2/1401

This commit is contained in:
Your Name 2022-05-21 17:56:04 +04:30
parent cf90a92139
commit cfe2c8ef50
12 changed files with 997 additions and 607 deletions

30
public/.htaccess Normal file
View File

@ -0,0 +1,30 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteBase /
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteBase /
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteBase /
RewriteRule ^ index.html [L]
</IfModule>

View File

@ -20,6 +20,8 @@ import useAppConfig from '@core/app-config/useAppConfig'
import { useWindowSize, useCssVar } from '@vueuse/core'
import store from '@/store'
import ability from '@/libs/acl/ability'
import { initialAbility, fullAbility } from '@/libs/acl/config'
const LayoutVertical = () => import('@/layouts/vertical/LayoutVertical.vue')
const LayoutHorizontal = () => import('@/layouts/horizontal/LayoutHorizontal.vue')
@ -75,6 +77,9 @@ export default {
setup()
{
// Reset the user's permissions
ability.update(fullAbility)
const { skin, skinClasses } = useAppConfig()
const { enableScrollToTop } = $themeConfig.layout

View File

@ -1,21 +1,68 @@
import useJwt from '@/auth/jwt/useJwt'
import { initialAbility, fullAbility } from '@/libs/acl/config'
import router from '@/router'
import ability from '@/libs/acl/ability'
/**
* Return if user is logged in
* Return if user is logged in or not.
* This is completely up to you and how you want to store the token in your
* frontend application e.g. If you are using cookies to store the application
* please update this function
*/
// eslint-disable-next-line arrow-body-style
// export const isUserLoggedIn = () => {
// return localStorage.getItem('userDataAdmin') && localStorage.getItem(useJwt.jwtConfig.storageTokenKeyName)
// }
*/
export const isUserLoggedIn = () => {
return localStorage.getItem('userDataAdmin') !== null
return localStorage.getItem('accessToken') !== null
}
/**
* Return the access token.
* Note that this function does not check whether the user is logged in and
* thus, whether a token is available or not. This must be checked by whoever
* calls this function, using the above isUserLoggedIn() function.
*/
export const getAccessToken = () => localStorage.getItem('accessToken')
/**
* Return the user's data.
*/
export const getUserData = () => JSON.parse(localStorage.getItem('userDataAdmin'))
/**
* Login the user with the provided token. It does three things:
* - store the token in the local storage
* - set the admins permissions
* - redirect the user to the home page
*
* Might be updated later on to use cookies instead of local storage.
*/
export const login = (token, userData) => {
// Store the user's access token
localStorage.setItem('accessToken', token)
localStorage.setItem('userDataAdmin', JSON.stringify(userData))
// Set the user's permissions
// TODO(pooya): fullAbility is for test purposes right now. Update it to
// use the actual user's permissions.
ability.update(fullAbility)
// Redirect to home page
router.push('/')
}
/**
* Logout the user from the application.
* It does undo everything that was done in the login() function.
*/
export const logout = () => {
// Remove the access token
localStorage.removeItem('accessToken')
// Reset user permissions
ability.update(initialAbility)
// Redirect to login page
router.push({ name: 'login' })
}
/**
* This function is used for demo purpose route navigation
* In real app you won't need this function because your app will navigate to same route for each users regardless of ability

View File

@ -1,5 +1,6 @@
import axios from 'axios'
import router from '@/router'
import { getAccessToken } from '@/auth/utils'
const baseURL = 'https://api.ira-lex.com/'
@ -11,8 +12,8 @@ const ConfiguredAxios = axios.create({
'Access-Control-Allow-Header': 'Content-Type',
'Accept': "application/json",
'Content-Type' : 'application/json',
// 'Auth': localStorage.getItem("accessToken") || localStorage.accessToken,
'Auth': 'lua vpXyFsb8AbgMJ4iZ2N0knRB2MNEC9pMU6a4Mbp3eIZxE4K6XrfX58TGOeENnSV5p',
'Auth': getAccessToken() || '',
// 'Auth': 'lua vpXyFsb8AbgMJ4iZ2N0knRB2MNEC9pMU6a4Mbp3eIZxE4K6XrfX58TGOeENnSV5p',
'Cache-Control': 'no-cache',
'Pragma':'Pragma',
'Expires': '0',
@ -21,9 +22,9 @@ const ConfiguredAxios = axios.create({
ConfiguredAxios.interceptors.request.use(
config => {
// config.headers["Auth"] = localStorage.getItem("accessToken")
config.headers["Auth"] = 'lua vpXyFsb8AbgMJ4iZ2N0knRB2MNEC9pMU6a4Mbp3eIZxE4K6XrfX58TGOeENnSV5p'
config.headers["Access-Control-Allow-Origin"] = '*'
config.headers["Auth"] = getAccessToken() || ''
// config.headers["Auth"] = 'lua vpXyFsb8AbgMJ4iZ2N0knRB2MNEC9pMU6a4Mbp3eIZxE4K6XrfX58TGOeENnSV5p'
config.headers["Access-Control-Allow-Origin"] = '*'
return config
},
error => {
@ -39,10 +40,9 @@ ConfiguredAxios.interceptors.response.use(
function ({response})
{
console.log(response,'response response response')
if (response.status === 401)
{
router.push({path:'/login'});
router.push({ path: '/login' });
}
return Promise.reject(response);
}

View File

@ -2,6 +2,7 @@
<b-sidebar
id="user-filters--sidebar"
bg-variant="white"
v-model="IsOpen_D"
title="Filters"
v-bind:width="SidebarWidth"
body-class="p-2"
@ -19,46 +20,60 @@
ref="filters"
id="filters-repeater-form"
v-bind:style="{ height: trHeight }"
v-on:submit.prevent="RepeatAgain()"
v-on:submit.prevent="Repeat()"
>
<b-row
ref="row"
v-for="(Filter, Index) in Filters_D"
v-bind:key="Filter.ID"
v-bind:id="Filter.ID"
v-bind:key="Index"
>
<b-col md="3">
<b-col lg="3">
<b-form-group label="Field">
<v-select
<v-select
v-bind:options="RemainingTableColumns_D"
label="title"
label="Title"
v-bind:clearable="false"
v-model="Filters_D[Index].Field"
v-bind:value="Filter.Field"
v-on:input="OnFieldChanged($event, Index)"
/>
</b-form-group>
</b-col>
<b-col md="3">
<b-form-group label="Condition">
<v-select
<b-col lg="3">
<b-form-group label="Condition" v-if="Filter.Field.Type !== 'boolean'">
<v-select
v-bind:options="Conditions_D"
label="title"
label="Title"
v-bind:clearable="false"
v-model="Filters_D[Index].Condition"
v-bind:value="Filter.Condition"
v-on:input="OnConditionChanged($event, Index)"
/>
</b-form-group>
</b-col>
<b-col md="4">
<b-form-group label="Value">
<b-form-input />
<b-col lg="4">
<b-form-group label="Value" v-if="Filter.Condition.Value !== 'isnull'">
<b-form-checkbox
v-if="Filter.Field.Type === 'boolean'"
style="user-select: none;"
v-model="Filter.Value"
v-bind:value="true"
v-bind:unchecked-value="false"
>
</b-form-checkbox>
<b-form-input
v-else-if="Filter.Field.Type === 'integer'"
type="number"
v-model="Filter.Value"
/>
<b-form-input v-else type="text" v-model="Filter.Value" />
</b-form-group>
</b-col>
<b-col md="2" class="mb-1">
<b-col lg="2" class="mb-1">
<b-form-group label=" ">
<b-button
v-ripple.400="'rgba(234, 84, 85, 0.15)'"
variant="outline-danger"
class="mt-0 mt-md-2"
v-on:click="RemoveFilter(Index)"
v-on:click="Remove(Index)"
>
<feather-icon icon="XIcon" class="mr-25" />
<span>Delete</span>
@ -80,12 +95,29 @@
<hr>
<div class="mt-1 d-flex justify-content-end" style="column-gap: 1rem;">
<!-- Add Button -->
<b-button variant="outline-primary" v-ripple.400="'rgba(255, 255, 255, 0.15)'" v-on:click="RepeatAgain()">
<b-button
variant="outline-primary"
v-ripple.400="'rgba(255, 255, 255, 0.15)'"
v-on:click="Repeat()"
v-bind:disabled="RemainingTableColumns_D.length === 0"
>
<feather-icon icon="PlusIcon" classes="mr-25" />
<span>Add New Filter</span>
</b-button>
<!-- Clear Button -->
<b-button
variant="primary"
v-ripple.400="'rgba(255, 255, 255, 0.15)'"
v-on:click="Clear()"
v-bind:disabled="Filters_D.length === 0"
>
<feather-icon icon="TrashIcon" class="mr-50" />
<span>Clear</span>
</b-button>
<!-- Apply Button -->
<b-button
<b-button
variant="primary"
v-ripple.400="'rgba(255, 255, 255, 0.15)'"
v-on:click="ApplyFilters()"
@ -102,6 +134,7 @@ import { BSidebar, BRow, BCol, BCard, BButton, BForm, BFormGroup, BFormInput, BF
import vSelect from 'vue-select'
import Ripple from 'vue-ripple-directive'
import { heightTransition } from '@core/mixins/ui/transition'
import { Log } from '@/modules/core'
export default {
name: 'UserFiltersRepeatingFormComponent',
@ -125,43 +158,27 @@ export default {
mixins: [ heightTransition ],
props: {
table: {
// A ref to the table engine to apply the filters to
// so that e.g. instead of this.$refs.usersTable, we can use this.table
required: true,
}
},
data() {
return {
Filters_D: [
{
ID: 1,
Selected: 'male',
Selected1: 'designer',
PrevHeight: 0,
},
],
NextFilterID_D: 0,
IsOpen_D: false,
Filters_D: [],
RemainingTableColumns_D: [
{ value: 'first_name', type: 'string', title: 'First Name' },
{ value: 'last_name', type: 'string', title: 'Last Name' },
{ value: 'email_address', type: 'string', title: 'Email' },
{ value: 'is_main', type: 'boolean', title: 'Firm' },
{ value: 'subscription.charge', type: 'integer', title: 'Charge' },
{ value: 'total_uploaded_size', type: 'integer', title: 'Uploaded Size' },
{ value: 'total_firm_uploaded_size', type: 'integer', title: 'Firm Uploaded Size' },
{ Value: 'first_name', Type: 'string', Title: 'First Name' },
{ Value: 'email_address', Type: 'string', Title: 'Email' },
{ Value: 'is_main', Type: 'boolean', Title: 'Firm' },
{ Value: 'subscription__charge', Type: 'integer', Title: 'Charge' },
{ Value: 'total_uploaded_size', Type: 'integer', Title: 'Uploaded Size' },
{ Value: 'total_firm_uploaded_size', Type: 'integer', Title: 'Firm Uploaded Size' },
],
Conditions_D: [
{ value: 'isnull', title: 'Is Empty' },
{ value: '=', title: 'Equals' },
{ value: '!=', title: 'Not Equals' },
{ value: '>', title: 'Greater Than' },
{ value: '>=', title: 'Greater Than or Equals' },
{ value: '<', title: 'Less Than' },
{ value: '<=', title: 'Less Than or Equals' },
{ value: 'in', title: 'Contains' },
{ Value: 'isnull', Title: 'Is Empty' },
{ Value: '=', Title: 'Equals' },
{ Value: '!=', Title: 'Not Equals' },
{ Value: '>', Title: 'Greater Than' },
{ Value: '>=', Title: 'Greater Than or Equals' },
{ Value: '<', Title: 'Less Than' },
{ Value: '<=', Title: 'Less Than or Equals' },
{ Value: 'in', Title: 'Contains' },
],
}
},
@ -177,54 +194,114 @@ export default {
},
methods: {
// Initializes the height of the transition
InitTrHeight()
{
this.trSetHeight(null)
// this.$nextTick(() => {
// console.log('filters ref is', this.$refs)
this.$nextTick(() => {
this.trSetHeight(this.$refs.filters.scrollHeight)
this.RemoveFilter(0)
// console.log('This is getting executed')
// })
})
},
// Adds a new row to the filters form repeater
RepeatAgain()
Repeat()
{
const FieldType = this.RemainingTableColumns_D[0].Type
const Condition = FieldType === 'boolean' ? this.Conditions_D[1] : this.Conditions_D[0]
this.Filters_D.push({
ID: this.NextFilterID_D += 1,
Field: this.RemainingTableColumns_D[0],
Condition: this.Conditions_D[0],
Condition,
Value:
Condition.Value === 'isnull' ? undefined :
FieldType === 'boolean' ? false :
FieldType === 'integer' ? 0 :
FieldType === 'string' ? '' : undefined,
})
this.RemainingTableColumns_D.shift()
this.$nextTick(() => {
this.trAddHeight(this.$refs.row[0].offsetHeight)
})
},
// Deletes a row from the filters form repeater
RemoveFilter(Index)
Remove(Index)
{
this.RemainingTableColumns_D.push(this.Filters_D[Index].Field)
this.RemainingTableColumns_D.sort((a, b) => a.Title.localeCompare(b.Title))
this.Filters_D.splice(Index, 1)
this.trTrimHeight(this.$refs.row[0].offsetHeight)
},
// Removes all filters
Clear()
{
this.Filters_D.forEach(Item => this.RemainingTableColumns_D.push(Item.Field))
this.RemainingTableColumns_D.sort((a, b) => a.Title.localeCompare(b.Title))
this.Filters_D = []
this.InitTrHeight()
},
// Applies the filters to the table
ApplyFilters()
{
this.table.query.query = [
]
if( this.Query_D.IsMain )
this.table.query.query.push({
field: 'is_main',
condition: '=',
value: this.Query_D.IsMain,
})
this.table.fetch()
this.$emit('submit', this.Filters_D.map(Item => {
return {
field: Item.Field.Value,
condition: Item.Condition.Value,
value: Item.Value,
}
}))
this.IsOpen_D = false
// if( this.Query_D.IsMain )
// this.table.query.query.push({
// field: 'is_main',
// condition: '=',
// value: this.Query_D.IsMain,
// })
},
// Handles the change of a field.
OnFieldChanged(Value, Index)
{
this.RemainingTableColumns_D.push(this.Filters_D[Index].Field)
this.Filters_D[Index].Field = Value
this.Filters_D[Index].Condition = Value.Type === 'boolean' ? this.Conditions_D[1] : this.Conditions_D[0]
this.Filters_D[Index].Value =
Value.Type === 'boolean' ? false :
Value.Type === 'integer' ? 0 :
Value.Type === 'string' ? '' : undefined,
this.RemainingTableColumns_D = this.RemainingTableColumns_D.filter(Item => Item.Value !== Value.Value)
this.RemainingTableColumns_D.sort((a, b) => a.Title.localeCompare(b.Title))
},
// Handles the change of a condition.
OnConditionChanged(Value, Index)
{
this.Filters_D[Index].Condition = Value
this.Filters_D[Index].Value =
Value.Value === 'isnull' ? undefined :
this.Filters_D[Index].Value !== undefined ? this.Filters_D[Index].Value :
this.Filters_D[Index].Field.Type === 'boolean' ? false :
this.Filters_D[Index].Field.Type === 'integer' ? 0 :
this.Filters_D[Index].Field.Type === 'string' ? '' : undefined
},
},
created() { window.addEventListener('resize', this.InitTrHeight) },
mounted() { this.InitTrHeight() },
destroyed() { window.removeEventListener('resize', this.InitTrHeight) },
created()
{
window.addEventListener('resize', this.InitTrHeight)
},
mounted()
{
this.InitTrHeight()
this.RemainingTableColumns_D.sort((a, b) => a.Title.localeCompare(b.Title))
},
destroyed()
{
window.removeEventListener('resize', this.InitTrHeight)
},
}
</script>

View File

@ -21,9 +21,13 @@
</b-input-group-append>
</b-input-group>
</b-col>
<b-col md="6">
<b-col md="6" class="d-flex align-items-center">
<a class="left-table-btn" v-on:click="fullScreen">
<feather-icon v-bind:icon="getFullIcon" svg-classes="w-5 h-5"/>
<feather-icon
v-bind:icon="getFullIcon"
svg-classes="w-5 h-5"
style="vertical-align: bottom;"
/>
</a>
<ADropdown :trigger="['hover']">
<div slot="overlay" class="p-2" style="min-width: 250px">
@ -32,25 +36,36 @@
<ADivider class="my-2"/>
<div class="d-flex flex-column align-items-start" style="max-height:150px;overflow:auto">
<Draggable v-model="cols">
<div v-for="item,index in cols" :key="index" class="flex items-start">
<feather-icon icon="MoreVerticalIcon" svg-classes="h-4 w-4 color-grey cursor-pointer"
class="mr-0"/>
<div v-for="item,index in cols" v-bind:key="index" class="d-flex align-items-start">
<feather-icon icon="MoreVerticalIcon" svg-classes="h-4 w-4 color-grey"
class="COLUMN_ANCHOR mr-0"/>
<feather-icon icon="MoreVerticalIcon" svg-classes="h-4 w-4 color-grey cursor-pointer"
style="position: relative;left: 9px;"/>
<ACheckbox v-model="item.show">
<!-- <ACheckbox v-model="item.show">
{{item.title}}
</ACheckbox>
</ACheckbox> -->
<b-form-checkbox v-model="item.show" style="display: inline;">
{{ item.title }}
</b-form-checkbox>
</div>
</Draggable>
</div>
</ACard>
</div>
<a class="left-table-btn ">
<feather-icon icon="SettingsIcon" svg-classes="w-5 h-5"/>
<feather-icon
icon="SettingsIcon"
svg-classes="w-5 h-5"
style="vertical-align: bottom;"
/>
</a>
</ADropdown>
<a class="left-table-btn refresh-btn" @click="refresh">
<feather-icon icon="RotateCwIcon" svg-classes="w-5 h-5"/>
<feather-icon
icon="RotateCwIcon"
svg-classes="w-5 h-5"
style="vertical-align: bottom;"
/>
</a>
</b-col>
</b-row>
@ -152,7 +167,7 @@ import Draggable from 'vuedraggable'
import axios from "../../axios";
import {openFullscreen, closeFullscreen} from "@/plugins/fullscreen";
import NumberXTableFilter from "./NumberXTableFilter";
import { BRow, BCol, BInputGroup, BInputGroupAppend, BFormInput, BButton } from 'bootstrap-vue'
import { BRow, BCol, BInputGroup, BInputGroupAppend, BFormInput, BFormCheckbox, BButton } from 'bootstrap-vue'
const list = [
@ -182,177 +197,198 @@ export default {
BInputGroup,
BInputGroupAppend,
BFormInput,
BFormCheckbox,
BButton,
},
props: {
model: {
type: XTbl.default,
},
is_pagenation:{
type: Boolean,
default: true
},
method:{
type: String,
default: "post"
},
search:{
type: Boolean,
default: true
},
options:{
type: Object,
default: {
placeholder:'Search',
noContent: 'No data',
is_row_selection: false,
is_load_req: true
}
}
},
data() {
return {
data: [],
testTheme:[],
list:[],
query: {
search: undefined,
total: 0,
limit: 10,
page: 1,
query:[]
},
locale: {
emptyText: this.options.noContent
},
loading: false,
full: false,
colSelector: false,
selectedRowKeys: [],
indicator: <a-icon type="loading" style="font-size: 24px" spin />,
}
},
methods: {
onChange(selectedRowKeys, selectedRows){
this.selectedRowKeys = selectedRowKeys
this.$emit('selectedRows',selectedRows,selectedRowKeys)
},
submitFilter({model, column}) {
if (!this.query.filters) {
this.query.filters = []
}
this.query.filters = this.query.filters.filter((item) => item.field !== column.key);
this.query.filters = this.query.filters.concat(model);
this.fetch()
},
change(item, filter, sorter) {
if (sorter) {
const {columnKey, order} = sorter;
// this.query.order = [`${order == 'ascend' ? '-' : '+'}${columnKey}`];
this.query.order_by = `${order == 'ascend' ? '-' : ''}${columnKey}`;
}
this.fetch();
},
get_rows(){
return this.data
},
changePage(item) {
this.query.page = item;
this.fetch();
this.$emit('changePage')
},
fullScreen() {
console.log("this.$refs.tblCard.$el ==> ", this.$refs.tblCard.$el);
if (this.full) {
closeFullscreen()
this.full = false;
return;
}
openFullscreen(this.$refs.tblCard.$el);
this.full = true;
},
requestData() {
return this.query;
},
refresh($event){
console.log($event,'$event $event')
this.$emit('refresh')
this.query.query = []
this.query.search = undefined
this.fetch()
},
async fetch() {
try {
this.loading = true;
if(this.method == "post"){
const {data: {rows, query}} = await axios.post(this.model.url, {...this.requestData()});
this.data = rows;
this.query.page = query.page
this.query.limit = query.limit;
this.query.total = query.total;
this.query.max_page = query.max_page;
this.$emit('rows',rows)
}else{
const {data} = await axios.get(this.model.url);
this.data = data;
}
} catch (e) {
// this.$ntSetError()
throw e
} finally {
this.loading = false;
}
},
noThings() {
},
getFilterData() {
},
onSearch(value) {
this.query.page = 1
this.query.search = value
this.query.query = [];
if (value) {
this.fetch();
}
},
showColSelector() {
this.colSelector = !this.colSelector;
}
},
computed: {
getFullIcon() {
return !this.full ? 'Maximize2Icon' : 'Minimize2Icon';
},
customRender() {
return this.model.cols.filter((item) => item.scopedSlots && item.scopedSlots.customRender).map((i) => i.scopedSlots.customRender)
},
cols: {
get() {
return this.model.cols || [];
},
set(value) {
this.model.cols = value;
}
},
getColsFilter() {
return this.cols.filter(item => item.filtered)
},
visibleCols() {
return this.cols.filter(item => item.show)
}
},
mounted() {
if(this.options.is_load_req){
this.fetch();
}
// console.log("this.model ==> ", this.model);
},
created() {
// console.log(this.options.noContent,'this.options.noContent')
// this.locale.emptyText = this.options.noContent
}
}
props: {
model: { type: XTbl.default },
is_pagenation: { type: Boolean, default: true },
method: { type: String, default: "post" },
search: { type: Boolean, default: true },
options:{
type: Object,
default: {
placeholder:'Search',
noContent: 'No data',
is_row_selection: false,
is_load_req: true
}
}
},
data()
{
return {
data: [],
testTheme:[],
list:[],
query: {
search: undefined,
total: 0,
limit: 10,
page: 1,
query: []
},
locale: {
emptyText: this.options.noContent
},
loading: false,
full: false,
colSelector: false,
selectedRowKeys: [],
indicator: <a-icon type="loading" style="font-size: 24px" spin />,
}
},
methods: {
onChange(selectedRowKeys, selectedRows)
{
this.selectedRowKeys = selectedRowKeys
this.$emit('selectedRows',selectedRows,selectedRowKeys)
},
submitFilter({model, column})
{
if (!this.query.filters) {
this.query.filters = []
}
this.query.filters = this.query.filters.filter((item) => item.field !== column.key);
this.query.filters = this.query.filters.concat(model);
this.fetch()
},
change(item, filter, sorter)
{
if (sorter) {
const {columnKey, order} = sorter;
// this.query.order = [`${order == 'ascend' ? '-' : '+'}${columnKey}`];
this.query.order_by = `${order == 'ascend' ? '-' : ''}${columnKey}`;
}
this.fetch();
},
get_rows(){
return this.data
},
changePage(item) {
this.query.page = item;
this.fetch();
this.$emit('changePage')
},
fullScreen() {
console.log("this.$refs.tblCard.$el ==> ", this.$refs.tblCard.$el);
if (this.full) {
closeFullscreen()
this.full = false;
return;
}
openFullscreen(this.$refs.tblCard.$el);
this.full = true;
},
requestData() {
return this.query;
},
refresh($event){
this.$emit('refresh')
this.query.query = []
this.query.search = undefined
this.fetch()
},
async fetch() {
try {
this.loading = true;
if(this.method == "post"){
const {data: {rows, query}} = await axios.post(this.model.url, {...this.requestData()});
this.data = rows;
this.query.page = query.page
this.query.limit = query.limit;
this.query.total = query.total;
this.query.max_page = query.max_page;
this.$emit('rows',rows)
}else{
const {data} = await axios.get(this.model.url);
this.data = data;
}
} catch (e) {
// this.$ntSetError()
throw e
} finally {
this.loading = false;
}
},
noThings() {
},
getFilterData() {
},
onSearch(value) {
this.query.page = 1
this.query.search = value
this.query.query = [];
if (value) {
this.fetch();
}
},
showColSelector() {
this.colSelector = !this.colSelector;
}
},
computed: {
getFullIcon()
{
return !this.full ? 'Maximize2Icon' : 'Minimize2Icon';
},
customRender()
{
return this.model.cols.filter((item) => item.scopedSlots && item.scopedSlots.customRender).map((i) => i.scopedSlots.customRender)
},
cols: {
get()
{
return this.model.cols || []
},
set(value)
{
this.model.cols = value
}
},
getColsFilter()
{
return this.cols.filter(item => item.filtered)
},
visibleCols()
{
return this.cols.filter(item => item.show)
}
},
mounted()
{
if( this.options.is_load_req )
this.fetch()
// console.log("this.model ==> ", this.model);
},
created()
{
// console.log(this.options.noContent,'this.options.noContent')
// this.locale.emptyText = this.options.noContent
}
}
</script>
<style scoped>
@ -393,4 +429,11 @@ export default {
/* display: flex;
align-items: center; */
}
.COLUMN_ANCHOR {
cursor: grab;
}
.COLUMN_ANCHOR:active {
cursor: grabbing;
}
</style>

View File

@ -1,8 +1,15 @@
export const initialAbility = [
{
action: 'read',
subject: 'Auth',
},
{
action: 'read',
subject: 'Auth',
},
]
export const fullAbility = [
{
action: 'manage',
subject: 'all',
},
]
export const _ = undefined

View File

@ -11,7 +11,7 @@ import App from './App.vue'
import './global-components'
// 3rd party plugins
import '@axios'
// import '@axios'
import '@/libs/acl'
import '@/libs/portal-vue'
import '@/libs/clipboard'
@ -23,6 +23,10 @@ import '@/libs/tour'
// Axios Mock Adapter
import '@/@fake-db/db'
// Axios Configured
import axios from '@/axios'
Vue.prototype.$http = axios
// BSV Plugin Registration
Vue.use(ToastPlugin)
Vue.use(ModalPlugin)

88
src/plugins/core.js Normal file
View File

@ -0,0 +1,88 @@
/*******************************************************************************
* Core *
* Contains various javascript utilities. *
* *
* Table of Contents: *
* - Number Thousand Separator *
* - Format Bytes *
* - Logging *
* - Is Number *
*******************************************************************************/
/*
|-----------------------------------------------------------------------
| Number Thousand Separator
|-----------------------------------------------------------------------
|
| A function which takes a number and a character and returns a string
| containing that number with the given character as thousands
| separators.
|
*/
export function SeparateNumberByThousands(Num, Separator = ',')
{
return Num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Separator)
// P.S: Thanks Github Copilot for saving me numerous hours of stackoverflowing 🙂
}
/*
|-----------------------------------------------------------------------
| Format Bytes
|-----------------------------------------------------------------------
|
| Converts bytes to the equivalent kilobytes, megabytes, gigabytes, etc.
|
*/
export function FormatBytes(Bytes, Decimals = 2)
{
if( Bytes === 0 ) return '0 Bytes'
const K = 1024
const Dm = (Decimals < 0) ? 0 : Decimals
const Sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const I = Math.floor(Math.log(Bytes) / Math.log(K))
return parseFloat((Bytes / Math.pow(K, I)).toFixed(Dm)) + ' ' + Sizes[I]
}
/*
|-----------------------------------------------------------------------
| Logging
|-----------------------------------------------------------------------
|
| Logs a message to the browser console.
| This function is provided to abstract all your logging calls, so you
| can change the style of all of them at once. It is useful to make the
| logs of your application look different so you can find them easier
| when there are hundreds of logs in the console.
|
*/
export function Log(Message, Data = '')
{
console.log(
`%c ${Message} `,
'background:black; color:#bada55; font-family:"PxPlus ToshibaSat 9x16"; font-size: 13px; border-radius: 4px; padding: 1px 3px;')
if( Data !== '' )
console.log(Data)
}
/*
|-----------------------------------------------------------------------
| Is Number
|-----------------------------------------------------------------------
|
| Takes a string and determines whether it is a valid number or not.
| This function shields against common bugs like whitespace, implicit
| partial parsing, radix, coercion of arrays, etc.
|
| Reference: stackoverflow.com/questions/175739/how-can-i-check-if-a-string-is-a-valid-number
|
*/
export function IsNumber(TheString)
{
if( typeof str != "string" ) return false // we only process strings!
return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
!isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
}

View File

@ -85,7 +85,7 @@
</b-card>
<UserFiltersRepeatingForm
v-bind:table="$refs.users"
v-on:submit="ApplyFilters($event)"
/>
<!-- class="mt-1" -->
<!-- v-if="Users_D.length > 0" -->
@ -187,6 +187,12 @@ export default {
// this.$refs.users.query.query = [
// ]
},
ApplyFilters(Filters)
{
this.$refs.users.query.query = Filters
this.$refs.users.fetch()
},
},
created()

View File

@ -4,8 +4,8 @@
<!-- Brand logo-->
<b-link class="brand-logo">
<vuexy-logo />
<h2 class="brand-text text-primary ml-1">Iralex</h2>
<LogoComponent />
<h2 class="brand-text text-primary ml-1">Iralex</h2>
</b-link>
<!-- Left Text-->
@ -22,10 +22,10 @@
Welcome to Iralex! 👋
</b-card-title>
<b-card-text class="mb-2">
Sign-in to your account
Sign-in to your account.
</b-card-text>
<b-alert variant="primary" show>
<!-- <b-alert variant="primary" show>
<div class="alert-body font-small-2">
<p>
<small class="mr-50">
@ -45,7 +45,7 @@
class="position-absolute"
style="top: 10; right: 10;"
/>
</b-alert>
</b-alert> -->
<!-- form -->
<validation-observer ref="loginForm" v-slot:default="{invalid}">
@ -60,8 +60,8 @@
>
<b-form-input
id="login-email"
v-model="userEmail"
v-bind:state="errors.length > 0 ? false:null"
v-model="emailAddress"
v-bind:state="errors.length > 0 ? false : null"
name="login-email"
placeholder="john@example.com"
/>
@ -109,75 +109,88 @@
</b-form-group>
<!-- checkbox -->
<b-form-group>
<!-- <b-form-group>
<b-form-checkbox id="remember-me" v-model="status" name="checkbox-1">
Remember Me
</b-form-checkbox>
</b-form-group>
</b-form-group> -->
<!-- submit buttons -->
<b-button type="submit" variant="primary" block v-bind:disabled="invalid">
<b-button
type="submit"
variant="primary"
block
v-bind:disabled="invalid"
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
>
Sign in
</b-button>
</b-form>
</validation-observer>
<b-card-text class="text-center mt-2">
<span>New on our platform? </span>
<b-link v-bind:to="{name:'auth-register'}">
<span>&nbsp;Create an account</span>
</b-link>
</b-card-text>
<!-- Create Account -->
<!-- <b-card-text class="text-center mt-2"> -->
<!-- <span>New on our platform? </span> -->
<!-- <b-link v-bind:to="{name:'auth-register'}"> -->
<!-- <span>&nbsp;Create an account</span> -->
<!-- </b-link> -->
<!-- </b-card-text> -->
<!-- divider -->
<div class="divider my-2">
<div class="divider-text">
or
</div>
</div>
<!-- Divider -->
<!-- <div class="divider my-2"> -->
<!-- <div class="divider-text"> -->
<!-- or -->
<!-- </div> -->
<!-- </div> -->
<!-- social buttons -->
<div class="auth-footer-btn d-flex justify-content-center">
<b-button variant="facebook" href="javascript:void(0)">
<feather-icon icon="FacebookIcon" />
</b-button>
<b-button variant="twitter" href="javascript:void(0)">
<feather-icon icon="TwitterIcon" />
</b-button>
<b-button variant="google" href="javascript:void(0)">
<feather-icon icon="MailIcon" />
</b-button>
<b-button variant="github" href="javascript:void(0)">
<feather-icon icon="GithubIcon" />
</b-button>
</div>
<!-- Social Buttons -->
<!-- <div class="auth-footer-btn d-flex justify-content-center"> -->
<!-- <b-button variant="facebook" href="javascript:void(0)"> -->
<!-- <feather-icon icon="FacebookIcon" /> -->
<!-- </b-button> -->
<!-- <b-button variant="twitter" href="javascript:void(0)"> -->
<!-- <feather-icon icon="TwitterIcon" /> -->
<!-- </b-button> -->
<!-- <b-button variant="google" href="javascript:void(0)"> -->
<!-- <feather-icon icon="MailIcon" /> -->
<!-- </b-button> -->
<!-- <b-button variant="github" href="javascript:void(0)"> -->
<!-- <feather-icon icon="GithubIcon" /> -->
<!-- </b-button> -->
<!-- </div> -->
</b-col>
</b-col>
<!-- /Login-->
</b-row>
<b-modal
id="modal"
title="Registeration Failed"
ok-only
ok-title="Ok"
variant="danger"
>
<b-card-text>{{ modalMessage }}</b-card-text>
</b-modal>
</div>
</template>
<script>
/* eslint-disable global-require */
import { ValidationProvider, ValidationObserver } from 'vee-validate'
import VuexyLogo from '@core/layouts/components/Logo.vue'
import {
BRow, BCol, BLink, BFormGroup, BFormInput, BInputGroupAppend, BInputGroup, BFormCheckbox, BCardText, BCardTitle, BImg, BForm, BButton, BAlert, VBTooltip,
} from 'bootstrap-vue'
import LogoComponent from '@core/layouts/components/Logo.vue'
import { BRow, BCol, BLink, BFormGroup, BFormInput, BInputGroupAppend, BInputGroup, BFormCheckbox, BCardText, BCardTitle, BImg, BForm, BButton, BAlert, VBTooltip, BModal, VBModal } from 'bootstrap-vue'
import Ripple from 'vue-ripple-directive'
import useJwt from '@/auth/jwt/useJwt'
import { required, email } from '@validations'
import { togglePasswordVisibility } from '@core/mixins/ui/forms'
import store from '@/store/index'
import { getHomeRouteForLoggedInUser } from '@/auth/utils'
import { login, getHomeRouteForLoggedInUser } from '@/auth/utils'
import { Log } from '@/plugins/core'
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
export default {
directives: {
'b-tooltip': VBTooltip,
},
components: {
BRow,
BCol,
@ -193,19 +206,27 @@ export default {
BForm,
BButton,
BAlert,
VuexyLogo,
BModal,
LogoComponent,
ValidationProvider,
ValidationObserver,
},
directives: {
'b-tooltip': VBTooltip,
'b-modal': VBModal,
Ripple,
},
mixins: [togglePasswordVisibility],
data() {
return {
status: '',
password: 'admin',
userEmail: 'admin@demo.com',
sideImg: require('@/assets/images/pages/login-v2.svg'),
status : '',
password : '', //'admin',
emailAddress : '', //'admin@demo.com',
sideImg : require('@/assets/images/pages/login-v2.svg'),
modalMessage : undefined,
// validation rules
required,
@ -234,41 +255,81 @@ export default {
methods: {
login()
{
this.$refs.loginForm.validate().then(success => {
if (success) {
useJwt.login({
email: this.userEmail,
password: this.password,
})
.then(response => {
const { userData } = response.data
useJwt.setToken(response.data.accessToken)
useJwt.setRefreshToken(response.data.refreshToken)
localStorage.setItem('userDataAdmin', JSON.stringify(userData))
this.$ability.update(userData.ability)
this.$refs.loginForm.validate().then(async success => {
if( success )
{
// useJwt.login({
// email: this.emailAddress,
// password: this.password,
// }).then(response => {
// const { userData } = response.data
// useJwt.setToken(response.data.accessToken)
// useJwt.setRefreshToken(response.data.refreshToken)
// localStorage.setItem('userDataAdmin', JSON.stringify(userData))
// this.$ability.update(userData.ability)
// ? This is just for demo purpose as well.
// ? Because we are showing eCommerce app's cart items count in navbar
this.$store.commit('app-ecommerce/UPDATE_CART_ITEMS_COUNT', userData.extras.eCommerceCartItemsCount)
// // ? This is just for demo purpose as well.
// // ? Because we are showing eCommerce app's cart items count in navbar
// this.$store.commit('app-ecommerce/UPDATE_CART_ITEMS_COUNT', userData.extras.eCommerceCartItemsCount)
// ? This is just for demo purpose. Don't think CASL is role based in this case, we used role in if condition just for ease
this.$router.replace(getHomeRouteForLoggedInUser(userData.role))
.then(() => {
this.$toast({
component: ToastificationContent,
position: 'top-right',
props: {
title: `Welcome ${userData.fullName || userData.username}`,
icon: 'CoffeeIcon',
variant: 'success',
text: `You have successfully logged in as ${userData.role}. Now you can start to explore!`,
},
})
// // ? This is just for demo purpose. Don't think CASL is role based in this case, we used role in if condition just for ease
// this.$router.replace(getHomeRouteForLoggedInUser(userData.role)).then(() => {
// this.$toast({
// component: ToastificationContent,
// position: 'top-right',
// props: {
// title: `Welcome ${userData.fullName || userData.username}`,
// icon: 'CoffeeIcon',
// variant: 'success',
// text: `You have successfully logged in as ${userData.role}. Now you can start to explore!`,
// },
// })
// }).catch(error => {
// this.$refs.loginForm.setErrors(error.response.data.error)
// })
// })
try
{
this.$store.commit('app/TOGGLE_OVERLAY')
// this.$store.commit('app/toggle_full_page_overlay')
const { data } = await this.$http.post('account/token/', {
password: this.password,
email_address: this.emailAddress,
})
.catch(error => {
this.$refs.loginForm.setErrors(error.response.data.error)
login(
data.token,
{
avatar: data.lawyer_user.avatar_url,
firstName: data.lawyer_user.first_name,
lastName: data.lawyer_user.last_name,
fullName: data.lawyer_user.first_name + ' ' + data.lawyer_user.last_name,
}
)
this.$toast({
component: ToastificationContent,
position: 'top-right',
props: {
title: `Welcome`,
icon: 'CoffeeIcon',
variant: 'success',
text: `You have successfully logged in. Now you can start to explore!`,
},
})
})
}
catch( ex )
{
if( ex.status == 404 )
this.modalMessage = 'Either the email or password is incorrect.'
else
this.modalMessage = 'Something went wrong. Please try again later.'
this.$bvModal.show('modal')
}
finally
{
this.$store.commit('app/TOGGLE_OVERLAY')
// this.$store.commit('app/toggle_full_page_overlay')
}
}
})
},
@ -277,5 +338,5 @@ export default {
</script>
<style lang="scss">
@import '@core/scss/vue/pages/page-auth.scss';
@import '@core/scss/vue/pages/page-auth.scss';
</style>

View File

@ -1,282 +1,304 @@
<template>
<div class="auth-wrapper auth-v2">
<b-row class="auth-inner m-0">
<!-- Brand logo-->
<b-link class="brand-logo">
<vuexy-logo />
<h2 class="brand-text text-primary ml-1">
Vuexy
</h2>
</b-link>
<div class="auth-wrapper auth-v2">
<FullPageLoadingComponent v-bind:show="$store.state.app.shallShowOverlay" />
<b-row class="auth-inner m-0">
<!-- Brand logo-->
<b-link class="brand-logo">
<vuexy-logo />
<h2 class="brand-text text-primary ml-1">
Iralex
</h2>
</b-link>
<!-- Left Text-->
<b-col lg="8" class="d-none d-lg-flex align-items-center p-5">
<div class="w-100 d-lg-flex align-items-center justify-content-center px-5">
<b-img fluid v-bind:src="imgUrl" alt="Register V2" />
</div>
</b-col>
<!-- Left Text-->
<b-col lg="8" class="d-none d-lg-flex align-items-center p-5">
<div class="w-100 d-lg-flex align-items-center justify-content-center px-5">
<b-img fluid v-bind:src="imgUrl" alt="Register V2" />
</div>
</b-col>
<!-- Register-->
<b-col
lg="4"
class="d-flex align-items-center auth-bg px-2 p-lg-5"
>
<b-col
sm="8"
md="6"
lg="12"
class="px-xl-2 mx-auto"
>
<b-card-title class="mb-1">
Adventure starts here 🚀
</b-card-title>
<b-card-text class="mb-2">
Make your app management easy and fun!
</b-card-text>
<!-- Register-->
<b-col lg="4" class="d-flex align-items-center auth-bg px-2 p-lg-5">
<b-col sm="8" md="6" lg="12" class="px-xl-2 mx-auto">
<b-card-title class="mb-1">Adventure starts here 🚀</b-card-title>
<b-card-text class="mb-2">Make your app management easy and fun!</b-card-text>
<!-- form -->
<validation-observer
ref="registerForm"
#default="{invalid}"
>
<b-form
class="auth-register-form mt-2"
@submit.prevent="register"
>
<!-- username -->
<b-form-group
label="Username"
label-for="register-username"
>
<validation-provider
#default="{ errors }"
name="Username"
vid="username"
rules="required"
>
<b-form-input
id="register-username"
v-model="username"
name="register-username"
:state="errors.length > 0 ? false:null"
placeholder="johndoe"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<!-- form -->
<validation-observer ref="registerForm" v-slot:default="{invalid}">
<b-form class="auth-register-form mt-2" v-on:submit.prevent="register">
<!-- first name -->
<b-form-group label="First Name" label-for="register-first-name">
<validation-provider
v-slot:default="{ errors }"
name="First Name"
vid="first-name"
rules="required"
>
<b-form-input
id="register-username"
v-model="Payload_D.first_name"
name="register-first-name"
v-bind:state="errors.length > 0 ? false : null"
placeholder="john"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<!-- email -->
<b-form-group
label="Email"
label-for="register-email"
>
<validation-provider
#default="{ errors }"
name="Email"
vid="email"
rules="required|email"
>
<b-form-input
id="register-email"
v-model="userEmail"
name="register-email"
:state="errors.length > 0 ? false:null"
placeholder="john@example.com"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<!-- last name -->
<b-form-group label="Last Name" label-for="register-last-name">
<validation-provider
v-slot:default="{ errors }"
name="Last Name"
vid="last-name"
rules="required"
>
<b-form-input
id="register-last-name"
v-model="Payload_D.last_name"
name="register-username"
v-bind:state="errors.length > 0 ? false : null"
placeholder="doe"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<!-- password -->
<b-form-group
label-for="register-password"
label="Password"
>
<validation-provider
#default="{ errors }"
name="Password"
vid="password"
rules="required"
>
<b-input-group
class="input-group-merge"
:class="errors.length > 0 ? 'is-invalid':null"
>
<b-form-input
id="register-password"
v-model="password"
class="form-control-merge"
:type="passwordFieldType"
:state="errors.length > 0 ? false:null"
name="register-password"
placeholder="············"
/>
<b-input-group-append is-text>
<feather-icon
:icon="passwordToggleIcon"
class="cursor-pointer"
@click="togglePasswordVisibility"
/>
</b-input-group-append>
</b-input-group>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<!-- email -->
<b-form-group label="Email" label-for="register-email">
<validation-provider
v-slot:default="{ errors }"
name="Email"
vid="email"
rules="required|email"
>
<b-form-input
id="register-email"
v-model="Payload_D.email_address"
name="register-email"
v-bind:state="errors.length > 0 ? false : null"
placeholder="john@example.com"
/>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group>
<b-form-group>
<b-form-checkbox
id="register-privacy-policy"
v-model="status"
name="checkbox-1"
>
I agree to
<b-link>privacy policy & terms</b-link>
</b-form-checkbox>
</b-form-group>
<!-- phone number -->
<b-form-group label="Phone Number" label-for="register-phone">
<validation-observer
v-slot:default="{ errors }"
name="Phone Number"
vid="phone"
rules="required"
>
<b-form-input
id="register-phone"
v-model="Payload_D.phone_number"
name="register-phone"
v-bind:state="errors.length > 0 ? false : null"
placeholder="+989130001234"
/>
</validation-observer>
</b-form-group>
<b-button
variant="primary"
block
type="submit"
:disabled="invalid"
>
Sign up
</b-button>
</b-form>
</validation-observer>
<!-- password -->
<!-- <b-form-group
label-for="register-password"
label="Password"
>
<validation-provider
v-slot:default="{ errors }"
name="Password"
vid="password"
rules="required"
>
<b-input-group
class="input-group-merge"
:class="errors.length > 0 ? 'is-invalid':null"
>
<b-form-input
id="register-password"
v-model="password"
class="form-control-merge"
:type="passwordFieldType"
:state="errors.length > 0 ? false:null"
name="register-password"
placeholder="············"
/>
<b-input-group-append is-text>
<feather-icon
:icon="passwordToggleIcon"
class="cursor-pointer"
@click="togglePasswordVisibility"
/>
</b-input-group-append>
</b-input-group>
<small class="text-danger">{{ errors[0] }}</small>
</validation-provider>
</b-form-group> -->
<p class="text-center mt-2">
<span>Already have an account?</span>
<b-link :to="{name:'auth-login'}">
<span>&nbsp;Sign in instead</span>
</b-link>
</p>
<b-form-group>
<b-form-checkbox
id="register-privacy-policy"
v-model="status"
name="checkbox-1"
>
I agree to
<b-link>privacy policy &amp; terms</b-link>
</b-form-checkbox>
</b-form-group>
<!-- divider -->
<div class="divider my-2">
<div class="divider-text">
or
</div>
</div>
<b-button variant="primary" block type="submit" v-bind:disabled="invalid">
Sign up
</b-button>
</b-form>
</validation-observer>
<div class="auth-footer-btn d-flex justify-content-center">
<b-button
variant="facebook"
href="javascript:void(0)"
>
<feather-icon icon="FacebookIcon" />
</b-button>
<b-button
variant="twitter"
href="javascript:void(0)"
>
<feather-icon icon="TwitterIcon" />
</b-button>
<b-button
variant="google"
href="javascript:void(0)"
>
<feather-icon icon="MailIcon" />
</b-button>
<b-button
variant="github"
href="javascript:void(0)"
>
<feather-icon icon="GithubIcon" />
</b-button>
</div>
</b-col>
</b-col>
<!-- /Register-->
</b-row>
</div>
<p class="text-center mt-2">
<span>Already have an account?</span>
<b-link v-bind:to="{name:'auth-login'}">
<span>&nbsp;Sign in instead</span>
</b-link>
</p>
<!-- divider -->
<div class="divider my-2">
<div class="divider-text">or</div>
</div>
<div class="auth-footer-btn d-flex justify-content-center">
<b-button variant="facebook" href="javascript:void(0)">
<feather-icon icon="FacebookIcon" />
</b-button>
<b-button variant="twitter" href="javascript:void(0)">
<feather-icon icon="TwitterIcon" />
</b-button>
<b-button variant="google" href="javascript:void(0)">
<feather-icon icon="MailIcon" />
</b-button>
<b-button variant="github" href="javascript:void(0)">
<feather-icon icon="GithubIcon" />
</b-button>
</div>
</b-col>
</b-col>
<!-- /Register-->
</b-row>
</div>
</template>
<script>
/* eslint-disable global-require */
import { ValidationProvider, ValidationObserver } from 'vee-validate'
import VuexyLogo from '@core/layouts/components/Logo.vue'
import {
BRow, BCol, BLink, BButton, BForm, BFormCheckbox, BFormGroup, BFormInput, BInputGroup, BInputGroupAppend, BImg, BCardTitle, BCardText,
} from 'bootstrap-vue'
import { BRow, BCol, BLink, BButton, BForm, BFormCheckbox, BFormGroup, BFormInput, BInputGroup, BInputGroupAppend, BImg, BCardTitle, BCardText } from 'bootstrap-vue'
import { required, email } from '@validations'
import { togglePasswordVisibility } from '@core/mixins/ui/forms'
import store from '@/store/index'
import useJwt from '@/auth/jwt/useJwt'
import FullPageLoadingComponent from '@/components/ui/FullPageLoadingComponent.vue'
export default {
components: {
VuexyLogo,
BRow,
BImg,
BCol,
BLink,
BButton,
BForm,
BCardText,
BCardTitle,
BFormCheckbox,
BFormGroup,
BFormInput,
BInputGroup,
BInputGroupAppend,
// validations
ValidationProvider,
ValidationObserver,
},
mixins: [togglePasswordVisibility],
data() {
return {
status: '',
username: '',
userEmail: '',
password: '',
sideImg: require('@/assets/images/pages/register-v2.svg'),
// validation
required,
email,
}
},
computed: {
passwordToggleIcon() {
return this.passwordFieldType === 'password' ? 'EyeIcon' : 'EyeOffIcon'
},
imgUrl() {
if (store.state.appConfig.layout.skin === 'dark') {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.sideImg = require('@/assets/images/pages/register-v2-dark.svg')
return this.sideImg
}
return this.sideImg
},
},
methods: {
register() {
this.$refs.registerForm.validate().then(success => {
if (success) {
useJwt.register({
username: this.username,
email: this.userEmail,
password: this.password,
})
.then(response => {
useJwt.setToken(response.data.accessToken)
useJwt.setRefreshToken(response.data.refreshToken)
localStorage.setItem('userData', JSON.stringify(response.data.userData))
this.$ability.update(response.data.userData.ability)
this.$router.push('/')
})
.catch(error => {
this.$refs.registerForm.setErrors(error.response.data.error)
})
}
})
},
},
components: {
VuexyLogo,
BRow,
BImg,
BCol,
BLink,
BButton,
BForm,
BCardText,
BCardTitle,
BFormCheckbox,
BFormGroup,
BFormInput,
BInputGroup,
BInputGroupAppend,
FullPageLoadingComponent,
// validations
ValidationProvider,
ValidationObserver,
},
mixins: [
togglePasswordVisibility
],
data()
{
return {
status: '',
sideImg: require('@/assets/images/pages/register-v2.svg'),
Payload_D: {
first_name: '',
last_name: '',
email_address: '',
phone_number: '',
},
// validation
required,
email,
}
},
computed: {
passwordToggleIcon()
{
return this.passwordFieldType === 'password' ? 'EyeIcon' : 'EyeOffIcon'
},
imgUrl()
{
if (store.state.appConfig.layout.skin === 'dark')
{
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.sideImg = require('@/assets/images/pages/register-v2-dark.svg')
return this.sideImg
}
return this.sideImg
},
},
methods: {
register()
{
this.$refs.registerForm.validate().then(async success => {
if( success )
{
this.$store.commit('app/TOGGLE_OVERLAY')
try
{
const { data } = await this.$http.post('/account/register/', this.Payload_D)
this.$store.commit('app/TOGGLE_OVERLAY')
}
catch (e)
{
this.$store.commit('app/TOGGLE_OVERLAY')
}
// useJwt.register({
// username: this.username,
// email: this.userEmail,
// password: this.password,
// })
// .then(response => {
// useJwt.setToken(response.data.accessToken)
// useJwt.setRefreshToken(response.data.refreshToken)
// localStorage.setItem('userData', JSON.stringify(response.data.userData))
// this.$ability.update(response.data.userData.ability)
// this.$router.push('/')
// })
// .catch(error => {
// this.$refs.registerForm.setErrors(error.response.data.error)
// })
}
})
},
},
}
/* eslint-disable global-require */
</script>
<style lang="scss">
@import '@core/scss/vue/pages/page-auth.scss';
@import '@core/scss/vue/pages/page-auth.scss';
</style>