Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Projeto - Assincronismo + NodeJS + Express

## Objetivo

Criar uma aplicação que facilite a organização e marcação de partidas
de futebol entre amigos.

## Funcionalidades

1. Criar partidas: Cada partida deve ter um título, um local, data e horário.
2. Criar lista de presença dos jogadores: Após criar a partida, deve ser permitido adicionar/remover uma lista com os participantes e um telefone para contato.
3. Acompanhar a presença: Essa funcionalidade será usada para "confirmar" quem vai estar presente no dia da partida marcada. Deverá ser apresentada a lista dos jogadores com uma opção para confirmar sua presença.
4. Excluir partida. Deve ser permitido excluir a partida.

## Módulos

Para esse projeto deve ser construído os seguintes módulos:

* Frontend utilizando HTML, CSS e Javascript para controlar os eventos da tela e realizar as requisições para o backend para salvar e recuperar os dados.
* É permitido utilizar bibliotecas para a estilização das páginas, tais como Bootstrap, Bulma, Semantic, UIKit, etc.

* Backend utilizando NodeJS + Express.
* Aqui, fique a vontade para utilizar outras bibliotecas que possam facilitar seu trabalho.

## Armazenamento de Dados

Os dados da aplicação devem ser guardados em um arquivo do tipo JSON.

Para isso, utilize as funções nativas do NodeJS para ler (readFile) e escrever arquivos (writeFile).
6 changes: 0 additions & 6 deletions Styles/cores.css

This file was deleted.

30 changes: 0 additions & 30 deletions Styles/styles.css

This file was deleted.

205 changes: 205 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
document.addEventListener('DOMContentLoaded', function() {
fetchMatches();

document.querySelector('#createMatchButton').addEventListener('click', function() {
const title = document.querySelector('#matchTitle').value;
const location = document.querySelector('#matchLocation').value;
const date = document.querySelector('#matchDate').value;
const time = document.querySelector('#matchTime').value;

fetch('http://localhost:3000/criarPartida', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
titulo: title,
local: location,
data: date,
horario: time
})
})
.then(response => response.text())
.then(data => {
alert(data);
fetchMatches();
})
.catch(error => console.error('Erro:', error));
});

// Enviando o formulário para Adicionar Jogador
document.querySelector('#addPlayerForm').addEventListener('submit', function(e) {
e.preventDefault();
const index = document.querySelector('#matchIndexForPlayer').value;
const playerName = document.querySelector('#playerName').value;
const playerPhone = document.querySelector('#playerPhone').value;

if (playerName && playerPhone) {
fetch(`http://localhost:3000/partidas/${index}/jogadores`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
nome: playerName,
telefone: playerPhone
})
})
.then(response => response.text())
.then(data => {
alert(data);
viewPlayers(index);
})
.catch(error => console.error('Erro:', error));
}
});

// Confirmando a Exclusão de Partida
document.querySelector('#confirmDeleteMatchButton').addEventListener('click', function() {
const index = document.querySelector('#matchIndexToDelete').value;
fetch(`http://localhost:3000/partidas/${index}`, {
method: 'DELETE',
})
.then(response => response.text())
.then(data => {
alert(data);
fetchMatches();
})
.catch(error => console.error('Erro:', error));
});
});

function fetchMatches() {
fetch('http://localhost:3000/partidas')
.then(response => response.json())
.then(partidas => {
const matchList = document.querySelector('#matchList');
matchList.innerHTML = '';
partidas.forEach((partida, index) => {
const listItem = document.createElement('li');
listItem.classList.add('list-group-item', 'match-item');
listItem.innerHTML = `
<div class="match-header">
<span>${partida.titulo} - ${partida.local} - ${partida.data} - ${partida.horario}</span>
<button class="btn btn-secondary btn-sm toggle-btn">▼</button>
</div>
<div class="match-options" style="display: none;">
<button class="btn btn-primary btn-sm" onclick="addPlayer(${index})">Adicionar Jogador</button>
<button class="btn btn-info btn-sm" onclick="viewPlayers(${index})">Ver Jogadores</button>
<button class="btn btn-danger btn-sm" onclick="deleteMatch(${index})">Excluir Partida</button>
</div>
`;

// Expandir e Recolher opções
const toggleBtn = listItem.querySelector('.toggle-btn');
toggleBtn.addEventListener('click', function() {
const optionsDiv = listItem.querySelector('.match-options');
const isVisible = optionsDiv.style.display === 'block';
optionsDiv.style.display = isVisible ? 'none' : 'block';
toggleBtn.textContent = isVisible ? '▼' : '▲';
});

matchList.appendChild(listItem);
});
})
.catch(error => console.error('Erro:', error));
}

function addPlayer(index) {
// Define o índice da partida
document.querySelector('#matchIndexForPlayer').value = index;

// Limpa os campos do formulário
document.querySelector('#playerName').value = '';
document.querySelector('#playerPhone').value = '';

$('#addPlayerModal').modal('show');
}

function viewPlayers(index) {
fetch(`http://localhost:3000/partidas/${index}/jogadores`)
.then(response => response.json())
.then(jogadores => {
const playerList = document.querySelector('#playerList');
playerList.innerHTML = ''; // Limpa a lista anterior
if (jogadores.length === 0) {
const li = document.createElement('li');
li.className = 'list-group-item';
li.textContent = 'Nenhum jogador adicionado ainda.';
playerList.appendChild(li);
} else {
jogadores.forEach((jogador, playerIndex) => {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center';

// Cria um span para exibir o nome e telefone do jogador
const nameSpan = document.createElement('span');
if(jogador.presenca) {
// Se o jogador estiver presente, o nome é exibido em verde (classe text-success)
nameSpan.className = 'text-success';
nameSpan.textContent = `${jogador.nome} (${jogador.telefone}) - Presente`;
} else {
nameSpan.textContent = `${jogador.nome} (${jogador.telefone})`;
}
li.appendChild(nameSpan);

const btnGroup = document.createElement('div');
// Botão para confirmar presença
const confirmBtn = document.createElement('button');
confirmBtn.className = 'btn btn-success btn-sm';
confirmBtn.textContent = 'Confirmar Presença';
confirmBtn.addEventListener('click', function() {
confirmPresence(index, playerIndex);
});
// Botão para excluir jogador
const deleteBtn = document.createElement('button');
deleteBtn.className = 'btn btn-danger btn-sm ml-2';
deleteBtn.textContent = 'Excluir';
deleteBtn.addEventListener('click', function() {
deletePlayer(index, playerIndex);
});
btnGroup.appendChild(confirmBtn);
btnGroup.appendChild(deleteBtn);
li.appendChild(btnGroup);
playerList.appendChild(li);
});
}

$('#viewPlayersModal').modal('show');
})
.catch(error => console.error('Erro:', error));
}

function confirmPresence(matchIndex, playerIndex) {
fetch(`http://localhost:3000/partidas/${matchIndex}/jogadores/${playerIndex}/confirm`, {
method: 'PATCH'
})
.then(response => response.text())
.then(data => {
alert(data);

viewPlayers(matchIndex);
})
.catch(error => console.error('Erro:', error));
}

function deletePlayer(matchIndex, playerIndex) {
if (confirm('Tem certeza que deseja excluir este jogador?')) {
fetch(`http://localhost:3000/partidas/${matchIndex}/jogadores/${playerIndex}`, {
method: 'DELETE'
})
.then(response => response.text())
.then(data => {
alert(data);

viewPlayers(matchIndex);
})
.catch(error => console.error('Erro:', error));
}
}

function deleteMatch(index) {
document.querySelector('#matchIndexToDelete').value = index;

$('#confirmDeleteMatchModal').modal('show');
}
Empty file added favicon.ico
Empty file.
Loading