Skip to content

Commit 02610f2

Browse files
committed
Vue Lab - Fixed lists
1 parent c2dceac commit 02610f2

2 files changed

Lines changed: 118 additions & 107 deletions

File tree

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

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

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export const useTodoStore = defineStore(
66
"todos",
77
() => {
88
const lists = ref<TodoList[]>([{ id: 1, name: "Default List", todos: [] }]);
9-
const todos = ref<Todo[]>([]);
109
const editingId = ref<number | null>(null);
1110
const filter = ref<FilterType>("all");
1211
const searchQuery = ref("");
@@ -35,6 +34,8 @@ export const useTodoStore = defineStore(
3534
activeListId.value = id;
3635
};
3736

37+
const todos = computed(() => activeList.value?.todos || []);
38+
3839
const filteredTodos = computed(() => {
3940
let filtered = todos.value;
4041

@@ -67,20 +68,29 @@ export const useTodoStore = defineStore(
6768
};
6869

6970
const toggleTodo = (id: number) => {
70-
const todo = todos.value.find((t) => t.id === id);
71-
if (todo) {
72-
todo.completed = !todo.completed;
71+
const list = lists.value.find((l) => l.id === activeListId.value);
72+
if (list) {
73+
const todo = list.todos.find((t) => t.id === id);
74+
if (todo) {
75+
todo.completed = !todo.completed;
76+
}
7377
}
7478
};
7579

7680
const deleteTodo = (id: number) => {
77-
todos.value = todos.value.filter((t) => t.id !== id);
81+
const list = lists.value.find((l) => l.id === activeListId.value);
82+
if (list) {
83+
list.todos = list.todos.filter((t) => t.id !== id);
84+
}
7885
};
7986

8087
const editTodo = (id: number, newTitle: string) => {
81-
const todo = todos.value.find((t) => t.id === id);
82-
if (todo) {
83-
todo.title = newTitle;
88+
const list = lists.value.find((l) => l.id === activeListId.value);
89+
if (list) {
90+
const todo = list.todos.find((t) => t.id === id);
91+
if (todo) {
92+
todo.title = newTitle;
93+
}
8494
}
8595
editingId.value = null;
8696
};
@@ -102,21 +112,30 @@ export const useTodoStore = defineStore(
102112
};
103113

104114
const deleteAllTodos = () => {
105-
todos.value = [];
115+
const list = lists.value.find((l) => l.id === activeListId.value);
116+
if (list) {
117+
list.todos = [];
118+
}
106119
};
107120

108121
const completeAllTodos = () => {
109-
todos.value = todos.value.map((todo) => ({
110-
...todo,
111-
completed: true,
112-
}));
122+
const list = lists.value.find((l) => l.id === activeListId.value);
123+
if (list) {
124+
list.todos = list.todos.map((todo) => ({
125+
...todo,
126+
completed: true,
127+
}));
128+
}
113129
};
114130

115131
const uncompleteAllTodos = () => {
116-
todos.value = todos.value.map((todo) => ({
117-
...todo,
118-
completed: false,
119-
}));
132+
const list = lists.value.find((l) => l.id === activeListId.value);
133+
if (list) {
134+
list.todos = list.todos.map((todo) => ({
135+
...todo,
136+
completed: false,
137+
}));
138+
}
120139
};
121140

122141
return {

0 commit comments

Comments
 (0)