Upload files to "/"
This commit is contained in:
commit
9699b5b650
84
app.js
Normal file
84
app.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Funkcja do dodawania nowego zadania
|
||||||
|
async function addTask() {
|
||||||
|
const taskDescription = document.getElementById('new-task').value;
|
||||||
|
|
||||||
|
if (!taskDescription) {
|
||||||
|
alert('Opis zadania nie może być pusty!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:8000/add_task', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ task_description: taskDescription })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Odpowiedź sieci nie była OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
console.log('Zadanie dodane:', result);
|
||||||
|
document.getElementById('new-task').value = '';
|
||||||
|
loadTasks(); // Ponowne załadowanie zadań po dodaniu nowego
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Błąd podczas dodawania zadania:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funkcja do ładowania zadań
|
||||||
|
async function loadTasks() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:8000/get_tasks');
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Odpowiedź sieci nie była OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tasks = await response.json();
|
||||||
|
const taskList = document.getElementById('task-list');
|
||||||
|
taskList.innerHTML = '';
|
||||||
|
tasks.forEach(task => {
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
listItem.textContent = task.task_description;
|
||||||
|
|
||||||
|
// Przycisk do usuwania zadania
|
||||||
|
const deleteButton = document.createElement('button');
|
||||||
|
deleteButton.textContent = 'Usuń';
|
||||||
|
deleteButton.onclick = () => deleteTask(task.id);
|
||||||
|
|
||||||
|
listItem.appendChild(deleteButton);
|
||||||
|
taskList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Błąd podczas ładowania zadań:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funkcja do usuwania zadania
|
||||||
|
async function deleteTask(taskId) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`http://localhost:8000/delete_task/${taskId}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Odpowiedź sieci nie była OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
console.log('Zadanie usunięte:', result);
|
||||||
|
loadTasks(); // Ponowne załadowanie zadań po usunięciu
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Błąd podczas usuwania zadania:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nasłuchiwanie na załadowanie DOM
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
loadTasks();
|
||||||
|
});
|
||||||
|
|
20
index.html
Normal file
20
index.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>To-Do App</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>To-Do List</h1>
|
||||||
|
<div class="input-container">
|
||||||
|
<input type="text" id="new-task" placeholder="Enter new task">
|
||||||
|
<button onclick="addTask()">Add Task</button>
|
||||||
|
</div>
|
||||||
|
<ul id="task-list"></ul>
|
||||||
|
</div>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
97
serwer.py
Normal file
97
serwer.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
from wsgiref.simple_server import make_server
|
||||||
|
import json
|
||||||
|
import pyodbc
|
||||||
|
|
||||||
|
# Nagłówki odpowiedzi HTTP
|
||||||
|
response_headers = [
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
('Access-Control-Allow-Origin', '*'),
|
||||||
|
('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'),
|
||||||
|
('Access-Control-Allow-Headers', 'Content-Type')
|
||||||
|
]
|
||||||
|
|
||||||
|
# Konfiguracja połączenia z bazą danych
|
||||||
|
conn = pyodbc.connect(
|
||||||
|
'DRIVER={ODBC Driver 17 for SQL Server};'
|
||||||
|
'SERVER=mssql-2017.labs.wmi.amu.edu.pl;'
|
||||||
|
'DATABASE=dbad_s490127;'
|
||||||
|
'UID=dbad_s490127;'
|
||||||
|
'PWD=Bjf5w2Hhco'
|
||||||
|
)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
def application(environ, start_response):
|
||||||
|
path = environ.get('PATH_INFO', '') # Pobranie ścieżki żądania
|
||||||
|
method = environ.get('REQUEST_METHOD', '') # Pobranie metody HTTP
|
||||||
|
|
||||||
|
response_headers = [
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
('Access-Control-Allow-Origin', '*'),
|
||||||
|
('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'),
|
||||||
|
('Access-Control-Allow-Headers', 'Content-Type')
|
||||||
|
]
|
||||||
|
|
||||||
|
# Obsługa preflight requests dla CORS
|
||||||
|
if method == 'OPTIONS':
|
||||||
|
start_response('200 OK', response_headers)
|
||||||
|
return [b'']
|
||||||
|
|
||||||
|
# Obsługa dodawania nowego zadania
|
||||||
|
if path == '/add_task' and method == 'POST':
|
||||||
|
try:
|
||||||
|
# Odczytanie i sparsowanie treści żądania
|
||||||
|
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
|
||||||
|
request_body = environ['wsgi.input'].read(request_body_size)
|
||||||
|
data = json.loads(request_body)
|
||||||
|
task_description = data.get('task_description', '')
|
||||||
|
|
||||||
|
# Dodanie zadania do bazy danych, jeśli opis jest podany
|
||||||
|
if task_description:
|
||||||
|
cursor.execute("INSERT INTO Tasks (task_description) OUTPUT INSERTED.id VALUES (?)", (task_description,))
|
||||||
|
task_id = cursor.fetchone()[0] # Pobranie ID nowo dodanego zadania
|
||||||
|
conn.commit() # Zatwierdzenie zmian w bazie danych
|
||||||
|
response = json.dumps({'message': 'Task added successfully', 'id': task_id})
|
||||||
|
status = '200 OK'
|
||||||
|
else:
|
||||||
|
response = json.dumps({'message': 'Task description is required'}) # Brak opisu zadania
|
||||||
|
status = '400 Bad Request'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)}) # Obsługa błędu
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
# Obsługa pobierania wszystkich zadań
|
||||||
|
elif path == '/get_tasks' and method == 'GET':
|
||||||
|
try:
|
||||||
|
cursor.execute("SELECT id, task_description FROM Tasks") # Pobranie zadań z bazy danych
|
||||||
|
tasks = cursor.fetchall()
|
||||||
|
tasks_list = [{'id': task[0], 'task_description': task[1]} for task in tasks] # Przygotowanie listy zadań
|
||||||
|
response = json.dumps(tasks_list) # Konwersja listy zadań do formatu JSON
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)}) # Obsługa błędu
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
# Obsługa usuwania konkretnego zadania
|
||||||
|
elif path.startswith('/delete_task/') and method == 'DELETE':
|
||||||
|
try:
|
||||||
|
task_id = int(path.split('/')[-1]) # Wyodrębnienie ID zadania z URL
|
||||||
|
cursor.execute("DELETE FROM Tasks WHERE id = ?", (task_id,)) # Usunięcie zadania z bazy danych
|
||||||
|
conn.commit() # Zatwierdzenie zmian w bazie danych
|
||||||
|
response = json.dumps({'message': 'Task deleted successfully'})
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)}) # Obsługa błędu
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
# Obsługa nieznanych ścieżek
|
||||||
|
else:
|
||||||
|
response = json.dumps({'message': 'Not Found'}) # Nieznana ścieżka
|
||||||
|
status = '404 Not Found'
|
||||||
|
|
||||||
|
start_response(status, response_headers) # Wysłanie odpowiedzi HTTP
|
||||||
|
return [response.encode('utf-8')]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
httpd = make_server('', 8000, application) # Utworzenie serwera na porcie 8000
|
||||||
|
print("Serving on port 8000...")
|
||||||
|
httpd.serve_forever() # Rozpoczęcie obsługi żądań
|
101
styles.css
Normal file
101
styles.css
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* Reset some default browser styles */
|
||||||
|
body, h1, ul, li, button, input {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.completed {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
li button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li button:first-of-type {
|
||||||
|
background-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
li button:first-of-type:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
|
||||||
|
li button:last-of-type {
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
li button:last-of-type:hover {
|
||||||
|
background-color: #c82333;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user