Commit 61ef56a1 authored by catea792's avatar catea792

update feature categories

parent 6c99a80b
<!-- eslint-disable vue/no-parsing-error -->
<template>
<v-footer dark padless>
<v-card flat tile class="indigo lighten-1 white--text text-center">
<v-card-text>
<v-btn v-for="icon in icons" :key="icon" class="mx-4 white--text" icon>
<v-icon size="24px">
{{ icon }}
</v-icon>
</v-btn>
</v-card-text>
<v-card-text class="white--text pt-0">
Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet.
Mauris cursus commodo interdum. Praesent ut risus eget metus luctus
accumsan id ultrices nunc. Sed at orci sed massa consectetur dignissim a
sit amet dui. Duis commodo vitae velit et faucibus. Morbi vehicula
lacinia malesuada. Nulla placerat augue vel ipsum ultrices, cursus
iaculis dui sollicitudin. Vestibulum eu ipsum vel diam elementum tempor
vel ut orci. Orci varius natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus.
</v-card-text>
<v-divider />
<div class="footer-bottom">
<div class="footer-bottom-left">
<figure class="payment">
<img
src="~/assets/images/payment.png"
alt="payment"
width="159"
height="29"
>
</figure>
</div>
<p class="copyright">
Riode eCommerce © 2022. All Rights Reserved
</p>
<div class="footer-bottom-right">
<div class="social-link">
<v-btn
v-for="icon in icons"
:key="icon"
class="mx-4 white--text"
icon
>
<v-icon size="24px">
{{ icon }}
</v-icon>
</v-btn>
</div>
</div>
<v-footer class="mt-12 flex-wrap" min-height="350px" dark padless>
<v-row class="d-flex justify-space-between align-center">
<v-col
cols="12"
md="3"
>
<v-img
width="153px"
src="https://d-themes.com/html/riode/images/logo-footer.png"
/>
</v-col>
<div class="flex-column">
<h3>Subscribe to our Newsletter</h3>
<h4>Get all the latest information, Sales and Offers.</h4>
</div>
</v-card>
<v-col
cols="12"
md="4"
>
<v-text-field label="email address here ..."></v-text-field>
</v-col>
<v-btn color="primary">SUBSCRIBE</v-btn>
</v-row>
<v-divider></v-divider>
</v-footer>
</template>
<script>
export default {
name: 'FooterBar',
data: () => ({
icons: ['mdi-facebook', 'mdi-twitter', 'mdi-linkedin', 'mdi-instagram']
icons: ['mdi-facebook', 'mdi-twitter', 'mdi-linkedin', 'mdi-instagram'],
img: 'https://d-themes.com/html/riode/images/logo-footer.png'
})
}
</script>
<style>
.footer-bottom-left {
position: absolute;
left: 0;
}
.footer-bottom-right {
position: absolute;
right: 0;
}
.copyright {
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
</style>
<style></style>
......@@ -3,120 +3,73 @@
<div>
<!-- header top -->
<div class="header-top">
<v-container>
<v-container class="pa-0">
<v-row no-gutters>
<v-col
cols="12"
sm="6"
>
<v-list-item-content>
<v-list-item-title>Hello message</v-list-item-title>
</v-list-item-content>
<v-col cols="12" sm="8" class="header-top-left">
<span>Hello message</span>
</v-col>
<v-col
cols="12"
sm="6"
class="d-flex"
>
<div class="text-center">
<v-menu
open-on-hover
offset-y
>
<template #activator="{ on, attrs }">
<v-btn
plain
v-bind="attrs"
v-on="on"
>
<span>USD</span>
<v-icon>mdi-chevron-down</v-icon>
</v-btn>
</template>
<v-list
dense
<v-col cols="12" sm="4" class="header-top-right">
<div class="dropdown">
<span> USD </span>
<v-icon small>
mdi-chevron-down
</v-icon>
<div class="dropdown-content">
<div
v-for="(item, i) in currency"
:key="i"
class="dropdown-item"
>
<v-list-item>
<v-btn plain>
USD
</v-btn>
</v-list-item>
<v-list-item>
<v-btn plain>
EUR
</v-btn>
</v-list-item>
</v-list>
</v-menu>
<span>
{{ item.text }}
</span>
</div>
</div>
</div>
<div class="text-center">
<v-menu
open-on-hover
offset-y
>
<template #activator="{ on, attrs }">
<v-btn
plain
v-bind="attrs"
v-on="on"
>
<span>Eng</span>
<v-icon>mdi-chevron-down</v-icon>
</v-btn>
</template>
<v-list
dense
<div class="dropdown">
<span> ENG </span>
<v-icon small>
mdi-chevron-down
</v-icon>
<div class="dropdown-content">
<div
v-for="(item, i) in languages"
:key="i"
class="dropdown-item"
>
<v-list-item>
<v-btn plain>
Eng
</v-btn>
</v-list-item>
<v-list-item>
<v-btn plain>
FRH
</v-btn>
</v-list-item>
</v-list>
</v-menu>
<span>
{{ item.text }}
</span>
</div>
</div>
</div>
<v-divider vertical />
<v-btn
plain
v-bind="attrs"
v-on="on"
>
<v-icon>mdi-map-marker-outline</v-icon>
<div class="header-info">
<v-icon small>
mdi-map-marker-outline
</v-icon>
<span>Contact</span>
</v-btn>
<v-btn
plain
v-bind="attrs"
v-on="on"
>
<v-icon>mdi-alert-circle-outline</v-icon>
</div>
<div class="header-info">
<v-icon small>
mdi-alert-circle-outline
</v-icon>
<span>Need help</span>
</v-btn>
<v-btn
plain
v-bind="attrs"
v-on="on"
@click="openDialogLogin"
>
<v-icon>mdi-account-outline</v-icon>
<span>login</span>
</v-btn>
<v-icon>mdi-slash-forward</v-icon>
<v-btn
plain
v-bind="attrs"
v-on="on"
@click="openDialogSignUp"
>
<span>Signup</span>
</v-btn>
</div>
<div class="authentication">
<div class="header-info" @click="openDialogLogin">
<v-icon small>
mdi-account-outline
</v-icon>
<span>Login</span>
</div>
<v-icon small>
mdi-slash-forward
</v-icon>
<div class="header-info" @click="openDialogSignUp">
<span>Signup</span>
</div>
</div>
</v-col>
</v-row>
</v-container>
......@@ -125,77 +78,54 @@
<!-- header middle -->
<div class="header-middle d-flex">
<v-container py-5 d-flex>
<v-col
cols="12"
md="3"
>
<v-img
width="153px"
src="https://d-themes.com/html/riode/images/logo.png"
/>
</v-col>
<v-col
cols="12"
md="5"
>
<v-form
ref="form"
class="d-flex"
>
<v-container class="header-middle-content" py-7>
<v-col cols="12" md="8" class="header-middle-left padding-0">
<div class="logo">
<v-img
width="153px"
src="https://d-themes.com/html/riode/images/logo.png"
/>
</div>
<v-form class="d-flex form-search">
<v-text-field
outlined
dense
hide-details="auto"
label="Search"
variant="outlined"
class="search-input"
/>
<v-btn
icon
>
<v-icon>
mdi-magnify
</v-icon>
</v-btn>
<span class="icon">
<v-icon> mdi-magnify </v-icon>
</span>
</v-form>
</v-col>
<v-col
cols="12"
md="4"
class="d-flex"
>
<v-btn
plain
v-bind="attrs"
v-on="on"
>
<v-col cols="12" md="4" class="header-middle-right padding-0">
<div class="hotline d-flex">
<v-icon large>
mdi-phone
mdi-phone-outline
</v-icon>
<span>Call us now:
<b>0123456789</b>
</span>
</v-btn>
<div class="contact">
<span>Call us now:</span>
<b>0(800) 123-456</b>
</div>
</div>
<v-divider vertical inset />
<v-btn
plain
v-bind="attrs"
v-on="on"
@click.stop="drawer = true"
>
<div class="wish-list" v-bind="attrs" v-on="on" @click.stop="drawer = true">
<v-icon large>
mdi-heart-outline
</v-icon>
</v-btn>
</div>
<v-divider vertical inset />
<v-btn
id="menu-activator"
plain
v-bind="attrs"
v-on="on"
>
<v-spacer />
<span>Cart:
<div id="menu-activator" class="cart" plain v-bind="attrs" v-on="on">
<span>Shopping cart:
<b>$:0.00</b>
</span>
<v-badge :content="15" floating>
<v-badge
:content="products.length || 0"
floating
bordered
overlap
>
<v-icon large>
mdi-cart-outline
</v-icon>
......@@ -203,20 +133,20 @@
<v-menu activator="#menu-activator" style="width: 300px">
<v-list dense three-line>
<v-list-item
v-for="item in items"
:key="item.title"
v-for="item in products"
:key="item.id"
link
>
<v-list-item-avatar>
<v-img :src="item.prependAvatar" />
<v-img :src="item.product.images[0]" />
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
<v-list-item-subtitle>{{ item.subtitle }}</v-list-item-subtitle>
<v-list-item-title>{{ item.product.name }}</v-list-item-title>
<v-list-item-subtitle>{{ item.quantity +"x"+ item.product.price }}</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn icon @click="remove(index)">
<v-btn icon @click="removeCart(item,index)">
<v-icon color="grey lighten-1">
mdi-close-circle-outline
</v-icon>
......@@ -227,18 +157,18 @@
<v-divider />
<div class="d-flex justify-space-between align-center ma-4">
<span>Subtotal: </span>
<span>139$ </span>
<span> {{ total + "$" }} </span>
</div>
<v-divider />
<v-btn
size="x-large"
color="primary"
class="d-flex mt-4 align-center mx-auto"
class="d-flex mt-4 align-center mx-auto"
>
GO TO CHECKOUT
</v-btn>
</v-menu>
</v-btn>
</div>
</v-col>
</v-container>
</div>
......@@ -250,8 +180,8 @@
<!-- end header bottom -->
<!-- show modal -->
<LoginModal :status="activeLogin" @close="activeLogin=false" />
<SignupModal :status="activeRegister" @close="activeRegister=false" />
<LoginModal :status="activeLogin" @close="activeLogin = false" />
<SignupModal :status="activeRegister" @close="activeRegister = false" />
<!-- show drawer -->
<v-navigation-drawer
v-model="drawer"
......@@ -262,35 +192,26 @@
>
<div class="d-flex justify-space-between drawer_header">
<b>WISHLIST</b>
<v-btn
plain
@click.stop="drawer = !drawer"
>
<v-btn plain @click.stop="drawer = !drawer">
Close
<v-icon>
mdi-arrow-right-thin
</v-icon>
<v-icon> mdi-arrow-right-thin </v-icon>
</v-btn>
</div>
<v-divider />
<v-list dense three-line>
<v-list-item
v-for="item in items"
:key="item.title"
link
>
<v-list-item v-for="item in wishlist" :key="item.name" link>
<v-list-item-avatar>
<v-img :src="item.prependAvatar" />
<v-img :src="item.product.images[0]" />
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
<v-list-item-subtitle>{{ item.subtitle }}</v-list-item-subtitle>
<v-list-item-title>{{ item.product.name }}</v-list-item-title>
<v-list-item-subtitle>{{ item.product.price }}</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn icon @click="remove(index)">
<v-btn icon @click="removeWishlist(item, index)">
<v-icon color="grey lighten-1">
mdi-close-circle-outline
</v-icon>
......@@ -306,6 +227,7 @@
import LoginModal from '~/components/LoginModal.vue'
import SignupModal from '~/components/RegisterModal.vue'
import NavBar from '~/components/user/NavBar'
import { eventBus } from '~/plugins/eventBus.js'
export default {
name: 'UserHeader',
......@@ -314,40 +236,39 @@ export default {
SignupModal,
NavBar
},
data: () => {
return {
products: [],
wishlist: [],
activeLogin: false,
activeRegister: false,
drawer: false,
items: [
{
prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',
title: 'Brunch this weekend?',
subtitle: '<span class="text-primary">Ali Connors</span> &mdash; I\'ll be in your neighborhood doing errands this weekend. Do you want to hang out?'
},
{
prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',
title: 'Summer BBQ',
subtitle: '<span class="text-primary">to Alex, Scott, Jennifer</span> &mdash; Wish I could come, but I\'m out of town this weekend.'
},
{
prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',
title: 'Oui oui',
subtitle: '<span class="text-primary">Sandra Adams</span> &mdash; Do you have Paris recommendations? Have you ever been?'
},
{
prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',
title: 'Birthday gift',
subtitle: '<span class="text-primary">Trevor Hansen</span> &mdash; Have any ideas about what we should get Heidi for her birthday?'
},
{
prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',
title: 'Recipe to try',
subtitle: '<span class="text-primary">Britta Holt</span> &mdash; We should eat this: Grate, Squash, Corn, and tomatillo Tacos.'
}
currency: [
{ text: 'USD', icon: 'mdi-clock' },
{ text: 'EUR', icon: 'mdi-account' }
],
languages: [
{ text: 'ENG', icon: 'mdi-clock' },
{ text: 'FRH', icon: 'mdi-account' }
]
}
},
computed: {
total () {
const arr = []
this.products.map((value) => {
return arr?.push(value.price)
})
return arr.reduce((acc, cur) => acc + cur, 0)
}
},
mounted () {
this.getCardProducts()
this.getWishlish()
this.updateWishlist()
this.updateCart()
},
methods: {
closeDialog () {
this.activeLogin = false
......@@ -358,52 +279,255 @@ export default {
this.activeLogin = true
},
openDialogSignUp () {
this.activeLogin = false
this.activeLogin = true
this.activeRegister = false
this.activeRegister = true
},
remove (index) {
this.items.splice(index, 1)
console.log(this.items)
removeCart (item, index) {
try {
this.$axios
.delete(`/carts/delete-cart-item/${item.id}`, {
headers: {
Authorization: `Bearer ${this.$auth.$storage.getUniversal(
'token'
)}`
}
})
.then((response) => {
this.products.splice(index, 1)
this.$toast.success('Remove product successfully!', {
duration: 1500
})
})
} catch (error) {
console.log(error)
this.$toast.error('ERR!', {
duration: 1500
})
}
},
async getCardProducts () {
await this.$axios
.get(`/carts/user-cart/${this.$auth.$storage.getUniversal('ID')}`, {
headers: {
Authorization: `Bearer ${this.$auth.$storage.getUniversal(
'token'
)}`
}
})
.then((response) => {
this.products = response.data.data
console.log(this.products)
})
.catch(function (error) {
console.log(error)
})
},
async getWishlish () {
await this.$axios
.get(`/wish-list/user-wish-list/${this.$auth.$storage.getUniversal('ID')}`, {
headers: {
Authorization: `Bearer ${this.$auth.$storage.getUniversal(
'token'
)}`
}
})
.then((response) => {
this.wishlist = response.data.data
console.log(this.wishlist)
})
.catch(function (error) {
console.log(error)
})
},
removeWishlist (item, index) {
try {
this.$axios
.delete(`/wish-list/delete-from-wish-list/${item.id}`, {
headers: {
Authorization: `Bearer ${this.$auth.$storage.getUniversal(
'token'
)}`
}
})
.then((response) => {
this.wishlist.splice(index, 1)
this.$toast.success('Remove product successfully!', {
duration: 1500
})
})
} catch (error) {
console.log(error)
this.$toast.error('ERR!', {
duration: 1500
})
}
},
updateWishlist () {
eventBus.$on('add-to-wish-list', (response) => {
this.getWishlish()
})
},
updateCart () {
eventBus.$on('add-to-cart', (response) => {
console.log('abc')
this.getCardProducts()
})
}
}
}
</script>
<style scoped>
.header-top{
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
b {
display: block;
}
.col-md {
align-items: center
}
.v-application .d-flex {
align-items: center;
}
.favorite-modal {
position: fixed;
}
.favorite-modal .modal_header {
padding: 20px 0px 20px 30px;
}
.modal_header > b {
font-weight: 700;
font-size: 16px;
}
.modal_header > button {
font-size: 12px;
}
.modal_header > i {
scale: 0.8;
}
.drawer_header{
padding: 20px 0 20px 30px;
}
.v-menu__content {
width: 300px;
top: 153px !important;
padding: 25px;
}
.header-top {
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
font-size: 12px;
color: rgba(0, 0, 0, 0.8);
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.header-top-left {
display: flex;
align-items: center;
}
.header-top-right {
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
}
.dropdown {
display: flex;
cursor: pointer;
position: relative;
}
.dropdown > span {
line-height: 2rem;
}
.dropdown-content {
display: none;
position: absolute;
top: 30px;
background: white;
box-shadow: 2px 2px 15px 3px rgba(1, 1, 1, 0.3);
}
.dropdown-item {
margin: 5px 7px;
}
.v-divider--vertical {
min-height: 70%;
max-height: 70%;
margin: 5px -1px;
}
.header-info {
cursor: pointer;
}
span:hover {
color: #2266cc;
cursor: pointer;
}
.dropdown:hover .dropdown-content {
display: block;
}
.header-info {
display: flex;
align-items: center;
}
.header-info:hover .span.v-icon{
color: #2266cc;
}
.authentication {
display: flex;
}
.v-icon.v-icon {
margin: 0 3px;
}
.header-middle-content {
display: flex;
padding-left: 0;
padding-right: 0;
font-size: 12px;
color: #000000;
}
.header-middle-left {
display: flex;
align-items: center;
padding-right: 0;
padding-left: 0;
justify-content: space-between;
}
.padding-0 {
padding: 0 !important;
}
.logo {
display: flex;
align-items: center;
}
.form-search {
width: 100%;
position: relative;
margin: 0 auto;
margin: 0 5vw;
}
.search-input {
width: inherit;
position: absolute;
}
span.icon {
position: absolute;
right: 5px;
cursor: pointer;
}
span.icon:hover .v-icon.v-icon{
color: #2266cc;
}
.header-middle-right {
display: flex;
justify-content: space-between;
}
b {
display: block;
font-size: 14px;
}
.hotline {
cursor: pointer;
}
.hotline:hover {
color: #2266cc;
}
.wish-list {
cursor: pointer;
}
.wish-list:hover .v-icon.v-icon {
color: #2266cc;
}
.cart {
display: flex;
}
.v-application .d-flex {
align-items: center;
}
.favorite-modal {
position: fixed;
}
.favorite-modal .modal_header {
padding: 20px 0px 20px 30px;
}
.modal_header > b {
font-weight: 700;
font-size: 16px;
}
.modal_header > button {
font-size: 12px;
}
.modal_header > i {
scale: 0.8;
}
.drawer_header {
padding: 20px 0 20px 30px;
}
.v-menu__content {
width: 300px;
top: 110px !important;
padding: 25px;
background-color: #ffffff;
}
</style>
<template>
<v-container>
<div class="navbar d-flex justify-space-between col-md-7">
<div>
<span>
Home
</span>
</div>
<div class="dropdown">
<span>
Products
</span>
<v-icon>mdi-chevron-down</v-icon>
<div class="dropdown-content elevation-10" :elevation="2">
<v-treeview
:active.sync="active"
rounded
dense
hoverable
activatable
:items="categories"
/>
<div class="navbar d-flex justify-space-between ">
<div class="d-flex justify-space-between col-md-7">
<div>
<span>
Home
</span>
</div>
<div class="dropdown">
<span>
Products
</span>
<v-icon>mdi-chevron-down</v-icon>
<div class="dropdown-content elevation-10" :elevation="2">
<v-treeview
:active.sync="active"
rounded
dense
hoverable
activatable
:items="categories"
@update:active="setCategory(item)"
>
<template #label="{ item }">
<nuxt-link :to="`/home-page/categories/${item.id}`" tag="div">
{{ item.name }}
</nuxt-link>
</template>
</v-treeview>
</div>
</div>
<div>
<span>
Pages
</span>
</div>
<div>
<span>
Blogs
</span>
</div>
<div>
<span>
About
</span>
</div>
</div>
<div>
<span>
Pages
</span>
</div>
<div>
<span>
Blogs
<div class="d-flex align-center ">
<v-icon>mdi-tag</v-icon>
<span class="mx-2">
Special offer!
</span>
</div>
<div>
<span>
About
<span class="mx-2">
Buy riode
</span>
</div>
</div>
......@@ -42,6 +60,8 @@
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
name: 'NavBar',
data: () => ({
......@@ -51,11 +71,14 @@ export default {
}),
computed: {
...mapState(['selectedCategory']),
...mapActions(['setSelectedCategory']),
selected () {
if (!this.active.length) { return undefined }
const id = this.active[0]
console.log(id)
return this.categories.find(category => category.id === id)
// console.log(this.categories.find(category => category.id === id).name)
return this.categories.find(category => category.id === id) || ''
}
},
......@@ -63,11 +86,10 @@ export default {
selected () {
if (!this.active.length) { return undefined }
const id = this.active[0]
return id
return id || ''
}
},
created () {
beforeCreate () {
this.$axios
.get('guest/categories/index')
.then((response) => {
......@@ -77,8 +99,13 @@ export default {
console.log(error)
})
},
mounted () {
},
methods: {
setCategory () {
console.log(this.selected)
this.$store.commit('category/setCurrentCategory', this.selected.name || '')
}
}
}
</script>
......
<template>
<v-app>
<UserHeader />
<UserHeader ref="child" />
<Nuxt />
<FooterBar />
</v-app>
</template>
<script>
import Header from '@/components/user/Header'
import FooterBar from '@/components/FooterBar'
export default {
component: {
Header
Header,
FooterBar
},
components: { FooterBar },
created () {
this.changeColor()
},
......@@ -25,5 +29,7 @@ export default {
</script>
<style>
body{
font-family: monospace;
}
</style>
......@@ -29,7 +29,8 @@ export default {
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
'~/plugins/axios.js',
'~/plugins/formatTime.js'
'~/plugins/formatTime.js',
'~/plugins/eventBus.js'
],
// Auto import components: https://go.nuxtjs.dev/config-components
......
<template>
<div>
<div>
<h1 style="text-align: center">ABOUT</h1>
</div>
<div>
<h1 style="text-align: center">
ABOUT
</h1>
</div>
</div>
</template>
\ No newline at end of file
</template>
......@@ -120,6 +120,7 @@ export default {
localStorage.setItem('token', resp.data.data.bearer_token)
this.$auth.$storage.setUniversal('token', resp.data.data.bearer_token)
this.$auth.$storage.setUniversal('userName', resp.data.data.name)
this.$auth.$storage.setUniversal('ID', resp.data.data.id)
this.$auth.$storage.setUniversal('loggedIn', 'true')
if (resp.status === 200) {
this.$toast.success('Successfully authenticated', {
......
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
modules: {
}
export const state = () => ({
products: []
})
export const mutations = {
setProducts (state, products) {
state.products = products
},
addProduct (state, product) {
state.products.push(product)
}
}
export const actions = {
async fetchProducts ({ commit }) {
// Lấy dữ liệu sản phẩm từ API
const products = await fetch('https://example.com/products')
.then(response => response.json())
.then(data => data)
// Lưu dữ liệu sản phẩm vào store Vuex
commit('setProducts', products)
}
}
export const getters = {
getProductById: state => (id) => {
return state.products.find(product => product.id === id)
}
}
export const strict = false
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment