From e87a4611c2f948ee333f74be4722ddca73f06586 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 5 Aug 2025 19:33:03 +0100 Subject: [PATCH 1/9] TodoList, not allowed to leave the field blank in the input --- TodoList/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TodoList/index.js b/TodoList/index.js index d3ab656..5c6e16e 100644 --- a/TodoList/index.js +++ b/TodoList/index.js @@ -7,6 +7,10 @@ let completedCount = 0; let totalCount = 0; addButton.addEventListener('click', function (e) { + if (input.value.length == 0) { + window.alert("Input notYou cannot leave the field blank valid") + } else { + e.preventDefault(); const paragraph1 = document.createElement('div'); const paragraph2 = document.createElement('div'); @@ -52,7 +56,7 @@ addButton.addEventListener('click', function (e) { } updateCountDisplay(); }); -}); +}}); function updateCountDisplay() { countDisplay.textContent = `${completedCount} of ${totalCount} tasks done`; From 85441c221f22f7621b930a7a7db2b8645413e3f3 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 5 Aug 2025 19:42:29 +0100 Subject: [PATCH 2/9] TodoList, not allowed to leave the field blank in the input --- TodoList/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TodoList/index.js b/TodoList/index.js index 5c6e16e..2a3b748 100644 --- a/TodoList/index.js +++ b/TodoList/index.js @@ -8,7 +8,7 @@ let totalCount = 0; addButton.addEventListener('click', function (e) { if (input.value.length == 0) { - window.alert("Input notYou cannot leave the field blank valid") + window.alert("You cannot leave the field blank valid") } else { e.preventDefault(); From 7f196408dbe1e863c4b56ed263093a1c1a555bd3 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 5 Aug 2025 19:44:10 +0100 Subject: [PATCH 3/9] TodoList, not allowed to leave the field blank in the input --- TodoList/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TodoList/index.js b/TodoList/index.js index 2a3b748..a7ffb1e 100644 --- a/TodoList/index.js +++ b/TodoList/index.js @@ -8,7 +8,7 @@ let totalCount = 0; addButton.addEventListener('click', function (e) { if (input.value.length == 0) { - window.alert("You cannot leave the field blank valid") + window.alert("You cannot leave the field blank") } else { e.preventDefault(); From 21c9a7c665c332267721a0d0315a1ae4cb47303f Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 6 Aug 2025 19:27:31 +0100 Subject: [PATCH 4/9] New exercice --- Multiply/modelo.html | 38 +++++++++++++++++++ Multiply/scrip.js | 23 +++++++++++ Multiply/style.css | 30 +++++++++++++++ TodoList/index.js | 90 ++++++++++++++++++++++---------------------- 4 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 Multiply/modelo.html create mode 100644 Multiply/scrip.js create mode 100644 Multiply/style.css diff --git a/Multiply/modelo.html b/Multiply/modelo.html new file mode 100644 index 0000000..702e9e9 --- /dev/null +++ b/Multiply/modelo.html @@ -0,0 +1,38 @@ + + + + + + Multiplication + + + +
+

Multiplication

+
+ +
+
+

Number: + + +

+
+ +
+

+ +

+
+
+ + +
+ victorRbcx

+
+ + + + \ No newline at end of file diff --git a/Multiply/scrip.js b/Multiply/scrip.js new file mode 100644 index 0000000..3c08643 --- /dev/null +++ b/Multiply/scrip.js @@ -0,0 +1,23 @@ +function calcular() { +var txtn = window.document.getElementById('txtnum') +var n = Number(txtn.value) +var lista = document.getElementById('listaNumeros') +lista.innerHTML = '' + + if ( txtn.value.length == 0 || isNaN(n)) { + window.alert('Enter a number to Multiply!') + var opcao = document.createElement('option') + opcao.text = 'Enter a number above' + lista.add(opcao); + } else { + + for(var i = 0; i <= 10; i++) { + var opcao = document.createElement('option') + var calc = n * i + opcao.value = `tab${i}` + opcao.text = `${n} x ${i} = ${calc}` + lista.add(opcao); + } + } + txtn.value = '' +} \ No newline at end of file diff --git a/Multiply/style.css b/Multiply/style.css new file mode 100644 index 0000000..674c6f4 --- /dev/null +++ b/Multiply/style.css @@ -0,0 +1,30 @@ +body { + background-color: rgb(115, 115, 201); + font: normal 15pt arial; +} + +header { + color: white; + text-align: center; +} + +section { + background-color: white; + border-radius: 10px; + padding: 15px; + width: 500px; + margin: auto; + text-align: center; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.493); +} + +#lista{ + text-align: left; +} + +footer { + color: white; + text-align: center; + font-style: italic; + margin-top: 20px; +} \ No newline at end of file diff --git a/TodoList/index.js b/TodoList/index.js index a7ffb1e..4ba800a 100644 --- a/TodoList/index.js +++ b/TodoList/index.js @@ -11,52 +11,52 @@ addButton.addEventListener('click', function (e) { window.alert("You cannot leave the field blank") } else { - e.preventDefault(); - const paragraph1 = document.createElement('div'); - const paragraph2 = document.createElement('div'); - const cont = document.createElement('div'); - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - paragraph1.appendChild(checkbox); - const text = document.createTextNode(input.value); - paragraph1.appendChild(text); - const editButton = document.createElement('button'); - editButton.textContent = '✒️'; - paragraph2.appendChild(editButton); - const deleteButton = document.createElement('button'); - deleteButton.textContent = '❎'; - paragraph2.appendChild(deleteButton); - cont.appendChild(paragraph1); - cont.appendChild(paragraph2); - todoContainer.appendChild(cont); - input.value = ''; - totalCount++; - updateCountDisplay(); - checkbox.addEventListener('click', function () { - if (checkbox.checked) { - cont.style.textDecoration = 'line-through'; - completedCount++; - } else { - cont.style.textDecoration = 'none'; - completedCount--; - } - updateCountDisplay(); - }); - editButton.addEventListener('click', function () { - const editText = prompt('Edit task:', text.textContent); - if (editText !== null) { - text.textContent = editText; - } - }); - deleteButton.addEventListener('click', function () { - todoContainer.removeChild(cont); - totalCount--; - if (checkbox.checked) { - completedCount--; - } + e.preventDefault(); + const paragraph1 = document.createElement('div'); + const paragraph2 = document.createElement('div'); + const cont = document.createElement('div'); + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + paragraph1.appendChild(checkbox); + const text = document.createTextNode(input.value); + paragraph1.appendChild(text); + const editButton = document.createElement('button'); + editButton.textContent = '✒️'; + paragraph2.appendChild(editButton); + const deleteButton = document.createElement('button'); + deleteButton.textContent = '❎'; + paragraph2.appendChild(deleteButton); + cont.appendChild(paragraph1); + cont.appendChild(paragraph2); + todoContainer.appendChild(cont); + input.value = ''; + totalCount++; updateCountDisplay(); - }); -}}); + checkbox.addEventListener('click', function () { + if (checkbox.checked) { + cont.style.textDecoration = 'line-through'; + completedCount++; + } else { + cont.style.textDecoration = 'none'; + completedCount--; + } + updateCountDisplay(); + }); + editButton.addEventListener('click', function () { + const editText = prompt('Edit task:', text.textContent); + if (editText !== null) { + text.textContent = editText; + } + }); + deleteButton.addEventListener('click', function () { + todoContainer.removeChild(cont); + totalCount--; + if (checkbox.checked) { + completedCount--; + } + updateCountDisplay(); + }); + }}); function updateCountDisplay() { countDisplay.textContent = `${completedCount} of ${totalCount} tasks done`; From b08e57bf49780ac5cd6bd29ea6107f8cddf73b6c Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 8 Aug 2025 19:26:45 +0100 Subject: [PATCH 5/9] Create new exercice, count-by-steps --- count-by-steps/modelo.html | 35 ++++++++++++++++++++++++ count-by-steps/scrip.js | 56 ++++++++++++++++++++++++++++++++++++++ count-by-steps/style.css | 26 ++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 count-by-steps/modelo.html create mode 100644 count-by-steps/scrip.js create mode 100644 count-by-steps/style.css diff --git a/count-by-steps/modelo.html b/count-by-steps/modelo.html new file mode 100644 index 0000000..0a66ca9 --- /dev/null +++ b/count-by-steps/modelo.html @@ -0,0 +1,35 @@ + + + + + + Count + + + +
+

Let's count

+
+ +
+
+

Start:

+ +

End:

+ +

Steps:

+ +

+ +
+ +

Preparing Count

+
+ +
+ victorRbcx

+
+ + + + \ No newline at end of file diff --git a/count-by-steps/scrip.js b/count-by-steps/scrip.js new file mode 100644 index 0000000..bffab8b --- /dev/null +++ b/count-by-steps/scrip.js @@ -0,0 +1,56 @@ +function count() { + var ini = window.document.getElementById('txtinicio') + var fim = window.document.getElementById('txtfim') + var passo = window.document.getElementById('txtpasso') + var res = document.querySelector('p#conta') + + var i = Number(ini.value) + var f = Number(fim.value) + var p = Number(passo.value) + + + if(ini.value.length == 0 || fim.value.length == 0 || passo.value.length == 0) { + window.alert('Fill in the start, end and step fields correctly') + res.innerHTML = 'Impossible to count' + } else if (p == 0 || p < 0) { + window.alert('Incorrect step, the program will assume the value 1') + res.innerHTML = `Counting:
` + p = 1 + + if (i < f) { + // Upward count with incorrect step + while (i <= f) { + res.innerHTML += `\u{1F449} ${i}` + i += p + } + res.innerHTML += `\u{1F449}` + res.innerHTML += '\u{1F3C1}' + } else { + // Countdown with incorrect step + while (i >= f) { + res.innerHTML += `\u{1F449} ${i}` + i -= p + } + res.innerHTML += `\u{1F449}` + res.innerHTML += '\u{1F3C1}' + } + + } else if (i < f) { + // Count up + res.innerHTML = `Counting:
` + while (i <= f) { + res.innerHTML += `\u{1F449} ${i}` + i += p + } + res.innerHTML += `\u{1F449} ` + res.innerHTML += '\u{1F3C1}' + } else { + // Countdown + res.innerHTML = `Counting:
` + while (i >= f) { + res.innerHTML += `\u{1F449} ${i}` + i -= p + } + } + +} \ No newline at end of file diff --git a/count-by-steps/style.css b/count-by-steps/style.css new file mode 100644 index 0000000..7d5bfec --- /dev/null +++ b/count-by-steps/style.css @@ -0,0 +1,26 @@ +body { + background-color: rgb(115, 115, 201); + font: normal 15pt arial; +} + +header { + color: white; + text-align: center; +} + +section { + background-color: white; + border-radius: 10px; + padding: 15px; + width: 500px; + margin: auto; + text-align: center; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.493); +} + +footer { + color: white; + text-align: center; + font-style: italic; + margin-top: 20px; +} \ No newline at end of file From 4e3e056fd9c61f14d6d33964da36d1e15cf1be31 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 8 Aug 2025 19:29:40 +0100 Subject: [PATCH 6/9] fix new exercice --- count-by-steps/modelo.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/count-by-steps/modelo.html b/count-by-steps/modelo.html index 0a66ca9..3488df3 100644 --- a/count-by-steps/modelo.html +++ b/count-by-steps/modelo.html @@ -19,7 +19,7 @@

Let's count

Steps:

-

+

From a7fe304ceafd409404621839929c1e492bb7f43f Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 8 Aug 2025 19:30:45 +0100 Subject: [PATCH 7/9] change name for index --- Multiply/{modelo.html => index.html} | 0 count-by-steps/{modelo.html => index.html} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Multiply/{modelo.html => index.html} (100%) rename count-by-steps/{modelo.html => index.html} (100%) diff --git a/Multiply/modelo.html b/Multiply/index.html similarity index 100% rename from Multiply/modelo.html rename to Multiply/index.html diff --git a/count-by-steps/modelo.html b/count-by-steps/index.html similarity index 100% rename from count-by-steps/modelo.html rename to count-by-steps/index.html From b3a51e0ce7276a0e5441c875aeb22b37a908d179 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 21 Aug 2025 18:25:37 +0100 Subject: [PATCH 8/9] new taskflow --- TaskFlow/index.html | 135 ++++++++++ TaskFlow/script.js | 569 ++++++++++++++++++++++++++++++++++++++++++ TaskFlow/styles.css | 594 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1298 insertions(+) create mode 100644 TaskFlow/index.html create mode 100644 TaskFlow/script.js create mode 100644 TaskFlow/styles.css diff --git a/TaskFlow/index.html b/TaskFlow/index.html new file mode 100644 index 0000000..32d89de --- /dev/null +++ b/TaskFlow/index.html @@ -0,0 +1,135 @@ + + + + + + TaskFlow - Gerenciador de Tarefas + + + + +
+ +
+
+

+ + TaskFlow +

+
+ + + Total: 0 + + + + Concluídas: 0 + +
+
+
+ + +
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+
+ + + + +
+
+ + +
+
+ +
+
+
+ +
+ +

Nenhuma tarefa encontrada

+

Adicione sua primeira tarefa para começar!

+
+
+
+ +
+

© 2025 TaskFlow - VictorRBCX + + + +

+
+
+ + + + + + + \ No newline at end of file diff --git a/TaskFlow/script.js b/TaskFlow/script.js new file mode 100644 index 0000000..18af92a --- /dev/null +++ b/TaskFlow/script.js @@ -0,0 +1,569 @@ + +class TaskManager { + constructor() { + this.tasks = this.loadTasks(); + this.currentFilter = 'todas'; + this.searchTerm = ''; + this.editingTaskId = null; + + this.init(); + } + + init() { + this.bindEvents(); + this.renderTasks(); + this.updateStats(); + this.setTodayAsDefaultDate(); + } + + bindEvents() { + // Botão adicionar tarefa + const addBtn = document.getElementById('addTaskBtn'); + addBtn.addEventListener('click', () => this.handleAddTask()); + + // Enter no input de tarefa + const taskInput = document.getElementById('taskInput'); + taskInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + this.handleAddTask(); + } + }); + + // Filtros + const filterBtns = document.querySelectorAll('.filter-btn'); + filterBtns.forEach(btn => { + btn.addEventListener('click', (e) => { + this.setActiveFilter(e.target.dataset.filter); + }); + }); + + // Busca + const searchInput = document.getElementById('searchInput'); + searchInput.addEventListener('input', (e) => { + this.searchTerm = e.target.value.toLowerCase(); + this.renderTasks(); + }); + + // Modal + const cancelBtn = document.getElementById('cancelBtn'); + cancelBtn.addEventListener('click', () => this.hideModal()); + + // Fechar modal clicando fora + const modal = document.getElementById('confirmModal'); + modal.addEventListener('click', (e) => { + if (e.target === modal) { + this.hideModal(); + } + }); + } + + // Define a data de hoje como padrão no input de data + + setTodayAsDefaultDate() { + const today = new Date().toISOString().split('T')[0]; + document.getElementById('taskDeadline').value = today; + } + + // Manipula a adição/edição de tarefas + + handleAddTask() { + const taskInput = document.getElementById('taskInput'); + const prioritySelect = document.getElementById('prioritySelect'); + const categorySelect = document.getElementById('categorySelect'); + const deadlineInput = document.getElementById('taskDeadline'); + + const title = taskInput.value.trim(); + const priority = prioritySelect.value; + const category = categorySelect.value; + const deadline = deadlineInput.value; + + if (!title) { + this.showNotification('Por favor, digite o texto da tarefa!', 'error'); + taskInput.focus(); + return; + } + + if (this.editingTaskId) { + this.updateTask(this.editingTaskId, { title, priority, category, deadline }); + this.editingTaskId = null; + document.getElementById('addTaskBtn').innerHTML = ' Adicionar'; + } else { + this.addTask({ title, priority, category, deadline }); + } + + // Limpar formulário + taskInput.value = ''; + prioritySelect.value = 'media'; + categorySelect.value = 'pessoal'; + this.setTodayAsDefaultDate(); + + taskInput.focus(); + } + + // Adiciona uma nova tarefa + addTask(taskData) { + const task = { + id: this.generateId(), + title: taskData.title, + priority: taskData.priority, + category: taskData.category, + deadline: taskData.deadline || null, + completed: false, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() + }; + + this.tasks.push(task); + this.saveTasks(); + this.renderTasks(); + this.updateStats(); + + this.showNotification('Tarefa adicionada com sucesso!', 'success'); + } + + // Atualiza uma tarefa existente + updateTask(id, updates) { + const taskIndex = this.tasks.findIndex(task => task.id === id); + if (taskIndex !== -1) { + this.tasks[taskIndex] = { + ...this.tasks[taskIndex], + ...updates, + updatedAt: new Date().toISOString() + }; + + this.saveTasks(); + this.renderTasks(); + this.updateStats(); + + this.showNotification('Tarefa atualizada com sucesso!', 'success'); + } + } + + // Remove uma tarefa + deleteTask(id) { + const task = this.tasks.find(t => t.id === id); + if (!task) return; + + this.showConfirmModal( + `Tem certeza que deseja excluir a tarefa "${task.title}"?`, + () => { + this.tasks = this.tasks.filter(task => task.id !== id); + this.saveTasks(); + this.renderTasks(); + this.updateStats(); + this.showNotification('Tarefa excluída com sucesso!', 'success'); + } + ); + } + + // Alterna o status de conclusão de uma tarefa + toggleTask(id) { + const taskIndex = this.tasks.findIndex(task => task.id === id); + if (taskIndex !== -1) { + this.tasks[taskIndex].completed = !this.tasks[taskIndex].completed; + this.tasks[taskIndex].updatedAt = new Date().toISOString(); + + this.saveTasks(); + this.renderTasks(); + this.updateStats(); + + const status = this.tasks[taskIndex].completed ? 'concluída' : 'reativada'; + this.showNotification(`Tarefa ${status}!`, 'info'); + } + } + + // Inicia a edição de uma tarefa + editTask(id) { + const task = this.tasks.find(t => t.id === id); + if (!task) return; + + this.editingTaskId = id; + + // Preencher formulário + document.getElementById('taskInput').value = task.title; + document.getElementById('prioritySelect').value = task.priority; + document.getElementById('categorySelect').value = task.category; + document.getElementById('taskDeadline').value = task.deadline || ''; + + // Alterar botão + document.getElementById('addTaskBtn').innerHTML = ' Salvar'; + + // Focar no input + document.getElementById('taskInput').focus(); + document.getElementById('taskInput').scrollIntoView({ behavior: 'smooth' }); + } + + // Define o filtro ativo + setActiveFilter(filter) { + this.currentFilter = filter; + + // Atualizar botões + document.querySelectorAll('.filter-btn').forEach(btn => { + btn.classList.remove('active'); + }); + document.querySelector(`[data-filter="${filter}"]`).classList.add('active'); + + this.renderTasks(); + } + + // Filtra as tarefas baseado no filtro atual e termo de busca + getFilteredTasks() { + let filtered = [...this.tasks]; + + // Aplicar filtro + switch (this.currentFilter) { + case 'pendentes': + filtered = filtered.filter(task => !task.completed); + break; + case 'concluidas': + filtered = filtered.filter(task => task.completed); + break; + case 'alta': + filtered = filtered.filter(task => task.priority === 'alta'); + break; + } + + // Aplicar busca + if (this.searchTerm) { + filtered = filtered.filter(task => + task.title.toLowerCase().includes(this.searchTerm) || + task.category.toLowerCase().includes(this.searchTerm) + ); + } + + // Ordenar: não concluídas primeiro, depois por prioridade + return filtered.sort((a, b) => { + if (a.completed !== b.completed) { + return a.completed - b.completed; + } + + const priorityOrder = { 'alta': 0, 'media': 1, 'baixa': 2 }; + return priorityOrder[a.priority] - priorityOrder[b.priority]; + }); + } + + // Renderiza a lista de tarefas + renderTasks() { + const container = document.getElementById('tasksContainer'); + const emptyState = document.getElementById('emptyState'); + const filteredTasks = this.getFilteredTasks(); + + if (filteredTasks.length === 0) { + container.style.display = 'none'; + emptyState.style.display = 'block'; + return; + } + + container.style.display = 'block'; + emptyState.style.display = 'none'; + + container.innerHTML = filteredTasks.map(task => this.createTaskHTML(task)).join(''); + + // Vincular eventos dos botões + this.bindTaskEvents(); + } + + // Cria o HTML para uma tarefa + createTaskHTML(task) { + const deadlineInfo = this.getDeadlineInfo(task.deadline); + const categoryLabel = this.getCategoryLabel(task.category); + + return ` +
+ + +
+
${this.escapeHtml(task.title)}
+
+ ${task.priority} + ${categoryLabel} + ${deadlineInfo.html} + + + ${this.formatDate(task.createdAt)} + +
+
+ +
+ + +
+
+ `; + } + + // Vincula eventos dos botões das tarefas + bindTaskEvents() { + document.querySelectorAll('.task-checkbox').forEach(checkbox => { + checkbox.addEventListener('change', (e) => { + const taskId = Number(e.target.closest('.task-item').dataset.taskId); + this.toggleTask(taskId); + }); + }); + + document.querySelectorAll('.task-btn.edit').forEach(btn => { + btn.addEventListener('click', () => { + const taskId = Number(btn.closest('.task-item').dataset.taskId); + this.editTask(taskId); + }); + }); + + document.querySelectorAll('.task-btn.delete').forEach(btn => { + btn.addEventListener('click', () => { + const taskId = Number(btn.closest('.task-item').dataset.taskId); + this.deleteTask(taskId); + }); + }); +} + + // Obtém informações sobre o prazo da tarefa + getDeadlineInfo(deadline) { + if (!deadline) { + return { html: '', isOverdue: false }; + } + + const deadlineDate = new Date(deadline); + const today = new Date(); + const diffTime = deadlineDate - today; + const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + let className = 'task-deadline'; + let icon = 'fas fa-clock'; + let text = this.formatDate(deadline, true); + + if (diffDays < 0) { + className += ' overdue'; + icon = 'fas fa-exclamation-triangle'; + text += ` (${Math.abs(diffDays)} dias atrasado)`; + } else if (diffDays === 0) { + className += ' today'; + icon = 'fas fa-exclamation'; + text += ' (hoje)'; + } else if (diffDays === 1) { + text += ' (amanhã)'; + } + + return { + html: ` ${text}`, + isOverdue: diffDays < 0 + }; + } + + // Obtém o rótulo da categoria + getCategoryLabel(category) { + const labels = { + 'pessoal': 'Pessoal', + 'trabalho': 'Trabalho', + 'estudos': 'Estudos', + 'saude': 'Saúde', + 'outros': 'Outros' + }; + return labels[category] || category; + } + + // Atualiza as estatísticas no cabeçalho + updateStats() { + const totalTasks = this.tasks.length; + const completedTasks = this.tasks.filter(task => task.completed).length; + + document.getElementById('totalTasks').textContent = totalTasks; + document.getElementById('completedTasks').textContent = completedTasks; + } + + // Mostra o modal de confirmação + showConfirmModal(message, onConfirm) { + const modal = document.getElementById('confirmModal'); + const messageEl = document.getElementById('confirmMessage'); + const confirmBtn = document.getElementById('confirmBtn'); + + messageEl.textContent = message; + modal.classList.add('active'); + + // Remover listados anteriores + const newConfirmBtn = confirmBtn.cloneNode(true); + confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn); + + // Adicionar nova lista + newConfirmBtn.addEventListener('click', () => { + onConfirm(); + this.hideModal(); + }); + } + + // Esconde o modal + hideModal() { + document.getElementById('confirmModal').classList.remove('active'); + } + + // Mostra notificação (implementação simples) + showNotification(message, type = 'info') { + // Por simplicidade, usando alert. Em produção, implementaria um sistema de toast + console.log(`[${type.toUpperCase()}] ${message}`); + + // Você pode implementar um sistema de toast mais sofisticado aqui + const originalTitle = document.title; + document.title = `${message} - TaskFlow`; + setTimeout(() => { + document.title = originalTitle; + }, 3000); + } + + // Gera um ID único para as tarefas + generateId() { + return Date.now() + Math.random(); + } + + // Formata uma data para exibição + formatDate(dateString, dateOnly = false) { + const date = new Date(dateString); + const options = dateOnly + ? { day: '2-digit', month: '2-digit', year: 'numeric' } + : { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit' }; + + return date.toLocaleDateString('pt-BR', options); + } + + // Escapa HTML para prevenir XSS + escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } + + // Carrega tarefas do localStorage + loadTasks() { + try { + const tasksJson = localStorage.getItem('taskflow_tasks'); + return tasksJson ? JSON.parse(tasksJson) : []; + } catch (error) { + console.error('Erro ao carregar tarefas:', error); + return []; + } + } + + // Salva tarefas no localStorage + saveTasks() { + try { + localStorage.setItem('taskflow_tasks', JSON.stringify(this.tasks)); + } catch (error) { + console.error('Erro ao salvar tarefas:', error); + } + } + + // Exporta tarefas como JSON + exportTasks() { + const data = { + tasks: this.tasks, + exportDate: new Date().toISOString(), + version: '1.0.0' + }; + + const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = `taskflow_backup_${new Date().toISOString().split('T')[0]}.json`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + + URL.revokeObjectURL(url); + + this.showNotification('Tarefas exportadas com sucesso!', 'success'); + } + + // Limpa todas as tarefas concluídas + clearCompleted() { + const completedCount = this.tasks.filter(task => task.completed).length; + + if (completedCount === 0) { + this.showNotification('Não há tarefas concluídas para limpar.', 'info'); + return; + } + + this.showConfirmModal( + `Tem certeza que deseja excluir ${completedCount} tarefa(s) concluída(s)?`, + () => { + this.tasks = this.tasks.filter(task => !task.completed); + this.saveTasks(); + this.renderTasks(); + this.updateStats(); + this.showNotification('Tarefas concluídas removidas!', 'success'); + } + ); + } +} + +// O que falta : + +/** + * TODO: + * + * 1. Sistema de tags/etiquetas para tarefas + * 2. Drag & drop para reordenar tarefas + * 3. Subtarefas/checklist dentro de tarefas + * 4. Modo escuro/claro + * 5. Sincronização com APIs externas + * 6. Notificações push + * 7. Sistema de templates de tarefas + * 8. Relatórios e estatísticas avançadas + * 9. Filtros por data + * 10. Anexos em tarefas + * 11. Comentários em tarefas + * 12. Sistema de colaboração/compartilhamento + * 13. Integração com calendário + * 14. Backup automático + * 15. Atalhos de teclado + * 16. Widgets de produtividade + * 17. Integração com Pomodoro Timer + * 18. Gamificação (pontos, conquistas) + * 19. Temas personalizáveis + * 20. PWA (Progressive Web App) features + */ + +// Inicializar aplicação +document.addEventListener('DOMContentLoaded', () => { + window.taskManager = new TaskManager(); + + console.log('🚀 TaskFlow inicializado com sucesso!'); + console.log('💡 Este é um projeto open source. Contribua no GitHub!'); + console.log('🎯 Visite: https://github.com/your-repo/taskflow'); +}); + +// Atalhos de teclado +document.addEventListener('keydown', (e) => { + // Ctrl/Cmd + Enter para adicionar tarefa rapidamente + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { + e.preventDefault(); + if (window.taskManager) { + window.taskManager.handleAddTask(); + } + } + + // Esc para cancelar edição + if (e.key === 'Escape') { + if (window.taskManager && window.taskManager.editingTaskId) { + window.taskManager.editingTaskId = null; + document.getElementById('addTaskBtn').innerHTML = ' Adicionar'; + document.getElementById('taskInput').value = ''; + } + } +}); + +// Prevenir perda de dados ao fechar a página +window.addEventListener('beforeunload', (e) => { + const taskInput = document.getElementById('taskInput'); + if (taskInput && taskInput.value.trim()) { + e.preventDefault(); + e.returnValue = 'Você tem uma tarefa não salva. Deseja realmente sair?'; + } +}); \ No newline at end of file diff --git a/TaskFlow/styles.css b/TaskFlow/styles.css new file mode 100644 index 0000000..651eac4 --- /dev/null +++ b/TaskFlow/styles.css @@ -0,0 +1,594 @@ + +/* Reset e Configurações Base */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + /* Cores Principais */ + --primary-color: #667eea; + --primary-dark: #5a67d8; + --secondary-color: #764ba2; + --accent-color: #f093fb; + + /* Cores de Status */ + --success-color: #48bb78; + --warning-color: #ed8936; + --danger-color: #f56565; + --info-color: #4299e1; + + /* Cores Neutras */ + --text-primary: #2d3748; + --text-secondary: #718096; + --text-muted: #a0aec0; + --background-light: #f7fafc; + --background-white: #ffffff; + --border-color: #e2e8f0; + --shadow-light: 0 1px 3px 0 rgba(0, 0, 0, 0.1); + --shadow-medium: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + --shadow-heavy: 0 10px 15px -3px rgba(0, 0, 0, 0.1); + + /* Tamanhos */ + --border-radius: 8px; + --border-radius-lg: 12px; + --spacing-xs: 0.25rem; + --spacing-sm: 0.5rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; +} + +body { + font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%); + min-height: 100vh; + color: var(--text-primary); + line-height: 1.6; +} + +.app-container { + max-width: 1200px; + margin: 0 auto; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +/* Header Styles */ +.header { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + border-bottom: 1px solid var(--border-color); + padding: var(--spacing-lg) var(--spacing-md); + position: sticky; + top: 0; + z-index: 100; + box-shadow: var(--shadow-light); +} + +.header-content { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: var(--spacing-md); +} + +.app-title { + font-size: 1.8rem; + font-weight: 700; + color: var(--primary-color); + display: flex; + align-items: center; + gap: var(--spacing-sm); +} + +.app-title i { + font-size: 1.6rem; +} + +.header-stats { + display: flex; + gap: var(--spacing-lg); +} + +.stat { + display: flex; + align-items: center; + gap: var(--spacing-xs); + color: var(--text-secondary); + font-weight: 500; +} + +.stat i { + color: var(--primary-color); +} + +/* Main Content */ +.main-content { + flex: 1; + padding: var(--spacing-xl) var(--spacing-md); + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +/* Task Input Section */ +.task-input-section { + background: var(--background-white); + border-radius: var(--border-radius-lg); + padding: var(--spacing-xl); + box-shadow: var(--shadow-medium); + border: 1px solid var(--border-color); +} + +.input-container { + display: flex; + flex-direction: column; + gap: var(--spacing-md); +} + +.input-group { + display: flex; + gap: var(--spacing-md); + flex-wrap: wrap; +} + +.input-extra { + display: flex; + gap: var(--spacing-md); + flex-wrap: wrap; +} + +input[type="text"], input[type="date"], select { + padding: var(--spacing-md); + border: 2px solid var(--border-color); + border-radius: var(--border-radius); + font-size: 1rem; + transition: all 0.3s ease; + outline: none; +} + +input[type="text"]:focus, input[type="date"]:focus, select:focus { + border-color: var(--primary-color); + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); +} + +#taskInput { + flex: 1; + min-width: 300px; +} + +#prioritySelect, #categorySelect { + min-width: 150px; +} + +/* Buttons */ +.btn-primary, .btn-secondary, .btn-danger { + padding: var(--spacing-md) var(--spacing-lg); + border: none; + border-radius: var(--border-radius); + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); + text-decoration: none; +} + +.btn-primary { + background: linear-gradient(135deg, var(--primary-color), var(--primary-dark)); + color: white; +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-heavy); +} + +.btn-secondary { + background: var(--text-muted); + color: white; +} + +.btn-danger { + background: var(--danger-color); + color: white; +} + +.btn-danger:hover { + background: #e53e3e; +} + +/* Filters Section */ +.filters-section { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: var(--spacing-md); + background: var(--background-white); + padding: var(--spacing-lg); + border-radius: var(--border-radius-lg); + box-shadow: var(--shadow-light); +} + +.filters { + display: flex; + gap: var(--spacing-sm); + flex-wrap: wrap; +} + +.filter-btn { + padding: var(--spacing-sm) var(--spacing-md); + border: 2px solid var(--border-color); + background: var(--background-white); + color: var(--text-secondary); + border-radius: var(--border-radius); + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: var(--spacing-xs); + font-size: 0.9rem; + font-weight: 500; +} + +.filter-btn:hover { + border-color: var(--primary-color); + color: var(--primary-color); +} + +.filter-btn.active { + background: var(--primary-color); + color: white; + border-color: var(--primary-color); +} + +.search-container { + position: relative; +} + +#searchInput { + padding: var(--spacing-sm) var(--spacing-md); + padding-right: 2.5rem; + border: 2px solid var(--border-color); + border-radius: var(--border-radius); + width: 250px; +} + +.search-icon { + position: absolute; + right: var(--spacing-md); + top: 50%; + transform: translateY(-50%); + color: var(--text-muted); +} + +/* Tasks Section */ +.tasks-section { + flex: 1; +} + +.tasks-container { + display: flex; + flex-direction: column; + gap: var(--spacing-md); +} + +/* Task Item */ +.task-item { + background: var(--background-white); + border-radius: var(--border-radius-lg); + padding: var(--spacing-lg); + box-shadow: var(--shadow-light); + border-left: 4px solid var(--border-color); + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.task-item:hover { + box-shadow: var(--shadow-medium); + transform: translateY(-1px); +} + +.task-item.completed { + opacity: 0.7; + border-left-color: var(--success-color); +} + +.task-item.alta { + border-left-color: var(--danger-color); +} + +.task-item.media { + border-left-color: var(--warning-color); +} + +.task-item.baixa { + border-left-color: var(--info-color); +} + +.task-checkbox { + width: 20px; + height: 20px; + cursor: pointer; +} + +.task-content { + flex: 1; + display: flex; + flex-direction: column; + gap: var(--spacing-xs); +} + +.task-title { + font-size: 1.1rem; + font-weight: 600; + color: var(--text-primary); +} + +.task-title.completed { + text-decoration: line-through; + color: var(--text-muted); +} + +.task-meta { + display: flex; + align-items: center; + gap: var(--spacing-md); + font-size: 0.85rem; + color: var(--text-secondary); +} + +.task-priority { + padding: 2px 8px; + border-radius: 12px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; +} + +.task-priority.alta { + background: rgba(245, 101, 101, 0.1); + color: var(--danger-color); +} + +.task-priority.media { + background: rgba(237, 137, 54, 0.1); + color: var(--warning-color); +} + +.task-priority.baixa { + background: rgba(66, 153, 225, 0.1); + color: var(--info-color); +} + +.task-category { + padding: 2px 8px; + background: rgba(102, 126, 234, 0.1); + color: var(--primary-color); + border-radius: 12px; + font-size: 0.75rem; + font-weight: 500; +} + +.task-deadline { + color: var(--warning-color); +} + +.task-deadline.overdue { + color: var(--danger-color); + font-weight: 600; +} + +.task-actions { + display: flex; + gap: var(--spacing-sm); +} + +.task-btn { + padding: var(--spacing-sm); + border: none; + border-radius: var(--border-radius); + cursor: pointer; + transition: all 0.3s ease; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; +} + +.task-btn.edit { + background: rgba(66, 153, 225, 0.1); + color: var(--info-color); +} + +.task-btn.delete { + background: rgba(245, 101, 101, 0.1); + color: var(--danger-color); +} + +.task-btn:hover { + transform: scale(1.1); +} + +/* Empty State */ +.empty-state { + text-align: center; + padding: var(--spacing-xl); + color: var(--text-muted); +} + +.empty-state i { + font-size: 4rem; + margin-bottom: var(--spacing-md); + color: var(--border-color); +} + +.empty-state h3 { + font-size: 1.5rem; + margin-bottom: var(--spacing-sm); + color: var(--text-secondary); +} + +/* Modal */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); +} + +.modal.active { + display: flex; + align-items: center; + justify-content: center; +} + +.modal-content { + background: var(--background-white); + padding: var(--spacing-xl); + border-radius: var(--border-radius-lg); + box-shadow: var(--shadow-heavy); + max-width: 400px; + width: 90%; + text-align: center; +} + +.modal-content h3 { + margin-bottom: var(--spacing-md); + color: var(--text-primary); +} + +.modal-content p { + margin-bottom: var(--spacing-lg); + color: var(--text-secondary); +} + +.modal-actions { + display: flex; + gap: var(--spacing-md); + justify-content: center; +} + +/* Footer */ +.footer { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + padding: var(--spacing-lg); + text-align: center; + border-top: 1px solid var(--border-color); + color: var(--text-secondary); +} + +.footer a { + color: var(--primary-color); + text-decoration: none; + margin-left: var(--spacing-xs); +} + +.footer a:hover { + color: var(--primary-dark); +} + +/* Responsive Design */ +@media (max-width: 768px) { + .header-content { + flex-direction: column; + text-align: center; + } + + .input-group { + flex-direction: column; + } + + .input-extra { + flex-direction: column; + } + + .filters-section { + flex-direction: column; + } + + .filters { + justify-content: center; + } + + #searchInput { + width: 100%; + } + + .task-item { + flex-direction: column; + align-items: flex-start; + } + + .task-meta { + flex-wrap: wrap; + } + + .modal-content { + margin: var(--spacing-md); + } +} + +@media (max-width: 480px) { + .main-content { + padding: var(--spacing-md); + } + + .task-input-section { + padding: var(--spacing-md); + } + + .modal-actions { + flex-direction: column; + } +} + +/* Animações */ +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.task-item { + animation: slideIn 0.3s ease-out; +} + +/* Scrollbar personalizada */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: var(--background-light); +} + +::-webkit-scrollbar-thumb { + background: var(--border-color); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--text-muted); +} \ No newline at end of file From 3c0591685ecbee60c445fdce00292be4fc3a4203 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 26 Aug 2025 18:45:01 +0100 Subject: [PATCH 9/9] fix and improve multiply and count-by-steps --- Multiply/index.html | 2 +- Multiply/scrip.js | 23 -- Multiply/script.js | 33 +++ TaskFlow/index.html | 135 --------- TaskFlow/script.js | 569 ------------------------------------ TaskFlow/styles.css | 594 -------------------------------------- count-by-steps/index.html | 2 +- count-by-steps/scrip.js | 56 ---- count-by-steps/script.js | 50 ++++ 9 files changed, 85 insertions(+), 1379 deletions(-) delete mode 100644 Multiply/scrip.js create mode 100644 Multiply/script.js delete mode 100644 TaskFlow/index.html delete mode 100644 TaskFlow/script.js delete mode 100644 TaskFlow/styles.css delete mode 100644 count-by-steps/scrip.js create mode 100644 count-by-steps/script.js diff --git a/Multiply/index.html b/Multiply/index.html index 702e9e9..a5603c1 100644 --- a/Multiply/index.html +++ b/Multiply/index.html @@ -33,6 +33,6 @@

Multiplication

victorRbcx

- + \ No newline at end of file diff --git a/Multiply/scrip.js b/Multiply/scrip.js deleted file mode 100644 index 3c08643..0000000 --- a/Multiply/scrip.js +++ /dev/null @@ -1,23 +0,0 @@ -function calcular() { -var txtn = window.document.getElementById('txtnum') -var n = Number(txtn.value) -var lista = document.getElementById('listaNumeros') -lista.innerHTML = '' - - if ( txtn.value.length == 0 || isNaN(n)) { - window.alert('Enter a number to Multiply!') - var opcao = document.createElement('option') - opcao.text = 'Enter a number above' - lista.add(opcao); - } else { - - for(var i = 0; i <= 10; i++) { - var opcao = document.createElement('option') - var calc = n * i - opcao.value = `tab${i}` - opcao.text = `${n} x ${i} = ${calc}` - lista.add(opcao); - } - } - txtn.value = '' -} \ No newline at end of file diff --git a/Multiply/script.js b/Multiply/script.js new file mode 100644 index 0000000..862ec07 --- /dev/null +++ b/Multiply/script.js @@ -0,0 +1,33 @@ +function calcular() { + const txtn = document.getElementById('txtnum'); + const lista = document.getElementById('listaNumeros'); + const rawValue = txtn.value.trim(); + + lista.innerHTML = ''; + + if (rawValue === '' || Number.isNaN(Number(rawValue))) { + + window.alert('Enter a number to Multiply!'); + + const option = document.createElement('option'); + option.textContent = 'Enter a number above'; + option.disabled = true; + lista.appendChild(option); + + txtn.focus(); + return; + } + + const n = Number(rawValue); + + for (let i = 0; i <= 10; i += 1) { + const option = document.createElement('option'); + const calc = n * i; + option.value = `tab${i}`; + option.textContent = `${n} x ${i} = ${calc}`; + lista.appendChild(option); + } + + txtn.value = ''; + txtn.focus(); +} diff --git a/TaskFlow/index.html b/TaskFlow/index.html deleted file mode 100644 index 32d89de..0000000 --- a/TaskFlow/index.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - TaskFlow - Gerenciador de Tarefas - - - - -
- -
-
-

- - TaskFlow -

-
- - - Total: 0 - - - - Concluídas: 0 - -
-
-
- - -
- -
-
-
- - - -
-
- - -
-
-
- -
-
- - - - -
-
- - -
-
- -
-
-
- -
- -

Nenhuma tarefa encontrada

-

Adicione sua primeira tarefa para começar!

-
-
-
- -
-

© 2025 TaskFlow - VictorRBCX - - - -

-
-
- - - - - - - \ No newline at end of file diff --git a/TaskFlow/script.js b/TaskFlow/script.js deleted file mode 100644 index 18af92a..0000000 --- a/TaskFlow/script.js +++ /dev/null @@ -1,569 +0,0 @@ - -class TaskManager { - constructor() { - this.tasks = this.loadTasks(); - this.currentFilter = 'todas'; - this.searchTerm = ''; - this.editingTaskId = null; - - this.init(); - } - - init() { - this.bindEvents(); - this.renderTasks(); - this.updateStats(); - this.setTodayAsDefaultDate(); - } - - bindEvents() { - // Botão adicionar tarefa - const addBtn = document.getElementById('addTaskBtn'); - addBtn.addEventListener('click', () => this.handleAddTask()); - - // Enter no input de tarefa - const taskInput = document.getElementById('taskInput'); - taskInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - this.handleAddTask(); - } - }); - - // Filtros - const filterBtns = document.querySelectorAll('.filter-btn'); - filterBtns.forEach(btn => { - btn.addEventListener('click', (e) => { - this.setActiveFilter(e.target.dataset.filter); - }); - }); - - // Busca - const searchInput = document.getElementById('searchInput'); - searchInput.addEventListener('input', (e) => { - this.searchTerm = e.target.value.toLowerCase(); - this.renderTasks(); - }); - - // Modal - const cancelBtn = document.getElementById('cancelBtn'); - cancelBtn.addEventListener('click', () => this.hideModal()); - - // Fechar modal clicando fora - const modal = document.getElementById('confirmModal'); - modal.addEventListener('click', (e) => { - if (e.target === modal) { - this.hideModal(); - } - }); - } - - // Define a data de hoje como padrão no input de data - - setTodayAsDefaultDate() { - const today = new Date().toISOString().split('T')[0]; - document.getElementById('taskDeadline').value = today; - } - - // Manipula a adição/edição de tarefas - - handleAddTask() { - const taskInput = document.getElementById('taskInput'); - const prioritySelect = document.getElementById('prioritySelect'); - const categorySelect = document.getElementById('categorySelect'); - const deadlineInput = document.getElementById('taskDeadline'); - - const title = taskInput.value.trim(); - const priority = prioritySelect.value; - const category = categorySelect.value; - const deadline = deadlineInput.value; - - if (!title) { - this.showNotification('Por favor, digite o texto da tarefa!', 'error'); - taskInput.focus(); - return; - } - - if (this.editingTaskId) { - this.updateTask(this.editingTaskId, { title, priority, category, deadline }); - this.editingTaskId = null; - document.getElementById('addTaskBtn').innerHTML = ' Adicionar'; - } else { - this.addTask({ title, priority, category, deadline }); - } - - // Limpar formulário - taskInput.value = ''; - prioritySelect.value = 'media'; - categorySelect.value = 'pessoal'; - this.setTodayAsDefaultDate(); - - taskInput.focus(); - } - - // Adiciona uma nova tarefa - addTask(taskData) { - const task = { - id: this.generateId(), - title: taskData.title, - priority: taskData.priority, - category: taskData.category, - deadline: taskData.deadline || null, - completed: false, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() - }; - - this.tasks.push(task); - this.saveTasks(); - this.renderTasks(); - this.updateStats(); - - this.showNotification('Tarefa adicionada com sucesso!', 'success'); - } - - // Atualiza uma tarefa existente - updateTask(id, updates) { - const taskIndex = this.tasks.findIndex(task => task.id === id); - if (taskIndex !== -1) { - this.tasks[taskIndex] = { - ...this.tasks[taskIndex], - ...updates, - updatedAt: new Date().toISOString() - }; - - this.saveTasks(); - this.renderTasks(); - this.updateStats(); - - this.showNotification('Tarefa atualizada com sucesso!', 'success'); - } - } - - // Remove uma tarefa - deleteTask(id) { - const task = this.tasks.find(t => t.id === id); - if (!task) return; - - this.showConfirmModal( - `Tem certeza que deseja excluir a tarefa "${task.title}"?`, - () => { - this.tasks = this.tasks.filter(task => task.id !== id); - this.saveTasks(); - this.renderTasks(); - this.updateStats(); - this.showNotification('Tarefa excluída com sucesso!', 'success'); - } - ); - } - - // Alterna o status de conclusão de uma tarefa - toggleTask(id) { - const taskIndex = this.tasks.findIndex(task => task.id === id); - if (taskIndex !== -1) { - this.tasks[taskIndex].completed = !this.tasks[taskIndex].completed; - this.tasks[taskIndex].updatedAt = new Date().toISOString(); - - this.saveTasks(); - this.renderTasks(); - this.updateStats(); - - const status = this.tasks[taskIndex].completed ? 'concluída' : 'reativada'; - this.showNotification(`Tarefa ${status}!`, 'info'); - } - } - - // Inicia a edição de uma tarefa - editTask(id) { - const task = this.tasks.find(t => t.id === id); - if (!task) return; - - this.editingTaskId = id; - - // Preencher formulário - document.getElementById('taskInput').value = task.title; - document.getElementById('prioritySelect').value = task.priority; - document.getElementById('categorySelect').value = task.category; - document.getElementById('taskDeadline').value = task.deadline || ''; - - // Alterar botão - document.getElementById('addTaskBtn').innerHTML = ' Salvar'; - - // Focar no input - document.getElementById('taskInput').focus(); - document.getElementById('taskInput').scrollIntoView({ behavior: 'smooth' }); - } - - // Define o filtro ativo - setActiveFilter(filter) { - this.currentFilter = filter; - - // Atualizar botões - document.querySelectorAll('.filter-btn').forEach(btn => { - btn.classList.remove('active'); - }); - document.querySelector(`[data-filter="${filter}"]`).classList.add('active'); - - this.renderTasks(); - } - - // Filtra as tarefas baseado no filtro atual e termo de busca - getFilteredTasks() { - let filtered = [...this.tasks]; - - // Aplicar filtro - switch (this.currentFilter) { - case 'pendentes': - filtered = filtered.filter(task => !task.completed); - break; - case 'concluidas': - filtered = filtered.filter(task => task.completed); - break; - case 'alta': - filtered = filtered.filter(task => task.priority === 'alta'); - break; - } - - // Aplicar busca - if (this.searchTerm) { - filtered = filtered.filter(task => - task.title.toLowerCase().includes(this.searchTerm) || - task.category.toLowerCase().includes(this.searchTerm) - ); - } - - // Ordenar: não concluídas primeiro, depois por prioridade - return filtered.sort((a, b) => { - if (a.completed !== b.completed) { - return a.completed - b.completed; - } - - const priorityOrder = { 'alta': 0, 'media': 1, 'baixa': 2 }; - return priorityOrder[a.priority] - priorityOrder[b.priority]; - }); - } - - // Renderiza a lista de tarefas - renderTasks() { - const container = document.getElementById('tasksContainer'); - const emptyState = document.getElementById('emptyState'); - const filteredTasks = this.getFilteredTasks(); - - if (filteredTasks.length === 0) { - container.style.display = 'none'; - emptyState.style.display = 'block'; - return; - } - - container.style.display = 'block'; - emptyState.style.display = 'none'; - - container.innerHTML = filteredTasks.map(task => this.createTaskHTML(task)).join(''); - - // Vincular eventos dos botões - this.bindTaskEvents(); - } - - // Cria o HTML para uma tarefa - createTaskHTML(task) { - const deadlineInfo = this.getDeadlineInfo(task.deadline); - const categoryLabel = this.getCategoryLabel(task.category); - - return ` -
- - -
-
${this.escapeHtml(task.title)}
-
- ${task.priority} - ${categoryLabel} - ${deadlineInfo.html} - - - ${this.formatDate(task.createdAt)} - -
-
- -
- - -
-
- `; - } - - // Vincula eventos dos botões das tarefas - bindTaskEvents() { - document.querySelectorAll('.task-checkbox').forEach(checkbox => { - checkbox.addEventListener('change', (e) => { - const taskId = Number(e.target.closest('.task-item').dataset.taskId); - this.toggleTask(taskId); - }); - }); - - document.querySelectorAll('.task-btn.edit').forEach(btn => { - btn.addEventListener('click', () => { - const taskId = Number(btn.closest('.task-item').dataset.taskId); - this.editTask(taskId); - }); - }); - - document.querySelectorAll('.task-btn.delete').forEach(btn => { - btn.addEventListener('click', () => { - const taskId = Number(btn.closest('.task-item').dataset.taskId); - this.deleteTask(taskId); - }); - }); -} - - // Obtém informações sobre o prazo da tarefa - getDeadlineInfo(deadline) { - if (!deadline) { - return { html: '', isOverdue: false }; - } - - const deadlineDate = new Date(deadline); - const today = new Date(); - const diffTime = deadlineDate - today; - const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); - - let className = 'task-deadline'; - let icon = 'fas fa-clock'; - let text = this.formatDate(deadline, true); - - if (diffDays < 0) { - className += ' overdue'; - icon = 'fas fa-exclamation-triangle'; - text += ` (${Math.abs(diffDays)} dias atrasado)`; - } else if (diffDays === 0) { - className += ' today'; - icon = 'fas fa-exclamation'; - text += ' (hoje)'; - } else if (diffDays === 1) { - text += ' (amanhã)'; - } - - return { - html: ` ${text}`, - isOverdue: diffDays < 0 - }; - } - - // Obtém o rótulo da categoria - getCategoryLabel(category) { - const labels = { - 'pessoal': 'Pessoal', - 'trabalho': 'Trabalho', - 'estudos': 'Estudos', - 'saude': 'Saúde', - 'outros': 'Outros' - }; - return labels[category] || category; - } - - // Atualiza as estatísticas no cabeçalho - updateStats() { - const totalTasks = this.tasks.length; - const completedTasks = this.tasks.filter(task => task.completed).length; - - document.getElementById('totalTasks').textContent = totalTasks; - document.getElementById('completedTasks').textContent = completedTasks; - } - - // Mostra o modal de confirmação - showConfirmModal(message, onConfirm) { - const modal = document.getElementById('confirmModal'); - const messageEl = document.getElementById('confirmMessage'); - const confirmBtn = document.getElementById('confirmBtn'); - - messageEl.textContent = message; - modal.classList.add('active'); - - // Remover listados anteriores - const newConfirmBtn = confirmBtn.cloneNode(true); - confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn); - - // Adicionar nova lista - newConfirmBtn.addEventListener('click', () => { - onConfirm(); - this.hideModal(); - }); - } - - // Esconde o modal - hideModal() { - document.getElementById('confirmModal').classList.remove('active'); - } - - // Mostra notificação (implementação simples) - showNotification(message, type = 'info') { - // Por simplicidade, usando alert. Em produção, implementaria um sistema de toast - console.log(`[${type.toUpperCase()}] ${message}`); - - // Você pode implementar um sistema de toast mais sofisticado aqui - const originalTitle = document.title; - document.title = `${message} - TaskFlow`; - setTimeout(() => { - document.title = originalTitle; - }, 3000); - } - - // Gera um ID único para as tarefas - generateId() { - return Date.now() + Math.random(); - } - - // Formata uma data para exibição - formatDate(dateString, dateOnly = false) { - const date = new Date(dateString); - const options = dateOnly - ? { day: '2-digit', month: '2-digit', year: 'numeric' } - : { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit' }; - - return date.toLocaleDateString('pt-BR', options); - } - - // Escapa HTML para prevenir XSS - escapeHtml(unsafe) { - return unsafe - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); - } - - // Carrega tarefas do localStorage - loadTasks() { - try { - const tasksJson = localStorage.getItem('taskflow_tasks'); - return tasksJson ? JSON.parse(tasksJson) : []; - } catch (error) { - console.error('Erro ao carregar tarefas:', error); - return []; - } - } - - // Salva tarefas no localStorage - saveTasks() { - try { - localStorage.setItem('taskflow_tasks', JSON.stringify(this.tasks)); - } catch (error) { - console.error('Erro ao salvar tarefas:', error); - } - } - - // Exporta tarefas como JSON - exportTasks() { - const data = { - tasks: this.tasks, - exportDate: new Date().toISOString(), - version: '1.0.0' - }; - - const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); - const url = URL.createObjectURL(blob); - - const a = document.createElement('a'); - a.href = url; - a.download = `taskflow_backup_${new Date().toISOString().split('T')[0]}.json`; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - - URL.revokeObjectURL(url); - - this.showNotification('Tarefas exportadas com sucesso!', 'success'); - } - - // Limpa todas as tarefas concluídas - clearCompleted() { - const completedCount = this.tasks.filter(task => task.completed).length; - - if (completedCount === 0) { - this.showNotification('Não há tarefas concluídas para limpar.', 'info'); - return; - } - - this.showConfirmModal( - `Tem certeza que deseja excluir ${completedCount} tarefa(s) concluída(s)?`, - () => { - this.tasks = this.tasks.filter(task => !task.completed); - this.saveTasks(); - this.renderTasks(); - this.updateStats(); - this.showNotification('Tarefas concluídas removidas!', 'success'); - } - ); - } -} - -// O que falta : - -/** - * TODO: - * - * 1. Sistema de tags/etiquetas para tarefas - * 2. Drag & drop para reordenar tarefas - * 3. Subtarefas/checklist dentro de tarefas - * 4. Modo escuro/claro - * 5. Sincronização com APIs externas - * 6. Notificações push - * 7. Sistema de templates de tarefas - * 8. Relatórios e estatísticas avançadas - * 9. Filtros por data - * 10. Anexos em tarefas - * 11. Comentários em tarefas - * 12. Sistema de colaboração/compartilhamento - * 13. Integração com calendário - * 14. Backup automático - * 15. Atalhos de teclado - * 16. Widgets de produtividade - * 17. Integração com Pomodoro Timer - * 18. Gamificação (pontos, conquistas) - * 19. Temas personalizáveis - * 20. PWA (Progressive Web App) features - */ - -// Inicializar aplicação -document.addEventListener('DOMContentLoaded', () => { - window.taskManager = new TaskManager(); - - console.log('🚀 TaskFlow inicializado com sucesso!'); - console.log('💡 Este é um projeto open source. Contribua no GitHub!'); - console.log('🎯 Visite: https://github.com/your-repo/taskflow'); -}); - -// Atalhos de teclado -document.addEventListener('keydown', (e) => { - // Ctrl/Cmd + Enter para adicionar tarefa rapidamente - if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { - e.preventDefault(); - if (window.taskManager) { - window.taskManager.handleAddTask(); - } - } - - // Esc para cancelar edição - if (e.key === 'Escape') { - if (window.taskManager && window.taskManager.editingTaskId) { - window.taskManager.editingTaskId = null; - document.getElementById('addTaskBtn').innerHTML = ' Adicionar'; - document.getElementById('taskInput').value = ''; - } - } -}); - -// Prevenir perda de dados ao fechar a página -window.addEventListener('beforeunload', (e) => { - const taskInput = document.getElementById('taskInput'); - if (taskInput && taskInput.value.trim()) { - e.preventDefault(); - e.returnValue = 'Você tem uma tarefa não salva. Deseja realmente sair?'; - } -}); \ No newline at end of file diff --git a/TaskFlow/styles.css b/TaskFlow/styles.css deleted file mode 100644 index 651eac4..0000000 --- a/TaskFlow/styles.css +++ /dev/null @@ -1,594 +0,0 @@ - -/* Reset e Configurações Base */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -:root { - /* Cores Principais */ - --primary-color: #667eea; - --primary-dark: #5a67d8; - --secondary-color: #764ba2; - --accent-color: #f093fb; - - /* Cores de Status */ - --success-color: #48bb78; - --warning-color: #ed8936; - --danger-color: #f56565; - --info-color: #4299e1; - - /* Cores Neutras */ - --text-primary: #2d3748; - --text-secondary: #718096; - --text-muted: #a0aec0; - --background-light: #f7fafc; - --background-white: #ffffff; - --border-color: #e2e8f0; - --shadow-light: 0 1px 3px 0 rgba(0, 0, 0, 0.1); - --shadow-medium: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - --shadow-heavy: 0 10px 15px -3px rgba(0, 0, 0, 0.1); - - /* Tamanhos */ - --border-radius: 8px; - --border-radius-lg: 12px; - --spacing-xs: 0.25rem; - --spacing-sm: 0.5rem; - --spacing-md: 1rem; - --spacing-lg: 1.5rem; - --spacing-xl: 2rem; -} - -body { - font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%); - min-height: 100vh; - color: var(--text-primary); - line-height: 1.6; -} - -.app-container { - max-width: 1200px; - margin: 0 auto; - min-height: 100vh; - display: flex; - flex-direction: column; -} - -/* Header Styles */ -.header { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - border-bottom: 1px solid var(--border-color); - padding: var(--spacing-lg) var(--spacing-md); - position: sticky; - top: 0; - z-index: 100; - box-shadow: var(--shadow-light); -} - -.header-content { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: var(--spacing-md); -} - -.app-title { - font-size: 1.8rem; - font-weight: 700; - color: var(--primary-color); - display: flex; - align-items: center; - gap: var(--spacing-sm); -} - -.app-title i { - font-size: 1.6rem; -} - -.header-stats { - display: flex; - gap: var(--spacing-lg); -} - -.stat { - display: flex; - align-items: center; - gap: var(--spacing-xs); - color: var(--text-secondary); - font-weight: 500; -} - -.stat i { - color: var(--primary-color); -} - -/* Main Content */ -.main-content { - flex: 1; - padding: var(--spacing-xl) var(--spacing-md); - display: flex; - flex-direction: column; - gap: var(--spacing-xl); -} - -/* Task Input Section */ -.task-input-section { - background: var(--background-white); - border-radius: var(--border-radius-lg); - padding: var(--spacing-xl); - box-shadow: var(--shadow-medium); - border: 1px solid var(--border-color); -} - -.input-container { - display: flex; - flex-direction: column; - gap: var(--spacing-md); -} - -.input-group { - display: flex; - gap: var(--spacing-md); - flex-wrap: wrap; -} - -.input-extra { - display: flex; - gap: var(--spacing-md); - flex-wrap: wrap; -} - -input[type="text"], input[type="date"], select { - padding: var(--spacing-md); - border: 2px solid var(--border-color); - border-radius: var(--border-radius); - font-size: 1rem; - transition: all 0.3s ease; - outline: none; -} - -input[type="text"]:focus, input[type="date"]:focus, select:focus { - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); -} - -#taskInput { - flex: 1; - min-width: 300px; -} - -#prioritySelect, #categorySelect { - min-width: 150px; -} - -/* Buttons */ -.btn-primary, .btn-secondary, .btn-danger { - padding: var(--spacing-md) var(--spacing-lg); - border: none; - border-radius: var(--border-radius); - font-size: 1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - display: inline-flex; - align-items: center; - gap: var(--spacing-sm); - text-decoration: none; -} - -.btn-primary { - background: linear-gradient(135deg, var(--primary-color), var(--primary-dark)); - color: white; -} - -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-heavy); -} - -.btn-secondary { - background: var(--text-muted); - color: white; -} - -.btn-danger { - background: var(--danger-color); - color: white; -} - -.btn-danger:hover { - background: #e53e3e; -} - -/* Filters Section */ -.filters-section { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: var(--spacing-md); - background: var(--background-white); - padding: var(--spacing-lg); - border-radius: var(--border-radius-lg); - box-shadow: var(--shadow-light); -} - -.filters { - display: flex; - gap: var(--spacing-sm); - flex-wrap: wrap; -} - -.filter-btn { - padding: var(--spacing-sm) var(--spacing-md); - border: 2px solid var(--border-color); - background: var(--background-white); - color: var(--text-secondary); - border-radius: var(--border-radius); - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: var(--spacing-xs); - font-size: 0.9rem; - font-weight: 500; -} - -.filter-btn:hover { - border-color: var(--primary-color); - color: var(--primary-color); -} - -.filter-btn.active { - background: var(--primary-color); - color: white; - border-color: var(--primary-color); -} - -.search-container { - position: relative; -} - -#searchInput { - padding: var(--spacing-sm) var(--spacing-md); - padding-right: 2.5rem; - border: 2px solid var(--border-color); - border-radius: var(--border-radius); - width: 250px; -} - -.search-icon { - position: absolute; - right: var(--spacing-md); - top: 50%; - transform: translateY(-50%); - color: var(--text-muted); -} - -/* Tasks Section */ -.tasks-section { - flex: 1; -} - -.tasks-container { - display: flex; - flex-direction: column; - gap: var(--spacing-md); -} - -/* Task Item */ -.task-item { - background: var(--background-white); - border-radius: var(--border-radius-lg); - padding: var(--spacing-lg); - box-shadow: var(--shadow-light); - border-left: 4px solid var(--border-color); - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: var(--spacing-md); -} - -.task-item:hover { - box-shadow: var(--shadow-medium); - transform: translateY(-1px); -} - -.task-item.completed { - opacity: 0.7; - border-left-color: var(--success-color); -} - -.task-item.alta { - border-left-color: var(--danger-color); -} - -.task-item.media { - border-left-color: var(--warning-color); -} - -.task-item.baixa { - border-left-color: var(--info-color); -} - -.task-checkbox { - width: 20px; - height: 20px; - cursor: pointer; -} - -.task-content { - flex: 1; - display: flex; - flex-direction: column; - gap: var(--spacing-xs); -} - -.task-title { - font-size: 1.1rem; - font-weight: 600; - color: var(--text-primary); -} - -.task-title.completed { - text-decoration: line-through; - color: var(--text-muted); -} - -.task-meta { - display: flex; - align-items: center; - gap: var(--spacing-md); - font-size: 0.85rem; - color: var(--text-secondary); -} - -.task-priority { - padding: 2px 8px; - border-radius: 12px; - font-size: 0.75rem; - font-weight: 600; - text-transform: uppercase; -} - -.task-priority.alta { - background: rgba(245, 101, 101, 0.1); - color: var(--danger-color); -} - -.task-priority.media { - background: rgba(237, 137, 54, 0.1); - color: var(--warning-color); -} - -.task-priority.baixa { - background: rgba(66, 153, 225, 0.1); - color: var(--info-color); -} - -.task-category { - padding: 2px 8px; - background: rgba(102, 126, 234, 0.1); - color: var(--primary-color); - border-radius: 12px; - font-size: 0.75rem; - font-weight: 500; -} - -.task-deadline { - color: var(--warning-color); -} - -.task-deadline.overdue { - color: var(--danger-color); - font-weight: 600; -} - -.task-actions { - display: flex; - gap: var(--spacing-sm); -} - -.task-btn { - padding: var(--spacing-sm); - border: none; - border-radius: var(--border-radius); - cursor: pointer; - transition: all 0.3s ease; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; -} - -.task-btn.edit { - background: rgba(66, 153, 225, 0.1); - color: var(--info-color); -} - -.task-btn.delete { - background: rgba(245, 101, 101, 0.1); - color: var(--danger-color); -} - -.task-btn:hover { - transform: scale(1.1); -} - -/* Empty State */ -.empty-state { - text-align: center; - padding: var(--spacing-xl); - color: var(--text-muted); -} - -.empty-state i { - font-size: 4rem; - margin-bottom: var(--spacing-md); - color: var(--border-color); -} - -.empty-state h3 { - font-size: 1.5rem; - margin-bottom: var(--spacing-sm); - color: var(--text-secondary); -} - -/* Modal */ -.modal { - display: none; - position: fixed; - z-index: 1000; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(5px); -} - -.modal.active { - display: flex; - align-items: center; - justify-content: center; -} - -.modal-content { - background: var(--background-white); - padding: var(--spacing-xl); - border-radius: var(--border-radius-lg); - box-shadow: var(--shadow-heavy); - max-width: 400px; - width: 90%; - text-align: center; -} - -.modal-content h3 { - margin-bottom: var(--spacing-md); - color: var(--text-primary); -} - -.modal-content p { - margin-bottom: var(--spacing-lg); - color: var(--text-secondary); -} - -.modal-actions { - display: flex; - gap: var(--spacing-md); - justify-content: center; -} - -/* Footer */ -.footer { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - padding: var(--spacing-lg); - text-align: center; - border-top: 1px solid var(--border-color); - color: var(--text-secondary); -} - -.footer a { - color: var(--primary-color); - text-decoration: none; - margin-left: var(--spacing-xs); -} - -.footer a:hover { - color: var(--primary-dark); -} - -/* Responsive Design */ -@media (max-width: 768px) { - .header-content { - flex-direction: column; - text-align: center; - } - - .input-group { - flex-direction: column; - } - - .input-extra { - flex-direction: column; - } - - .filters-section { - flex-direction: column; - } - - .filters { - justify-content: center; - } - - #searchInput { - width: 100%; - } - - .task-item { - flex-direction: column; - align-items: flex-start; - } - - .task-meta { - flex-wrap: wrap; - } - - .modal-content { - margin: var(--spacing-md); - } -} - -@media (max-width: 480px) { - .main-content { - padding: var(--spacing-md); - } - - .task-input-section { - padding: var(--spacing-md); - } - - .modal-actions { - flex-direction: column; - } -} - -/* Animações */ -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.task-item { - animation: slideIn 0.3s ease-out; -} - -/* Scrollbar personalizada */ -::-webkit-scrollbar { - width: 8px; -} - -::-webkit-scrollbar-track { - background: var(--background-light); -} - -::-webkit-scrollbar-thumb { - background: var(--border-color); - border-radius: 4px; -} - -::-webkit-scrollbar-thumb:hover { - background: var(--text-muted); -} \ No newline at end of file diff --git a/count-by-steps/index.html b/count-by-steps/index.html index 3488df3..c4dc6de 100644 --- a/count-by-steps/index.html +++ b/count-by-steps/index.html @@ -30,6 +30,6 @@

Let's count

victorRbcx

- + \ No newline at end of file diff --git a/count-by-steps/scrip.js b/count-by-steps/scrip.js deleted file mode 100644 index bffab8b..0000000 --- a/count-by-steps/scrip.js +++ /dev/null @@ -1,56 +0,0 @@ -function count() { - var ini = window.document.getElementById('txtinicio') - var fim = window.document.getElementById('txtfim') - var passo = window.document.getElementById('txtpasso') - var res = document.querySelector('p#conta') - - var i = Number(ini.value) - var f = Number(fim.value) - var p = Number(passo.value) - - - if(ini.value.length == 0 || fim.value.length == 0 || passo.value.length == 0) { - window.alert('Fill in the start, end and step fields correctly') - res.innerHTML = 'Impossible to count' - } else if (p == 0 || p < 0) { - window.alert('Incorrect step, the program will assume the value 1') - res.innerHTML = `Counting:
` - p = 1 - - if (i < f) { - // Upward count with incorrect step - while (i <= f) { - res.innerHTML += `\u{1F449} ${i}` - i += p - } - res.innerHTML += `\u{1F449}` - res.innerHTML += '\u{1F3C1}' - } else { - // Countdown with incorrect step - while (i >= f) { - res.innerHTML += `\u{1F449} ${i}` - i -= p - } - res.innerHTML += `\u{1F449}` - res.innerHTML += '\u{1F3C1}' - } - - } else if (i < f) { - // Count up - res.innerHTML = `Counting:
` - while (i <= f) { - res.innerHTML += `\u{1F449} ${i}` - i += p - } - res.innerHTML += `\u{1F449} ` - res.innerHTML += '\u{1F3C1}' - } else { - // Countdown - res.innerHTML = `Counting:
` - while (i >= f) { - res.innerHTML += `\u{1F449} ${i}` - i -= p - } - } - -} \ No newline at end of file diff --git a/count-by-steps/script.js b/count-by-steps/script.js new file mode 100644 index 0000000..362345c --- /dev/null +++ b/count-by-steps/script.js @@ -0,0 +1,50 @@ +function count() { + const ini = document.getElementById('txtinicio'); + const fim = document.getElementById('txtfim'); + const passo = document.getElementById('txtpasso'); + const res = document.querySelector('p#conta'); + + let i = Number(ini.value); + let f = Number(fim.value); + let p = Number(passo.value); + + if (ini.value.length === 0 || fim.value.length === 0 || passo.value.length === 0) { + window.alert('Fill in the start, end and step fields correctly'); + res.innerHTML = 'Impossible to count'; + } else if (p <= 0) { + window.alert('Incorrect step, the program will assume the value 1'); + res.innerHTML = 'Counting:
'; + p = 1; + + if (i < f) { + // Upward count with incorrect step + while (i <= f) { + res.innerHTML += `\u{1F449} ${i}`; + i += p; + } + } else { + // Countdown with incorrect step + while (i >= f) { + res.innerHTML += `\u{1F449} ${i}`; + i -= p; + } + } + res.innerHTML += '\u{1F449} \u{1F3C1}'; + } else if (i < f) { + // Count up + res.innerHTML = 'Counting:
'; + while (i <= f) { + res.innerHTML += `\u{1F449} ${i}`; + i += p; + } + res.innerHTML += '\u{1F449} \u{1F3C1}'; + } else { + // Countdown + res.innerHTML = 'Counting:
'; + while (i >= f) { + res.innerHTML += `\u{1F449} ${i}`; + i -= p; + } + res.innerHTML += '\u{1F449} \u{1F3C1}'; + } +}