const express = require('express');
const mysql = require('mysql2/promise');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3000;
[Link](cors());
[Link]([Link]());
// Konfigurasi koneksi MySQL
const dbConfig = {
host: 'localhost',
user: 'root', // Ganti sesuai user MySQL Anda
password: '', // Ganti sesuai password MySQL Anda
database: 'kanban_db',
};
let pool;
async function initDb() {
pool = await [Link](dbConfig);
}
initDb().catch((err) => {
[Link]('Failed to initialize database pool:', err);
[Link](1);
});
// Endpoint untuk mendapatkan daftar PIC
[Link]('/api/pics', async (req, res) => {
try {
const [rows] = await [Link]('SELECT id, name FROM pic ORDER BY name');
[Link]([Link]((r) => [Link]));
} catch (error) {
[Link]('Error fetching PICs:', error);
[Link](500).json({ error: 'Failed to fetch PICs' });
}
});
// Endpoint untuk menambah PIC baru
[Link]('/api/pics', async (req, res) => {
try {
const { name } = [Link];
if (!name || ![Link]()) {
return [Link](400).json({ error: 'Name is required' });
}
await [Link]('INSERT INTO pic (name) VALUES (?)', [[Link]()]);
[Link]({ message: 'PIC added successfully' });
} catch (error) {
[Link]('Error adding PIC:', error);
[Link](500).json({ error: 'Failed to add PIC' });
}
});
// Endpoint untuk mendapatkan daftar Activity (Task options)
[Link]('/api/task-options', async (req, res) => {
try {
const [rows] = await [Link]('SELECT id, name FROM activity ORDER BY name');
[Link]([Link]((r) => [Link]));
} catch (error) {
[Link]('Error fetching task options:', error);
[Link](500).json({ error: 'Failed to fetch task options' });
}
});
// Endpoint untuk menambah Activity baru
[Link]('/api/task-options', async (req, res) => {
try {
const { name } = [Link];
if (!name || ![Link]()) {
return [Link](400).json({ error: 'Name is required' });
}
await [Link]('INSERT INTO activity (name) VALUES (?)', [[Link]()]);
[Link]({ message: 'Activity added successfully' });
} catch (error) {
[Link]('Error adding Activity:', error);
[Link](500).json({ error: 'Failed to add Activity' });
}
});
// Endpoint untuk mendapatkan daftar task lengkap
[Link]('/api/tasks', async (req, res) => {
try {
const [rows] = await [Link](`
SELECT
[Link], [Link], [Link], [Link],
[Link] AS pic,
t.timestamp_todo, t.timestamp_progress, t.timestamp_done,
t.timestamp_archived
FROM task t
JOIN pic p ON t.pic_id = [Link]
ORDER BY [Link]
`);
const tasks = [Link]((row) => ({
id: [Link](),
content: [Link],
pic: [Link],
detail: [Link],
status: [Link],
timestamps: {
todo: row.timestamp_todo ? row.timestamp_todo.toISOString() : null,
progress: row.timestamp_progress ? row.timestamp_progress.toISOString() :
null,
done: row.timestamp_done ? row.timestamp_done.toISOString() : null,
archived: row.timestamp_archived ? row.timestamp_archived.toISOString() :
null,
},
}));
[Link](tasks);
} catch (error) {
[Link]('Error fetching tasks:', error);
[Link](500).json({ error: 'Failed to fetch tasks' });
}
});
// Endpoint untuk menambah task baru
[Link]('/api/tasks', async (req, res) => {
try {
const { content, pic, detail, status, timestamps } = [Link];
if (!content || !pic || !status) {
return [Link](400).json({ error: 'content, pic, and status are
required' });
}
// Cari pic_id dari nama PIC
const [picRows] = await [Link]('SELECT id FROM pic WHERE name = ?', [pic]);
if ([Link] === 0) {
return [Link](400).json({ error: 'PIC not found' });
}
const pic_id = picRows[0].id;
// Insert task
const [result] = await [Link](
`INSERT INTO task
(content, pic_id, detail, status, timestamp_todo, timestamp_progress,
timestamp_done, timestamp_archived)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[
content,
pic_id,
detail || '',
status,
timestamps?.todo ? new Date([Link]) : null,
timestamps?.progress ? new Date([Link]) : null,
timestamps?.done ? new Date([Link]) : null,
timestamps?.archived ? new Date([Link]) : null,
]
);
[Link]({ message: 'Task added successfully', id: [Link] });
} catch (error) {
[Link]('Error adding task:', error);
[Link](500).json({ error: 'Failed to add task' });
}
});
// Endpoint untuk update task status dan timestamps
[Link]('/api/tasks/update', async (req, res) => {
try {
const { id, status, timestamps } = [Link];
if (!id || !status || !timestamps) {
return [Link](400).json({ error: 'id, status, and timestamps are
required' });
}
// Update task
await [Link](
`UPDATE task SET
status = ?,
timestamp_todo = ?,
timestamp_progress = ?,
timestamp_done = ?,
timestamp_archived = ?
WHERE id = ?`,
[
status,
[Link] ? new Date([Link]) : null,
[Link] ? new Date([Link]) : null,
[Link] ? new Date([Link]) : null,
[Link] ? new Date([Link]) : null,
id,
]
);
[Link]({ message: 'Task updated successfully' });
} catch (error) {
[Link]('Error updating task:', error);
[Link](500).json({ error: 'Failed to update task' });
}
});
[Link](port, () => {
[Link](`Kanban backend listening at [Link]
});