aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorMateja <mail@matejamaric.com>2021-07-24 18:58:17 +0200
committerMateja <mail@matejamaric.com>2021-07-24 18:58:17 +0200
commitd30fd3054c66d707a8210872b7db6cf4a1a98793 (patch)
tree6667713fc67fcaaa4e4dae291d95828fc5e802ad /client
parent080ca69a42ae8c510560bd176484adafd2c29a0c (diff)
downloadmevn-ecommerce-d30fd3054c66d707a8210872b7db6cf4a1a98793.tar.gz
mevn-ecommerce-d30fd3054c66d707a8210872b7db6cf4a1a98793.zip
Added boilerplate pages and `ProductCard` component.
Diffstat (limited to 'client')
-rw-r--r--client/package-lock.json5
-rw-r--r--client/package.json1
-rw-r--r--client/src/App.vue14
-rw-r--r--client/src/components/ExampleComponent.vue14
-rw-r--r--client/src/components/ProductCard.vue20
-rw-r--r--client/src/router/index.js34
-rw-r--r--client/src/views/Checkout.vue9
-rw-r--r--client/src/views/ExamplePage.vue5
-rw-r--r--client/src/views/Home.vue11
-rw-r--r--client/src/views/Login.vue77
-rw-r--r--client/src/views/Product.vue30
-rw-r--r--client/src/views/Register.vue111
12 files changed, 299 insertions, 32 deletions
diff --git a/client/package-lock.json b/client/package-lock.json
index b7fc6a8..24dc872 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -11229,6 +11229,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "validator": {
+ "version": "13.6.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
+ "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/client/package.json b/client/package.json
index 0ed3938..17dc6f0 100644
--- a/client/package.json
+++ b/client/package.json
@@ -11,6 +11,7 @@
"@popperjs/core": "^2.9.2",
"bootstrap": "^5.0.2",
"core-js": "^3.6.5",
+ "validator": "^13.6.0",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
diff --git a/client/src/App.vue b/client/src/App.vue
index c8219c0..3a66a9e 100644
--- a/client/src/App.vue
+++ b/client/src/App.vue
@@ -10,7 +10,13 @@
<router-link class="nav-link" active-class="active" to="/">Home</router-link>
</li>
<li class="nav-item">
- <router-link class="nav-link" active-class="active" to="/example">Example</router-link>
+ <router-link class="nav-link" active-class="active" to="/checkout">Checkout</router-link>
+ </li>
+ <li class="nav-item">
+ <router-link class="nav-link" active-class="active" to="/register">Register</router-link>
+ </li>
+ <li class="nav-item">
+ <router-link class="nav-link" active-class="active" to="/login">Login</router-link>
</li>
</ul>
</div>
@@ -21,4 +27,10 @@
</div>
</template>
+<script>
+export default {
+
+}
+</script>
+
<style lang="scss"></style>
diff --git a/client/src/components/ExampleComponent.vue b/client/src/components/ExampleComponent.vue
deleted file mode 100644
index 5e207f9..0000000
--- a/client/src/components/ExampleComponent.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-<template>
- <div>
- <p v-text="msg"></p>
- </div>
-</template>
-
-<script>
-export default {
- name: 'ExampleComponent',
- props: {
- msg: String
- }
-}
-</script>
diff --git a/client/src/components/ProductCard.vue b/client/src/components/ProductCard.vue
new file mode 100644
index 0000000..57698e5
--- /dev/null
+++ b/client/src/components/ProductCard.vue
@@ -0,0 +1,20 @@
+<template>
+ <div class="card">
+ <img :src="productImg" class="card-img-top">
+ <div class="card-body">
+ <h5 class="card-title">{{ productName }}</h5>
+ <a :href="productLink" class="btn btn-dark w-100">Details</a>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'ProductCard',
+ props: {
+ productName: String,
+ productImg: String,
+ productLink: String
+ }
+}
+</script>
diff --git a/client/src/router/index.js b/client/src/router/index.js
index 22d739e..eee610c 100644
--- a/client/src/router/index.js
+++ b/client/src/router/index.js
@@ -1,6 +1,9 @@
import {createRouter, createWebHistory} from 'vue-router';
-import Home from '../views/Home.vue';
-import ExamplePage from '../views/ExamplePage.vue';
+import Home from '@/views/Home.vue';
+import Product from '@/views/Product.vue';
+import Checkout from '@/views/Checkout.vue';
+import Login from '@/views/Login.vue';
+import Register from '@/views/Register.vue';
const routes = [
{
@@ -9,15 +12,30 @@ const routes = [
component: Home
},
{
- path: '/example',
- name: 'Example',
- component: ExamplePage
+ path: '/product/:id',
+ name: 'Product',
+ component: Product
+ },
+ {
+ path: '/checkout',
+ name: 'Checkout',
+ component: Checkout
+ },
+ {
+ path: '/login',
+ name: 'Login',
+ component: Login
+ },
+ {
+ path: '/register',
+ name: 'Register',
+ component: Register
}
-]
+];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
-})
+});
-export default router
+export default router;
diff --git a/client/src/views/Checkout.vue b/client/src/views/Checkout.vue
new file mode 100644
index 0000000..42523ca
--- /dev/null
+++ b/client/src/views/Checkout.vue
@@ -0,0 +1,9 @@
+<template>
+ Checkout page
+</template>
+
+<script>
+export default {
+
+}
+</script>
diff --git a/client/src/views/ExamplePage.vue b/client/src/views/ExamplePage.vue
deleted file mode 100644
index 1cb803e..0000000
--- a/client/src/views/ExamplePage.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-<template>
- <div>
- Example Page.
- </div>
-</template>
diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue
index 77ed4e4..3e89885 100644
--- a/client/src/views/Home.vue
+++ b/client/src/views/Home.vue
@@ -1,15 +1,18 @@
<template>
- <div>
- <ExampleComponent msg="Example text inside example component."/>
+ <div class="row mt-5">
+ <div class="col-lg-3 col-md-4 col-sm-6">
+ <ProductCard/>
+ </div>
</div>
</template>
<script>
-import ExampleComponent from '@/components/ExampleComponent';
+import ProductCard from '@/components/ProductCard';
+
export default {
name: 'Home',
components: {
- ExampleComponent
+ ProductCard
}
}
</script>
diff --git a/client/src/views/Login.vue b/client/src/views/Login.vue
new file mode 100644
index 0000000..8789a5e
--- /dev/null
+++ b/client/src/views/Login.vue
@@ -0,0 +1,77 @@
+<template>
+ <div class="mt-5">
+ <div class="row d-flex justify-content-center">
+ <div class="col-md-7">
+ <div class="card px-5 py-4">
+
+ <div class="text-center mb-4">
+ <h4>Login</h4>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>Email</span>
+ <input type="text" v-model="email"
+ :class="{'form-control': true, 'is-invalid' : !validEmail(email) && emailBlured}"
+ @blur="emailBlured = true">
+ <div class="invalid-feedback">A valid email is required!</div>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>Password</span>
+ <input type="password" v-model="password"
+ :class="{'form-control': true, 'is-invalid' : !validPassword(password) && passwordBlured}"
+ @blur="passwordBlured = true">
+ <div class="invalid-feedback">Password is required!</div>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <button @click.stop.prevent="login" class="btn btn-dark w-100">Login</button>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import validator from 'validator';
+
+export default {
+ name: 'Login',
+ data() {
+ return {
+ valid: false,
+ email: "",
+ emailBlured : false,
+ password: "",
+ passwordBlured:false
+ }
+ },
+ methods: {
+ validEmail: (email) => validator.isEmail(email),
+ validPassword: (password) => password.length,
+
+ validate() {
+ this.emailBlured = true;
+ this.passwordBlured = true;
+ if (this.validEmail(this.email) && this.validPassword(this.password)) {
+ this.valid = true;
+ }
+ },
+
+ login() {
+ this.validate();
+ if (this.valid) {
+ alert('Successfully logged in!');
+ }
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+ .forms-inputs input:focus {
+ border: 2px solid #000
+ }
+</style>
diff --git a/client/src/views/Product.vue b/client/src/views/Product.vue
new file mode 100644
index 0000000..e03c900
--- /dev/null
+++ b/client/src/views/Product.vue
@@ -0,0 +1,30 @@
+<template>
+ <div class="row">
+ <div class="col-md-4">
+ <img :src="productImg">
+ </div>
+ <div class="col-md-4">
+ <h3>{{ productName }}</h3>
+ <p>{{ productDescription }}</p>
+ <div class="btn btn-primary" @click="buy">Add to cart</div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'Product',
+ data() {
+ return {
+ productName: String,
+ productDescription: String,
+ productImg: String
+ }
+ },
+ methods: {
+ buy() {
+
+ }
+ }
+}
+</script>
diff --git a/client/src/views/Register.vue b/client/src/views/Register.vue
new file mode 100644
index 0000000..e1679de
--- /dev/null
+++ b/client/src/views/Register.vue
@@ -0,0 +1,111 @@
+<template>
+ <div class="mt-5">
+ <div class="row d-flex justify-content-center">
+ <div class="col-md-7">
+ <div class="card px-5 py-4">
+ <div class="form-data" v-if="!submitted">
+
+ <div class="text-center mb-4">
+ <h4>Register</h4>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>First name</span>
+ <input type="text" v-model="firstname"
+ :class="{'form-control':true, 'is-invalid' : !validName(firstname) && firstnameBlured}"
+ @blur="firstnameBlured = true">
+ <div class="invalid-feedback">A valid first name is required!</div>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>Last name</span>
+ <input type="text" v-model="lastname"
+ :class="{'form-control':true, 'is-invalid' : !validName(lastname) && lastnameBlured}"
+ @blur="lastnameBlured = true">
+ <div class="invalid-feedback">A valid last name is required!</div>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>Email</span>
+ <input type="text" v-model="email"
+ :class="{'form-control':true, 'is-invalid' : !validEmail(email) && emailBlured}"
+ @blur="emailBlured = true">
+ <div class="invalid-feedback">A valid email is required!</div>
+ </div>
+
+ <div class="forms-inputs mb-4">
+ <span>Password</span>
+ <input type="password" v-model="password"
+ :class="{'form-control':true, 'is-invalid' : !validPassword(password) && passwordBlured}"
+ @blur="passwordBlured = true">
+ <div class="invalid-feedback">Password must be 8 character!</div>
+ </div>
+
+ <div class="mb-3">
+ <button @click.stop.prevent="submit" class="btn btn-dark w-100">Register</button>
+ </div>
+
+ </div>
+ <div class="success-data" v-else>
+
+ <div class="text-center d-flex flex-column">
+ <span class="text-center">You have been successfully registered!</span>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import validator from 'validator';
+
+export default {
+ name: 'Register',
+ data() {
+ return {
+ valid : false,
+ submitted : false,
+ firstname: "",
+ firstnameBlured: false,
+ lastname: "",
+ lastnameBlured: false,
+ email : "",
+ emailBlured : false,
+ password:"",
+ passwordBlured:false,
+ }
+ },
+ methods: {
+ validate() {
+ this.firstnameBlured = true;
+ this.lastnameBlured = true;
+ this.emailBlured = true;
+ this.passwordBlured = true;
+ if (this.validName(this.firstname) && this.validName(this.lastname) && this.validEmail(this.email) && this.validPassword(this.password)) {
+ this.valid = true;
+ }
+ },
+
+ validEmail: (email) => validator.isEmail(email),
+ //validPassword: (password) => validator.isStrongPassword(password, { minLength: 8 }),
+ validPassword: (password) => password.length > 7,
+ validName: (name) => validator.isAlpha(name) && name.length,
+
+ submit() {
+ this.validate();
+ if (this.valid) {
+ this.submitted = true;
+ }
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+ .forms-inputs input:focus {
+ border: 2px solid #000
+ }
+</style>