Implement tag management with SQLite; update save and retrieve endpoints
This commit is contained in:
@@ -56,7 +56,7 @@
|
|||||||
<label for="time">Tid (valfritt)</label>
|
<label for="time">Tid (valfritt)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input type="text" id="tags" placeholder="Taggar">
|
<input type="text" id="tags" placeholder="Taggar" autocomplete="off">
|
||||||
<label for="tags">Taggar</label>
|
<label for="tags">Taggar</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn waves-effect waves-light" type="submit">Spara uppgift</button>
|
<button class="btn waves-effect waves-light" type="submit">Spara uppgift</button>
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
export function saveTags(tags) {
|
export async function saveTags(newTags) {
|
||||||
|
const existingTags = await loadTags();
|
||||||
|
const allTags = Array.from(new Set([...existingTags, ...newTags]));
|
||||||
|
|
||||||
return fetch('/save-tags', {
|
return fetch('/save-tags', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ tags })
|
body: JSON.stringify({ tags: allTags })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,17 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const auth = require('../middleware/auth');
|
const auth = require('../middleware/auth');
|
||||||
const logger = require('../logger');
|
const logger = require('../logger');
|
||||||
|
const sqlite3 = require('sqlite3').verbose();
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const dataDir = '/data';
|
const dataDir = '/data';
|
||||||
|
|
||||||
|
const db = new sqlite3.Database('/data/sessions.sqlite', (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error opening database:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Ensure the /data directory exists
|
// Ensure the /data directory exists
|
||||||
if (!fs.existsSync(dataDir)) {
|
if (!fs.existsSync(dataDir)) {
|
||||||
fs.mkdirSync(dataDir, { recursive: true });
|
fs.mkdirSync(dataDir, { recursive: true });
|
||||||
@@ -68,28 +75,31 @@ router.post('/add-task', auth, async (req, res) => {
|
|||||||
// Endpoint to save tags
|
// Endpoint to save tags
|
||||||
router.post('/save-tags', auth, async (req, res) => {
|
router.post('/save-tags', auth, async (req, res) => {
|
||||||
const { tags } = req.body;
|
const { tags } = req.body;
|
||||||
const filePath = path.join(dataDir, 'tags.json');
|
const placeholders = tags.map(() => '(?)').join(',');
|
||||||
try {
|
const sql = `INSERT OR IGNORE INTO tags (tag) VALUES ${placeholders}`;
|
||||||
await fs.promises.writeFile(filePath, JSON.stringify(tags));
|
|
||||||
res.send({ message: 'Tags saved successfully!' });
|
db.run(sql, tags, function(err) {
|
||||||
logger.info(`New tags saved: ${tags}`);
|
if (err) {
|
||||||
} catch (err) {
|
logger.error('Error saving tags:', err);
|
||||||
logger.error('Error saving tags:', err);
|
res.status(500).send('Error saving tags.');
|
||||||
res.status(500).send('Error saving tags.');
|
} else {
|
||||||
}
|
res.send({ message: 'Tags saved successfully!' });
|
||||||
|
logger.info(`New tags saved: ${tags}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Endpoint to retrieve tags
|
// Endpoint to retrieve tags
|
||||||
router.get('/get-tags', auth, async (req, res) => {
|
router.get('/get-tags', auth, async (req, res) => {
|
||||||
const filePath = path.join(dataDir, 'tags.json');
|
db.all('SELECT tag FROM tags', [], (err, rows) => {
|
||||||
try {
|
if (err) {
|
||||||
const data = await fs.promises.readFile(filePath, 'utf-8');
|
logger.error('Error retrieving tags:', err);
|
||||||
const tags = JSON.parse(data);
|
res.status(500).json({ error: 'Error retrieving tags' });
|
||||||
res.json(tags);
|
} else {
|
||||||
} catch (err) {
|
const tags = rows.map(row => row.tag);
|
||||||
logger.error('Error retrieving tags:', err);
|
res.json(tags);
|
||||||
res.status(500).json({ error: 'Error retrieving tags' });
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
48
server.js
48
server.js
@@ -4,6 +4,7 @@ const bodyParser = require('body-parser');
|
|||||||
const session = require('express-session');
|
const session = require('express-session');
|
||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require('cookie-parser');
|
||||||
const SQLiteStore = require('connect-sqlite3')(session);
|
const SQLiteStore = require('connect-sqlite3')(session);
|
||||||
|
const sqlite3 = require('sqlite3').verbose();
|
||||||
const tasksRouter = require('./routes/tasks');
|
const tasksRouter = require('./routes/tasks');
|
||||||
const authRouter = require('./routes/auth');
|
const authRouter = require('./routes/auth');
|
||||||
const authMiddleware = require('./middleware/auth');
|
const authMiddleware = require('./middleware/auth');
|
||||||
@@ -12,6 +13,21 @@ const logger = require('./logger');
|
|||||||
const app = express();
|
const app = express();
|
||||||
const port = 3044;
|
const port = 3044;
|
||||||
|
|
||||||
|
const db = new sqlite3.Database('/data/sessions.sqlite', (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error opening database:', err);
|
||||||
|
} else {
|
||||||
|
db.run(`CREATE TABLE IF NOT EXISTS tags (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
tag TEXT UNIQUE
|
||||||
|
)`, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error creating tags table:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static('public'));
|
app.use(express.static('public'));
|
||||||
@@ -27,8 +43,7 @@ app.use(session({
|
|||||||
ttl: 30 * 24 * 60 * 60 // 1 month
|
ttl: 30 * 24 * 60 * 60 // 1 month
|
||||||
}),
|
}),
|
||||||
cookie: {
|
cookie: {
|
||||||
//secure: process.env.NODE_ENV === 'production', // Ensure cookies are only sent over HTTPS in production
|
secure: process.env.NODE_ENV === 'production', // Ensure cookies are only sent over HTTPS in production
|
||||||
secure: false,
|
|
||||||
maxAge: 30 * 24 * 60 * 60 * 1000 // 1 month
|
maxAge: 30 * 24 * 60 * 60 * 1000 // 1 month
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -36,6 +51,35 @@ app.use(session({
|
|||||||
app.use('/', authRouter);
|
app.use('/', authRouter);
|
||||||
app.use('/', authMiddleware, tasksRouter);
|
app.use('/', authMiddleware, tasksRouter);
|
||||||
|
|
||||||
|
// Add routes for handling tags
|
||||||
|
app.post('/save-tags', authMiddleware, (req, res) => {
|
||||||
|
const { tags } = req.body;
|
||||||
|
const placeholders = tags.map(() => '(?)').join(',');
|
||||||
|
const sql = `INSERT OR IGNORE INTO tags (tag) VALUES ${placeholders}`;
|
||||||
|
|
||||||
|
db.run(sql, tags, function(err) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Error saving tags:', err);
|
||||||
|
res.status(500).send('Error saving tags.');
|
||||||
|
} else {
|
||||||
|
res.send({ message: 'Tags saved successfully!' });
|
||||||
|
logger.info(`New tags saved: ${tags}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/get-tags', authMiddleware, (req, res) => {
|
||||||
|
db.all('SELECT tag FROM tags', [], (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Error retrieving tags:', err);
|
||||||
|
res.status(500).json({ error: 'Error retrieving tags' });
|
||||||
|
} else {
|
||||||
|
const tags = rows.map(row => row.tag);
|
||||||
|
res.json(tags);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
logger.info(`Server running at http://localhost:${port}`);
|
logger.info(`Server running at http://localhost:${port}`);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user