Första incheckningen. Protyp för PWA för att skapa todos
This commit is contained in:
22
manifest.json
Normal file
22
manifest.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "Task Manager",
|
||||||
|
"short_name": "TaskApp",
|
||||||
|
"description": "An app to manage tasks in Org mode format.",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"theme_color": "#4CAF50",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icons/icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
31
public/app.js
Normal file
31
public/app.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
document.getElementById('taskForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Get form values
|
||||||
|
const subject = document.getElementById('subject').value;
|
||||||
|
const description = document.getElementById('description').value;
|
||||||
|
const deadline = document.getElementById('deadline').value;
|
||||||
|
|
||||||
|
// Structure data for Org mode
|
||||||
|
const taskData = {
|
||||||
|
subject,
|
||||||
|
description,
|
||||||
|
deadline
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send data to backend using fetch
|
||||||
|
fetch('/add-task', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(taskData)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById('responseMessage').textContent = data.message;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
document.getElementById('responseMessage').textContent = "Error saving task!";
|
||||||
|
});
|
||||||
|
});
|
||||||
43
public/index.html
Normal file
43
public/index.html
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sv-SE">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Task Input App</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<!-- Flatpickr for dates -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>TODO</h1>
|
||||||
|
<form id="taskForm">
|
||||||
|
<label for="subject">Uppgift:</label>
|
||||||
|
<input type="text" id="subject" required><br><br>
|
||||||
|
|
||||||
|
<label for="description">Beskrivning:</label>
|
||||||
|
<textarea id="description"></textarea><br><br>
|
||||||
|
|
||||||
|
<label for="deadline">Datum:</label>
|
||||||
|
<input type="date" id="deadline" lang="sv-SE" required><br><br>
|
||||||
|
|
||||||
|
<button type="submit">Spara</button>
|
||||||
|
</form>
|
||||||
|
<p id="responseMessage"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="app.js"></script>
|
||||||
|
<script>
|
||||||
|
// Set today's date as the default for the date input
|
||||||
|
const today = new Date().toISOString().split('T')[0];
|
||||||
|
document.getElementById('deadline').value = today;
|
||||||
|
// Initialize flatpickr with Swedish locale and Monday as the first day of the week
|
||||||
|
flatpickr("#deadline", {
|
||||||
|
locale: "sv", // Set Swedish locale
|
||||||
|
weekNumbers: true, // Show week numbers
|
||||||
|
firstDayOfWeek: 1 // Start weeks on Monday
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
48
public/style.css
Normal file
48
public/style.css
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 300px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
|
width: 90%;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
#responseMessage {
|
||||||
|
text-align: center;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
33
server.js
Normal file
33
server.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const port = 3044;
|
||||||
|
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.use(express.static('public'));
|
||||||
|
|
||||||
|
// Endpoint to receive task data and append to file
|
||||||
|
app.post('/add-task', (req, res) => {
|
||||||
|
const { subject, description, deadline } = req.body;
|
||||||
|
|
||||||
|
const orgFormattedData = `
|
||||||
|
* TODO ${subject}
|
||||||
|
${description}
|
||||||
|
SCHEDULED: <${deadline}>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const filePath = path.join(__dirname, 'tasks.org');
|
||||||
|
fs.appendFile(filePath, orgFormattedData, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send('Error writing to file.');
|
||||||
|
}
|
||||||
|
res.send({ message: 'Task added successfully!' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server running at http://localhost:${port}`);
|
||||||
|
});
|
||||||
23
service-worker.js
Normal file
23
service-worker.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open('task-manager-cache').then((cache) => {
|
||||||
|
return cache.addAll([
|
||||||
|
'/',
|
||||||
|
'/index.html',
|
||||||
|
'/style.css',
|
||||||
|
'/app.js',
|
||||||
|
'/manifest.json',
|
||||||
|
'/icons/icon-192x192.png',
|
||||||
|
'/icons/icon-512x512.png'
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
event.respondWith(
|
||||||
|
caches.match(event.request).then((cachedResponse) => {
|
||||||
|
return cachedResponse || fetch(event.request);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user