add header and footer from comp library

parent d0577a9e
...@@ -4,13 +4,7 @@ To create a shopping cart using fake Json api ...@@ -4,13 +4,7 @@ To create a shopping cart using fake Json api
This template should help get you started developing with Vue 3 in Vite. This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup ## Project Setup
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
"@sangarajuguptanisum/vue-custom-components": "^0.0.3", "@sangarajuguptanisum/vue-custom-components": "^0.0.3",
"axios": "^1.6.2", "axios": "^1.6.2",
"vue": "^3.3.10", "vue": "^3.3.10",
"vue-header-footer-mfe": "^0.0.7",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
"vuex": "^4.1.0" "vuex": "^4.1.0"
}, },
...@@ -9518,6 +9519,67 @@ ...@@ -9518,6 +9519,67 @@
"eslint": ">=6.0.0" "eslint": ">=6.0.0"
} }
}, },
"node_modules/vue-header-footer-mfe": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/vue-header-footer-mfe/-/vue-header-footer-mfe-0.0.7.tgz",
"integrity": "sha512-QOGDOUAjx0CqMMul+4eq5cWEKbmiD4N0j2pKFYPU5JqiaZSeBPks5Xic9TAUJRwnFAd9izcpjarFas6cGMQwTw==",
"dependencies": {
"@sangarajuguptanisum/vue-custom-components": "^0.0.3",
"pinia": "^2.1.7",
"vue": "^3.3.11",
"vue-router": "^4.2.5"
}
},
"node_modules/vue-header-footer-mfe/node_modules/pinia": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
"integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
"dependencies": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": ">=0.14.5"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.3.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/vue-header-footer-mfe/node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-router": { "node_modules/vue-router": {
"version": "4.2.5", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
"@sangarajuguptanisum/vue-custom-components": "^0.0.3", "@sangarajuguptanisum/vue-custom-components": "^0.0.3",
"axios": "^1.6.2", "axios": "^1.6.2",
"vue": "^3.3.10", "vue": "^3.3.10",
"vue-header-footer-mfe": "^0.0.7",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
"vuex": "^4.1.0" "vuex": "^4.1.0"
}, },
......
<template> <template>
<Header></Header> <CHeader :kartItems="$store.state.cart.length"> </CHeader>
<div class="content"> <div class="content">
<router-view class="content" /> <router-view />
</div> </div>
<CFooter></CFooter>
</template> </template>
<script> <script>
import Header from '../src/components/Header/Header.vue' import { CHeader, CFooter } from 'vue-header-footer-mfe'
export default { export default {
name: "App", name: 'App',
components: { data() {
Header return {}
}, },
components: {},
methods: {},
created() { created() {
this.$store.dispatch('getProductsAction') this.$store.dispatch('getProductsAction')
...@@ -21,4 +22,8 @@ export default { ...@@ -21,4 +22,8 @@ export default {
} }
</script> </script>
<style scoped></style> <style scoped>
.content {
min-height: 100vh;
}
</style>
<template> <template>
<h1>About page loaded</h1> <h1>About page loaded</h1>
<SButton isLoading="true"></SButton> <SButton isLoading="true"></SButton>
</template> </template>
<script> <script>
import {SButton} from '@sangarajuguptanisum/vue-custom-components'; import { SButton } from '@sangarajuguptanisum/vue-custom-components'
export default { export default {
name: 'About',
components: {},
data() {
name: "About", return {}
components: { },
methods: {}
},
data() {
return {}
},
methods: {}
} }
</script> </script>
\ No newline at end of file
<template> <template>
<div v-if="$store.state.cart.length == 0"> <div v-if="$store.state.cart.length == 0">shopping cart is empty</div>
<div v-else>
shopping cart is empty <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead>
</div> <tr>
<div v-else> <th
v-for="heading in headings"
<table class=" min-w-full divide-y divide-gray-200 dark:divide-gray-700"> scope="col"
<thead> class="px-6 py-3 text-start text-xs font-medium text-gray-500 uppercase"
<tr> >
<th v-for="heading in headings" scope="col" {{ heading }}
class="px-6 py-3 text-start text-xs font-medium text-gray-500 uppercase">{{ heading }}</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200 dark:divide-gray-700"> <tbody class="divide-y divide-gray-200 dark:divide-gray-700">
<tr v-for="(product, index) in $store.state.cart"> <tr v-for="(product, index) in $store.state.cart" :key="product.key">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">{{ index + 1 }}</td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">{{ product.title }} {{ index + 1 }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 w-20 dark:text-gray-200"><img <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">
:src="product.image" /> {{ product.title }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">{{ product.category }} <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 w-20 dark:text-gray-200">
</td> <img :src="product.image" />
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">{{ product.price }} </td>
</td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"><button type="button" {{ product.category }}
class="bg-red-500 my-2 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" </td>
@click="removeProduct(product.id)">Delete</button> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">
</td> {{ product.price }}
</tr> </td>
</tbody> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
</table> <button
type="button"
class="bg-red-500 my-2 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
@click="removeProduct(product.id)"
>
Delete
</button>
</div> </td>
</tr>
</tbody>
</table>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "Cart", name: 'Cart',
data() { data() {
return { return {
cartItems: {}, cartItems: {},
headings: ["", "Name", "Image", "Category", "price", "Action"] headings: ['', 'Name', 'Image', 'Category', 'price', 'Action']
} }
}, },
methods: { methods: {
removeProduct(productId) { removeProduct(productId) {
this.$store.commit('removeProductFromCart', productId) this.$store.commit('removeProductFromCart', productId)
} }
}, },
beforeMount() { beforeMount() {}
},
} }
</script> </script>
\ No newline at end of file
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from '@vue/test-utils'
import { jest } from '@jest/globals'; import { jest } from '@jest/globals'
import CategoriesList from "../CategoriesList/CategoriesList.vue"; import CategoriesList from '../CategoriesList/CategoriesList.vue'
const product = { const product = {
id: 1, id: 1,
title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops", title: 'Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops',
price: 109.95, price: 109.95,
description: "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday", description:
'Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday',
category: "men's clothing", category: "men's clothing",
image: "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg", image: 'https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg',
rating: { rating: {
rate: 3.9, rate: 3.9,
count: 120 count: 120
...@@ -37,15 +38,11 @@ const wrapper = shallowMount(CategoriesList, { ...@@ -37,15 +38,11 @@ const wrapper = shallowMount(CategoriesList, {
} }
}) })
describe("Catergory", () => { describe('Catergory', () => {
it('To check the component redendered or not', () => {
it("To check the component redendered or not", () => { console.log(wrapper.html(), 'fsd')
console.log(wrapper.html(),"fsd")
expect(wrapper.contains('product-card-stub')).toBe(true);
expect((wrapper.find('product-card-stub')).attributes('product')).toBe();
expect(wrapper.contains('product-card-stub')).toBe(true)
expect(wrapper.find('product-card-stub').attributes('product')).toBe()
}) })
})
})
\ No newline at end of file
<template> <template>
<p class="text-xl pb-8"><router-link class="underline" to="/">Home</router-link> / {{ $route.params.product }} </p> <p class="text-xl pb-8">
<router-link class="underline" to="/">Home</router-link> / {{ $route.params.product }}
</p>
<div> <div>
<!-- Display products catelog --> <!-- Display products catelog -->
<div class="grid grid-cols-4 gap-8"> <div class="grid grid-cols-4 gap-8">
<!-- Rendering product card by passing prop --> <!-- Rendering product card by passing prop -->
<ProductCard v-for="product in products" :key="product.id" :product="product"></ProductCard> <ProductCard v-for="product in products" :key="product.id" :product="product"></ProductCard>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import ProductCard from '../../components/ProductCard/ProductCard.vue'
import ProductCard from '../../components/ProductCard/ProductCard.vue';
export default { export default {
name: "CategoriesList", name: 'CategoriesList',
components:{ProductCard}, components: { ProductCard },
data() { data() {
return { return {
products: [], products: [],
categoeryName: "" categoeryName: ''
}; }
}, },
methods: { methods: {
async getProductsByCategory() { async getProductsByCategory() {
// const { data } = await axios.get("https://fakestoreapi.com/products"); // const { data } = await axios.get("https://fakestoreapi.com/products");
this.products = this.$store.state.products.filter((item) => (item.category).toLowerCase() === (this.$route.params.product).toLowerCase()); this.products = this.$store.state.products.filter(
// console.log("test", this.products, "sample") (item) => item.category.toLowerCase() === this.$route.params.product.toLowerCase()
}, )
}, // console.log("test", this.products, "sample")
beforeMount() { }
this.categoeryName = this.$route.params.product },
this.getProductsByCategory(); beforeMount() {
}, this.categoeryName = this.$route.params.product
this.getProductsByCategory()
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>
\ No newline at end of file
import { mount } from "@vue/test-utils" import { mount } from '@vue/test-utils'
import Contact from "../Contact/Contact.vue"; import Contact from '../Contact/Contact.vue'
describe('notification.vue', () => {
describe("notification.vue", () => { test('sample', () => {
test("sample", () => { const wrapper = mount(Contact)
expect(wrapper.text()).toEqual('Contact page Loaded')
const wrapper = mount(Contact); })
expect(wrapper.text()).toEqual( })
"Contact page Loaded"
);
});
});
\ No newline at end of file
<template> <template>
<h1> <h1>Contact page Loaded</h1>
Contact page Loaded
</h1>
</template> </template>
<script> <script>
export default { export default {
name: "Contact", name: 'Contact',
components: {}, components: {},
data() { data() {
return {} return {}
} }
} }
</script> </script>
<style scoped></style> <style scoped></style>
\ No newline at end of file
<template> <template>
<h1 class="mt-4 mb-10 text-4xl" >Categories</h1> <h1 class="mt-4 mb-10 text-4xl">Categories</h1>
<div class= "grid grid-cols-4 gap-2"> <div class="grid grid-cols-4 gap-2">
<!-- <div class="border-double border-8 border-green-600">Electronics</div> --> <!-- <div class="border-double border-8 border-green-600">Electronics</div> -->
<router-link to="/categories/electronics"> <router-link to="/categories/electronics">
<button class="cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded"> <button class="cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded">
Electronics Electronics
</button> </button>
</router-link> </router-link>
<router-link to="/categories/Jewelery"> <router-link to="/categories/Jewelery">
<button class=" cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded"> <button class="cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded">
Jewelery Jewelery
</button> </button>
</router-link> </router-link>
<router-link to="/categories/Men's clothing"> <router-link to="/categories/Men's clothing">
<button class=" cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded"> <button class="cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded">
Men's clothing Men's clothing
</button> </button>
</router-link> </router-link>
<router-link to="/categories/Women's clothing"> <router-link to="/categories/Women's clothing">
<button class=" cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded"> <button class="cat-btn bg-teal-500 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded">
Women's clothing Women's clothing
</button> </button>
</router-link> </router-link>
</div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: 'Home',
name: "Home", components: {}
components: {}
} }
</script> </script>
<style scoped> <style scoped>
.cat-btn{ .cat-btn {
height: 15rem; height: 15rem;
width: 15rem; width: 15rem;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<p class="text-xl pb-8"><router-link class="underline" :to="`/categories/${product.category}`">Home/{{ product.category <p class="text-xl pb-8">
}}</router-link>/{{ product.id }} </p> <router-link class="underline" :to="`/categories/${product.category}`"
<router-link :to="`/categories/${product.category}/${product.id}`"></router-link> >Home/{{ product.category }}</router-link
<p class="text-xl font-bold py-8 ">Product Detail</p> >/{{ product.id }}
<div class="max-w-sm w-full lg:max-w-full lg:flex"> </p>
<div class="h-48 lg:h-auto lg:w-48 flex-none bg-cover rounded-t lg:rounded-t-none lg:rounded-l text-center overflow-hidden" <router-link :to="`/categories/${product.category}/${product.id}`"></router-link>
:style="{ backgroundImage: `url('${product.image}')` }" title="Woman holding a mug"> <p class="text-xl font-bold py-8">Product Detail</p>
</div> <div class="max-w-sm w-full lg:max-w-full lg:flex">
<div <div
class="border-r border-b border-l border-gray-400 lg:border-l-0 lg:border-t lg:border-gray-400 bg-white rounded-b lg:rounded-b-none lg:rounded-r p-4 flex flex-col justify-between leading-normal"> class="h-48 lg:h-auto lg:w-48 flex-none bg-cover rounded-t lg:rounded-t-none lg:rounded-l text-center overflow-hidden"
<div class="mb-8"> :style="{ backgroundImage: `url('${product.image}')` }"
<div class="font-bold text-xl py-4">Description:</div> title="Woman holding a mug"
<div class="font-bold">{{ product.title }}</div> ></div>
<div class="text-gray-900 mb-2">{{ product.description }}</div> <div
<p class="text-gray-700 text-base">${{ product.price }}</p> class="border-r border-b border-l border-gray-400 lg:border-l-0 lg:border-t lg:border-gray-400 bg-white rounded-b lg:rounded-b-none lg:rounded-r p-4 flex flex-col justify-between leading-normal"
</div> >
<div> <div class="mb-8">
<button @click="addToCart(product)" <div class="font-bold text-xl py-4">Description:</div>
class="bg-teal-500 my-2 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded">Add to Cart</button> <div class="font-bold">{{ product.title }}</div>
</div> <div class="text-gray-900 mb-2">{{ product.description }}</div>
</div> <p class="text-gray-700 text-base">${{ product.price }}</p>
</div>
<div>
<button
@click="addToCart(product)"
class="bg-teal-500 my-2 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded"
>
Add to Cart
</button>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "ProductDetail", name: 'ProductDetail',
data() { data() {
return { return {
product: {} product: {}
} }
}, },
methods: { methods: {
async getProductById() { async getProductById() {
console.log("thisss",this.$store.state.products) console.log('thisss', this.$store.state.products)
this.product = this.$store.state.products.find(item => item.id === parseInt(this.$route.params.id)); this.product = this.$store.state.products.find(
console.log("thisid", this.$route.params.id,this.product); (item) => item.id === parseInt(this.$route.params.id)
}, )
addToCart(product) { console.log('thisid', this.$route.params.id, this.product)
this.$store.commit('addProductsToCart', product)
}
},
beforeMount() {
this.getProductById();
}, },
addToCart(product) {
this.$store.commit('addProductsToCart', product)
}
},
beforeMount() {
this.getProductById()
}
} }
</script> </script>
<style></style> <style></style>
\ No newline at end of file
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
font-weight: normal; font-weight: normal;
} }
.content { .content {
margin: 0 1rem; margin: 0 1rem;
padding: 2rem; padding: 2rem;
} }
......
<template>
<label>
{{ label }}
<input
class="border w-full py-2 px-2 rounded shadow hover:border-teal-600 ring-1 ring-inset ring-gray-300 font-mono"
:name="name" :type="type" :value="value" @input="updateValue" />
</label>
</template>
<script >
export default {
name: "CustomInput",
props: {
label: String,
name: String,
type: {
type: String,
default: 'text',
},
value: String
},
methods: {
updateValue(event) {
console.log("testttt custim", event.target.value)
this.$emit('input-test', event.target.value)
},
},
data() {
return {
}
}
}
</script>
\ No newline at end of file
<template>
<nav class="flex items-center justify-between flex-wrap bg-teal-500 p-6 sticky top-0">
<!-- <div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl tracking-tight">Shopping Cart</span>
</div> -->
<div class="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
<div class="text-sm lg:flex-grow text-white ">
<router-link class="block mt-4 text-3xl lg:inline-block lg:mt-0 text-white hover:text-teal-200 mr-4" to="/">
Shopping Cart
</router-link>
<router-link class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4" to="/about">
About
</router-link>
<router-link class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4" to="/contact">
Contact
</router-link>
<router-link
class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-teal-500 hover:bg-white mt-4 lg:mt-0" to="/cart" >Cart{{$store.state.cart.length>0? $store.state.cart.length:""}}</router-link>
</div>
<div>
<p class="text-xl text-white capitalize" v-if="user">{{ user }}</p>
<SLogin v-else loginText="CustomLogin Button" @user-login="setUserInfo"></SLogin>
</div>
</div>
</nav>
</template>
<script>
// import Login from '../Login/Login.vue'
import {SLogin} from '@sangarajuguptanisum/vue-custom-components';
export default{
name:"Header",
data(){
return{
user:""
}
},
components:{
// Login
},
methods:{
setUserInfo(data){
this.user = data.user.name;
console.log(data);
}
}
}
</script>
\ No newline at end of file
<template>
<div class="fixed right-0 inline-block " @mouseover="isVisible = true" @mouseleave="isVisible = false"
@keydown.enter="isVisible = !isVisible">
<button type="button"
class="inline-block relative -top-4 right-2 text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-teal-500 hover:bg-white mt-4 lg:mt-0">
<span class="flex-shrink-0">Login</span>
</button>
<transition enter-active-class="transition duration-300 ease-out transform"
enter-class="-translate-y-3 scale-95 opacity-0" enter-to-class="translate-y-0 scale-100 opacity-100"
leave-active-class="transition duration-150 ease-in transform" leave-class="translate-y-0 opacity-100"
leave-to-class="-translate-y-3 opacity-0">
<div v-show="isVisible" class="fixed right-0 pt-2">
<div class="relative py-1 bg-white border border-gray-200 rounded-md shadow-xl">
<div class="relative">
<div class='flyout-width flex items-center justify-center min-h-screen'>
<div class='w-full max-w-lg px-10 py-8 mx-auto bg-teal-500 border rounded-lg shadow-2xl'>
<div class='max-w-md mx-auto space-y-3'>
<h3 class="text-lg font-semibold">Account {{ this.buttonName.toLowerCase() ==='proceed'? '':this.buttonName }} Form</h3>
<div>
<form>
<CustomInput label="Email:" name="email" :value="email"
@input-test="updateEmail">
</CustomInput>
<CustomInput v-if="userRegistration === true" label="username" name="username"
:value="username" @input-test="updateuserName"></CustomInput>
<CustomInput v-if="userLogin === true || userRegistration === true " label="Password" name="password"
:value="password" type="password" @input-test="updatePassword"></CustomInput>
</form>
</div>
<div class="flex gap-3 pt-3 items-center">
<button
class="border hover:border-teal-600 px-4 py-2 rounded-lg shadow ring-1 ring-inset ring-gray-300"
@click="handle_function_call(buttonName)">{{ buttonName }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import CustomInput from '../CustomInput/CustomInput.vue'
export default {
name: "Login",
components: {
CustomInput
},
data() {
return {
buttonName: "proceed",
isVisible: false,
email: "",
password: "",
password1:"",
username: "",
userLogin: false,
userRegistration: false,
testingEmails: ['sanga@gmail.com', 'raju@gmail.com', 'gupta@gmail.com']
}
},
methods: {
updateEmail(val) {
this.email = val;
console.log("email", this.email);
},
updatePassword(val) {
this.password = val;
},
updateuserName(val){
this.username = val
},
proceed() {
console.log("proceed entered",this.email)
if (this.testingEmails.includes(this.email)) {
this.buttonName = "Login"
this.userLogin = true;
this.userRegistration = false;
}
else {
this.buttonName = "Register"
this.userLogin = false;
this.userRegistration = true;
}
},
register(){
this.password = "";
this.email="";
this.username = ""
},
login(){
this.password = "";
this.email="";
},
handle_function_call(function_name) {
console.log(function_name, "function_name",function_name.toLowerCase() == 'proceed');
const fun = function_name.toLowerCase();
if (fun === 'proceed') {
this.proceed();
}
else if(fun === 'register'){
this.register();
console.log("resgister",this.username,this.email,this.password)
}
else if(fun === 'login'){
console.log("login")
}
},
},
}
</script>
<style scoped>.flyout-width {
width: 35rem;
}</style>
\ No newline at end of file
import {shallowMount} from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils'
import ProductCard from '../ProductCard/ProductCard.vue'; import ProductCard from '../ProductCard/ProductCard.vue'
// import VueRouter from 'vue-router' // import VueRouter from 'vue-router'
describe('ProductCard', () => {
const wrapper = shallowMount(ProductCard, {
props: {
describe('ProductCard',()=>{ product: {
const wrapper = shallowMount(ProductCard,{ id: 5,
props:{ title: 'braclet',
product: { price: 695,
id: 5, description: 'From',
title: "braclet", category: 'jewelery',
price: 695, image: 'https://fakestoreapi.com/img/71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg',
description: "From", rating: {
category: "jewelery", rate: 4.6,
image: "https://fakestoreapi.com/img/71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg", count: 400
rating: { }
rate: 4.6, }
count: 400
}
}
}, },
stubs: ['router-link', 'router-view'], stubs: ['router-link', 'router-view']
}); })
it("To test if the component loaded with card details",()=>{ it('To test if the component loaded with card details', () => {
console.log(wrapper.html(),"testing"); console.log(wrapper.html(), 'testing')
expect(wrapper.classes()).toContain('card'); expect(wrapper.classes()).toContain('card')
expect(wrapper.find('.card-img').exists()).toBe(true); expect(wrapper.find('.card-img').exists()).toBe(true)
const liList = wrapper.findAll('li'); const liList = wrapper.findAll('li')
expect(liList.at(0).text()).toBe('braclet'); expect(liList.at(0).text()).toBe('braclet')
expect(liList.at(1).text()).toBe("Price:$695"); expect(liList.at(1).text()).toBe('Price:$695')
expect(liList.at(2).text()).toBe("Category: jewelery") expect(liList.at(2).text()).toBe('Category: jewelery')
})
it('To test the router link loaded with correct routing value', () => {
}); const router = wrapper.find('router-link')
expect(router.attributes('to')).toBe('/categories/jewelery/5')
it("To test the router link loaded with correct routing value",()=>{ })
const router = wrapper.find('router-link');
expect(router.attributes('to')).toBe('/categories/jewelery/5')
});
}) })
<template> <template>
<div class="card"> <div class="card">
<div class="max-w-sm rounded overflow-hidden shadow-lg"> <div class="max-w-sm rounded overflow-hidden shadow-lg">
<img class="w-full card-img p-10" :src="product.image" alt="Sunset in the mountains"> <img class="w-full card-img p-10" :src="product.image" alt="Sunset in the mountains" />
<div class="px-6 py-4 configure"> <div class="px-6 py-4 configure">
<ul class="text-gray-700 text-base"> <ul class="text-gray-700 text-base">
<li class="text-xl">{{ product.title }}</li> <li class="text-xl">{{ product.title }}</li>
<li>Price:${{ product.price }}</li> <li>Price:${{ product.price }}</li>
<li> Category: {{ product.category }}</li> <li>Category: {{ product.category }}</li>
</ul> </ul>
<router-link :to="`/categories/${product.category}/${product.id}`"> <router-link :to="`/categories/${product.category}/${product.id}`">
<button class="bg-blue-500 my-2 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">More <button class="bg-blue-500 my-2 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Details</button> More Details
</router-link> </button>
</div> </router-link>
</div>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "ProductCard", name: 'ProductCard',
props:['product'], props: ['product']
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card { .card {
min-height: 35rem; min-height: 35rem;
.card-img { .card-img {
height: 20rem; height: 20rem;
width: 100%; width: 100%;
} }
.configure { .configure {
min-height: 15rem; min-height: 15rem;
} }
} }
</style> </style>
\ No newline at end of file
import 'vue-header-footer-mfe/dist/index.css'
import '@sangarajuguptanisum/vue-custom-components/dist/index.css'; import '@sangarajuguptanisum/vue-custom-components/dist/index.css'
import '@sangarajuguptanisum/vue-custom-components/dist/style.css'; import '@sangarajuguptanisum/vue-custom-components/dist/style.css'
import vueComponents from '@sangarajuguptanisum/vue-custom-components' import vueComponents from '@sangarajuguptanisum/vue-custom-components'
import vueCustomComponents from 'vue-header-footer-mfe'
import './assets/main.css' import './assets/main.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHistory } from 'vue-router'
import store from './store/index.js' import store from './store/index.js'
import Home from '../src/views/Home/Home.Vue' import Home from '../src/views/Home/Home.Vue'
import About from '../src/views/About/About.vue' import About from '../src/views/About/About.vue'
import Contact from "../src/views/Contact/Contact.vue" import Contact from '../src/views/Contact/Contact.vue'
import CategoriesList from "../src/views/CategoriesList/CategoriesList.vue" import CategoriesList from '../src/views/CategoriesList/CategoriesList.vue'
import ProductDetail from "../src/views/ProductDetail/ProductDetail.vue" import ProductDetail from '../src/views/ProductDetail/ProductDetail.vue'
import Cart from "../src/views/Cart/Cart.vue" import Cart from '../src/views/Cart/Cart.vue'
const app = createApp(App); const app = createApp(App)
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes: [ routes: [
{ name: "Home", path: '/', component: Home }, { name: 'Home', path: '/', component: Home },
{ name: "About", path: '/about', component: About }, { name: 'About', path: '/about', component: About },
{ name: "Contact", path: '/contact', component: Contact }, { name: 'Contact', path: '/contact', component: Contact },
{ name: "Categories", path: '/categories/:product', component: CategoriesList }, { name: 'Categories', path: '/categories/:product', component: CategoriesList },
{ name: "ProductDetail", path: '/categories/:product/:id', component: ProductDetail }, { name: 'ProductDetail', path: '/categories/:product/:id', component: ProductDetail },
{ name: "Cart", path: "/cart", component: Cart } { name: 'Cart', path: '/cart', component: Cart }
]
]
}) })
app.use(vueCustomComponents)
app.use(vueComponents) app.use(vueComponents)
app.use(router) app.use(router)
app.use(store) app.use(store)
......
import { createStore } from 'vuex' import { createStore } from 'vuex'
import axios from "axios"; import axios from 'axios'
export default createStore({ export default createStore({
state: {
state: { products: [],
products: [], cart: []
cart: [], },
mutations: {
getProducts(state, products) {
state.products = products
}, },
mutations: { addProductsToCart(state, products) {
getProducts(state, products) { //Mutating the state
state.products = products state.cart.push(products)
}, // console.log(state,"steteee")
addProductsToCart(state, products) {
//Mutating the state
state.cart.push(products);
// console.log(state,"steteee")
},
removeProductFromCart(state, productId) {
const index = state.cart.findIndex(item => item.id === productId)
state.cart.splice(index, 1);
}
}, },
actions: { removeProductFromCart(state, productId) {
async getProductsAction(context) { const index = state.cart.findIndex((item) => item.id === productId)
state.cart.splice(index, 1)
const { data } = await axios.get("https://fakestoreapi.com/products"); }
context.commit('getProducts', data) },
actions: {
} async getProductsAction(context) {
const { data } = await axios.get('https://fakestoreapi.com/products')
context.commit('getProducts', data)
} }
}) }
\ 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