Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Sign in
Toggle navigation
K
kiaisoft_tuananh_nuxt
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
TTS Tran Viet Anh
kiaisoft_tuananh_nuxt
Commits
9f846362
Commit
9f846362
authored
Feb 13, 2023
by
TTS Kieu Tuan Anh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add middleware
parent
b8f3a8df
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
277 additions
and
84 deletions
+277
-84
Navbar.vue
components/Navbar.vue
+1
-1
web.js
middleware/web.js
+2
-2
index.vue
pages/categories/index.vue
+117
-13
index.vue
pages/posts/index.vue
+34
-9
index.vue
pages/products/index.vue
+47
-6
index.vue
pages/users/index.vue
+76
-53
No files found.
components/Navbar.vue
View file @
9f846362
...
...
@@ -86,7 +86,7 @@ export default {
const
resp
=
await
this
.
$axios
.
post
(
'
/logout
'
,
{
token
:
this
.
$auth
.
$storage
.
getUniversal
(
'
token
'
)
})
if
(
resp
.
status
===
'
200
'
)
{
if
(
resp
.
status
===
200
)
{
this
.
$toast
.
success
(
'
Logout!
'
,
{
duration
:
2000
})
...
...
middleware/web.js
View file @
9f846362
export
default
({
redirect
,
store
})
=>
{
if
(
typeof
localStorage
!==
'
undefined
'
&&
!
localStorage
.
getItem
(
'
token
'
))
{
export
default
({
redirect
,
store
,
$auth
})
=>
{
if
(
!
$auth
.
$storage
.
getLocalStorage
(
'
token
'
))
{
return
redirect
(
'
/login
'
)
}
}
pages/categories/index.vue
View file @
9f846362
...
...
@@ -110,8 +110,18 @@
accept=
"image/*"
label=
"Image"
prepend-icon=
"mdi-camera"
@
change=
"fileSelected"
/>
</v-col>
<v-col
cols=
"12"
>
<img
v-if=
"file"
contain
max-height=
"300"
max-width=
"500"
:src=
"file"
>
</v-col>
<v-img
v-if=
"typeof eImage === 'string'"
:src=
"eImage"
/>
</v-row>
</v-container>
...
...
@@ -122,7 +132,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog2 = false"
@
click=
"dialog2 = false
; clearFile()
"
>
Close
</v-btn>
...
...
@@ -140,8 +150,6 @@
<v-data-table
:headers=
"headers"
:items=
"categories"
:item-class=
"indentation"
sort-by=
"calories"
class=
"elevation-1"
>
<
template
#top
>
<v-toolbar
flat
>
<v-toolbar-title>
Category Manage
</v-toolbar-title>
<v-divider
class=
"mx-4"
inset
vertical
/>
<v-spacer
/>
<v-toolbar-title
style=
"float: right"
>
<v-dialog
...
...
@@ -157,7 +165,7 @@
v-bind=
"attrs"
v-on=
"on"
>
New Category
CREATE NEW
</v-btn>
</
template
>
<v-card>
...
...
@@ -189,7 +197,7 @@
required
/>
</v-col>
<v-col
cols=
"12"
>
<
!-- <
v-col cols="12">
<v-select
v-model="parent_id"
:items="categories"
...
...
@@ -198,14 +206,67 @@
label="Parent*"
:rules="requiredRules"
/>
</v-col> -->
<v-col
cols=
"12"
>
<v-card
class=
"mx-auto"
max-width=
"500"
dark
>
<v-sheet
class=
"pa-4"
>
<v-text-field
v-model=
"search"
label=
"Search Company Directory"
dark
flat
solo-inverted
hide-details
clearable
clear-icon=
"mdi-close-circle-outline"
/>
<v-checkbox
v-model=
"caseSensitive"
dark
hide-details
label=
"Case sensitive search"
/>
</v-sheet>
<v-card-text>
<v-treeview
v-model=
"parent_id"
:items=
"categories"
:search=
"search"
:filter=
"filter"
:open.sync=
"open"
selectable
item-value=
"id"
:rule=
"singleRules"
>
<!-- <template #prepend="{ item }">
<v-icon
v-if="item.children"
v-text="`mdi-${item.id === 1 ? 'home-variant' : 'folder-network'}`"
/>
</template> -->
</v-treeview>
</v-card-text>
</v-card>
</v-col>
<v-col
cols=
"12"
>
<v-file-input
v-model=
"image"
label=
"Image"
prepend-icon=
"mdi-camera"
@
change=
"fileSelected"
/>
</v-col>
<v-col
cols=
"12"
>
<img
v-if=
"file"
:src=
"file"
contain
>
</v-col>
</v-row>
</v-container>
<small>
*indicates required field
</small>
...
...
@@ -215,7 +276,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog1 = false"
@
click=
"dialog1 = false
; clearFile()
"
>
Close
</v-btn>
...
...
@@ -323,7 +384,11 @@ export default {
middleware
:
[
'
web
'
],
data
:
()
=>
{
return
{
parent_id
:
''
,
open
:
[
1
,
2
],
search
:
null
,
caseSensitive
:
false
,
file
:
null
,
parent_id
:
[],
name
:
''
,
ordering
:
''
,
image
:
null
,
...
...
@@ -342,7 +407,7 @@ export default {
groupable
:
false
},
{
text
:
'
Name
'
,
value
:
'
name
'
,
groupable
:
false
},
{
text
:
'
Odering
'
,
value
:
'
ordering
'
,
groupable
:
false
},
{
text
:
'
O
r
dering
'
,
value
:
'
ordering
'
,
groupable
:
false
},
{
text
:
'
Created
'
,
value
:
'
created_at
'
,
groupable
:
false
},
{
text
:
'
Updated
'
,
value
:
'
updated_at
'
,
groupable
:
false
},
{
text
:
'
Actions
'
,
value
:
'
actions
'
,
sortable
:
false
,
groupable
:
false
}
...
...
@@ -359,7 +424,7 @@ export default {
name
:
''
,
id
:
''
,
ordering
:
''
,
parent_id
:
''
,
parent_id
:
[]
,
created_at
:
''
,
updated_at
:
''
},
...
...
@@ -394,12 +459,21 @@ export default {
numberRules
:
[
v
=>
!!
v
||
'
This field is required
'
,
v
=>
v
>
0
||
'
value must be a positive integer
'
],
singleRules
:
[
v
=>
!!
v
||
'
This field is required
'
,
v
=>
(
v
.
length
<
2
)
||
'
Chose 1 pls -____-
'
]
}
},
computed
:
{
formTitle
()
{
return
this
.
editedIndex
===
-
1
?
'
New Item
'
:
'
Edit Item
'
},
filter
()
{
return
this
.
caseSensitive
?
(
item
,
search
,
textKey
)
=>
item
[
textKey
].
includes
(
search
)
:
undefined
}
},
watch
:
{
...
...
@@ -505,6 +579,7 @@ export default {
})
})
this
.
getCategories
()
this
.
clearFile
()
this
.
clearData
()
},
deleteCategory
()
{
...
...
@@ -579,17 +654,42 @@ export default {
})
this.editedItem = response.data.data
Object.assign(this.categories[this.editedIndex], this.editedItem)
this.clearFile()
})
} catch (error) {
console.log(error)
}
},
clearData () {
// eslint-disable-next-line no-unused-expressions, no-sequences
this.parent_id = '',
this.name = '',
this.ordering = '',
this.parent_id = []
this.name = ''
this.ordering = ''
this.image = null
},
fileSelected (event) {
if (event) {
this.file = URL.createObjectURL(event)
console.log(this.file)
} else {
this.file = null
}
},
clearFile () {
this.file = null
},
onOpen (e) {
// ignore initial open
if (!this.__initial) {
this.__initial = true
return
}
console.log('toggle arrow clicked', e)
},
onSelected (e) {
console.log('checkbox clicked', e)
this.parent_id = e[0]
console.log(this.parent_id)
}
}
}
...
...
@@ -618,4 +718,8 @@ export default {
.depth-5
>
td
:nth-child
(
2
)
{
padding-left
:
150px
!important
;
}
img
{
width
:
100%
;
height
:
100%
}
</
style
>
pages/posts/index.vue
View file @
9f846362
<!-- eslint-disable vue/require-v-for-key -->
<!-- eslint-disable-next-line no-console -->
<
template
>
<div>
<div>
...
...
@@ -156,8 +157,18 @@
small-chips
dense
prepend-icon=
"mdi-camera"
@
change=
"fileSelected"
/>
</v-col>
<v-col
cols=
"12"
class=
"v-image v-responsive theme--dark"
>
<img
v-if=
"file"
contain
max-height=
"300"
max-width=
"500"
:src=
"file"
>
</v-col>
</v-row>
</v-container>
<small>
*indicates required field
</small>
...
...
@@ -167,7 +178,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog = false"
@
click=
"dialog = false
; clearFile()
"
>
Close
</v-btn>
...
...
@@ -205,8 +216,6 @@
<v-data-table
:headers=
"headers"
:items=
"posts"
sort-by=
"calories"
class=
"elevation-1"
>
<
template
#top
>
<v-toolbar
flat
>
<v-toolbar-title>
Post Manage
</v-toolbar-title>
<v-divider
class=
"mx-4"
inset
vertical
/>
<v-spacer
/>
<v-toolbar-title>
<!-- modal-create -->
...
...
@@ -224,7 +233,7 @@
v-bind=
"attrs"
v-on=
"on"
>
New Post
create new
</v-btn>
</
template
>
<v-card>
...
...
@@ -290,7 +299,7 @@
@
change=
"fileSelected"
/>
</v-col>
<v-col
cols=
"12"
>
<v-col
cols=
"12"
class=
"v-image v-responsive theme--dark"
>
<img
v-if=
"file"
contain
...
...
@@ -308,7 +317,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog1 = false"
@
click=
"dialog1 = false
; clearFile()
"
>
Close
</v-btn>
...
...
@@ -398,9 +407,9 @@ export default {
href
:
'
/home
'
},
{
text
:
'
P
roduc
t
'
,
text
:
'
P
os
t
'
,
disabled
:
false
,
href
:
'
/p
roduc
ts
'
href
:
'
/p
os
ts
'
}
],
statusDefault
:
[
...
...
@@ -593,6 +602,8 @@ export default {
this
.
editedItem
=
response
.
data
.
data
console
.
log
(
this
.
editedItem
)
this
.
posts
.
push
(
this
.
editedItem
)
this
.
clearData
()
this
.
clearFile
()
})
.
catch
((
errors
)
=>
{
self
.
$toast
.
error
(
'
something went wrong while trying create!
'
,
{
...
...
@@ -682,6 +693,7 @@ export default {
})
this.editedItem = response.data.data
Object.assign(this.posts[currentPostIndex], this.editedItem)
this.clearFile()
})
.catch((error) => {
console.log(error)
...
...
@@ -697,11 +709,24 @@ export default {
} else {
this.file = null
}
},
clearData () {
this.title = ''
this.category_id = null
this.content = ''
this.status = null
this.images = []
},
clearFile () {
this.file = null
}
}
}
</
script
>
<
style
>
img
{
width
:
100%
;
height
:
100%
;
}
</
style
>
pages/products/index.vue
View file @
9f846362
...
...
@@ -172,9 +172,16 @@
small-chips
dense
multiple
@
change=
"fileSelected"
@
click:clear=
"clearImage"
/>
</v-col>
<v-img
v-if=
"typeof eImages === 'string'"
:src=
"eImages"
/>
<v-col
v-if=
"files"
cols=
"12"
>
<v-col
v-for=
"(image, index) in files"
:key=
"index"
cols=
"12"
>
<v-img
:src=
"image"
contain
/>
</v-col>
</v-col>
<!-- <v-img v-if="typeof eImages === 'string'" :src="eImages" /> -->
<v-col
cols=
"12"
>
<v-btn
class=
"mx-2"
...
...
@@ -251,7 +258,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog3 = false"
@
click=
"dialog3 = false
; clearImage();
"
>
Close
</v-btn>
...
...
@@ -311,8 +318,6 @@
>
<
template
#top
>
<v-toolbar
flat
>
<v-toolbar-title>
Product Manage
</v-toolbar-title>
<v-divider
class=
"mx-4"
inset
vertical
/>
<v-spacer
/>
<v-toolbar-title>
<v-dialog
...
...
@@ -328,7 +333,7 @@
v-bind=
"attrs"
v-on=
"on"
>
New Product
create new
</v-btn>
</
template
>
<v-card>
...
...
@@ -388,8 +393,15 @@
:rules=
"imageRules"
lazy-validation
prepend-icon=
"mdi-camera"
@
change=
"fileSelected"
@
click:clear=
"clearImage"
/>
</v-col>
<v-col
v-if=
"files"
cols=
"12"
>
<v-col
v-for=
"(image, index) in files"
:key=
"index"
cols=
"12"
>
<v-img
:src=
"image"
contain
/>
</v-col>
</v-col>
<v-col
cols=
"12"
>
<v-btn
class=
"mx-2"
...
...
@@ -466,7 +478,7 @@
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog1 = false"
@
click=
"dialog1 = false
; clearData ();
"
>
Close
</v-btn>
...
...
@@ -514,6 +526,7 @@ export default {
middleware
:
[
'
web
'
],
data
:
()
=>
{
return
{
files
:
[],
name
:
''
,
id
:
''
,
category_id
:
''
,
...
...
@@ -759,6 +772,7 @@ export default {
this
.
editedItem
=
response
.
data
.
data
console
.
log
(
this
.
editedItem
)
this
.
products
.
push
(
this
.
editedItem
)
this
.
clearData
()
})
.
catch
((
errors
)
=>
{
console
.
log
(
errors
.
response
.
data
.
message
)
...
...
@@ -910,6 +924,33 @@ export default {
}
this.eVariants.splice(currentVariantIndex, 1)
}
},
fileSelected (event) {
if (event) {
for (let i = 0; i < event.length; i++) {
console.log(event[i])
this.files.push(URL.createObjectURL(event[i]))
}
}
console.log(this.files)
},
clearData () {
this.name = ''
this.category_id = ''
this.price = ''
this.description = ''
this.images = []
this.variants = [
{
color: '',
size: '',
quantity: ''
}
]
this.files.length = 0
},
clearImage () {
this.files.length = 0
}
}
}
...
...
pages/users/index.vue
View file @
9f846362
...
...
@@ -18,29 +18,31 @@
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col
cols=
"12"
sm=
"6"
md=
"4"
>
<v-text-field
v-model=
"eName"
label=
"Legal name*"
:rules=
"nameRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"eEmail"
label=
"Email*"
:rules=
"emailRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"ePassword"
label=
"Password*"
type=
"password"
:rules=
"passwordRules"
required
/>
</v-col>
</v-row>
<v-form
ref=
"formEdit"
>
<v-row>
<v-col
cols=
"12"
sm=
"6"
md=
"4"
>
<v-text-field
v-model=
"eName"
label=
"Legal name*"
:rules=
"nameRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"eEmail"
label=
"Email*"
:rules=
"emailRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"ePassword"
label=
"Password*"
type=
"password"
:rules=
"passwordRules"
required
/>
</v-col>
</v-row>
</v-form>
</v-container>
<small>
*indicates required field
</small>
</v-card-text>
<v-card-actions>
<v-spacer
/>
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog2 = false"
>
<v-btn
color=
"blue darken-1"
text
@
click=
"dialog2 = false
; clearData();
"
>
Close
</v-btn>
<v-btn
...
...
@@ -48,8 +50,9 @@
text
type=
"submit"
@
click=
"
dialog2 = false;
//
dialog2 = false;
updateUser();
validateForm();
"
>
Save
...
...
@@ -90,20 +93,17 @@
>
<
template
#top
>
<v-toolbar
flat
>
<v-toolbar-title>
User Manage
</v-toolbar-title>
<v-divider
class=
"mx-4"
inset
vertical
/>
<v-spacer
/>
<v-toolbar-title
style=
"float: right"
>
<v-dialog
v-model=
"dialog1"
persistent
max-width=
"600px"
@
submit.prevent=
"createUser"
lazy-validation
>
<template
#activator
="
{ on, attrs }">
<v-btn
color=
"primary"
dark
v-bind=
"attrs"
v-on=
"on"
>
New USER
CREATE NEW
</v-btn>
</
template
>
<v-card>
...
...
@@ -112,33 +112,35 @@
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col
cols=
"12"
sm=
"6"
md=
"4"
>
<v-text-field
v-model=
"name"
label=
"Legal name*"
:rules=
"nameRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"email"
label=
"Email*"
:rules=
"emailRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"password"
label=
"Password*"
type=
"password"
:rules=
"passwordRules"
required
/>
</v-col>
</v-row>
<v-form
ref=
"form"
>
<v-row>
<v-col
cols=
"12"
sm=
"6"
md=
"4"
>
<v-text-field
v-model=
"name"
label=
"Legal name*"
:rules=
"nameRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"email"
label=
"Email*"
:rules=
"emailRules"
required
/>
</v-col>
<v-col
cols=
"12"
>
<v-text-field
v-model=
"password"
label=
"Password*"
type=
"password"
:rules=
"passwordRules"
required
/>
</v-col>
</v-row>
</v-form>
</v-container>
<small>
*indicates required field
</small>
</v-card-text>
...
...
@@ -152,8 +154,9 @@
text
type=
"submit"
@
click=
"
dialog1 = false;
//
dialog1 = false;
createUser();
validateForm()
"
>
Save
...
...
@@ -211,6 +214,7 @@ export default {
middleware
:
[
'
web
'
],
data
:
()
=>
{
return
{
valid
:
true
,
email
:
''
,
name
:
''
,
password
:
''
,
...
...
@@ -224,9 +228,8 @@ export default {
align
:
'
start
'
,
value
:
'
index
'
},
{
text
:
'
Name
'
,
value
:
'
name
'
},
{
text
:
'
Name
'
,
value
:
'
name
'
,
sortable
:
false
},
{
text
:
'
email
'
,
value
:
'
email
'
},
{
text
:
'
status
'
,
value
:
'
id
'
,
sortable
:
false
},
{
text
:
'
created
'
,
value
:
'
created_at
'
},
{
text
:
'
updated
'
,
value
:
'
updated_at
'
},
{
text
:
'
Actions
'
,
value
:
'
actions
'
,
sortable
:
false
}
...
...
@@ -378,6 +381,7 @@ export default {
}
)
.
then
((
response
)
=>
{
this
.
dialog1
=
false
self
.
$toast
.
success
(
'
User created successfully!
'
,
{
duration
:
3000
})
...
...
@@ -385,8 +389,11 @@ export default {
this
.
editedItem
=
response
.
data
.
data
console
.
log
(
this
.
editedItem
)
this
.
users
.
push
(
this
.
editedItem
)
this
.
clearData
()
})
.
catch
((
errors
)
=>
{
this
.
dialog1
=
true
this
.
validate
()
console
.
log
(
errors
.
response
.
data
.
message
)
this
.
message
=
errors
.
response
.
data
.
message
self
.
$toast
.
error
(
'
something went wrong while trying create!
'
,
{
...
...
@@ -443,6 +450,7 @@ export default {
}
)
.then((response) => {
this.dialog2 = false
self.$toast.success('User updated successfully!', {
duration: 3000
})
...
...
@@ -460,6 +468,21 @@ export default {
getID (item) {
this.eID = item.id
this.editedIndex = this.users.indexOf(item)
},
clearData () {
this.name = ''
this.email = ''
this.password = ''
},
async validate (name) {
const { valid } = await this.$refs.form.validate()
if (valid) { alert('Form is valid') }
},
async validateForm (name) {
const { valid } = await this.$refs.formEdit.validate()
if (valid) { alert('Form is valid') }
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment