Toggle deleteMode with button in Header
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
@color-2: #ffffff;
|
@color-2: #ffffff;
|
||||||
@color-3: #ff9700;
|
@color-3: #ff9700;
|
||||||
@text-color: #333;
|
@text-color: #333;
|
||||||
|
@text-error: #d63031;
|
||||||
|
|
||||||
@headerHeight: 58px;
|
@headerHeight: 58px;
|
||||||
@footerHeight: 58px;
|
@footerHeight: 58px;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: #d63031;
|
color: @text-error;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<article class="grid-item">
|
<article class="grid-item">
|
||||||
<DeleteItem :item="item" />
|
<DeleteItem v-if="deleteMode" :item="item" />
|
||||||
<router-link :to="`/fruit/${item.id}`">
|
<router-link :to="`/fruit/${item.id}`">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
<img :src="item.image" :alt="item.name" />
|
<img :src="item.image" :alt="item.name" />
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
import DeleteItem from "./DeleteItem";
|
import DeleteItem from "./DeleteItem";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -28,6 +29,9 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
item: Object
|
item: Object
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(["deleteMode"])
|
||||||
|
},
|
||||||
filters: {
|
filters: {
|
||||||
noDecimal(value) {
|
noDecimal(value) {
|
||||||
return parseInt(value).toFixed();
|
return parseInt(value).toFixed();
|
||||||
|
|||||||
@@ -5,13 +5,28 @@
|
|||||||
<h1>Fruits</h1>
|
<h1>Fruits</h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<button class="action-btn" @click="() => $store.commit('toggleModal')">+</button>
|
<div class="actions">
|
||||||
|
<button
|
||||||
|
class="action-btn action-btn--delete"
|
||||||
|
@click="() => $store.commit('toggleDeleteMode')"
|
||||||
|
>
|
||||||
|
{{ deleteMode ? "🚫" : "🗑" }}
|
||||||
|
</button>
|
||||||
|
<button class="action-btn action-btn--add" @click="() => $store.commit('toggleModal')">
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Header"
|
name: "Header",
|
||||||
|
computed: {
|
||||||
|
...mapState(["deleteMode"])
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -50,19 +65,35 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-btn {
|
.actions {
|
||||||
width: 42px;
|
display: flex;
|
||||||
height: 42px;
|
align-items: center;
|
||||||
border: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
color: @color-2;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: lighter;
|
|
||||||
text-align: center;
|
|
||||||
background: linear-gradient(112.4deg, #1c9797 11.05%, #147171 89.93%);
|
|
||||||
|
|
||||||
&:hover {
|
.action-btn {
|
||||||
background: linear-gradient(0deg, #1c9797 11.05%, #147171 89.93%);
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: @color-2;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: lighter;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 1rem;
|
||||||
|
|
||||||
|
&--delete {
|
||||||
|
border: 1px solid @text-error;
|
||||||
|
background: lighten(#cecece, 10%);
|
||||||
|
font-size: 24px;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--add {
|
||||||
|
background: linear-gradient(112.4deg, #1c9797 11.05%, #147171 89.93%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(0deg, #1c9797 11.05%, #147171 89.93%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ export default {
|
|||||||
removeFruit: async ({ commit }, id) => {
|
removeFruit: async ({ commit }, id) => {
|
||||||
await axios
|
await axios
|
||||||
.delete(`http://localhost:3000/fruit/${id}`)
|
.delete(`http://localhost:3000/fruit/${id}`)
|
||||||
.then(() => commit("removeFruit", id))
|
.then(() => {
|
||||||
|
commit("removeFruit", id);
|
||||||
|
commit("toggleDeleteMode");
|
||||||
|
})
|
||||||
.catch(err => console.log(err));
|
.catch(err => console.log(err));
|
||||||
},
|
},
|
||||||
getImageFromUnsplash: async ({ commit }, keyword) => {
|
getImageFromUnsplash: async ({ commit }, keyword) => {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ export const state = {
|
|||||||
fruits: [],
|
fruits: [],
|
||||||
fruit: {},
|
fruit: {},
|
||||||
modalIsOpen: false,
|
modalIsOpen: false,
|
||||||
loading: true
|
loading: true,
|
||||||
|
deleteMode: false
|
||||||
};
|
};
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|||||||
@@ -18,5 +18,8 @@ export default {
|
|||||||
},
|
},
|
||||||
setLoading: (state, loading) => {
|
setLoading: (state, loading) => {
|
||||||
state.loading = loading;
|
state.loading = loading;
|
||||||
|
},
|
||||||
|
toggleDeleteMode: state => {
|
||||||
|
state.deleteMode = !state.deleteMode;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<img :src="fruit.image" :alt="fruit.name" />
|
<img :src="fruit.image" :alt="fruit.name" />
|
||||||
<section>
|
<section>
|
||||||
<DeleteItem :item="fruit" :redirect="() => $router.push('/')" />
|
<DeleteItem v-if="deleteMode" :item="fruit" :redirect="() => $router.push('/')" />
|
||||||
<h3>
|
<h3>
|
||||||
{{ fruit.name }}
|
{{ fruit.name }}
|
||||||
<span class="tag" :style="{ backgroundColor: fruit.color }">{{ fruit.taste }}</span>
|
<span class="tag" :style="{ backgroundColor: fruit.color }">{{ fruit.taste }}</span>
|
||||||
@@ -42,7 +42,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["fruit"]),
|
...mapState(["fruit", "deleteMode"]),
|
||||||
expirationState() {
|
expirationState() {
|
||||||
return new Date(this.fruit.expires) < new Date() ? "expired" : "expires";
|
return new Date(this.fruit.expires) < new Date() ? "expired" : "expires";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
background-color: #d63031;
|
background-color: @text-error;
|
||||||
color: @color-2;
|
color: @color-2;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
import { mount, RouterLinkStub } from "@vue/test-utils";
|
|
||||||
// import axios from "axios";
|
|
||||||
import store from "@/store/index.js";
|
|
||||||
import Fruits from "@/views/Fruits.vue";
|
|
||||||
|
|
||||||
// jest.mock("axios", () => ({
|
|
||||||
// get: jest.fn(() => Promise.resolve({ data: {} }))
|
|
||||||
// }));
|
|
||||||
|
|
||||||
describe("Test Fruits page.", () => {
|
|
||||||
it("dispatches getFruits on mounted", async () => {
|
|
||||||
// axios.get.mockImplementationOnce(() => Promise.resolve({ data: { data: "value" } }));
|
|
||||||
mount(Fruits, { store, stubs: { RouterLink: RouterLinkStub } });
|
|
||||||
|
|
||||||
await store.dispatch("getFruits");
|
|
||||||
expect(store.state.fruits.length).toBe(7);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user