Commit c2d2891c authored by Le Dinh Trung's avatar Le Dinh Trung

Merge branch 'feature/manage-categories' into 'dev'

Feature/manage categories

See merge request !5
parents a25b6fbb 5b0c67dc
:root {
--color: #26c;
}
body {
color: rgb(99, 99, 99);
font-size: 0.8rem;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
.header {
height: auto;
}
.header-top {
height: 40px;
width: 100%;
display: flex;
border-bottom: rgba(0, 0, 0, 0.12) 1px solid;
justify-content: space-between;
align-items: center;
}
.header-left {
display: flex;
margin-left: 70px;
align-items: center;
}
.header-left a {
margin-right: 3rem;
display: flex;
}
.header-right {
display: flex;
margin-right: 70px;
align-items: center;
}
.header-right a {
color: inherit;
padding: 0 0.5rem;
align-items: center;
}
.dropdown span {
margin-bottom: 10px;
cursor: pointer;
}
.dropdown:hover span {
color: var(--color);
}
.dropdown-box {
display: none;
position: absolute;
list-style: none;
width: inherit;
padding: 0 5px;
background-color: rgb(255, 255, 255);
box-shadow: 0 5px 30px 2px rgb(0 0 0 / 20%);
}
.dropdown-box li {
margin: 5px 0px;
}
.dropdown-box a {
color: inherit;
padding: 0.4rem 0.2rem;
}
.dropdown:hover .dropdown-box {
display: block;
}
.header-search {
position: relative;
min-width: 500px;
margin: 0 3rem 0 1rem;
}
.header-search .form-input {
display: flex;
position: relative;
}
.header-search .form-input input.form-control {
border: 2px solid var(--color);
font-size: 1rem;
}
.btn-search {
position: absolute;
right: 0px;
}
.header-middle .header-right {
color: #222;
}
.header-right .icon-box-content span {
font-size: 0.7rem;
}
a {
text-decoration: none;
color: #222;
}
a:hover {
text-decoration: none;
color: var(--color);
}
.header-right .cart-label p {
font-weight: bold;
margin-bottom: 0;
}
.header-right .cart .icon-bag {
width: fit-content;
height: fit-content;
}
.cart-count {
position: absolute;
margin-left: -0.7rem;
width: 1rem;
height: 1rem;
font-size: 0.7rem;
line-height: 1.4;
text-align: center;
border-radius: 50%;
background-color: var(--color);
color: #fff;
z-index: 1;
}
.navbar {
padding: 1rem 0;
}
.navbar a {
font-size: 1rem;
font-weight: bold;
margin-bottom: 10px;
}
.category-children {
padding: 5px 10px;
min-width: 10rem;
}
.category-children .category-child a {
margin: 0;
font-size: 0.9rem;
font-weight: normal;
}
.dropdown:hover .category-item > a {
color: var(--color);
}
<template>
<footer id="container">
<div id="contacts">
<div id="contacts--contact">
<p>xavier.seignard+drangies@gmail.com</p>
<p>+84965615899</p>
<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></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>
<div id="contacts--social">
<div></div>
<div></div>
<div></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>
<div id="mentions">
<p>2018 | mentions légales</p>
</div>
</footer>
</v-card>
</v-footer>
</template>
<script>
export default {
name: "footer",
};
export default {
data: () => ({
icons: [
'mdi-facebook',
'mdi-twitter',
'mdi-linkedin',
'mdi-instagram',
],
}),
}
</script>
<style>
#container {
min-height: calc(100vh - 40px);
padding-top: 20px;
margin-top: 20px;
width: 100vw;
color: white;
background-color: #17a2b8;
display: flex;
flex-direction: column;
align-items: center;
}
#contacts {
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
}
#contacts--contact {
text-align: right;
}
#contacts--social {
width: 20%;
display: flex;
justify-content: space-between;
.footer-bottom-left {
position: absolute;
left: 0;
}
#contacts--social div {
height: 30px;
width: 30px;
background-color: white;
border-radius: 50%;
.footer-bottom-right {
position: absolute;
right: 0;
}
#mentions p {
font-size: 0.5em;
.copyright {
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
</style>
\ No newline at end of file
<template>
<div>
<!-- header top -->
<div class="header-top">
<div class="header-left">
<span class="welcome-message">This is a wellcome message!</span>
</div>
<div class="header-right">
<div class="dropdown">
<span class="mr-1">USD</span>
<b-icon icon="chevron-down" font-scale=".7"></b-icon>
<ul class="dropdown-box">
<li><a href="#USD">USD</a></li>
<li><a href="#EUR">EUR</a></li>
</ul>
</div>
<!-- End DropDown Menu -->
<div class="dropdown ml-4">
<span class="mr-1">ENG</span>
<b-icon icon="chevron-down" font-scale=".7"></b-icon>
<ul class="dropdown-box">
<li>
<a href="#USD">ENG</a>
</li>
<li>
<a href="#EUR">FRH</a>
</li>
</ul>
</div>
<!-- End DropDown Menu -->
<v-divider class="mx-4" vertical></v-divider>
<a href="#" class="contact">
<b-icon icon="geo-alt"></b-icon>
Contact
</a>
<a href="#" class="help">
<b-icon icon="info-circle"></b-icon>
Need Help
</a>
<a @click="openModal" v-b-modal.modal-login class="login-toggle link-to-tab d-md-show">
<b-icon icon="person" font-scale="1.3"></b-icon>
Sign in
</a>
<span class="delimiter">/</span>
<a href="#register" class="register-toggle link-to-tab d-md-show ml-0"
>Register</a
>
</div>
</div>
<!-- end header top -->
<!-- header middle -->
<div class="header-middle d-flex">
<div class="header-left my-4">
<a href="#" class="logo">
<img src="~/assets/images/logo.png" alt="" srcset="" width="160px" />
</a>
<div class="header-search">
<form action="" class="form-input">
<input
type="text"
name="search"
placeholder="Search..."
class="form-control"
/>
<button type="submit" value="btn" class="btn btn-search">
<b-icon icon="search"></b-icon>
</button>
</form>
</div>
</div>
<div class="header-right">
<a href="#" class="hotline d-flex">
<b-icon icon="telephone" font-scale="2"></b-icon>
<div class="icon-box-content ml-2">
<span class="icon-box-title">Call Us Now:</span>
<h6>0(800) 123-456</h6>
</div>
</a>
<div class="d-flex" style="height: 30px">
<v-divider class="mx-3" vertical></v-divider>
</div>
<div class="wishlist">
<a href="#">
<b-icon icon="heart" font-scale="2"></b-icon>
</a>
</div>
<div class="d-flex" style="height: 30px">
<v-divider class="mx-3" vertical></v-divider>
</div>
<div class="cart">
<a href="#" class="d-flex">
<div class="cart-label">
<span class="cart-name">Shopping Cart:</span>
<p class="cart-price">$0.00</p>
</div>
<div class="icon-bag ml-2">
<b-icon icon="bag" font-scale="2.5"> </b-icon>
<span class="cart-count">2</span>
</div>
</a>
</div>
</div>
</div>
<!-- end header middle -->
<div class="header-bottom d-flex">
<div class="header-left">
<NavBar />
</div>
<div class="header-right">
</div>
</div>
</div>
</template>
<script>
import NavBar from "@/components/Shared/Header/NavBar";
import LoginForm from "@/components/Shared/Header/LoginForm";
export default {
name: "Header",
components: {
NavBar,
LoginForm,
},
methods: {
openModal() { this.$bvModal.show('modal-login') }
}
};
</script>
<style>
:root {
--color: #26c;
}
body {
color: rgb(99, 99, 99);
font-size: 0.8rem;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
.header {
height: auto;
}
.header-top {
height: 40px;
width: 100%;
display: flex;
border-bottom: rgba(0, 0, 0, 0.12) 1px solid;
justify-content: space-between;
align-items: center;
}
.header-left {
display: flex;
margin-left: 70px;
align-items: center;
}
.header-left a {
margin-right: 3rem;
display: flex;
}
.header-right {
display: flex;
margin-right: 70px;
align-items: center;
}
.header-right a {
color: inherit;
padding: 0 0.5rem;
align-items: center;
}
.dropdown span {
margin-bottom: 10px;
cursor: pointer;
}
.dropdown:hover span {
color: var(--color);
}
.dropdown-box {
display: none;
position: absolute;
list-style: none;
width: inherit;
padding: 0 5px;
background-color: rgb(255, 255, 255);
box-shadow: 0 5px 30px 2px rgb(0 0 0 / 20%);
}
.dropdown-box li {
margin: 5px 0px;
}
.dropdown-box a {
color: inherit;
padding: 0.4rem 0.2rem;
}
.dropdown:hover .dropdown-box {
display: block;
}
.header-search {
position: relative;
min-width: 500px;
margin: 0 3rem 0 1rem;
}
.header-search .form-input {
display: flex;
position: relative;
}
.header-search .form-input input.form-control {
border: 2px solid var(--color);
font-size: 1rem;
}
.btn-search {
position: absolute;
right: 0px;
}
.header-middle .header-right {
color: #222;
}
.header-right .icon-box-content span {
font-size: 0.7rem;
}
a {
text-decoration: none;
color: #222;
}
a:hover {
text-decoration: none;
color: var(--color);
}
.header-right .cart-label p {
font-weight: bold;
margin-bottom: 0;
}
.header-right .cart .icon-bag {
width: fit-content;
height: fit-content;
}
.cart-count {
position: absolute;
margin-left: -0.7rem;
width: 1rem;
height: 1rem;
font-size: 0.7rem;
line-height: 1.4;
text-align: center;
border-radius: 50%;
background-color: var(--color);
color: #fff;
z-index: 1;
}
.navbar {
padding: 1rem 0;
}
.navbar a {
font-size: 1rem;
font-weight: bold;
margin-bottom: 10px;
}
.category-children {
padding: 5px 10px;
min-width: 10rem;
}
.category-children .category-child a {
margin: 0;
font-size: 0.9rem;
font-weight: normal;
}
.dropdown:hover .category-item > a {
color: var(--color);
}
</style>
\ No newline at end of file
<template>
<b-modal id="modal-login" title="Create User" class="modal fade" v-if="showModal">
<p class="my-4">
<form >
<label>Name :</label>
<input
type="text"
class="form-control mb-2"
placeholder="name"
v-model="name"
max="255"
min="1"
required
/>
<label>Email :</label>
<input
type="email"
class="form-control mb-2"
placeholder="Email"
v-model="email"
required
/>
<label>Password :</label>
<input
type="password"
class="form-control mb-2"
placeholder="password"
v-model="password"
required
/>
</form>
</p>
<template #modal-footer>
<button v-b-modal.modal-close_visit @click="$bvModal.hide('modal-login')" class="btn btn-danger btn-sm m-1">Close</button>
<button @click="" v-b-modal.modal-close_visit class="btn btn-success btn-sm m-1">Submit</button>
</template>
</b-modal>
</template>
<script>
export default {
name: "LoginForm",
data() {
return {
}
},
methods: {
show() {
this.showModal = true
},
hide(){
this.showModal = false
}
}
}
</script>
\ No newline at end of file
<template>
<div>
<div class="navbar d-flex">
<a class="" href="#">Home</a>
<div class="dropdown" v-for="(item, index) in categories" :key="index">
<div class="category-item" v-if="item.ordering == 1">
<a href="">{{ item.name }}</a>
<ul
class="category-children dropdown-box"
v-if="item.children.length > 0"
>
<li
class="category-child"
v-for="(children, index) in item.children"
:key="index"
>
<a href="">{{ children.name }}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "NavBar",
data() {
return {
categories: [],
};
},
mounted() {
this.getCategories();
},
methods: {
async getCategories() {
try {
const response = await axios.get(
"http://localhost:8000/api/categories"
);
console.log(response.data.data);
this.categories = response.data.data;
} catch (error) {
console.error(error);
}
},
},
};
</script>
<style scoped>
</style>
\ No newline at end of file
......@@ -6,14 +6,15 @@
variant="info"
style="background-color: #6f2ca6 !important"
>
<sidebar />
<SideBar />
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-nav-item href="/home/users">USER</b-nav-item>
<b-nav-item href="#">CATEGORY</b-nav-item>
<b-nav-item href="/home/categories">CATEGORY</b-nav-item>
<b-nav-item href="/home/products">PRODUCT</b-nav-item>
</b-navbar-nav>
<!-- Right aligned nav items -->
......@@ -37,7 +38,7 @@ export default {
};
</script>
<script>
import sidebar from "@/components/sidebar";
import sidebar from "@/components/SideBar";
import vuex from
export default {
......
<template>
<div>
<Nav />
<nuxt />
</div>
</template>
<script>
import Nav from "@/components/Nav";
export default {
components: { Nav },
};
</script>
<template>
<div>
<Header />
<nuxt />
</div>
</template>
<script>
import Header from "@/components/Shared/Header/Header";
import NavBar from "@/components/Shared/Header/NavBar";
import Footer from "@/components/Footer";
export default {
components: {
Header,
Footer,
NavBar,
},
};
</script>
<template>
<div>
<Nuxt />
</div>
</template>
<script>
export default {};
</script>
<style>
</style>
\ No newline at end of file
<template>
<nuxt />
</template>
\ No newline at end of file
......@@ -24,11 +24,11 @@ export default {
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
plugins: ['~/plugins/axios.js'],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
......@@ -41,16 +41,22 @@ export default {
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/bootstrap
'@nuxtjs/bootstrap-vue',
'bootstrap-vue/nuxt',
'@nuxtjs/axios',
'@nuxtjs/auth-next',
'@nuxtjs/toast',
],
bootstrapVue: {
icons: true
},
axios: {
baseURL: process.env.API_URL || ' http://127.0.0.1:8000/api/',
debug: process.env.DEBUG || false,
proxyHeaders: false,
credentials: false,
},
auth: {
......@@ -73,5 +79,6 @@ export default {
}
}
]
},
},
}
This diff is collapsed.
<template>
<div>
<div>
<h1 style="text-align: center">ABOUT</h1>
</div>
</div>
</template>
\ No newline at end of file
This diff is collapsed.
<template>
<div>
<div>
<Nav />
<h1 style="text-align: center">HOME</h1>
</div>
</div>
......@@ -13,13 +12,10 @@ import axios from "axios";
import VueAxios from "vue-axios";
import Nav from "@/components/Nav";
import Footer from "@/components/Footer";
export default {
layout: "admin",
components: { Nav },
components: { Footer },
middleware: ["web"],
middleware: ['web'],
};
</script>
<style></style>
<template>
<div>
<b-breadcrumb>
<b-breadcrumb-item href="/home">
<b-icon icon="house-fill" scale="1.25" shift-v="1.25" aria-hidden="true"></b-icon>
Home
</b-breadcrumb-item>
<b-breadcrumb-item href="/home/categories">Product</b-breadcrumb-item>
</b-breadcrumb>
</div>
</template>
<script>
import { onMounted } from "vue";
import axios from "axios";
import VueAxios from "vue-axios";
import Nav from "@/components/Nav";
export default {
layout: "admin",
components: { Nav },
middleware: ['web'],
};
</script>
\ No newline at end of file
<template>
<div>
<div>
<Nav />
</div>
<b-breadcrumb>
<b-breadcrumb-item href="/home">
......@@ -35,7 +34,6 @@
v-model="email"
required
/>
<label>Password :</label>
<input
type="password"
......@@ -44,7 +42,6 @@
v-model="password"
required
/>
</form>
</p>
<template #modal-footer>
......@@ -74,7 +71,6 @@
v-model="eEmail"
required
/>
<label>Password :</label>
<input
type="password"
......@@ -195,7 +191,6 @@
</template>
</v-data-table>
</div>
</template>
<script>
import Nav from "@/components/Nav";
......@@ -206,11 +201,11 @@ import Toasted from 'vue-toasted';
import { ModalPlugin } from 'bootstrap-vue';
export default {
layout: "admin",
components: { Nav },
components: { Navigation },
components: { notification },
middleware: ["web"],
data: () => {
return {
email:'',
......@@ -350,7 +345,6 @@ export default {
duration: 3000
});
});
},
deleteUser(userID) {
if(confirm("Do you really want to delete?")){
......@@ -361,9 +355,7 @@ export default {
console.log(error)
}
}
},
editUser(userID) {
this.$bvModal.show('modal-edit');
this.eID = userID;
......
......@@ -60,9 +60,10 @@
<script>
import Nav from "@/components/Nav";
import notification from "@/components/notification";
import Toasted from 'vue-toasted';
import Toasted from "vue-toasted";
export default {
layout: "none",
components: { Nav },
components: { notification },
components: { NuxtLogo },
......@@ -72,6 +73,7 @@ export default {
import { reactive } from "vue";
import axios from "axios";
export default {
layout: "none",
data: () => {
return {
email: "",
......@@ -92,6 +94,7 @@ export default {
body: JSON.stringify({
email: this.email,
password: this.password,
status: this.status,
}),
}).then((response) => {
return response.json();
......@@ -102,47 +105,30 @@ export default {
this.$auth.$storage.setUniversal("userName", resp.data.name);
this.$auth.$storage.setUniversal("loggedIn", "true");
if (resp.status == "success") {
this.$toast.success('Successfully authenticated',{
duration: 2000
this.$toast.success("Successfully authenticated", {
duration: 2000,
});
this.$router.push("home");
}
} catch (e) {
// this.error = "Username or Password not valid";
this.$toast.error('Username or Password not valid',{
duration: 2000
this.$toast.error("Username or Password not valid", {
duration: 2000,
});
this.$router.push("/");
}
// async login() {
// try {
// const response = await this.$axios.post('http://127.0.0.1:8000/api/login', {
// email: this.email,
// password: this.password
// });
// await this.$auth.setToken('local', "Bearer " + response.data.access);
// await this.$auth.setRefreshToken('local', response.data.refresh);
// await this.$auth.setUserToken(response.data.access);
// } catch (e) {
// this.error = 'Username or Password not valid'
// }
},
checkForm: function (e) {
if (this.name && this.age) {
return true;
}
this.errors = [];
if (!this.name) {
this.errors.push("Name required.");
}
if (!this.age) {
this.errors.push("Age required.");
}
e.preventDefault();
},
},
......
......@@ -63,6 +63,7 @@
import { reactive } from "vue";
export default {
layout: "none",
data: () => {
return {
name: "",
......@@ -77,6 +78,7 @@ export default {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
name: this.name,
......
<template>
<div>content</div>
</template>
<script>
export default {
layout: "default",
};
</script>
<style>
</style>
\ No newline at end of file
export default ({ $axios}) => {
$axios.onRequest(config => {
config.headers.common['Content-Type'] = 'multipart/form-data';
});
}
\ No newline at end of file
import { LocalScheme } from '~auth/runtime'
export default class CustomScheme extends LocalScheme {
// Override `fetchUser` method of `local` scheme
async fetchUser (endpoint) {
// Token is required but not available
if (!this.check().valid) {
return
}
// User endpoint is disabled.
if (!this.options.endpoints.user) {
this.$auth.setUser({})
return
}
// Try to fetch user and then set
return this.$auth.requestWith(
this.name,
endpoint,
this.options.endpoints.user
).then((response) => {
const user = getProp(response.data, this.options.user.property)
// Transform the user object
const customUser = {
...user,
fullName: user.firstName + ' ' + user.lastName,
roles: ['user']
}
// Set the custom user
// The `customUser` object will be accessible through `this.$auth.user`
// Like `this.$auth.user.fullName` or `this.$auth.user.roles`
this.$auth.setUser(customUser)
return response
}).catch((error) => {
this.$auth.callOnError(error, { method: 'fetchUser' })
})
}
}
\ No newline at end of file
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