Estilos Gerais:
Botões e Entradas:
Filtragem e Ordenação:
Bloco e Projeto:
Calendário:
Tarefas Completas e Relatórios:
Tabela
Tabela
Linhas de Checklist
<tr>
<td><input type="checkbox" class="checklist"> Por que da tarefa?</td>
<td><input type="checkbox" class="checklist"> Traz dinheiro?</td>
<td><input type="checkbox" class="checklist"> Tipo de custo</td>
<td><input type="checkbox" class="checklist"> Gera reels?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Onde será a tarefa?</td>
<td><input type="checkbox" class="checklist"> Valor</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de custo</td>
<td><input type="checkbox" class="checklist"> Aula no YouTube?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Como será feita essa tarefa?</td>
<td><input type="checkbox" class="checklist"> 0%</td>
<td><input type="checkbox" class="checklist"> Tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Gera encontro?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Recorrente?</td>
<td><input type="checkbox" class="checklist"> Nome do cargo</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Passível de negociação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Hábito?</td>
<td><input type="checkbox" class="checklist"> Departamento</td>
<td><input type="checkbox" class="checklist"> Tipo de receita</td>
<td><input type="checkbox" class="checklist"> Passível de acordo?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Pago?</td>
<td><input type="checkbox" class="checklist"> Fornecedor?</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de receita</td>
<td><input type="checkbox" class="checklist"> Compra feita?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Leva ao objetivo?</td>
<td><input type="checkbox" class="checklist"> Nome da empresa</td>
<td><input type="checkbox" class="checklist"> Resultado</td>
<td><input type="checkbox" class="checklist"> Compra do cliente?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É uma decisão?</td>
<td><input type="checkbox" class="checklist"> Status</td>
<td><input type="checkbox" class="checklist"> Detalhe do resultado</td>
<td><input type="checkbox" class="checklist"> Compra a fazer?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem um guardião?</td>
<td><input type="checkbox" class="checklist"> Filial?</td>
<td><input type="checkbox" class="checklist"> Gera storie?</td>
<td><input type="checkbox" class="checklist"> Método de pagamento</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de dor</td>
<td><input type="checkbox" class="checklist"> Compromisso?</td>
<td><input type="checkbox" class="checklist"> Post para blog?</td>
<td><input type="checkbox" class="checklist"> É dívida?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de humor</td>
<td><input type="checkbox" class="checklist"> Know-how?</td>
<td><input type="checkbox" class="checklist"> Post para grupo?</td>
<td><input type="checkbox" class="checklist"> Antecipação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É um sacrifício?</td>
<td><input type="checkbox" class="checklist"> Necessita de parceiro?</td>
<td><input type="checkbox" class="checklist"> Conteúdo para feed?</td>
<td><input type="checkbox" class="checklist"> Alta margem?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Ferramenta que facilita</td>
<td><input type="checkbox" class="checklist"> Delegável?</td>
<td><input type="checkbox" class="checklist"> Alto desconto?</td>
<td><input type="checkbox" class="checklist"> Agrega ao inventário?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem sinergia?</td>
<td><input type="checkbox" class="checklist"> Automatizável?</td>
<td><input type="checkbox" class="checklist"> Orçamento?</td>
<td><input type="checkbox" class="checklist"> Agrega à marca?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
<td><input type="checkbox" class="checklist"> Recebimento de dinheiro?</td>
<td><input type="checkbox" class="checklist"> Redução de custo?</td>
<td><input type="checkbox" class="checklist"> Tempo de qualidade?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Plano de contingência?</td>
<td><input type="checkbox" class="checklist"> Despesa?</td>
<td><input type="checkbox" class="checklist"> Quebra se mãe doente?</td>
<td><input type="checkbox" class="checklist"> Status da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Validada?</td>
<td><input type="checkbox" class="checklist"> Previsão de recebimento?</td>
<td><input type="checkbox" class="checklist"> Quebra se doente?</td>
<td><input type="checkbox" class="checklist"> Dificuldade da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Relevante?</td>
<td><input type="checkbox" class="checklist"> Previsão de saída?</td>
<td><input type="checkbox" class="checklist"> Quebra se Covid?</td>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Gera brigas?</td>
<td><input type="checkbox" class="checklist"> Coerência empreendedora</td>
<td><input type="checkbox" class="checklist"> Perfil</td>
<td><input type="checkbox" class="checklist"> Feito por</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Melhor ambiente</td>
<td><input type="checkbox" class="checklist"> É um marco?</td>
<td><input type="checkbox" class="checklist"> Nível da atividade</td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Atividade de risco?</td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Tem redundância?</td>
<td></td>
<td></td>
</tr>
</table>
</center>
<br>
<br>
<b>
<subtitle> >>> Adicione as suas tarefas aqui!!!</subtitle>
<br>
<br>
Adição de tarefas
<div class="add-task-container">
<input type="text" id="newTask" class="add-task-input" placeholder="Digite uma nova tarefa" onkeydown="handleKeyPress(event)">
<input type="text" id="newTag" class="add-tag-input" placeholder="Digite uma tag">
<input type="number" id="newNumber" class="add-number-input" placeholder="Número" min="1">
<input type="text" id="newPerson" class="add-person-input" placeholder="Atribuir a">
<input type="date" id="newDate" class="add-date-input" placeholder="Data de realização">
<input type="date" id="newEndDate" class="add-end-date-input" placeholder="Data de término">
<input type="time" id="newTime" class="add-time-input" placeholder="Horário">
<input type="number" id="newAmount" class="add-amount-input" placeholder="Quanto" step="0.01">
<input type="text" id="newReason" class="add-reason-input" placeholder="Por que da tarefa?">
<input type="text" id="newLocation" class="add-location-input" placeholder="Onde será a tarefa?">
<input type="text" id="newMethod" class="add-method-input" placeholder="Como será feita essa tarefa?">
<button onclick="addTask()" class="add-task-button">Adicionar Tarefa</button>
<button onclick="addCustomField()" class="add-task-button">Adicionar Campo Personalizado</button>
</div>
Filtragem e ordenação de tarefas
<div class="filter-container">
<input type="text" id="wordFilter" placeholder="Digite uma palavra para filtrar" oninput="filterTasksByWord()">
<button onclick="filterTasksByWord()">Filtrar</button>
<label for="tagFilter">Filtrar por tag:</label>
<select id="tagFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="personFilter">Filtrar por pessoa:</label>
<select id="personFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="customFieldFilter">Filtrar por campo personalizado:</label>
<input type="text" id="customFieldFilter" class="filter-dropdown" placeholder="Digite o valor exato" oninput="filterTasks()">
<button onclick="sortTasksByNumber()" class="sort-button">Ordenar por Número</button>
<button onclick="filterBlockers()" class="sort-button">Mostrar Bloqueantes</button>
<button onclick="generateBlockerReport()" class="sort-button">Gerar Relatório de Bloqueantes</button>
</div>
Títulos e hecklists
<div id="projectTitle" class="project-title"></div> <div id="checklistItems" class="checklist-items"> <!-- Itens de checklist serão adicionados aqui dinamicamente --> </div>
Agenda e calendário
<div class="agenda">
<h1>Minha Agenda com Calendário Mensal e Horários</h1>
<div id="eventsList" class="checklist-items">
<!-- Lista de eventos será preenchida dinamicamente -->
</div>
<div class="calendar" id="calendar">
<!-- Calendário será preenchido dinamicamente -->
</div>
</div>
<div id="calendar">
<div class="day" data-date="2024-07-30">
<h3>30/07/2024</h3>
<div class="taskContainer" id="tasks_2024-07-30">
<!-- Tarefas do dia 30/07/2024 -->
</div>
</div>
<div class="day" data-date="2024-07-31">
<h3>31/07/2024</h3>
<div class="taskContainer" id="tasks_2024-07-31">
<!-- Tarefas do dia 31/07/2024 -->
</div>
</div>
</div>
Histórico de atividades concluídas
<div class="completed-tasks-container">
<h2>Histórico de Atividades Concluídas</h2>
<div id="completedTasks">
<!-- Atividades concluídas serão adicionadas aqui dinamicamente -->
</div>
</div>
Relatório de atividades concluídas
<div class="report-container"> <h2>Relatório de Atividades Bloqueantes</h2> <div id="blockerReport"> <!-- Relatório de bloqueantes será preenchido dinamicamente --> </div> </div>
Inclusão de biblioteca externa
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
Funções de checklist
function addTask() {
// Obtém valores dos inputs
const taskInput = document.getElementById('newTask');
const taskName = taskInput.value.trim();
const tagInput = document.getElementById('newTag');
const tagName = tagInput.value.trim().toLowerCase();
const numberInput = document.getElementById('newNumber');
const taskNumber = numberInput.value.trim();
const personInput = document.getElementById('newPerson');
const personName = personInput.value.trim();
const dateInput = document.getElementById('newDate');
const taskDate = dateInput.value;
const endDateInput = document.getElementById('newEndDate');
const endDate = endDateInput.value;
const timeInput = document.getElementById('newTime');
const taskTime = timeInput.value;
const amountInput = document.getElementById('newAmount');
const amount = amountInput.value.trim();
const reasonInput = document.getElementById('newReason');
const taskReason = reasonInput.value.trim();
const locationInput = document.getElementById('newLocation');
const taskLocation = locationInput.value.trim();
const methodInput = document.getElementById('newMethod');
const taskMethod = methodInput.value.trim();
// Verifica se os campos obrigatórios estão preenchidos
if (taskName !== '' && taskNumber !== '') {
const checklistItems = document.getElementById('checklistItems');
const newTaskId = `task-${Date.now()}`;
const taskContainer = document.createElement('div');
taskContainer.className = 'checklist-container';
taskContainer.setAttribute('data-tag', tagName);
taskContainer.setAttribute('data-number', taskNumber);
taskContainer.setAttribute('data-person', personName);
taskContainer.setAttribute('data-date', taskDate);
taskContainer.setAttribute('data-end-date', endDate);
taskContainer.setAttribute('data-time', taskTime);
taskContainer.setAttribute('data-amount', amount);
taskContainer.setAttribute('data-reason', taskReason);
taskContainer.setAttribute('data-location', taskLocation);
taskContainer.setAttribute('data-method', taskMethod);
// Cria elementos HTML para a tarefa
const taskHeader = document.createElement('div');
taskHeader.style.display = 'flex';
taskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = taskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = newTaskId;
checkbox.className = 'checklist-input';
checkbox.addEventListener('change', function() {
label.classList.toggle('completed', checkbox.checked);
if (checkbox.checked) {
moveToCompleted(taskContainer);
} else {
checklistItems.appendChild(taskContainer);
}
saveChecklistState();
});
const label = document.createElement('label');
label.htmlFor = newTaskId;
label.className = 'checklist-label';
label.textContent = taskName;
label.addEventListener('click', function() {
setProjectTitle(label.textContent);
});
// Criação de campos editáveis para a tarefa
const numberInputField = document.createElement('input');
numberInputField.type = 'number';
numberInputField.value = taskNumber;
numberInputField.className = 'edit-number-input';
numberInputField.placeholder = "Número";
numberInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-number', numberInputField.value);
saveChecklistState();
});
const tagInputField = document.createElement('input');
tagInputField.type = 'text';
tagInputField.value = tagName;
tagInputField.className = 'edit-tag-input';
tagInputField.placeholder = "Tag";
tagInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-tag', tagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const personInputField = document.createElement('input');
personInputField.type = 'text';
personInputField.value = personName;
personInputField.className = 'edit-person-input';
personInputField.placeholder = "Atribuir a";
personInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-person', personInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const dateInputField = document.createElement('input');
dateInputField.type = 'date';
dateInputField.value = taskDate;
dateInputField.className = 'edit-date-input';
dateInputField.placeholder = "Data de realização";
dateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-date', dateInputField.value);
saveChecklistState();
updateCalendar();
});
const endDateInputField = document.createElement('input');
endDateInputField.type = 'date';
endDateInputField.value = endDate;
endDateInputField.className = 'edit-end-date-input';
endDateInputField.placeholder = "Data de término";
endDateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-end-date', endDateInputField.value);
saveChecklistState();
updateCalendar();
});
const timeInputField = document.createElement('input');
timeInputField.type = 'time';
timeInputField.value = taskTime;
timeInputField.className = 'edit-time-input';
timeInputField.placeholder = "Horário";
timeInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-time', timeInputField.value);
saveChecklistState();
updateCalendar();
});
const amountInputField = document.createElement('input');
amountInputField.type = 'number';
amountInputField.value = amount;
amountInputField.className = 'edit-amount-input';
amountInputField.placeholder = "Quanto";
amountInputField.step = "0.01";
amountInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-amount', amountInputField.value);
saveChecklistState();
});
const reasonInputField = document.createElement('input');
reasonInputField.type = 'text';
reasonInputField.value = taskReason;
reasonInputField.className = 'edit-reason-input';
reasonInputField.placeholder = "Por que da tarefa?";
reasonInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-reason', reasonInputField.value);
saveChecklistState();
});
const locationInputField = document.createElement('input');
locationInputField.type = 'text';
locationInputField.value = taskLocation;
locationInputField.className = 'edit-location-input';
locationInputField.placeholder = "Onde será a tarefa?";
locationInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-location', locationInputField.value);
saveChecklistState();
});
const methodInputField = document.createElement('input');
methodInputField.type = 'text';
methodInputField.value = taskMethod;
methodInputField.className = 'edit-method-input';
methodInputField.placeholder = "Como será feita essa tarefa?";
methodInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-method', methodInputField.value);
saveChecklistState();
});
// Botão para remover a tarefa
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'remove-task-button';
removeButton.textContent = 'x';
removeButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta tarefa?')) {
taskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
// Botão para marcar a tarefa como bloqueante
const blockerButton = document.createElement('button');
blockerButton.type = 'button';
blockerButton.className = 'blocker-button';
blockerButton.innerHTML = '⚠';
blockerButton.addEventListener('click', function() {
taskContainer.classList.toggle('blocker');
saveChecklistState();
});
// Botão para adicionar subtarefa
const addSubTaskButton = document.createElement('button');
addSubTaskButton.type = 'button';
addSubTaskButton.className = 'add-task-button';
addSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubTaskButton.style.marginLeft = '10px';
addSubTaskButton.addEventListener('click', function() {
const subTaskName = prompt('Digite a nova subtarefa:');
if (subTaskName) {
addSubTask(taskContainer, subTaskName);
}
});
// Botão para adicionar campo personalizado
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(taskContainer);
});
// Lista aninhada para subtarefas
const nestedList = document.createElement('div');
nestedList.className = 'nested-list';
// Adiciona todos os elementos ao cabeçalho da tarefa
taskHeader.appendChild(toggleButton);
taskHeader.appendChild(checkbox);
taskHeader.appendChild(label);
taskHeader.appendChild(tagInputField);
taskHeader.appendChild(numberInputField);
taskHeader.appendChild(personInputField);
taskHeader.appendChild(dateInputField);
taskHeader.appendChild(endDateInputField);
taskHeader.appendChild(timeInputField);
taskHeader.appendChild(amountInputField);
taskHeader.appendChild(reasonInputField);
taskHeader.appendChild(locationInputField);
taskHeader.appendChild(methodInputField);
taskHeader.appendChild(blockerButton);
taskHeader.appendChild(removeButton);
taskHeader.appendChild(addSubTaskButton);
taskHeader.appendChild(customFieldButton);
// Adiciona o cabeçalho e a lista aninhada ao contêiner da tarefa
taskContainer.appendChild(taskHeader);
taskContainer.appendChild(nestedList);
// Adiciona a nova tarefa à lista de tarefas
checklistItems.appendChild(taskContainer);
// Limpa os inputs
taskInput.value = '';
tagInput.value = '';
numberInput.value = '';
personInput.value = '';
dateInput.value = '';
endDateInput.value = '';
timeInput.value = '';
amountInput.value = '';
reasonInput.value = '';
locationInput.value = '';
methodInput.value = '';
// Salva o estado da checklist, atualiza os filtros e o calendário
saveChecklistState();
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
}
Subtarefas
function addSubTask(parentTaskContainer, subTaskName) {
// Função semelhante à addTask, mas para subtarefas
}
Funções auxiliares
function setProjectTitle(title) {
const projectTitle = document.getElementById('projectTitle');
projectTitle.textContent = title;
}
function saveChecklistState() {
const tasks = [];
const checklistItems = document.querySelectorAll('#checklistItems > .checklist-container');
checklistItems.forEach((taskContainer) => {
const taskData = getTaskData(taskContainer);
tasks.push(taskData);
});
localStorage.setItem('checklistItems', JSON.stringify(tasks));
}
function getTaskData(taskContainer) {
// Extrai dados da tarefa e subtarefas
}
function getCustomFields(taskContainer) {
// Extrai campos personalizados da tarefa
}
function restoreChecklistState() {
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
tasks.forEach((task) => {
addTaskFromData(task);
});
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
function addTaskFromData(task) {
// Adiciona tarefa a partir dos dados salvos
}
function addSubTaskFromData(nestedList, subTask) {
// Adiciona subtarefa a partir dos dados salvos
}
function initializeSortable(container) {
new Sortable(container, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: () => {
saveChecklistState();
}
});
}
Filtrahem e ordenação
function updateFilterDropdown() {
// Atualiza dropdown de filtros com tags das tarefas
}
function updatePersonFilterDropdown() {
// Atualiza dropdown de filtros com pessoas atribuídas às tarefas
}
function filterTasks() {
// Filtra tarefas com base nos critérios selecionados
}
function filterTasksByWord() {
// Filtra tarefas com base em uma palavra-chave
}
function sortTasksByNumber() {
// Ordena tarefas pelo número
}
function filterBlockers() {
// Mostra apenas tarefas bloqueantes
}
function generateBlockerReport() {
// Gera relatório de tarefas bloqueantes
}
Outras funções
function moveToCompleted(taskContainer) {
// Move tarefa para a seção de tarefas concluídas
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
addTask();
}
}
function updateCalendar() {
// Atualiza o calendário com base nas datas das tarefas
}
function addEventToDay(dayElement, eventName, eventTime) {
// Adiciona evento ao dia no calendário
}
function saveEventToLocalStorage(day, eventName, eventTime) {
// Salva evento no localStorage
}
function addEventToCalendar(date, eventName, eventTime, isEnd) {
// Adiciona evento ao calendário
}
function addCustomField(taskContainer) {
const fieldName = prompt('Digite o nome do campo personalizado:');
if (fieldName) {
const customField = document.createElement('input');
customField.type = 'text';
customField.placeholder = fieldName;
customField.className = 'custom-field-input';
customField.addEventListener('change', function() {
saveChecklistState();
});
const taskHeader = taskContainer.querySelector('div');
taskHeader.appendChild(customField);
saveChecklistState();
}
}
document.addEventListener('DOMContentLoaded', () => {
restoreChecklistState();
initializeSortable(document.getElementById('checklistItems'));
initializeSortable(document.getElementById('eventsList'));
});
function updateCalendar() {
// Atualiza o calendário com base nas datas das tarefas
const taskContainers = document.querySelectorAll('.taskContainer');
taskContainers.forEach(container => {
initializeSortable(container);
});
}
function addEventToDay(dayElement, eventName, eventTime) {
const eventElement = document.createElement('div');
eventElement.className = 'event';
eventElement.innerHTML = `<span>${eventName} - ${eventTime}</span>`;
dayElement.appendChild(eventElement);
initializeSortable(dayElement);
}
function saveEventToLocalStorage(day, eventName, eventTime) {
const events = JSON.parse(localStorage.getItem('events')) || {};
if (!events[day]) {
events[day] = [];
}
events[day].push({ name: eventName, time: eventTime });
localStorage.setItem('events', JSON.stringify(events));
}
function addEventToCalendar(date, eventName, eventTime, isEnd) {
const dayElement = document.querySelector(`#tasks_${date}`);
if (dayElement) {
addEventToDay(dayElement, eventName, eventTime);
saveEventToLocalStorage(date, eventName, eventTime);
}
}
function initializeSortable(element) {
Sortable.create(element, {
group: 'calendarTasks',
animation: 150,
onEnd: function(evt) {
const item = evt.item;
const fromContainer = evt.from;
const toContainer = evt.to;
const fromDate = fromContainer.id.split('_')[1];
const toDate = toContainer.id.split('_')[1];
if (fromDate !== toDate) {
console.log(`Moved task from ${fromDate} to ${toDate}`);
// Atualize o evento com a nova data
updateEventDate(item, toDate);
}
}
});
}
function updateEventDate(eventElement, newDate) {
const eventName = eventElement.querySelector('span').textContent.split(' - ')[0];
const eventTime = eventElement.querySelector('span').textContent.split(' - ')[1];
// Remova do dia antigo no localStorage
const oldDate = eventElement.closest('.taskContainer').id.split('_')[1];
let events = JSON.parse(localStorage.getItem('events')) || {};
if (events[oldDate]) {
events[oldDate] = events[oldDate].filter(event => event.name !== eventName || event.time !== eventTime);
localStorage.setItem('events', JSON.stringify(events));
}
// Adicione ao novo dia no localStorage
saveEventToLocalStorage(newDate, eventName, eventTime);
// Atualize o elemento HTML
const newDayElement = document.querySelector(`#tasks_${newDate}`);
if (newDayElement) {
newDayElement.appendChild(eventElement);
}
}
document.addEventListener('DOMContentLoaded', () => {
restoreChecklistState();
initializeSortable(document.getElementById('checklistItems'));
initializeSortable(document.getElementById('eventsList'));
updateCalendar();
});
relatório de
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ballaminut Networking - Sistema de produtividade</title>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
background-color: #f2f2f2;
}
td {
vertical-align: top;
}
.checklist {
margin-right: 5px;
}
.checklist-container {
display: flex;
flex-direction: column;
margin: 10px 0;
}
.nested-list {
margin-left: 20px;
display: none;
}
.checklist-label {
font-size: 18px;
margin-left: 10px;
text-decoration: none;
cursor: pointer;
}
.checklist-label.completed {
text-decoration: line-through;
}
.checklist-input {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: orange;
}
.add-task-container {
margin-bottom: 20px;
}
.add-task-input,
.add-tag-input,
.add-number-input,
.add-person-input,
.add-date-input,
.add-end-date-input,
.add-time-input,
.add-amount-input,
.add-reason-input,
.add-location-input,
.add-method-input {
padding: 5px;
font-size: 16px;
}
.add-task-button {
margin-left: 10px;
padding: 8px 16px;
font-size: 16px;
cursor: pointer;
background-color: orange;
color: white;
border: none;
border-radius: 5px;
}
.add-task-button:hover {
background-color: black;
}
.remove-task-button {
cursor: pointer;
margin-left: 5px;
padding: 2px 4px;
font-size: 10px;
background-color: white;
color: gray;
border: none;
border-radius: 3px;
opacity: 0.8;
}
.remove-task-button:hover {
background-color: lightgray;
}
.edit-number-input,
.edit-tag-input,
.edit-person-input,
.edit-date-input,
.edit-end-date-input,
.edit-time-input,
.edit-amount-input,
.edit-reason-input,
.edit-location-input,
.edit-method-input {
width: 100px;
font-size: 14px;
padding: 2px;
margin-left: 10px;
}
.filter-container {
margin-bottom: 20px;
}
.filter-dropdown {
padding: 5px;
font-size: 16px;
}
.sort-button {
padding: 5px 10px;
font-size: 16px;
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
margin-left: 10px;
}
.sort-button:hover {
background-color: #0056b3;
}
.blocker-button {
cursor: pointer;
margin-left: 5px;
padding: 2px 4px;
font-size: 14px;
background-color: transparent;
color: red;
border: none;
border-radius: 3px;
}
.blocker-button:hover {
color: darkred;
}
.blocker {
background-color: #ffcccc;
}
.project-title {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.toggle {
cursor: pointer;
font-weight: bold;
margin-right: 10px;
}
.calendar {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 20px;
}
.calendar-month {
width: 100%;
text-align: center;
font-weight: bold;
margin: 20px 0;
}
.calendar-day {
width: calc(100% / 7 - 10px);
text-align: center;
border: 1px solid #ccc;
padding: 5px;
cursor: pointer;
}
.calendar-day.occupied {
background-color: #ccc;
}
.calendar-hour {
font-size: 0.8em;
margin-top: 2px;
}
.calendar-week {
display: flex;
justify-content: space-between;
width: 100%;
}
.calendar-event {
background-color: orange;
color: white;
margin: 2px 0;
padding: 2px;
}
.calendar-event.end {
background-color: blue;
color: white;
}
.completed-tasks-container {
margin-top: 40px;
}
.completed-task {
text-decoration: line-through;
color: gray;
}
.report-container {
margin-top: 40px;
}
.report-item {
margin-bottom: 10px;
}
</style>
</head>
<body>
<center><h1>Ballaminut Networking - Sistema de produtividade</h1>
<table>
<tr>
<th>Detalhes</th>
<th>Detalhes</th>
<th>Detalhes</th>
<th>Detalhes</th>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Por que da tarefa?</td>
<td><input type="checkbox" class="checklist"> Traz dinheiro?</td>
<td><input type="checkbox" class="checklist"> Tipo de custo</td>
<td><input type="checkbox" class="checklist"> Gera reels?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Onde será a tarefa?</td>
<td><input type="checkbox" class="checklist"> Valor</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de custo</td>
<td><input type="checkbox" class="checklist"> Aula no YouTube?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Como será feita essa tarefa?</td>
<td><input type="checkbox" class="checklist"> 0%</td>
<td><input type="checkbox" class="checklist"> Tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Gera encontro?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Recorrente?</td>
<td><input type="checkbox" class="checklist"> Nome do cargo</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Passível de negociação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Hábito?</td>
<td><input type="checkbox" class="checklist"> Departamento</td>
<td><input type="checkbox" class="checklist"> Tipo de receita</td>
<td><input type="checkbox" class="checklist"> Passível de acordo?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Pago?</td>
<td><input type="checkbox" class="checklist"> Fornecedor?</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de receita</td>
<td><input type="checkbox" class="checklist"> Compra feita?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Leva ao objetivo?</td>
<td><input type="checkbox" class="checklist"> Nome da empresa</td>
<td><input type="checkbox" class="checklist"> Resultado</td>
<td><input type="checkbox" class="checklist"> Compra do cliente?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É uma decisão?</td>
<td><input type="checkbox" class="checklist"> Status</td>
<td><input type="checkbox" class="checklist"> Detalhe do resultado</td>
<td><input type="checkbox" class="checklist"> Compra a fazer?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem um guardião?</td>
<td><input type="checkbox" class="checklist"> Filial?</td>
<td><input type="checkbox" class="checklist"> Gera storie?</td>
<td><input type="checkbox" class="checklist"> Método de pagamento</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de dor</td>
<td><input type="checkbox" class="checklist"> Compromisso?</td>
<td><input type="checkbox" class="checklist"> Post para blog?</td>
<td><input type="checkbox" class="checklist"> É dívida?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de humor</td>
<td><input type="checkbox" class="checklist"> Know-how?</td>
<td><input type="checkbox" class="checklist"> Post para grupo?</td>
<td><input type="checkbox" class="checklist"> Antecipação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É um sacrifício?</td>
<td><input type="checkbox" class="checklist"> Necessita de parceiro?</td>
<td><input type="checkbox" class="checklist"> Conteúdo para feed?</td>
<td><input type="checkbox" class="checklist"> Alta margem?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Ferramenta que facilita</td>
<td><input type="checkbox" class="checklist"> Delegável?</td>
<td><input type="checkbox" class="checklist"> Alto desconto?</td>
<td><input type="checkbox" class="checklist"> Agrega ao inventário?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem sinergia?</td>
<td><input type="checkbox" class="checklist"> Automatizável?</td>
<td><input type="checkbox" class="checklist"> Orçamento?</td>
<td><input type="checkbox" class="checklist"> Agrega à marca?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
<td><input type="checkbox" class="checklist"> Recebimento de dinheiro?</td>
<td><input type="checkbox" class="checklist"> Redução de custo?</td>
<td><input type="checkbox" class="checklist"> Tempo de qualidade?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Plano de contingência?</td>
<td><input type="checkbox" class="checklist"> Despesa?</td>
<td><input type="checkbox" class="checklist"> Quebra se mãe doente?</td>
<td><input type="checkbox" class="checklist"> Status da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Validada?</td>
<td><input type="checkbox" class="checklist"> Previsão de recebimento?</td>
<td><input type="checkbox" class="checklist"> Quebra se doente?</td>
<td><input type="checkbox" class="checklist"> Dificuldade da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Relevante?</td>
<td><input type="checkbox" class="checklist"> Previsão de saída?</td>
<td><input type="checkbox" class="checklist"> Quebra se Covid?</td>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Gera brigas?</td>
<td><input type="checkbox" class="checklist"> Coerência empreendedora</td>
<td><input type="checkbox" class="checklist"> Perfil</td>
<td><input type="checkbox" class="checklist"> Feito por</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Melhor ambiente</td>
<td><input type="checkbox" class="checklist"> É um marco?</td>
<td><input type="checkbox" class="checklist"> Nível da atividade</td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Atividade de risco?</td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Tem redundância?</td>
<td></td>
<td></td>
</tr>
</table>
</center>
<br>
<br>
<b>
<subtitle> >>> Adicione as suas tarefas aqui!!!</subtitle>
<br>
<br>
<div class="add-task-container">
<input type="text" id="newTask" class="add-task-input" placeholder="Digite uma nova tarefa" onkeydown="handleKeyPress(event)">
<input type="text" id="newTag" class="add-tag-input" placeholder="Digite uma tag">
<input type="number" id="newNumber" class="add-number-input" placeholder="Número" min="1">
<input type="text" id="newPerson" class="add-person-input" placeholder="Atribuir a">
<input type="date" id="newDate" class="add-date-input" placeholder="Data de realização">
<input type="date" id="newEndDate" class="add-end-date-input" placeholder="Data de término">
<input type="time" id="newTime" class="add-time-input" placeholder="Horário">
<input type="number" id="newAmount" class="add-amount-input" placeholder="Quanto" step="0.01">
<input type="text" id="newReason" class="add-reason-input" placeholder="Por que da tarefa?">
<input type="text" id="newLocation" class="add-location-input" placeholder="Onde será a tarefa?">
<input type="text" id="newMethod" class="add-method-input" placeholder="Como será feita essa tarefa?">
<button onclick="addTask()" class="add-task-button">Adicionar Tarefa</button>
<button onclick="addCustomField()" class="add-task-button">Adicionar Campo Personalizado</button>
</div>
<div class="filter-container">
<input type="text" id="wordFilter" placeholder="Digite uma palavra para filtrar" oninput="filterTasksByWord()">
<button onclick="filterTasksByWord()">Filtrar</button>
<label for="tagFilter">Filtrar por tag:</label>
<select id="tagFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="personFilter">Filtrar por pessoa:</label>
<select id="personFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="customFieldFilter">Filtrar por campo personalizado:</label>
<input type="text" id="customFieldFilter" class="filter-dropdown" placeholder="Digite o valor exato" oninput="filterTasks()">
<button onclick="sortTasksByNumber()" class="sort-button">Ordenar por Número</button>
<button onclick="filterBlockers()" class="sort-button">Mostrar Bloqueantes</button>
<button onclick="generateBlockerReport()" class="sort-button">Gerar Relatório de Bloqueantes</button>
</div>
<div id="projectTitle" class="project-title"></div>
<div id="checklistItems" class="checklist-items">
<!-- Itens de checklist serão adicionados aqui dinamicamente -->
</div>
<div class="agenda">
<h1>Minha Agenda com Calendário Mensal e Horários</h1>
<div id="eventsList" class="checklist-items">
<!-- Lista de eventos será preenchida dinamicamente -->
</div>
<div class="calendar" id="calendar">
<!-- Calendário será preenchido dinamicamente -->
</div>
</div>
<div class="completed-tasks-container">
<h2>Histórico de Atividades Concluídas</h2>
<div id="completedTasks">
<!-- Atividades concluídas serão adicionadas aqui dinamicamente -->
</div>
</div>
<div class="report-container">
<h2>Relatório de Atividades Bloqueantes</h2>
<div id="blockerReport">
<!-- Relatório de bloqueantes será preenchido dinamicamente -->
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<script>
// Funções de checklist
function addTask() {
const taskInput = document.getElementById('newTask');
const taskName = taskInput.value.trim();
const tagInput = document.getElementById('newTag');
const tagName = tagInput.value.trim().toLowerCase();
const numberInput = document.getElementById('newNumber');
const taskNumber = numberInput.value.trim();
const personInput = document.getElementById('newPerson');
const personName = personInput.value.trim();
const dateInput = document.getElementById('newDate');
const taskDate = dateInput.value;
const endDateInput = document.getElementById('newEndDate');
const endDate = endDateInput.value;
const timeInput = document.getElementById('newTime');
const taskTime = timeInput.value;
const amountInput = document.getElementById('newAmount');
const amount = amountInput.value.trim();
const reasonInput = document.getElementById('newReason');
const taskReason = reasonInput.value.trim();
const locationInput = document.getElementById('newLocation');
const taskLocation = locationInput.value.trim();
const methodInput = document.getElementById('newMethod');
const taskMethod = methodInput.value.trim();
if (taskName !== '' && taskNumber !== '') {
const checklistItems = document.getElementById('checklistItems');
const newTaskId = `task-${Date.now()}`;
const taskContainer = document.createElement('div');
taskContainer.className = 'checklist-container';
taskContainer.setAttribute('data-tag', tagName);
taskContainer.setAttribute('data-number', taskNumber);
taskContainer.setAttribute('data-person', personName);
taskContainer.setAttribute('data-date', taskDate);
taskContainer.setAttribute('data-end-date', endDate);
taskContainer.setAttribute('data-time', taskTime);
taskContainer.setAttribute('data-amount', amount);
taskContainer.setAttribute('data-reason', taskReason);
taskContainer.setAttribute('data-location', taskLocation);
taskContainer.setAttribute('data-method', taskMethod);
const taskHeader = document.createElement('div');
taskHeader.style.display = 'flex';
taskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = taskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = newTaskId;
checkbox.className = 'checklist-input';
checkbox.addEventListener('change', function() {
label.classList.toggle('completed', checkbox.checked);
if (checkbox.checked) {
moveToCompleted(taskContainer);
} else {
checklistItems.appendChild(taskContainer);
}
saveChecklistState();
});
const label = document.createElement('label');
label.htmlFor = newTaskId;
label.className = 'checklist-label';
label.textContent = taskName;
label.addEventListener('click', function() {
setProjectTitle(label.textContent);
});
const numberInputField = document.createElement('input');
numberInputField.type = 'number';
numberInputField.value = taskNumber;
numberInputField.className = 'edit-number-input';
numberInputField.placeholder = "Número";
numberInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-number', numberInputField.value);
saveChecklistState();
});
const tagInputField = document.createElement('input');
tagInputField.type = 'text';
tagInputField.value = tagName;
tagInputField.className = 'edit-tag-input';
tagInputField.placeholder = "Tag";
tagInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-tag', tagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const personInputField = document.createElement('input');
personInputField.type = 'text';
personInputField.value = personName;
personInputField.className = 'edit-person-input';
personInputField.placeholder = "Atribuir a";
personInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-person', personInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const dateInputField = document.createElement('input');
dateInputField.type = 'date';
dateInputField.value = taskDate;
dateInputField.className = 'edit-date-input';
dateInputField.placeholder = "Data de realização";
dateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-date', dateInputField.value);
saveChecklistState();
updateCalendar();
});
const endDateInputField = document.createElement('input');
endDateInputField.type = 'date';
endDateInputField.value = endDate;
endDateInputField.className = 'edit-end-date-input';
endDateInputField.placeholder = "Data de término";
endDateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-end-date', endDateInputField.value);
saveChecklistState();
updateCalendar();
});
const timeInputField = document.createElement('input');
timeInputField.type = 'time';
timeInputField.value = taskTime;
timeInputField.className = 'edit-time-input';
timeInputField.placeholder = "Horário";
timeInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-time', timeInputField.value);
saveChecklistState();
updateCalendar();
});
const amountInputField = document.createElement('input');
amountInputField.type = 'number';
amountInputField.value = amount;
amountInputField.className = 'edit-amount-input';
amountInputField.placeholder = "Quanto";
amountInputField.step = "0.01";
amountInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-amount', amountInputField.value);
saveChecklistState();
});
const reasonInputField = document.createElement('input');
reasonInputField.type = 'text';
reasonInputField.value = taskReason;
reasonInputField.className = 'edit-reason-input';
reasonInputField.placeholder = "Por que da tarefa?";
reasonInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-reason', reasonInputField.value);
saveChecklistState();
});
const locationInputField = document.createElement('input');
locationInputField.type = 'text';
locationInputField.value = taskLocation;
locationInputField.className = 'edit-location-input';
locationInputField.placeholder = "Onde será a tarefa?";
locationInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-location', locationInputField.value);
saveChecklistState();
});
const methodInputField = document.createElement('input');
methodInputField.type = 'text';
methodInputField.value = taskMethod;
methodInputField.className = 'edit-method-input';
methodInputField.placeholder = "Como será feita essa tarefa?";
methodInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-method', methodInputField.value);
saveChecklistState();
});
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'remove-task-button';
removeButton.textContent = 'x';
removeButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta tarefa?')) {
taskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const blockerButton = document.createElement('button');
blockerButton.type = 'button';
blockerButton.className = 'blocker-button';
blockerButton.innerHTML = '⚠';
blockerButton.addEventListener('click', function() {
taskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubTaskButton = document.createElement('button');
addSubTaskButton.type = 'button';
addSubTaskButton.className = 'add-task-button';
addSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubTaskButton.style.marginLeft = '10px';
addSubTaskButton.addEventListener('click', function() {
const subTaskName = prompt('Digite a nova subtarefa:');
if (subTaskName) {
addSubTask(taskContainer, subTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(taskContainer);
});
const nestedList = document.createElement('div');
nestedList.className = 'nested-list';
taskHeader.appendChild(toggleButton);
taskHeader.appendChild(checkbox);
taskHeader.appendChild(label);
taskHeader.appendChild(tagInputField);
taskHeader.appendChild(numberInputField);
taskHeader.appendChild(personInputField);
taskHeader.appendChild(dateInputField);
taskHeader.appendChild(endDateInputField);
taskHeader.appendChild(timeInputField);
taskHeader.appendChild(amountInputField);
taskHeader.appendChild(reasonInputField);
taskHeader.appendChild(locationInputField);
taskHeader.appendChild(methodInputField);
taskHeader.appendChild(blockerButton);
taskHeader.appendChild(removeButton);
taskHeader.appendChild(addSubTaskButton);
taskHeader.appendChild(customFieldButton);
taskContainer.appendChild(taskHeader);
taskContainer.appendChild(nestedList);
checklistItems.appendChild(taskContainer);
taskInput.value = '';
tagInput.value = '';
numberInput.value = '';
personInput.value = '';
dateInput.value = '';
endDateInput.value = '';
timeInput.value = '';
amountInput.value = '';
reasonInput.value = '';
locationInput.value = '';
methodInput.value = '';
saveChecklistState();
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
}
function addSubTask(parentTaskContainer, subTaskName) {
const nestedList = parentTaskContainer.querySelector('.nested-list');
const subTaskId = `subtask-${Date.now()}`;
const subTaskContainer = document.createElement('div');
subTaskContainer.className = 'checklist-container';
subTaskContainer.setAttribute('data-tag', '');
subTaskContainer.setAttribute('data-number', '');
subTaskContainer.setAttribute('data-person', '');
subTaskContainer.setAttribute('data-date', '');
subTaskContainer.setAttribute('data-end-date', '');
subTaskContainer.setAttribute('data-time', '');
subTaskContainer.setAttribute('data-amount', '');
subTaskContainer.setAttribute('data-reason', '');
subTaskContainer.setAttribute('data-location', '');
subTaskContainer.setAttribute('data-method', '');
const subTaskHeader = document.createElement('div');
subTaskHeader.style.display = 'flex';
subTaskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = subTaskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const subCheckbox = document.createElement('input');
subCheckbox.type = 'checkbox';
subCheckbox.id = subTaskId;
subCheckbox.className = 'checklist-input';
subCheckbox.addEventListener('change', function() {
subLabel.classList.toggle('completed', subCheckbox.checked);
if (subCheckbox.checked) {
moveToCompleted(subTaskContainer);
} else {
nestedList.appendChild(subTaskContainer);
}
saveChecklistState();
});
const subLabel = document.createElement('label');
subLabel.htmlFor = subTaskId;
subLabel.className = 'checklist-label';
subLabel.textContent = subTaskName;
const subNumberInputField = document.createElement('input');
subNumberInputField.type = 'number';
subNumberInputField.value = '';
subNumberInputField.className = 'edit-number-input';
subNumberInputField.placeholder = "Número";
subNumberInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-number', subNumberInputField.value);
saveChecklistState();
});
const subTagInputField = document.createElement('input');
subTagInputField.type = 'text';
subTagInputField.value = '';
subTagInputField.className = 'edit-tag-input';
subTagInputField.placeholder = "Tag";
subTagInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-tag', subTagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const subPersonInputField = document.createElement('input');
subPersonInputField.type = 'text';
subPersonInputField.value = '';
subPersonInputField.className = 'edit-person-input';
subPersonInputField.placeholder = "Atribuir a";
subPersonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-person', subPersonInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const subDateInputField = document.createElement('input');
subDateInputField.type = 'date';
subDateInputField.value = '';
subDateInputField.className = 'edit-date-input';
subDateInputField.placeholder = "Data de realização";
subDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-date', subDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subEndDateInputField = document.createElement('input');
subEndDateInputField.type = 'date';
subEndDateInputField.value = '';
subEndDateInputField.className = 'edit-end-date-input';
subEndDateInputField.placeholder = "Data de término";
subEndDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-end-date', subEndDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subTimeInputField = document.createElement('input');
subTimeInputField.type = 'time';
subTimeInputField.value = '';
subTimeInputField.className = 'edit-time-input';
subTimeInputField.placeholder = "Horário";
subTimeInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-time', subTimeInputField.value);
saveChecklistState();
updateCalendar();
});
const subAmountInputField = document.createElement('input');
subAmountInputField.type = 'number';
subAmountInputField.value = '';
subAmountInputField.className = 'edit-amount-input';
subAmountInputField.placeholder = "Quanto";
subAmountInputField.step = "0.01";
subAmountInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-amount', subAmountInputField.value);
saveChecklistState();
});
const subReasonInputField = document.createElement('input');
subReasonInputField.type = 'text';
subReasonInputField.value = '';
subReasonInputField.className = 'edit-reason-input';
subReasonInputField.placeholder = "Por que da tarefa?";
subReasonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-reason', subReasonInputField.value);
saveChecklistState();
});
const subLocationInputField = document.createElement('input');
subLocationInputField.type = 'text';
subLocationInputField.value = '';
subLocationInputField.className = 'edit-location-input';
subLocationInputField.placeholder = "Onde será a tarefa?";
subLocationInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-location', subLocationInputField.value);
saveChecklistState();
});
const subMethodInputField = document.createElement('input');
subMethodInputField.type = 'text';
subMethodInputField.value = '';
subMethodInputField.className = 'edit-method-input';
subMethodInputField.placeholder = "Como será feita essa tarefa?";
subMethodInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-method', subMethodInputField.value);
saveChecklistState();
});
const subRemoveButton = document.createElement('button');
subRemoveButton.type = 'button';
subRemoveButton.className = 'remove-task-button';
subRemoveButton.textContent = 'x';
subRemoveButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta subtarefa?')) {
subTaskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const subBlockerButton = document.createElement('button');
subBlockerButton.type = 'button';
subBlockerButton.className = 'blocker-button';
subBlockerButton.innerHTML = '⚠';
subBlockerButton.addEventListener('click', function() {
subTaskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubSubTaskButton = document.createElement('button');
addSubSubTaskButton.type = 'button';
addSubSubTaskButton.className = 'add-task-button';
addSubSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubSubTaskButton.style.marginLeft = '10px';
addSubSubTaskButton.addEventListener('click', function() {
const subSubTaskName = prompt('Digite a nova subtarefa:');
if (subSubTaskName) {
addSubTask(subTaskContainer, subSubTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(subTaskContainer);
});
subTaskHeader.appendChild(toggleButton);
subTaskHeader.appendChild(subCheckbox);
subTaskHeader.appendChild(subLabel);
subTaskHeader.appendChild(subTagInputField);
subTaskHeader.appendChild(subNumberInputField);
subTaskHeader.appendChild(subPersonInputField);
subTaskHeader.appendChild(subDateInputField);
subTaskHeader.appendChild(subEndDateInputField);
subTaskHeader.appendChild(subTimeInputField);
subTaskHeader.appendChild(subAmountInputField);
subTaskHeader.appendChild(subReasonInputField);
subTaskHeader.appendChild(subLocationInputField);
subTaskHeader.appendChild(subMethodInputField);
subTaskHeader.appendChild(subBlockerButton);
subTaskHeader.appendChild(subRemoveButton);
subTaskHeader.appendChild(addSubSubTaskButton);
subTaskHeader.appendChild(customFieldButton);
subTaskContainer.appendChild(subTaskHeader);
const subNestedList = document.createElement('div');
subNestedList.className = 'nested-list';
subTaskContainer.appendChild(subNestedList);
nestedList.appendChild(subTaskContainer);
initializeSortable(subNestedList);
updateCalendar();
}
function setProjectTitle(title) {
const projectTitle = document.getElementById('projectTitle');
projectTitle.textContent = title;
}
function saveChecklistState() {
const tasks = [];
const checklistItems = document.querySelectorAll('#checklistItems > .checklist-container');
checklistItems.forEach((taskContainer) => {
const taskHeader = taskContainer.querySelector('div');
const checkbox = taskContainer.querySelector('.checklist-input');
const label = taskContainer.querySelector('.checklist-label');
const tag = taskContainer.querySelector('.edit-tag-input').value.toLowerCase();
const number = taskContainer.querySelector('.edit-number-input').value;
const person = taskContainer.querySelector('.edit-person-input').value;
const date = taskContainer.querySelector('.edit-date-input').value;
const endDate = taskContainer.querySelector('.edit-end-date-input').value;
const time = taskContainer.querySelector('.edit-time-input').value;
const amount = taskContainer.querySelector('.edit-amount-input').value;
const reason = taskContainer.querySelector('.edit-reason-input').value;
const location = taskContainer.querySelector('.edit-location-input').value;
const method = taskContainer.querySelector('.edit-method-input').value;
const isBlocker = taskContainer.classList.contains('blocker');
const subTasks = Array.from(taskContainer.querySelector('.nested-list').children).map(subTask => getTaskData(subTask));
const customFields = getCustomFields(taskContainer);
tasks.push({
id: checkbox.id,
name: label.textContent,
checked: checkbox.checked,
tag: tag,
number: number,
person: person,
date: date,
endDate: endDate,
time: time,
amount: amount,
reason: reason,
location: location,
method: method,
blocker: isBlocker,
subTasks: subTasks,
customFields: customFields
});
});
localStorage.setItem('checklistItems', JSON.stringify(tasks));
}
function getTaskData(taskContainer) {
const checkbox = taskContainer.querySelector('.checklist-input');
const label = taskContainer.querySelector('.checklist-label');
const tag = taskContainer.querySelector('.edit-tag-input').value.toLowerCase();
const number = taskContainer.querySelector('.edit-number-input').value;
const person = taskContainer.querySelector('.edit-person-input').value;
const date = taskContainer.querySelector('.edit-date-input').value;
const endDate = taskContainer.querySelector('.edit-end-date-input').value;
const time = taskContainer.querySelector('.edit-time-input').value;
const amount = taskContainer.querySelector('.edit-amount-input').value;
const reason = taskContainer.querySelector('.edit-reason-input').value;
const location = taskContainer.querySelector('.edit-location-input').value;
const method = taskContainer.querySelector('.edit-method-input').value;
const isBlocker = taskContainer.classList.contains('blocker');
const subTasks = Array.from(taskContainer.querySelector('.nested-list').children).map(subTask => getTaskData(subTask));
const customFields = getCustomFields(taskContainer);
return {
id: checkbox.id,
name: label.textContent,
checked: checkbox.checked,
tag: tag,
number: number,
person: person,
date: date,
endDate: endDate,
time: time,
amount: amount,
reason: reason,
location: location,
method: method,
blocker: isBlocker,
subTasks: subTasks,
customFields: customFields
};
}
function getCustomFields(taskContainer) {
const customFields = {};
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
customFieldInputs.forEach(input => {
customFields[input.placeholder] = input.value;
});
return customFields;
}
function restoreChecklistState() {
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
tasks.forEach((task) => {
addTaskFromData(task);
});
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
function addTaskFromData(task) {
const checklistItems = document.getElementById('checklistItems');
const taskContainer = document.createElement('div');
taskContainer.className = 'checklist-container';
taskContainer.setAttribute('data-tag', task.tag);
taskContainer.setAttribute('data-number', task.number);
taskContainer.setAttribute('data-person', task.person);
taskContainer.setAttribute('data-date', task.date);
taskContainer.setAttribute('data-end-date', task.endDate);
taskContainer.setAttribute('data-time', task.time);
taskContainer.setAttribute('data-amount', task.amount);
taskContainer.setAttribute('data-reason', task.reason);
taskContainer.setAttribute('data-location', task.location);
taskContainer.setAttribute('data-method', task.method);
const taskHeader = document.createElement('div');
taskHeader.style.display = 'flex';
taskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = taskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = task.id;
checkbox.className = 'checklist-input';
checkbox.checked = task.checked;
checkbox.addEventListener('change', function() {
label.classList.toggle('completed', checkbox.checked);
if (checkbox.checked) {
moveToCompleted(taskContainer);
} else {
checklistItems.appendChild(taskContainer);
}
saveChecklistState();
});
const label = document.createElement('label');
label.htmlFor = task.id;
label.className = 'checklist-label';
label.textContent = task.name;
if (task.checked) {
label.classList.add('completed');
}
label.addEventListener('click', function() {
setProjectTitle(label.textContent);
});
const numberInputField = document.createElement('input');
numberInputField.type = 'number';
numberInputField.value = task.number;
numberInputField.className = 'edit-number-input';
numberInputField.placeholder = "Número";
numberInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-number', numberInputField.value);
saveChecklistState();
});
const tagInputField = document.createElement('input');
tagInputField.type = 'text';
tagInputField.value = task.tag;
tagInputField.className = 'edit-tag-input';
tagInputField.placeholder = "Tag";
tagInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-tag', tagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const personInputField = document.createElement('input');
personInputField.type = 'text';
personInputField.value = task.person;
personInputField.className = 'edit-person-input';
personInputField.placeholder = "Atribuir a";
personInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-person', personInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const dateInputField = document.createElement('input');
dateInputField.type = 'date';
dateInputField.value = task.date;
dateInputField.className = 'edit-date-input';
dateInputField.placeholder = "Data de realização";
dateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-date', dateInputField.value);
saveChecklistState();
updateCalendar();
});
const endDateInputField = document.createElement('input');
endDateInputField.type = 'date';
endDateInputField.value = task.endDate;
endDateInputField.className = 'edit-end-date-input';
endDateInputField.placeholder = "Data de término";
endDateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-end-date', endDateInputField.value);
saveChecklistState();
updateCalendar();
});
const timeInputField = document.createElement('input');
timeInputField.type = 'time';
timeInputField.value = task.time;
timeInputField.className = 'edit-time-input';
timeInputField.placeholder = "Horário";
timeInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-time', timeInputField.value);
saveChecklistState();
updateCalendar();
});
const amountInputField = document.createElement('input');
amountInputField.type = 'number';
amountInputField.value = task.amount;
amountInputField.className = 'edit-amount-input';
amountInputField.placeholder = "Quanto";
amountInputField.step = "0.01";
amountInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-amount', amountInputField.value);
saveChecklistState();
});
const reasonInputField = document.createElement('input');
reasonInputField.type = 'text';
reasonInputField.value = task.reason;
reasonInputField.className = 'edit-reason-input';
reasonInputField.placeholder = "Por que da tarefa?";
reasonInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-reason', reasonInputField.value);
saveChecklistState();
});
const locationInputField = document.createElement('input');
locationInputField.type = 'text';
locationInputField.value = task.location;
locationInputField.className = 'edit-location-input';
locationInputField.placeholder = "Onde será a tarefa?";
locationInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-location', locationInputField.value);
saveChecklistState();
});
const methodInputField = document.createElement('input');
methodInputField.type = 'text';
methodInputField.value = task.method;
methodInputField.className = 'edit-method-input';
methodInputField.placeholder = "Como será feita essa tarefa?";
methodInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-method', methodInputField.value);
saveChecklistState();
});
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'remove-task-button';
removeButton.textContent = 'x';
removeButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta tarefa?')) {
taskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const blockerButton = document.createElement('button');
blockerButton.type = 'button';
blockerButton.className = 'blocker-button';
blockerButton.innerHTML = '⚠';
blockerButton.addEventListener('click', function() {
taskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubTaskButton = document.createElement('button');
addSubTaskButton.type = 'button';
addSubTaskButton.className = 'add-task-button';
addSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubTaskButton.style.marginLeft = '10px';
addSubTaskButton.addEventListener('click', function() {
const subTaskName = prompt('Digite a nova subtarefa:');
if (subTaskName) {
addSubTask(taskContainer, subTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(taskContainer);
});
const nestedList = document.createElement('div');
nestedList.className = 'nested-list';
if (task.subTasks) {
task.subTasks.forEach(subTask => {
addSubTaskFromData(nestedList, subTask);
});
}
if (task.customFields) {
for (const fieldName in task.customFields) {
const customField = document.createElement('input');
customField.type = 'text';
customField.value = task.customFields[fieldName];
customField.placeholder = fieldName;
customField.className = 'custom-field-input';
taskHeader.appendChild(customField);
}
}
taskHeader.appendChild(toggleButton);
taskHeader.appendChild(checkbox);
taskHeader.appendChild(label);
taskHeader.appendChild(tagInputField);
taskHeader.appendChild(numberInputField);
taskHeader.appendChild(personInputField);
taskHeader.appendChild(dateInputField);
taskHeader.appendChild(endDateInputField);
taskHeader.appendChild(timeInputField);
taskHeader.appendChild(amountInputField);
taskHeader.appendChild(reasonInputField);
taskHeader.appendChild(locationInputField);
taskHeader.appendChild(methodInputField);
taskHeader.appendChild(blockerButton);
taskHeader.appendChild(removeButton);
taskHeader.appendChild(addSubTaskButton);
taskHeader.appendChild(customFieldButton);
taskContainer.appendChild(taskHeader);
taskContainer.appendChild(nestedList);
if (task.blocker) {
taskContainer.classList.add('blocker');
}
checklistItems.appendChild(taskContainer);
initializeSortable(nestedList);
updateCalendar();
}
function addSubTaskFromData(nestedList, subTask) {
const subTaskContainer = document.createElement('div');
subTaskContainer.className = 'checklist-container';
subTaskContainer.setAttribute('data-tag', subTask.tag);
subTaskContainer.setAttribute('data-number', subTask.number);
subTaskContainer.setAttribute('data-person', subTask.person);
subTaskContainer.setAttribute('data-date', subTask.date);
subTaskContainer.setAttribute('data-end-date', subTask.endDate);
subTaskContainer.setAttribute('data-time', subTask.time);
subTaskContainer.setAttribute('data-amount', subTask.amount);
subTaskContainer.setAttribute('data-reason', subTask.reason);
subTaskContainer.setAttribute('data-location', subTask.location);
subTaskContainer.setAttribute('data-method', subTask.method);
const subTaskHeader = document.createElement('div');
subTaskHeader.style.display = 'flex';
subTaskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = subTaskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const subCheckbox = document.createElement('input');
subCheckbox.type = 'checkbox';
subCheckbox.id = subTask.id;
subCheckbox.className = 'checklist-input';
subCheckbox.checked = subTask.checked;
subCheckbox.addEventListener('change', function() {
subLabel.classList.toggle('completed', subCheckbox.checked);
if (subCheckbox.checked) {
moveToCompleted(subTaskContainer);
} else {
nestedList.appendChild(subTaskContainer);
}
saveChecklistState();
});
const subLabel = document.createElement('label');
subLabel.htmlFor = subTask.id;
subLabel.className = 'checklist-label';
subLabel.textContent = subTask.name;
if (subTask.checked) {
subLabel.classList.add('completed');
}
const subNumberInputField = document.createElement('input');
subNumberInputField.type = 'number';
subNumberInputField.value = subTask.number;
subNumberInputField.className = 'edit-number-input';
subNumberInputField.placeholder = "Número";
subNumberInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-number', subNumberInputField.value);
saveChecklistState();
});
const subTagInputField = document.createElement('input');
subTagInputField.type = 'text';
subTagInputField.value = subTask.tag;
subTagInputField.className = 'edit-tag-input';
subTagInputField.placeholder = "Tag";
subTagInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-tag', subTagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const subPersonInputField = document.createElement('input');
subPersonInputField.type = 'text';
subPersonInputField.value = subTask.person;
subPersonInputField.className = 'edit-person-input';
subPersonInputField.placeholder = "Atribuir a";
subPersonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-person', subPersonInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const subDateInputField = document.createElement('input');
subDateInputField.type = 'date';
subDateInputField.value = subTask.date;
subDateInputField.className = 'edit-date-input';
subDateInputField.placeholder = "Data de realização";
subDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-date', subDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subEndDateInputField = document.createElement('input');
subEndDateInputField.type = 'date';
subEndDateInputField.value = subTask.endDate;
subEndDateInputField.className = 'edit-end-date-input';
subEndDateInputField.placeholder = "Data de término";
subEndDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-end-date', subEndDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subTimeInputField = document.createElement('input');
subTimeInputField.type = 'time';
subTimeInputField.value = subTask.time;
subTimeInputField.className = 'edit-time-input';
subTimeInputField.placeholder = "Horário";
subTimeInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-time', subTimeInputField.value);
saveChecklistState();
updateCalendar();
});
const subAmountInputField = document.createElement('input');
subAmountInputField.type = 'number';
subAmountInputField.value = subTask.amount;
subAmountInputField.className = 'edit-amount-input';
subAmountInputField.placeholder = "Quanto";
subAmountInputField.step = "0.01";
subAmountInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-amount', subAmountInputField.value);
saveChecklistState();
});
const subReasonInputField = document.createElement('input');
subReasonInputField.type = 'text';
subReasonInputField.value = subTask.reason;
subReasonInputField.className = 'edit-reason-input';
subReasonInputField.placeholder = "Por que da tarefa?";
subReasonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-reason', subReasonInputField.value);
saveChecklistState();
});
const subLocationInputField = document.createElement('input');
subLocationInputField.type = 'text';
subLocationInputField.value = subTask.location;
subLocationInputField.className = 'edit-location-input';
subLocationInputField.placeholder = "Onde será a tarefa?";
subLocationInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-location', subLocationInputField.value);
saveChecklistState();
});
const subMethodInputField = document.createElement('input');
subMethodInputField.type = 'text';
subMethodInputField.value = subTask.method;
subMethodInputField.className = 'edit-method-input';
subMethodInputField.placeholder = "Como será feita essa tarefa?";
subMethodInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-method', subMethodInputField.value);
saveChecklistState();
});
const subRemoveButton = document.createElement('button');
subRemoveButton.type = 'button';
subRemoveButton.className = 'remove-task-button';
subRemoveButton.textContent = 'x';
subRemoveButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta subtarefa?')) {
subTaskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const subBlockerButton = document.createElement('button');
subBlockerButton.type = 'button';
subBlockerButton.className = 'blocker-button';
subBlockerButton.innerHTML = '⚠';
subBlockerButton.addEventListener('click', function() {
subTaskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubSubTaskButton = document.createElement('button');
addSubSubTaskButton.type = 'button';
addSubSubTaskButton.className = 'add-task-button';
addSubSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubSubTaskButton.style.marginLeft = '10px';
addSubSubTaskButton.addEventListener('click', function() {
const subSubTaskName = prompt('Digite a nova subtarefa:');
if (subSubTaskName) {
addSubTask(subTaskContainer, subSubTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(subTaskContainer);
});
subTaskHeader.appendChild(toggleButton);
subTaskHeader.appendChild(subCheckbox);
subTaskHeader.appendChild(subLabel);
subTaskHeader.appendChild(subTagInputField);
subTaskHeader.appendChild(subNumberInputField);
subTaskHeader.appendChild(subPersonInputField);
subTaskHeader.appendChild(subDateInputField);
subTaskHeader.appendChild(subEndDateInputField);
subTaskHeader.appendChild(subTimeInputField);
subTaskHeader.appendChild(subAmountInputField);
subTaskHeader.appendChild(subReasonInputField);
subTaskHeader.appendChild(subLocationInputField);
subTaskHeader.appendChild(subMethodInputField);
subTaskHeader.appendChild(subBlockerButton);
subTaskHeader.appendChild(subRemoveButton);
subTaskHeader.appendChild(addSubSubTaskButton);
subTaskHeader.appendChild(customFieldButton);
subTaskContainer.appendChild(subTaskHeader);
const subNestedList = document.createElement('div');
subNestedList.className = 'nested-list';
subTaskContainer.appendChild(subNestedList);
nestedList.appendChild(subTaskContainer);
initializeSortable(subNestedList);
updateCalendar();
}
function initializeSortable(container) {
new Sortable(container, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: () => {
saveChecklistState();
}
});
const nestedLists = container.querySelectorAll('.nested-list');
nestedLists.forEach(nestedList => {
new Sortable(nestedList, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: () => {
saveChecklistState();
}
});
});
}
function updateFilterDropdown() {
const tags = new Set();
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
function collectTags(task) {
if (task.tag) {
tags.add(task.tag);
}
if (task.subTasks) {
task.subTasks.forEach(subTask => collectTags(subTask));
}
}
tasks.forEach((task) => {
collectTags(task);
});
const tagFilter = document.getElementById('tagFilter');
tagFilter.innerHTML = '<option value="">Todas</option>';
tags.forEach((tag) => {
const option = document.createElement('option');
option.value = tag;
option.textContent = tag;
tagFilter.appendChild(option);
});
}
function updatePersonFilterDropdown() {
const people = new Set();
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
function collectPeople(task) {
if (task.person) {
people.add(task.person);
}
if (task.subTasks) {
task.subTasks.forEach(subTask => collectPeople(subTask));
}
}
tasks.forEach((task) => {
collectPeople(task);
});
const personFilter = document.getElementById('personFilter');
personFilter.innerHTML = '<option value="">Todas</option>';
people.forEach((person) => {
const option = document.createElement('option');
option.value = person;
option.textContent = person;
personFilter.appendChild(option);
});
}
function filterTasks() {
const selectedTag = document.getElementById('tagFilter').value;
const selectedPerson = document.getElementById('personFilter').value;
const customFieldFilter = document.getElementById('customFieldFilter').value.trim().toLowerCase();
function matchesCustomFilters(taskContainer) {
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
for (const input of customFieldInputs) {
if (input.value.toLowerCase() === customFieldFilter) {
return true;
}
}
return customFieldFilter === '';
}
function matchesFilters(taskContainer) {
const tag = taskContainer.getAttribute('data-tag');
const person = taskContainer.getAttribute('data-person');
const matchesTag = selectedTag === '' || tag === selectedTag;
const matchesPerson = selectedPerson === '' || person === selectedPerson;
const matchesCustom = matchesCustomFilters(taskContainer);
return matchesTag && matchesPerson && matchesCustom;
}
function filterTask(taskContainer) {
const showTask = matchesFilters(taskContainer);
const subTasks = taskContainer.querySelectorAll('.checklist-container');
let showSubTasks = false;
subTasks.forEach(subTask => {
const showSubTask = filterTask(subTask);
showSubTasks = showSubTasks || showSubTask;
});
taskContainer.style.display = showTask || showSubTasks ? 'block' : 'none';
return showTask || showSubTasks;
}
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
filterTask(taskContainer);
});
}
function filterTasksByWord() {
const wordFilter = document.getElementById('wordFilter').value.trim().toLowerCase();
function matchesWordFilter(taskContainer) {
const label = taskContainer.querySelector('.checklist-label');
const labelText = label ? label.textContent.toLowerCase() : '';
const matchesWord = wordFilter === '' || labelText.includes(wordFilter);
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
const matchesCustomFields = Array.from(customFieldInputs).some(input => input.value.toLowerCase().includes(wordFilter));
return matchesWord || matchesCustomFields;
}
function filterTask(taskContainer) {
const showTask = matchesWordFilter(taskContainer);
const subTasks = taskContainer.querySelectorAll('.checklist-container');
let showSubTasks = false;
subTasks.forEach(subTask => {
const showSubTask = filterTask(subTask);
showSubTasks = showSubTasks || showSubTask;
});
taskContainer.style.display = showTask || showSubTasks ? 'block' : 'none';
return showTask || showSubTasks;
}
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
filterTask(taskContainer);
});
}
function sortTasksByNumber() {
const checklistItems = document.getElementById('checklistItems');
const tasks = Array.from(checklistItems.querySelectorAll('.checklist-container'));
tasks.sort((a, b) => {
const numberA = parseInt(a.getAttribute('data-number') || 0);
const numberB = parseInt(b.getAttribute('data-number') || 0);
return numberA - numberB;
});
tasks.forEach((task) => {
checklistItems.appendChild(task);
});
saveChecklistState();
}
function filterBlockers() {
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
const isBlocker = taskContainer.classList.contains('blocker');
taskContainer.style.display = isBlocker ? '' : 'none';
});
}
function generateBlockerReport() {
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
const blockers = tasks.filter(task => task.blocker);
const reportContainer = document.getElementById('blockerReport');
reportContainer.innerHTML = '';
blockers.forEach((task) => {
const reportItem = document.createElement('div');
reportItem.className = 'report-item';
reportItem.textContent = `Tarefa: ${task.name}, Número: ${task.number}, Tag: ${task.tag}, Atribuída a: ${task.person}, Data: ${task.date}, Motivo: ${task.reason}`;
reportContainer.appendChild(reportItem);
if (task.subTasks) {
task.subTasks.forEach(subTask => {
const subReportItem = document.createElement('div');
subReportItem.className = 'report-item';
subReportItem.style.marginLeft = '20px';
subReportItem.textContent = `Subtarefa: ${subTask.name}, Número: ${subTask.number}, Tag: ${subTask.tag}, Atribuída a: ${subTask.person}, Data: ${subTask.date}, Motivo: ${subTask.reason}`;
reportContainer.appendChild(subReportItem);
});
}
});
}
function moveToCompleted(taskContainer) {
const completedTasks = document.getElementById('completedTasks');
const completedTaskContainer = taskContainer.cloneNode(true);
completedTaskContainer.querySelectorAll('.checklist-input').forEach(input => input.disabled = true);
completedTaskContainer.querySelectorAll('.remove-task-button').forEach(button => button.remove());
completedTaskContainer.querySelectorAll('.blocker-button').forEach(button => button.remove());
completedTaskContainer.querySelectorAll('.add-task-button').forEach(button => button.remove());
completedTaskContainer.classList.add('completed-task');
completedTasks.appendChild(completedTaskContainer);
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
addTask();
}
}
function updateCalendar() {
const calendar = document.getElementById('calendar');
calendar.innerHTML = '';
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth();
function createCalendar(month, year) {
const monthName = new Date(year, month).toLocaleString('default', { month: 'long' });
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const weeks = [];
let week = [];
for (let i = 0; i < firstDay; i++) {
week.push('');
}
for (let day = 1; day <= daysInMonth; day++) {
week.push(day);
if (week.length === 7) {
weeks.push(week);
week = [];
}
}
if (week.length > 0) {
while (week.length < 7) {
week.push('');
}
weeks.push(week);
}
const calendarMonth = document.createElement('div');
calendarMonth.className = 'calendar-month';
calendarMonth.textContent = `${monthName} ${year}`;
calendar.appendChild(calendarMonth);
weeks.forEach(week => {
const calendarWeek = document.createElement('div');
calendarWeek.className = 'calendar-week';
week.forEach(day => {
const calendarDay = document.createElement('div');
calendarDay.className = 'calendar-day';
calendarDay.textContent = day;
if (day !== '') {
calendarDay.addEventListener('click', () => {
const taskName = prompt('Digite o nome do evento:');
const taskTime = prompt('Digite o horário do evento (HH:MM):');
if (taskName) {
addEventToDay(calendarDay, taskName, taskTime);
}
});
}
calendarWeek.appendChild(calendarDay);
});
calendar.appendChild(calendarWeek);
});
}
for (let i = -1; i <= 1; i++) {
const year = currentYear + Math.floor((currentMonth + i) / 12);
const month = (currentMonth + i) % 12;
createCalendar(month, year);
}
const eventsList = document.getElementById('eventsList');
eventsList.innerHTML = '';
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
tasks.forEach((task) => {
if (task.date) {
addEventToCalendar(task.date, task.name, task.time, false);
}
if (task.endDate) {
addEventToCalendar(task.endDate, task.name, task.time, true);
}
if (task.subTasks) {
task.subTasks.forEach((subTask) => {
if (subTask.date) {
addEventToCalendar(subTask.date, subTask.name, subTask.time, false);
}
if (subTask.endDate) {
addEventToCalendar(subTask.endDate, subTask.name, subTask.time, true);
}
});
}
});
}
function addEventToDay(dayElement, eventName, eventTime) {
const event = document.createElement('div');
event.className = 'calendar-event';
event.textContent = eventName;
if (eventTime) {
const time = document.createElement('div');
time.className = 'calendar-hour';
time.textContent = eventTime;
event.appendChild(time);
}
dayElement.appendChild(event);
saveEventToLocalStorage(dayElement.textContent, eventName, eventTime);
}
function saveEventToLocalStorage(day, eventName, eventTime) {
const events = JSON.parse(localStorage.getItem('calendarEvents')) || [];
const event = {
day: day,
name: eventName,
time: eventTime
};
events.push(event);
localStorage.setItem('calendarEvents', JSON.stringify(events));
}
function addEventToCalendar(date, eventName, eventTime, isEnd) {
const calendarDays = document.querySelectorAll('.calendar-day');
const dateObj = new Date(date);
const day = dateObj.getDate();
calendarDays.forEach((dayElement) => {
if (parseInt(dayElement.textContent) === day) {
const event = document.createElement('div');
event.className = isEnd ? 'calendar-event end' : 'calendar-event';
event.textContent = eventName;
if (eventTime) {
const time = document.createElement('div');
time.className = 'calendar-hour';
time.textContent = eventTime;
event.appendChild(time);
}
dayElement.appendChild(event);
}
});
}
function addCustomField(taskContainer) {
const fieldName = prompt('Digite o nome do campo personalizado:');
if (fieldName) {
const customField = document.createElement('input');
customField.type = 'text';
customField.placeholder = fieldName;
customField.className = 'custom-field-input';
customField.addEventListener('change', function() {
saveChecklistState();
});
const taskHeader = taskContainer.querySelector('div');
taskHeader.appendChild(customField);
saveChecklistState();
}
}
document.addEventListener('DOMContentLoaded', () => {
restoreChecklistState();
initializeSortable(document.getElementById('checklistItems'));
initializeSortable(document.getElementById('eventsList'));
});
</script>
</body>
</html>
relatório de
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ballaminut Networking - Sistema de produtividade</title>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
background-color: #f2f2f2;
}
td {
vertical-align: top;
}
.checklist {
margin-right: 5px;
}
.checklist-container {
display: flex;
flex-direction: column;
margin: 10px 0;
}
.nested-list {
margin-left: 20px;
display: none;
}
.checklist-label {
font-size: 18px;
margin-left: 10px;
text-decoration: none;
cursor: pointer;
}
.checklist-label.completed {
text-decoration: line-through;
}
.checklist-input {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: orange;
}
.add-task-container {
margin-bottom: 20px;
}
.add-task-input,
.add-tag-input,
.add-number-input,
.add-person-input,
.add-date-input,
.add-end-date-input,
.add-time-input,
.add-amount-input,
.add-reason-input,
.add-location-input,
.add-method-input {
padding: 5px;
font-size: 16px;
}
.add-task-button {
margin-left: 10px;
padding: 8px 16px;
font-size: 16px;
cursor: pointer;
background-color: orange;
color: white;
border: none;
border-radius: 5px;
}
.add-task-button:hover {
background-color: black;
}
.remove-task-button {
cursor: pointer;
margin-left: 5px;
padding: 2px 4px;
font-size: 10px;
background-color: white;
color: gray;
border: none;
border-radius: 3px;
opacity: 0.8;
}
.remove-task-button:hover {
background-color: lightgray;
}
.edit-number-input,
.edit-tag-input,
.edit-person-input,
.edit-date-input,
.edit-end-date-input,
.edit-time-input,
.edit-amount-input,
.edit-reason-input,
.edit-location-input,
.edit-method-input {
width: 100px;
font-size: 14px;
padding: 2px;
margin-left: 10px;
}
.filter-container {
margin-bottom: 20px;
}
.filter-dropdown {
padding: 5px;
font-size: 16px;
}
.sort-button {
padding: 5px 10px;
font-size: 16px;
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
margin-left: 10px;
}
.sort-button:hover {
background-color: #0056b3;
}
.blocker-button {
cursor: pointer;
margin-left: 5px;
padding: 2px 4px;
font-size: 14px;
background-color: transparent;
color: red;
border: none;
border-radius: 3px;
}
.blocker-button:hover {
color: darkred;
}
.blocker {
background-color: #ffcccc;
}
.project-title {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.toggle {
cursor: pointer;
font-weight: bold;
margin-right: 10px;
}
.calendar {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 20px;
}
.calendar-month {
width: 100%;
text-align: center;
font-weight: bold;
margin: 20px 0;
}
.calendar-day {
width: calc(100% / 7 - 10px);
text-align: center;
border: 1px solid #ccc;
padding: 5px;
cursor: pointer;
}
.calendar-day.occupied {
background-color: #ccc;
}
.calendar-hour {
font-size: 0.8em;
margin-top: 2px;
}
.calendar-week {
display: flex;
justify-content: space-between;
width: 100%;
}
.calendar-event {
background-color: orange;
color: white;
margin: 2px 0;
padding: 2px;
}
.calendar-event.end {
background-color: blue;
color: white;
}
.completed-tasks-container {
margin-top: 40px;
}
.completed-task {
text-decoration: line-through;
color: gray;
}
.report-container {
margin-top: 40px;
}
.report-item {
margin-bottom: 10px;
}
</style>
</head>
<body>
<center><h1>Ballaminut Networking - Sistema de produtividade</h1>
<table>
<tr>
<th>Detalhes</th>
<th>Detalhes</th>
<th>Detalhes</th>
<th>Detalhes</th>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Por que da tarefa?</td>
<td><input type="checkbox" class="checklist"> Traz dinheiro?</td>
<td><input type="checkbox" class="checklist"> Tipo de custo</td>
<td><input type="checkbox" class="checklist"> Gera reels?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Onde será a tarefa?</td>
<td><input type="checkbox" class="checklist"> Valor</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de custo</td>
<td><input type="checkbox" class="checklist"> Aula no YouTube?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Como será feita essa tarefa?</td>
<td><input type="checkbox" class="checklist"> 0%</td>
<td><input type="checkbox" class="checklist"> Tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Gera encontro?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Recorrente?</td>
<td><input type="checkbox" class="checklist"> Nome do cargo</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de despesa</td>
<td><input type="checkbox" class="checklist"> Passível de negociação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Hábito?</td>
<td><input type="checkbox" class="checklist"> Departamento</td>
<td><input type="checkbox" class="checklist"> Tipo de receita</td>
<td><input type="checkbox" class="checklist"> Passível de acordo?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Pago?</td>
<td><input type="checkbox" class="checklist"> Fornecedor?</td>
<td><input type="checkbox" class="checklist"> Detalhe do tipo de receita</td>
<td><input type="checkbox" class="checklist"> Compra feita?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Leva ao objetivo?</td>
<td><input type="checkbox" class="checklist"> Nome da empresa</td>
<td><input type="checkbox" class="checklist"> Resultado</td>
<td><input type="checkbox" class="checklist"> Compra do cliente?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É uma decisão?</td>
<td><input type="checkbox" class="checklist"> Status</td>
<td><input type="checkbox" class="checklist"> Detalhe do resultado</td>
<td><input type="checkbox" class="checklist"> Compra a fazer?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem um guardião?</td>
<td><input type="checkbox" class="checklist"> Filial?</td>
<td><input type="checkbox" class="checklist"> Gera storie?</td>
<td><input type="checkbox" class="checklist"> Método de pagamento</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de dor</td>
<td><input type="checkbox" class="checklist"> Compromisso?</td>
<td><input type="checkbox" class="checklist"> Post para blog?</td>
<td><input type="checkbox" class="checklist"> É dívida?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Nível de humor</td>
<td><input type="checkbox" class="checklist"> Know-how?</td>
<td><input type="checkbox" class="checklist"> Post para grupo?</td>
<td><input type="checkbox" class="checklist"> Antecipação?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> É um sacrifício?</td>
<td><input type="checkbox" class="checklist"> Necessita de parceiro?</td>
<td><input type="checkbox" class="checklist"> Conteúdo para feed?</td>
<td><input type="checkbox" class="checklist"> Alta margem?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Ferramenta que facilita</td>
<td><input type="checkbox" class="checklist"> Delegável?</td>
<td><input type="checkbox" class="checklist"> Alto desconto?</td>
<td><input type="checkbox" class="checklist"> Agrega ao inventário?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tem sinergia?</td>
<td><input type="checkbox" class="checklist"> Automatizável?</td>
<td><input type="checkbox" class="checklist"> Orçamento?</td>
<td><input type="checkbox" class="checklist"> Agrega à marca?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
<td><input type="checkbox" class="checklist"> Recebimento de dinheiro?</td>
<td><input type="checkbox" class="checklist"> Redução de custo?</td>
<td><input type="checkbox" class="checklist"> Tempo de qualidade?</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Plano de contingência?</td>
<td><input type="checkbox" class="checklist"> Despesa?</td>
<td><input type="checkbox" class="checklist"> Quebra se mãe doente?</td>
<td><input type="checkbox" class="checklist"> Status da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Validada?</td>
<td><input type="checkbox" class="checklist"> Previsão de recebimento?</td>
<td><input type="checkbox" class="checklist"> Quebra se doente?</td>
<td><input type="checkbox" class="checklist"> Dificuldade da tarefa</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Relevante?</td>
<td><input type="checkbox" class="checklist"> Previsão de saída?</td>
<td><input type="checkbox" class="checklist"> Quebra se Covid?</td>
<td><input type="checkbox" class="checklist"> Tipo de atividade</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Gera brigas?</td>
<td><input type="checkbox" class="checklist"> Coerência empreendedora</td>
<td><input type="checkbox" class="checklist"> Perfil</td>
<td><input type="checkbox" class="checklist"> Feito por</td>
</tr>
<tr>
<td><input type="checkbox" class="checklist"> Melhor ambiente</td>
<td><input type="checkbox" class="checklist"> É um marco?</td>
<td><input type="checkbox" class="checklist"> Nível da atividade</td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Atividade de risco?</td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" class="checklist"> Tem redundância?</td>
<td></td>
<td></td>
</tr>
</table>
</center>
<br>
<br>
<b>
<subtitle> >>> Adicione as suas tarefas aqui!!!</subtitle>
<br>
<br>
<div class="add-task-container">
<input type="text" id="newTask" class="add-task-input" placeholder="Digite uma nova tarefa" onkeydown="handleKeyPress(event)">
<input type="text" id="newTag" class="add-tag-input" placeholder="Digite uma tag">
<input type="number" id="newNumber" class="add-number-input" placeholder="Número" min="1">
<input type="text" id="newPerson" class="add-person-input" placeholder="Atribuir a">
<input type="date" id="newDate" class="add-date-input" placeholder="Data de realização">
<input type="date" id="newEndDate" class="add-end-date-input" placeholder="Data de término">
<input type="time" id="newTime" class="add-time-input" placeholder="Horário">
<input type="number" id="newAmount" class="add-amount-input" placeholder="Quanto" step="0.01">
<input type="text" id="newReason" class="add-reason-input" placeholder="Por que da tarefa?">
<input type="text" id="newLocation" class="add-location-input" placeholder="Onde será a tarefa?">
<input type="text" id="newMethod" class="add-method-input" placeholder="Como será feita essa tarefa?">
<button onclick="addTask()" class="add-task-button">Adicionar Tarefa</button>
<button onclick="addCustomField()" class="add-task-button">Adicionar Campo Personalizado</button>
</div>
<div class="filter-container">
<input type="text" id="wordFilter" placeholder="Digite uma palavra para filtrar" oninput="filterTasksByWord()">
<button onclick="filterTasksByWord()">Filtrar</button>
<label for="tagFilter">Filtrar por tag:</label>
<select id="tagFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="personFilter">Filtrar por pessoa:</label>
<select id="personFilter" class="filter-dropdown" onchange="filterTasks()">
<option value="">Todas</option>
</select>
<label for="customFieldFilter">Filtrar por campo personalizado:</label>
<input type="text" id="customFieldFilter" class="filter-dropdown" placeholder="Digite o valor exato" oninput="filterTasks()">
<button onclick="sortTasksByNumber()" class="sort-button">Ordenar por Número</button>
<button onclick="filterBlockers()" class="sort-button">Mostrar Bloqueantes</button>
<button onclick="generateBlockerReport()" class="sort-button">Gerar Relatório de Bloqueantes</button>
</div>
<div id="projectTitle" class="project-title"></div>
<div id="checklistItems" class="checklist-items">
<!-- Itens de checklist serão adicionados aqui dinamicamente -->
</div>
<div id="calendar">
<div class="day" data-date="2024-07-30">
<h3>30/07/2024</h3>
<div class="taskContainer" id="tasks_2024-07-30">
<!-- Tarefas do dia 30/07/2024 -->
</div>
</div>
<div class="day" data-date="2024-07-31">
<h3>31/07/2024</h3>
<div class="taskContainer" id="tasks_2024-07-31">
<!-- Tarefas do dia 31/07/2024 -->
</div>
</div>
</div>
<div class="completed-tasks-container">
<h2>Histórico de Atividades Concluídas</h2>
<div id="completedTasks">
<!-- Atividades concluídas serão adicionadas aqui dinamicamente -->
</div>
</div>
<div class="report-container">
<h2>Relatório de Atividades Bloqueantes</h2>
<div id="blockerReport">
<!-- Relatório de bloqueantes será preenchido dinamicamente -->
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<script>
// Funções de checklist
function addTask() {
const taskInput = document.getElementById('newTask');
const taskName = taskInput.value.trim();
const tagInput = document.getElementById('newTag');
const tagName = tagInput.value.trim().toLowerCase();
const numberInput = document.getElementById('newNumber');
const taskNumber = numberInput.value.trim();
const personInput = document.getElementById('newPerson');
const personName = personInput.value.trim();
const dateInput = document.getElementById('newDate');
const taskDate = dateInput.value;
const endDateInput = document.getElementById('newEndDate');
const endDate = endDateInput.value;
const timeInput = document.getElementById('newTime');
const taskTime = timeInput.value;
const amountInput = document.getElementById('newAmount');
const amount = amountInput.value.trim();
const reasonInput = document.getElementById('newReason');
const taskReason = reasonInput.value.trim();
const locationInput = document.getElementById('newLocation');
const taskLocation = locationInput.value.trim();
const methodInput = document.getElementById('newMethod');
const taskMethod = methodInput.value.trim();
if (taskName !== '' && taskNumber !== '') {
const checklistItems = document.getElementById('checklistItems');
const newTaskId = `task-${Date.now()}`;
const taskContainer = document.createElement('div');
taskContainer.className = 'checklist-container';
taskContainer.setAttribute('data-tag', tagName);
taskContainer.setAttribute('data-number', taskNumber);
taskContainer.setAttribute('data-person', personName);
taskContainer.setAttribute('data-date', taskDate);
taskContainer.setAttribute('data-end-date', endDate);
taskContainer.setAttribute('data-time', taskTime);
taskContainer.setAttribute('data-amount', amount);
taskContainer.setAttribute('data-reason', taskReason);
taskContainer.setAttribute('data-location', taskLocation);
taskContainer.setAttribute('data-method', taskMethod);
const taskHeader = document.createElement('div');
taskHeader.style.display = 'flex';
taskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = taskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = newTaskId;
checkbox.className = 'checklist-input';
checkbox.addEventListener('change', function() {
label.classList.toggle('completed', checkbox.checked);
if (checkbox.checked) {
moveToCompleted(taskContainer);
} else {
checklistItems.appendChild(taskContainer);
}
saveChecklistState();
});
const label = document.createElement('label');
label.htmlFor = newTaskId;
label.className = 'checklist-label';
label.textContent = taskName;
label.addEventListener('click', function() {
setProjectTitle(label.textContent);
});
const numberInputField = document.createElement('input');
numberInputField.type = 'number';
numberInputField.value = taskNumber;
numberInputField.className = 'edit-number-input';
numberInputField.placeholder = "Número";
numberInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-number', numberInputField.value);
saveChecklistState();
});
const tagInputField = document.createElement('input');
tagInputField.type = 'text';
tagInputField.value = tagName;
tagInputField.className = 'edit-tag-input';
tagInputField.placeholder = "Tag";
tagInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-tag', tagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const personInputField = document.createElement('input');
personInputField.type = 'text';
personInputField.value = personName;
personInputField.className = 'edit-person-input';
personInputField.placeholder = "Atribuir a";
personInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-person', personInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const dateInputField = document.createElement('input');
dateInputField.type = 'date';
dateInputField.value = taskDate;
dateInputField.className = 'edit-date-input';
dateInputField.placeholder = "Data de realização";
dateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-date', dateInputField.value);
saveChecklistState();
updateCalendar();
});
const endDateInputField = document.createElement('input');
endDateInputField.type = 'date';
endDateInputField.value = endDate;
endDateInputField.className = 'edit-end-date-input';
endDateInputField.placeholder = "Data de término";
endDateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-end-date', endDateInputField.value);
saveChecklistState();
updateCalendar();
});
const timeInputField = document.createElement('input');
timeInputField.type = 'time';
timeInputField.value = taskTime;
timeInputField.className = 'edit-time-input';
timeInputField.placeholder = "Horário";
timeInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-time', timeInputField.value);
saveChecklistState();
updateCalendar();
});
const amountInputField = document.createElement('input');
amountInputField.type = 'number';
amountInputField.value = amount;
amountInputField.className = 'edit-amount-input';
amountInputField.placeholder = "Quanto";
amountInputField.step = "0.01";
amountInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-amount', amountInputField.value);
saveChecklistState();
});
const reasonInputField = document.createElement('input');
reasonInputField.type = 'text';
reasonInputField.value = taskReason;
reasonInputField.className = 'edit-reason-input';
reasonInputField.placeholder = "Por que da tarefa?";
reasonInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-reason', reasonInputField.value);
saveChecklistState();
});
const locationInputField = document.createElement('input');
locationInputField.type = 'text';
locationInputField.value = taskLocation;
locationInputField.className = 'edit-location-input';
locationInputField.placeholder = "Onde será a tarefa?";
locationInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-location', locationInputField.value);
saveChecklistState();
});
const methodInputField = document.createElement('input');
methodInputField.type = 'text';
methodInputField.value = taskMethod;
methodInputField.className = 'edit-method-input';
methodInputField.placeholder = "Como será feita essa tarefa?";
methodInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-method', methodInputField.value);
saveChecklistState();
});
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'remove-task-button';
removeButton.textContent = 'x';
removeButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta tarefa?')) {
taskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const blockerButton = document.createElement('button');
blockerButton.type = 'button';
blockerButton.className = 'blocker-button';
blockerButton.innerHTML = '⚠';
blockerButton.addEventListener('click', function() {
taskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubTaskButton = document.createElement('button');
addSubTaskButton.type = 'button';
addSubTaskButton.className = 'add-task-button';
addSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubTaskButton.style.marginLeft = '10px';
addSubTaskButton.addEventListener('click', function() {
const subTaskName = prompt('Digite a nova subtarefa:');
if (subTaskName) {
addSubTask(taskContainer, subTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(taskContainer);
});
const nestedList = document.createElement('div');
nestedList.className = 'nested-list';
taskHeader.appendChild(toggleButton);
taskHeader.appendChild(checkbox);
taskHeader.appendChild(label);
taskHeader.appendChild(tagInputField);
taskHeader.appendChild(numberInputField);
taskHeader.appendChild(personInputField);
taskHeader.appendChild(dateInputField);
taskHeader.appendChild(endDateInputField);
taskHeader.appendChild(timeInputField);
taskHeader.appendChild(amountInputField);
taskHeader.appendChild(reasonInputField);
taskHeader.appendChild(locationInputField);
taskHeader.appendChild(methodInputField);
taskHeader.appendChild(blockerButton);
taskHeader.appendChild(removeButton);
taskHeader.appendChild(addSubTaskButton);
taskHeader.appendChild(customFieldButton);
taskContainer.appendChild(taskHeader);
taskContainer.appendChild(nestedList);
checklistItems.appendChild(taskContainer);
taskInput.value = '';
tagInput.value = '';
numberInput.value = '';
personInput.value = '';
dateInput.value = '';
endDateInput.value = '';
timeInput.value = '';
amountInput.value = '';
reasonInput.value = '';
locationInput.value = '';
methodInput.value = '';
saveChecklistState();
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
}
function addSubTask(parentTaskContainer, subTaskName) {
const nestedList = parentTaskContainer.querySelector('.nested-list');
const subTaskId = `subtask-${Date.now()}`;
const subTaskContainer = document.createElement('div');
subTaskContainer.className = 'checklist-container';
subTaskContainer.setAttribute('data-tag', '');
subTaskContainer.setAttribute('data-number', '');
subTaskContainer.setAttribute('data-person', '');
subTaskContainer.setAttribute('data-date', '');
subTaskContainer.setAttribute('data-end-date', '');
subTaskContainer.setAttribute('data-time', '');
subTaskContainer.setAttribute('data-amount', '');
subTaskContainer.setAttribute('data-reason', '');
subTaskContainer.setAttribute('data-location', '');
subTaskContainer.setAttribute('data-method', '');
const subTaskHeader = document.createElement('div');
subTaskHeader.style.display = 'flex';
subTaskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = subTaskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const subCheckbox = document.createElement('input');
subCheckbox.type = 'checkbox';
subCheckbox.id = subTaskId;
subCheckbox.className = 'checklist-input';
subCheckbox.addEventListener('change', function() {
subLabel.classList.toggle('completed', subCheckbox.checked);
if (subCheckbox.checked) {
moveToCompleted(subTaskContainer);
} else {
nestedList.appendChild(subTaskContainer);
}
saveChecklistState();
});
const subLabel = document.createElement('label');
subLabel.htmlFor = subTaskId;
subLabel.className = 'checklist-label';
subLabel.textContent = subTaskName;
const subNumberInputField = document.createElement('input');
subNumberInputField.type = 'number';
subNumberInputField.value = '';
subNumberInputField.className = 'edit-number-input';
subNumberInputField.placeholder = "Número";
subNumberInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-number', subNumberInputField.value);
saveChecklistState();
});
const subTagInputField = document.createElement('input');
subTagInputField.type = 'text';
subTagInputField.value = '';
subTagInputField.className = 'edit-tag-input';
subTagInputField.placeholder = "Tag";
subTagInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-tag', subTagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const subPersonInputField = document.createElement('input');
subPersonInputField.type = 'text';
subPersonInputField.value = '';
subPersonInputField.className = 'edit-person-input';
subPersonInputField.placeholder = "Atribuir a";
subPersonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-person', subPersonInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const subDateInputField = document.createElement('input');
subDateInputField.type = 'date';
subDateInputField.value = '';
subDateInputField.className = 'edit-date-input';
subDateInputField.placeholder = "Data de realização";
subDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-date', subDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subEndDateInputField = document.createElement('input');
subEndDateInputField.type = 'date';
subEndDateInputField.value = '';
subEndDateInputField.className = 'edit-end-date-input';
subEndDateInputField.placeholder = "Data de término";
subEndDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-end-date', subEndDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subTimeInputField = document.createElement('input');
subTimeInputField.type = 'time';
subTimeInputField.value = '';
subTimeInputField.className = 'edit-time-input';
subTimeInputField.placeholder = "Horário";
subTimeInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-time', subTimeInputField.value);
saveChecklistState();
updateCalendar();
});
const subAmountInputField = document.createElement('input');
subAmountInputField.type = 'number';
subAmountInputField.value = '';
subAmountInputField.className = 'edit-amount-input';
subAmountInputField.placeholder = "Quanto";
subAmountInputField.step = "0.01";
subAmountInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-amount', subAmountInputField.value);
saveChecklistState();
});
const subReasonInputField = document.createElement('input');
subReasonInputField.type = 'text';
subReasonInputField.value = '';
subReasonInputField.className = 'edit-reason-input';
subReasonInputField.placeholder = "Por que da tarefa?";
subReasonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-reason', subReasonInputField.value);
saveChecklistState();
});
const subLocationInputField = document.createElement('input');
subLocationInputField.type = 'text';
subLocationInputField.value = '';
subLocationInputField.className = 'edit-location-input';
subLocationInputField.placeholder = "Onde será a tarefa?";
subLocationInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-location', subLocationInputField.value);
saveChecklistState();
});
const subMethodInputField = document.createElement('input');
subMethodInputField.type = 'text';
subMethodInputField.value = '';
subMethodInputField.className = 'edit-method-input';
subMethodInputField.placeholder = "Como será feita essa tarefa?";
subMethodInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-method', subMethodInputField.value);
saveChecklistState();
});
const subRemoveButton = document.createElement('button');
subRemoveButton.type = 'button';
subRemoveButton.className = 'remove-task-button';
subRemoveButton.textContent = 'x';
subRemoveButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta subtarefa?')) {
subTaskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const subBlockerButton = document.createElement('button');
subBlockerButton.type = 'button';
subBlockerButton.className = 'blocker-button';
subBlockerButton.innerHTML = '⚠';
subBlockerButton.addEventListener('click', function() {
subTaskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubSubTaskButton = document.createElement('button');
addSubSubTaskButton.type = 'button';
addSubSubTaskButton.className = 'add-task-button';
addSubSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubSubTaskButton.style.marginLeft = '10px';
addSubSubTaskButton.addEventListener('click', function() {
const subSubTaskName = prompt('Digite a nova subtarefa:');
if (subSubTaskName) {
addSubTask(subTaskContainer, subSubTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(subTaskContainer);
});
subTaskHeader.appendChild(toggleButton);
subTaskHeader.appendChild(subCheckbox);
subTaskHeader.appendChild(subLabel);
subTaskHeader.appendChild(subTagInputField);
subTaskHeader.appendChild(subNumberInputField);
subTaskHeader.appendChild(subPersonInputField);
subTaskHeader.appendChild(subDateInputField);
subTaskHeader.appendChild(subEndDateInputField);
subTaskHeader.appendChild(subTimeInputField);
subTaskHeader.appendChild(subAmountInputField);
subTaskHeader.appendChild(subReasonInputField);
subTaskHeader.appendChild(subLocationInputField);
subTaskHeader.appendChild(subMethodInputField);
subTaskHeader.appendChild(subBlockerButton);
subTaskHeader.appendChild(subRemoveButton);
subTaskHeader.appendChild(addSubSubTaskButton);
subTaskHeader.appendChild(customFieldButton);
subTaskContainer.appendChild(subTaskHeader);
const subNestedList = document.createElement('div');
subNestedList.className = 'nested-list';
subTaskContainer.appendChild(subNestedList);
nestedList.appendChild(subTaskContainer);
initializeSortable(subNestedList);
updateCalendar();
}
function setProjectTitle(title) {
const projectTitle = document.getElementById('projectTitle');
projectTitle.textContent = title;
}
function saveChecklistState() {
const tasks = [];
const checklistItems = document.querySelectorAll('#checklistItems > .checklist-container');
checklistItems.forEach((taskContainer) => {
const taskHeader = taskContainer.querySelector('div');
const checkbox = taskContainer.querySelector('.checklist-input');
const label = taskContainer.querySelector('.checklist-label');
const tag = taskContainer.querySelector('.edit-tag-input').value.toLowerCase();
const number = taskContainer.querySelector('.edit-number-input').value;
const person = taskContainer.querySelector('.edit-person-input').value;
const date = taskContainer.querySelector('.edit-date-input').value;
const endDate = taskContainer.querySelector('.edit-end-date-input').value;
const time = taskContainer.querySelector('.edit-time-input').value;
const amount = taskContainer.querySelector('.edit-amount-input').value;
const reason = taskContainer.querySelector('.edit-reason-input').value;
const location = taskContainer.querySelector('.edit-location-input').value;
const method = taskContainer.querySelector('.edit-method-input').value;
const isBlocker = taskContainer.classList.contains('blocker');
const subTasks = Array.from(taskContainer.querySelector('.nested-list').children).map(subTask => getTaskData(subTask));
const customFields = getCustomFields(taskContainer);
tasks.push({
id: checkbox.id,
name: label.textContent,
checked: checkbox.checked,
tag: tag,
number: number,
person: person,
date: date,
endDate: endDate,
time: time,
amount: amount,
reason: reason,
location: location,
method: method,
blocker: isBlocker,
subTasks: subTasks,
customFields: customFields
});
});
localStorage.setItem('checklistItems', JSON.stringify(tasks));
}
function getTaskData(taskContainer) {
const checkbox = taskContainer.querySelector('.checklist-input');
const label = taskContainer.querySelector('.checklist-label');
const tag = taskContainer.querySelector('.edit-tag-input').value.toLowerCase();
const number = taskContainer.querySelector('.edit-number-input').value;
const person = taskContainer.querySelector('.edit-person-input').value;
const date = taskContainer.querySelector('.edit-date-input').value;
const endDate = taskContainer.querySelector('.edit-end-date-input').value;
const time = taskContainer.querySelector('.edit-time-input').value;
const amount = taskContainer.querySelector('.edit-amount-input').value;
const reason = taskContainer.querySelector('.edit-reason-input').value;
const location = taskContainer.querySelector('.edit-location-input').value;
const method = taskContainer.querySelector('.edit-method-input').value;
const isBlocker = taskContainer.classList.contains('blocker');
const subTasks = Array.from(taskContainer.querySelector('.nested-list').children).map(subTask => getTaskData(subTask));
const customFields = getCustomFields(taskContainer);
return {
id: checkbox.id,
name: label.textContent,
checked: checkbox.checked,
tag: tag,
number: number,
person: person,
date: date,
endDate: endDate,
time: time,
amount: amount,
reason: reason,
location: location,
method: method,
blocker: isBlocker,
subTasks: subTasks,
customFields: customFields
};
}
function getCustomFields(taskContainer) {
const customFields = {};
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
customFieldInputs.forEach(input => {
customFields[input.placeholder] = input.value;
});
return customFields;
}
function restoreChecklistState() {
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
tasks.forEach((task) => {
addTaskFromData(task);
});
updateFilterDropdown();
updatePersonFilterDropdown();
updateCalendar();
}
function addTaskFromData(task) {
const checklistItems = document.getElementById('checklistItems');
const taskContainer = document.createElement('div');
taskContainer.className = 'checklist-container';
taskContainer.setAttribute('data-tag', task.tag);
taskContainer.setAttribute('data-number', task.number);
taskContainer.setAttribute('data-person', task.person);
taskContainer.setAttribute('data-date', task.date);
taskContainer.setAttribute('data-end-date', task.endDate);
taskContainer.setAttribute('data-time', task.time);
taskContainer.setAttribute('data-amount', task.amount);
taskContainer.setAttribute('data-reason', task.reason);
taskContainer.setAttribute('data-location', task.location);
taskContainer.setAttribute('data-method', task.method);
const taskHeader = document.createElement('div');
taskHeader.style.display = 'flex';
taskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = taskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = task.id;
checkbox.className = 'checklist-input';
checkbox.checked = task.checked;
checkbox.addEventListener('change', function() {
label.classList.toggle('completed', checkbox.checked);
if (checkbox.checked) {
moveToCompleted(taskContainer);
} else {
checklistItems.appendChild(taskContainer);
}
saveChecklistState();
});
const label = document.createElement('label');
label.htmlFor = task.id;
label.className = 'checklist-label';
label.textContent = task.name;
if (task.checked) {
label.classList.add('completed');
}
label.addEventListener('click', function() {
setProjectTitle(label.textContent);
});
const numberInputField = document.createElement('input');
numberInputField.type = 'number';
numberInputField.value = task.number;
numberInputField.className = 'edit-number-input';
numberInputField.placeholder = "Número";
numberInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-number', numberInputField.value);
saveChecklistState();
});
const tagInputField = document.createElement('input');
tagInputField.type = 'text';
tagInputField.value = task.tag;
tagInputField.className = 'edit-tag-input';
tagInputField.placeholder = "Tag";
tagInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-tag', tagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const personInputField = document.createElement('input');
personInputField.type = 'text';
personInputField.value = task.person;
personInputField.className = 'edit-person-input';
personInputField.placeholder = "Atribuir a";
personInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-person', personInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const dateInputField = document.createElement('input');
dateInputField.type = 'date';
dateInputField.value = task.date;
dateInputField.className = 'edit-date-input';
dateInputField.placeholder = "Data de realização";
dateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-date', dateInputField.value);
saveChecklistState();
updateCalendar();
});
const endDateInputField = document.createElement('input');
endDateInputField.type = 'date';
endDateInputField.value = task.endDate;
endDateInputField.className = 'edit-end-date-input';
endDateInputField.placeholder = "Data de término";
endDateInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-end-date', endDateInputField.value);
saveChecklistState();
updateCalendar();
});
const timeInputField = document.createElement('input');
timeInputField.type = 'time';
timeInputField.value = task.time;
timeInputField.className = 'edit-time-input';
timeInputField.placeholder = "Horário";
timeInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-time', timeInputField.value);
saveChecklistState();
updateCalendar();
});
const amountInputField = document.createElement('input');
amountInputField.type = 'number';
amountInputField.value = task.amount;
amountInputField.className = 'edit-amount-input';
amountInputField.placeholder = "Quanto";
amountInputField.step = "0.01";
amountInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-amount', amountInputField.value);
saveChecklistState();
});
const reasonInputField = document.createElement('input');
reasonInputField.type = 'text';
reasonInputField.value = task.reason;
reasonInputField.className = 'edit-reason-input';
reasonInputField.placeholder = "Por que da tarefa?";
reasonInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-reason', reasonInputField.value);
saveChecklistState();
});
const locationInputField = document.createElement('input');
locationInputField.type = 'text';
locationInputField.value = task.location;
locationInputField.className = 'edit-location-input';
locationInputField.placeholder = "Onde será a tarefa?";
locationInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-location', locationInputField.value);
saveChecklistState();
});
const methodInputField = document.createElement('input');
methodInputField.type = 'text';
methodInputField.value = task.method;
methodInputField.className = 'edit-method-input';
methodInputField.placeholder = "Como será feita essa tarefa?";
methodInputField.addEventListener('change', function() {
taskContainer.setAttribute('data-method', methodInputField.value);
saveChecklistState();
});
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'remove-task-button';
removeButton.textContent = 'x';
removeButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta tarefa?')) {
taskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const blockerButton = document.createElement('button');
blockerButton.type = 'button';
blockerButton.className = 'blocker-button';
blockerButton.innerHTML = '⚠';
blockerButton.addEventListener('click', function() {
taskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubTaskButton = document.createElement('button');
addSubTaskButton.type = 'button';
addSubTaskButton.className = 'add-task-button';
addSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubTaskButton.style.marginLeft = '10px';
addSubTaskButton.addEventListener('click', function() {
const subTaskName = prompt('Digite a nova subtarefa:');
if (subTaskName) {
addSubTask(taskContainer, subTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(taskContainer);
});
const nestedList = document.createElement('div');
nestedList.className = 'nested-list';
if (task.subTasks) {
task.subTasks.forEach(subTask => {
addSubTaskFromData(nestedList, subTask);
});
}
if (task.customFields) {
for (const fieldName in task.customFields) {
const customField = document.createElement('input');
customField.type = 'text';
customField.value = task.customFields[fieldName];
customField.placeholder = fieldName;
customField.className = 'custom-field-input';
taskHeader.appendChild(customField);
}
}
taskHeader.appendChild(toggleButton);
taskHeader.appendChild(checkbox);
taskHeader.appendChild(label);
taskHeader.appendChild(tagInputField);
taskHeader.appendChild(numberInputField);
taskHeader.appendChild(personInputField);
taskHeader.appendChild(dateInputField);
taskHeader.appendChild(endDateInputField);
taskHeader.appendChild(timeInputField);
taskHeader.appendChild(amountInputField);
taskHeader.appendChild(reasonInputField);
taskHeader.appendChild(locationInputField);
taskHeader.appendChild(methodInputField);
taskHeader.appendChild(blockerButton);
taskHeader.appendChild(removeButton);
taskHeader.appendChild(addSubTaskButton);
taskHeader.appendChild(customFieldButton);
taskContainer.appendChild(taskHeader);
taskContainer.appendChild(nestedList);
if (task.blocker) {
taskContainer.classList.add('blocker');
}
checklistItems.appendChild(taskContainer);
initializeSortable(nestedList);
updateCalendar();
}
function addSubTaskFromData(nestedList, subTask) {
const subTaskContainer = document.createElement('div');
subTaskContainer.className = 'checklist-container';
subTaskContainer.setAttribute('data-tag', subTask.tag);
subTaskContainer.setAttribute('data-number', subTask.number);
subTaskContainer.setAttribute('data-person', subTask.person);
subTaskContainer.setAttribute('data-date', subTask.date);
subTaskContainer.setAttribute('data-end-date', subTask.endDate);
subTaskContainer.setAttribute('data-time', subTask.time);
subTaskContainer.setAttribute('data-amount', subTask.amount);
subTaskContainer.setAttribute('data-reason', subTask.reason);
subTaskContainer.setAttribute('data-location', subTask.location);
subTaskContainer.setAttribute('data-method', subTask.method);
const subTaskHeader = document.createElement('div');
subTaskHeader.style.display = 'flex';
subTaskHeader.style.alignItems = 'center';
const toggleButton = document.createElement('span');
toggleButton.className = 'toggle';
toggleButton.textContent = '+';
toggleButton.addEventListener('click', function() {
const nested = subTaskContainer.querySelector('.nested-list');
if (nested.style.display === 'block') {
nested.style.display = 'none';
toggleButton.textContent = '+';
} else {
nested.style.display = 'block';
toggleButton.textContent = '-';
}
});
const subCheckbox = document.createElement('input');
subCheckbox.type = 'checkbox';
subCheckbox.id = subTask.id;
subCheckbox.className = 'checklist-input';
subCheckbox.checked = subTask.checked;
subCheckbox.addEventListener('change', function() {
subLabel.classList.toggle('completed', subCheckbox.checked);
if (subCheckbox.checked) {
moveToCompleted(subTaskContainer);
} else {
nestedList.appendChild(subTaskContainer);
}
saveChecklistState();
});
const subLabel = document.createElement('label');
subLabel.htmlFor = subTask.id;
subLabel.className = 'checklist-label';
subLabel.textContent = subTask.name;
if (subTask.checked) {
subLabel.classList.add('completed');
}
const subNumberInputField = document.createElement('input');
subNumberInputField.type = 'number';
subNumberInputField.value = subTask.number;
subNumberInputField.className = 'edit-number-input';
subNumberInputField.placeholder = "Número";
subNumberInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-number', subNumberInputField.value);
saveChecklistState();
});
const subTagInputField = document.createElement('input');
subTagInputField.type = 'text';
subTagInputField.value = subTask.tag;
subTagInputField.className = 'edit-tag-input';
subTagInputField.placeholder = "Tag";
subTagInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-tag', subTagInputField.value.toLowerCase());
saveChecklistState();
updateFilterDropdown();
});
const subPersonInputField = document.createElement('input');
subPersonInputField.type = 'text';
subPersonInputField.value = subTask.person;
subPersonInputField.className = 'edit-person-input';
subPersonInputField.placeholder = "Atribuir a";
subPersonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-person', subPersonInputField.value);
saveChecklistState();
updatePersonFilterDropdown();
});
const subDateInputField = document.createElement('input');
subDateInputField.type = 'date';
subDateInputField.value = subTask.date;
subDateInputField.className = 'edit-date-input';
subDateInputField.placeholder = "Data de realização";
subDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-date', subDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subEndDateInputField = document.createElement('input');
subEndDateInputField.type = 'date';
subEndDateInputField.value = subTask.endDate;
subEndDateInputField.className = 'edit-end-date-input';
subEndDateInputField.placeholder = "Data de término";
subEndDateInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-end-date', subEndDateInputField.value);
saveChecklistState();
updateCalendar();
});
const subTimeInputField = document.createElement('input');
subTimeInputField.type = 'time';
subTimeInputField.value = subTask.time;
subTimeInputField.className = 'edit-time-input';
subTimeInputField.placeholder = "Horário";
subTimeInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-time', subTimeInputField.value);
saveChecklistState();
updateCalendar();
});
const subAmountInputField = document.createElement('input');
subAmountInputField.type = 'number';
subAmountInputField.value = subTask.amount;
subAmountInputField.className = 'edit-amount-input';
subAmountInputField.placeholder = "Quanto";
subAmountInputField.step = "0.01";
subAmountInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-amount', subAmountInputField.value);
saveChecklistState();
});
const subReasonInputField = document.createElement('input');
subReasonInputField.type = 'text';
subReasonInputField.value = subTask.reason;
subReasonInputField.className = 'edit-reason-input';
subReasonInputField.placeholder = "Por que da tarefa?";
subReasonInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-reason', subReasonInputField.value);
saveChecklistState();
});
const subLocationInputField = document.createElement('input');
subLocationInputField.type = 'text';
subLocationInputField.value = subTask.location;
subLocationInputField.className = 'edit-location-input';
subLocationInputField.placeholder = "Onde será a tarefa?";
subLocationInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-location', subLocationInputField.value);
saveChecklistState();
});
const subMethodInputField = document.createElement('input');
subMethodInputField.type = 'text';
subMethodInputField.value = subTask.method;
subMethodInputField.className = 'edit-method-input';
subMethodInputField.placeholder = "Como será feita essa tarefa?";
subMethodInputField.addEventListener('change', function() {
subTaskContainer.setAttribute('data-method', subMethodInputField.value);
saveChecklistState();
});
const subRemoveButton = document.createElement('button');
subRemoveButton.type = 'button';
subRemoveButton.className = 'remove-task-button';
subRemoveButton.textContent = 'x';
subRemoveButton.addEventListener('click', function() {
if (confirm('Você tem certeza que deseja apagar esta subtarefa?')) {
subTaskContainer.remove();
saveChecklistState();
updateCalendar();
}
});
const subBlockerButton = document.createElement('button');
subBlockerButton.type = 'button';
subBlockerButton.className = 'blocker-button';
subBlockerButton.innerHTML = '⚠';
subBlockerButton.addEventListener('click', function() {
subTaskContainer.classList.toggle('blocker');
saveChecklistState();
});
const addSubSubTaskButton = document.createElement('button');
addSubSubTaskButton.type = 'button';
addSubSubTaskButton.className = 'add-task-button';
addSubSubTaskButton.textContent = 'Adicionar Subtarefa';
addSubSubTaskButton.style.marginLeft = '10px';
addSubSubTaskButton.addEventListener('click', function() {
const subSubTaskName = prompt('Digite a nova subtarefa:');
if (subSubTaskName) {
addSubTask(subTaskContainer, subSubTaskName);
}
});
const customFieldButton = document.createElement('button');
customFieldButton.type = 'button';
customFieldButton.className = 'add-task-button';
customFieldButton.textContent = 'Adicionar Campo Personalizado';
customFieldButton.style.marginLeft = '10px';
customFieldButton.addEventListener('click', function() {
addCustomField(subTaskContainer);
});
subTaskHeader.appendChild(toggleButton);
subTaskHeader.appendChild(subCheckbox);
subTaskHeader.appendChild(subLabel);
subTaskHeader.appendChild(subTagInputField);
subTaskHeader.appendChild(subNumberInputField);
subTaskHeader.appendChild(subPersonInputField);
subTaskHeader.appendChild(subDateInputField);
subTaskHeader.appendChild(subEndDateInputField);
subTaskHeader.appendChild(subTimeInputField);
subTaskHeader.appendChild(subAmountInputField);
subTaskHeader.appendChild(subReasonInputField);
subTaskHeader.appendChild(subLocationInputField);
subTaskHeader.appendChild(subMethodInputField);
subTaskHeader.appendChild(subBlockerButton);
subTaskHeader.appendChild(subRemoveButton);
subTaskHeader.appendChild(addSubSubTaskButton);
subTaskHeader.appendChild(customFieldButton);
subTaskContainer.appendChild(subTaskHeader);
const subNestedList = document.createElement('div');
subNestedList.className = 'nested-list';
subTaskContainer.appendChild(subNestedList);
nestedList.appendChild(subTaskContainer);
initializeSortable(subNestedList);
updateCalendar();
}
function initializeSortable(container) {
new Sortable(container, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: () => {
saveChecklistState();
}
});
const nestedLists = container.querySelectorAll('.nested-list');
nestedLists.forEach(nestedList => {
new Sortable(nestedList, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: () => {
saveChecklistState();
}
});
});
}
function updateFilterDropdown() {
const tags = new Set();
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
function collectTags(task) {
if (task.tag) {
tags.add(task.tag);
}
if (task.subTasks) {
task.subTasks.forEach(subTask => collectTags(subTask));
}
}
tasks.forEach((task) => {
collectTags(task);
});
const tagFilter = document.getElementById('tagFilter');
tagFilter.innerHTML = '<option value="">Todas</option>';
tags.forEach((tag) => {
const option = document.createElement('option');
option.value = tag;
option.textContent = tag;
tagFilter.appendChild(option);
});
}
function updatePersonFilterDropdown() {
const people = new Set();
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
function collectPeople(task) {
if (task.person) {
people.add(task.person);
}
if (task.subTasks) {
task.subTasks.forEach(subTask => collectPeople(subTask));
}
}
tasks.forEach((task) => {
collectPeople(task);
});
const personFilter = document.getElementById('personFilter');
personFilter.innerHTML = '<option value="">Todas</option>';
people.forEach((person) => {
const option = document.createElement('option');
option.value = person;
option.textContent = person;
personFilter.appendChild(option);
});
}
function filterTasks() {
const selectedTag = document.getElementById('tagFilter').value;
const selectedPerson = document.getElementById('personFilter').value;
const customFieldFilter = document.getElementById('customFieldFilter').value.trim().toLowerCase();
function matchesCustomFilters(taskContainer) {
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
for (const input of customFieldInputs) {
if (input.value.toLowerCase() === customFieldFilter) {
return true;
}
}
return customFieldFilter === '';
}
function matchesFilters(taskContainer) {
const tag = taskContainer.getAttribute('data-tag');
const person = taskContainer.getAttribute('data-person');
const matchesTag = selectedTag === '' || tag === selectedTag;
const matchesPerson = selectedPerson === '' || person === selectedPerson;
const matchesCustom = matchesCustomFilters(taskContainer);
return matchesTag && matchesPerson && matchesCustom;
}
function filterTask(taskContainer) {
const showTask = matchesFilters(taskContainer);
const subTasks = taskContainer.querySelectorAll('.checklist-container');
let showSubTasks = false;
subTasks.forEach(subTask => {
const showSubTask = filterTask(subTask);
showSubTasks = showSubTasks || showSubTask;
});
taskContainer.style.display = showTask || showSubTasks ? 'block' : 'none';
return showTask || showSubTasks;
}
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
filterTask(taskContainer);
});
}
function filterTasksByWord() {
const wordFilter = document.getElementById('wordFilter').value.trim().toLowerCase();
function matchesWordFilter(taskContainer) {
const label = taskContainer.querySelector('.checklist-label');
const labelText = label ? label.textContent.toLowerCase() : '';
const matchesWord = wordFilter === '' || labelText.includes(wordFilter);
const customFieldInputs = taskContainer.querySelectorAll('.custom-field-input');
const matchesCustomFields = Array.from(customFieldInputs).some(input => input.value.toLowerCase().includes(wordFilter));
return matchesWord || matchesCustomFields;
}
function filterTask(taskContainer) {
const showTask = matchesWordFilter(taskContainer);
const subTasks = taskContainer.querySelectorAll('.checklist-container');
let showSubTasks = false;
subTasks.forEach(subTask => {
const showSubTask = filterTask(subTask);
showSubTasks = showSubTasks || showSubTask;
});
taskContainer.style.display = showTask || showSubTasks ? 'block' : 'none';
return showTask || showSubTasks;
}
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
filterTask(taskContainer);
});
}
function sortTasksByNumber() {
const checklistItems = document.getElementById('checklistItems');
const tasks = Array.from(checklistItems.querySelectorAll('.checklist-container'));
tasks.sort((a, b) => {
const numberA = parseInt(a.getAttribute('data-number') || 0);
const numberB = parseInt(b.getAttribute('data-number') || 0);
return numberA - numberB;
});
tasks.forEach((task) => {
checklistItems.appendChild(task);
});
saveChecklistState();
}
function filterBlockers() {
const tasks = document.querySelectorAll('#checklistItems > .checklist-container');
tasks.forEach((taskContainer) => {
const isBlocker = taskContainer.classList.contains('blocker');
taskContainer.style.display = isBlocker ? '' : 'none';
});
}
function generateBlockerReport() {
const tasks = JSON.parse(localStorage.getItem('checklistItems')) || [];
const blockers = tasks.filter(task => task.blocker);
const reportContainer = document.getElementById('blockerReport');
reportContainer.innerHTML = '';
blockers.forEach((task) => {
const reportItem = document.createElement('div');
reportItem.className = 'report-item';
reportItem.textContent = `Tarefa: ${task.name}, Número: ${task.number}, Tag: ${task.tag}, Atribuída a: ${task.person}, Data: ${task.date}, Motivo: ${task.reason}`;
reportContainer.appendChild(reportItem);
if (task.subTasks) {
task.subTasks.forEach(subTask => {
const subReportItem = document.createElement('div');
subReportItem.className = 'report-item';
subReportItem.style.marginLeft = '20px';
subReportItem.textContent = `Subtarefa: ${subTask.name}, Número: ${subTask.number}, Tag: ${subTask.tag}, Atribuída a: ${subTask.person}, Data: ${subTask.date}, Motivo: ${subTask.reason}`;
reportContainer.appendChild(subReportItem);
});
}
});
}
function updateCalendar() {
// Atualiza o calendário com base nas datas das tarefas
const taskContainers = document.querySelectorAll('.taskContainer');
taskContainers.forEach(container => {
initializeSortable(container);
});
}
function addEventToDay(dayElement, eventName, eventTime) {
const eventElement = document.createElement('div');
eventElement.className = 'event';
eventElement.innerHTML = `<span>${eventName} - ${eventTime}</span>`;
dayElement.appendChild(eventElement);
initializeSortable(dayElement);
}
function saveEventToLocalStorage(day, eventName, eventTime) {
const events = JSON.parse(localStorage.getItem('events')) || {};
if (!events[day]) {
events[day] = [];
}
events[day].push({ name: eventName, time: eventTime });
localStorage.setItem('events', JSON.stringify(events));
}
function addEventToCalendar(date, eventName, eventTime, isEnd) {
const dayElement = document.querySelector(`#tasks_${date}`);
if (dayElement) {
addEventToDay(dayElement, eventName, eventTime);
saveEventToLocalStorage(date, eventName, eventTime);
}
}
function initializeSortable(element) {
Sortable.create(element, {
group: 'calendarTasks',
animation: 150,
onEnd: function(evt) {
const item = evt.item;
const fromContainer = evt.from;
const toContainer = evt.to;
const fromDate = fromContainer.id.split('_')[1];
const toDate = toContainer.id.split('_')[1];
if (fromDate !== toDate) {
console.log(`Moved task from ${fromDate} to ${toDate}`);
// Atualize o evento com a nova data
updateEventDate(item, toDate);
}
}
});
}
function updateEventDate(eventElement, newDate) {
const eventName = eventElement.querySelector('span').textContent.split(' - ')[0];
const eventTime = eventElement.querySelector('span').textContent.split(' - ')[1];
// Remova do dia antigo no localStorage
const oldDate = eventElement.closest('.taskContainer').id.split('_')[1];
let events = JSON.parse(localStorage.getItem('events')) || {};
if (events[oldDate]) {
events[oldDate] = events[oldDate].filter(event => event.name !== eventName || event.time !== eventTime);
localStorage.setItem('events', JSON.stringify(events));
}
// Adicione ao novo dia no localStorage
saveEventToLocalStorage(newDate, eventName, eventTime);
// Atualize o elemento HTML
const newDayElement = document.querySelector(`#tasks_${newDate}`);
if (newDayElement) {
newDayElement.appendChild(eventElement);
}
}
document.addEventListener('DOMContentLoaded', () => {
restoreChecklistState();
initializeSortable(document.getElementById('checklistItems'));
initializeSortable(document.getElementById('eventsList'));
updateCalendar();
});
</script>
</body>
</html>