Skip to content

Commit a54c5dd

Browse files
committed
Vue Lab - Added actions to delete and complete todos.
1 parent b1c36c2 commit a54c5dd

3 files changed

Lines changed: 117 additions & 2 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<template>
2+
<ClientOnly>
3+
<div class="actions-container">
4+
<button
5+
@click="confirmDelete"
6+
class="action-button delete-all"
7+
:disabled="!hasTodos"
8+
>
9+
Delete All Tasks
10+
</button>
11+
<button
12+
@click="toggleAllCompletion"
13+
class="action-button toggle-all"
14+
:disabled="!hasTodos"
15+
>
16+
{{ allCompleted ? 'Uncomplete All' : 'Complete All' }}
17+
</button>
18+
</div>
19+
</ClientOnly>
20+
</template>
21+
22+
<script setup lang="ts">
23+
import { computed } from 'vue'
24+
import { storeToRefs } from 'pinia'
25+
import { useTodoStore } from '~/stores/todo-store'
26+
27+
const store = useTodoStore()
28+
const { todos } = storeToRefs(store)
29+
30+
const hasTodos = computed(() => todos.value.length > 0)
31+
const allCompleted = computed(() =>
32+
todos.value.length > 0 && todos.value.every(todo => todo.completed)
33+
)
34+
35+
const confirmDelete = () => {
36+
if (confirm('Are you sure you want to delete all tasks?')) {
37+
store.deleteAllTodos()
38+
}
39+
}
40+
41+
const toggleAllCompletion = () => {
42+
if (allCompleted.value) {
43+
store.uncompleteAllTodos()
44+
} else {
45+
store.completeAllTodos()
46+
}
47+
}
48+
</script>
49+
50+
<style scoped>
51+
.actions-container {
52+
display: flex;
53+
gap: 1rem;
54+
margin: 1rem 0;
55+
justify-content: center;
56+
}
57+
58+
.action-button {
59+
padding: 0.5rem 1rem;
60+
border-radius: 4px;
61+
border: none;
62+
cursor: pointer;
63+
font-weight: bold;
64+
transition: all 0.2s;
65+
}
66+
67+
.action-button:disabled {
68+
opacity: 0.5;
69+
cursor: not-allowed;
70+
}
71+
72+
.action-button:not(:disabled) {
73+
opacity: 1;
74+
}
75+
76+
.delete-all {
77+
background-color: #ff4444;
78+
color: white;
79+
}
80+
81+
.delete-all:hover:not(:disabled) {
82+
background-color: #ff6666;
83+
}
84+
85+
.toggle-all {
86+
background-color: #4CAF50;
87+
color: white;
88+
}
89+
90+
.toggle-all:hover:not(:disabled) {
91+
background-color: #45a049;
92+
}
93+
</style>

4 - Frameworks/Ejercicios/VUE/vue-lab/todo-app/pages/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<SearchBar />
66
<TodoFilter />
77
<TodoList :todos="store.filteredTodos" @toggle="toggleTodo" @delete="deleteTodo" />
8+
<TodoActions />
89
</div>
910
</template>
1011

4 - Frameworks/Ejercicios/VUE/vue-lab/todo-app/stores/todo-store.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ export const useTodoStore = defineStore(
2121

2222
switch (filter.value) {
2323
case "active":
24-
return filtered.value.filter((todo) => !todo.completed);
24+
return filtered.filter((todo) => !todo.completed);
2525
case "completed":
26-
return filtered.value.filter((todo) => todo.completed);
26+
return filtered.filter((todo) => todo.completed);
2727
default:
2828
return filtered;
2929
}
@@ -73,6 +73,24 @@ export const useTodoStore = defineStore(
7373
searchQuery.value = query;
7474
};
7575

76+
const deleteAllTodos = () => {
77+
todos.value = [];
78+
};
79+
80+
const completeAllTodos = () => {
81+
todos.value = todos.value.map((todo) => ({
82+
...todo,
83+
completed: true,
84+
}));
85+
};
86+
87+
const uncompleteAllTodos = () => {
88+
todos.value = todos.value.map((todo) => ({
89+
...todo,
90+
completed: false,
91+
}));
92+
};
93+
7694
return {
7795
todos,
7896
editingId,
@@ -87,6 +105,9 @@ export const useTodoStore = defineStore(
87105
setFilter,
88106
searchQuery,
89107
setSearchQuery,
108+
deleteAllTodos,
109+
completeAllTodos,
110+
uncompleteAllTodos,
90111
};
91112
},
92113
{

0 commit comments

Comments
 (0)