Skip to content

Commit 806e809

Browse files
committed
feat(ui): add random to-do on start and add a background art
1 parent 9f2e4c1 commit 806e809

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

public/to-do-list.svg

Lines changed: 1 addition & 0 deletions
Loading

src/App.vue

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,69 @@ const completedPercentage = computed(() => {
2121
return (completedTodos / totalOfTodos) * 100
2222
})
2323
24+
const isEmpty = computed(() => todoList.todos.length < 1)
25+
2426
const toast = useToast()
2527
26-
function addNewTodo() {
28+
function isTodoCreated(name: string) {
29+
const repeatedList = todoList.todos.filter(todo => slugger(todo.name) === slugger(name))
30+
31+
if (repeatedList.length > 0) return true
32+
else return false
33+
}
34+
35+
function addNewTodo(name: string) {
2736
// Prevent todo names less than 2 characters
28-
if (todoInput.value.length < 2) {
37+
if (name.length < 2) {
2938
error.value = true
3039
toast.warning("The to-do name has to be more than 2 characters")
3140
return
3241
}
3342
3443
// Prevent repeated todos
35-
const repeatedList = todoList.todos.filter(todo => slugger(todo.name) === slugger(todoInput.value))
36-
if (repeatedList.length > 0) {
44+
if (isTodoCreated(name)) {
3745
error.value = true
3846
toast.warning("There is already a to-do with that name")
3947
return
4048
}
4149
4250
4351
todoList.todos.push({
44-
name: todoInput.value,
52+
name: name,
4553
complete: false,
46-
id: slugger(todoInput.value) + '_' + Date.now()
54+
id: slugger(name) + '_' + Date.now()
4755
})
4856
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' })
4957
todoInput.value = ''
5058
5159
}
5260
61+
const randomTodos = [
62+
'Read "Foundation", Isaac Asimov.',
63+
'Watch "The Matrix"',
64+
'Watch "Inglourious Basterds"',
65+
'Watch "Mr. Robot" serie',
66+
'Play Skyrim game',
67+
'Listen "Da Ponte pra Cá", Racionais MC.',
68+
]
69+
const randomTodoTryTime = ref(1)
70+
71+
function addRandomTodo() {
72+
if (randomTodoTryTime.value > randomTodos.length) return
73+
74+
const randomIndex = Math.floor(Math.random() * randomTodos.length)
75+
const randomTodo = randomTodos[randomIndex]
76+
77+
78+
if (isTodoCreated(randomTodo)) {
79+
randomTodoTryTime.value += 1
80+
addRandomTodo()
81+
}
82+
else {
83+
addNewTodo(randomTodo)
84+
}
85+
}
86+
5387
function removeTodo(todoId: string) {
5488
todoList.todos = todoList.todos.filter((todo) => todo.id !== todoId)
5589
}
@@ -73,6 +107,8 @@ onMounted(() => {
73107
todoList.todos.push(...parsedTodoList)
74108
}
75109
110+
addRandomTodo()
111+
76112
todoInputComponent?.value?.addEventListener("animationend", () => {
77113
error.value = false
78114
})
@@ -83,24 +119,26 @@ onMounted(() => {
83119

84120
<template>
85121
<div class="space-y-5">
86-
<div class="fixed left-0 right-0 top-0 h-2 w-full" :class="todoList.todos.length > 0 && 'bg-neutral-100'">
122+
<div class="fixed top-0 left-0 right-0 w-full h-2" :class="todoList.todos.length > 0 && 'bg-neutral-100'">
87123
<div :data-percentage="completedPercentage"
88124
class='h-full bg-vue-light transition-all rounded-r-full data-[percentage="100"]:rounded-none'
89125
:style="{ width: completedPercentage + '%' }" />
90126
</div>
91127
<div :data-error="error" ref="todoInputComponent"
92128
class='content-container fixed bottom-20 space-y-1 data-[error="true"]:animate-shake'>
93129
<div class="flex items-stretch justify-between gap-3">
94-
<input type="text" v-model="todoInput" @keypress.enter="addNewTodo" placeholder="Some task"
130+
<input type="text" v-model="todoInput" @keypress.enter="() => addNewTodo(todoInput)" placeholder="Some task"
95131
class="h-12 w-full rounded-lg border-none bg-neutral-200/95 p-3 text-xl backdrop-blur-[80px] focus:bg-neutral-100/95 focus:ring-2 focus:ring-vue-light transition-colors" />
96-
<button @click="addNewTodo"
132+
<button @click="() => addNewTodo(todoInput)"
97133
class="flex aspect-square h-12 items-center justify-center rounded-lg bg-vue-dark/70 text-xl text-white backdrop-blur-[80px] transition-colors hover:bg-vue-dark">
98134
<PhPlus weight="bold" />
99135
</button>
100136
</div>
101137
</div>
102138

103-
<div class="content-container space-y-1">
139+
<div class="space-y-1 content-container">
140+
<img src="/to-do-list.svg" :data-is-empty="isEmpty"
141+
class="fixed opacity-50 -translate-x-1/2 data-[is-empty='false']:opacity-10 transition-opacity duration-500 -translate-y-1/3 w-96 -z-10 top-1/3 left-1/2" />
104142
<Todo v-for="todo in todoList.todos" :key="todo.id" :todo="todo" :remove-fn="removeTodo"
105143
:toggle-fn="toggleTodoCheck" />
106144
</div>

src/components/TodoItem.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ defineProps<{ todo: TodoData; removeFn: (id: string) => void; toggleFn: (id: str
55
</script>
66

77
<template>
8-
<div class="group flex items-center justify-between gap-5 rounded-lg p-2 text-xl animate-fade-up"
8+
<div class="flex items-center justify-between gap-5 p-2 text-xl rounded-lg group animate-fade-up"
99
:class="!todo.complete && 'bg-neutral-200/30'">
10-
<div class="flex w-full items-center gap-5 overflow-hidden">
10+
<div class="flex items-center w-full gap-5 overflow-hidden">
1111
<input type="checkbox" title="Mark to-do as completed" :checked="todo.complete" @click="toggleFn(todo.id)"
12-
class="cursor-pointer rounded border border-neutral-700 bg-transparent p-3 text-vue-light focus:outline-none focus:ring-0" />
12+
class="p-3 bg-transparent border rounded cursor-pointer border-neutral-700 text-vue-light focus:outline-none focus:ring-0" />
1313
<span :class="todo.complete && 'text-neutral-500 line-through'"
1414
class="overflow-hidden text-ellipsis whitespace-nowrap" :title="todo.name">{{ todo.name }}</span>
1515
</div>
1616
<button @click="removeFn(todo.id)" title="Delete to-do"
17-
class="text-neutral-500/20 transition-colors hover:text-red-700">
17+
class="transition-colors text-neutral-500/20 hover:text-red-700">
1818
<PhTrash weight="regular" />
1919
</button>
2020
</div>

0 commit comments

Comments
 (0)