99 lines
4.2 KiB
JavaScript
99 lines
4.2 KiB
JavaScript
const http = require("http");
|
||
const fs = require("fs");
|
||
const path = require("path");
|
||
|
||
const PORT = process.env.PORT || 3000;
|
||
const DATA = path.join(__dirname, "data.json");
|
||
|
||
const EVENT = { name: "Корпоративный ивент 2026", date: "30.10.2026", place: "Алматы, ДК «Жибек жолы»", capacity: 400 };
|
||
|
||
function db() {
|
||
try {
|
||
const d = JSON.parse(fs.readFileSync(DATA, "utf8"));
|
||
return { event: Object.assign(EVENT, d.event || {}), registrations: Array.isArray(d.registrations) ? d.registrations : [] };
|
||
} catch (_) {
|
||
return { event: EVENT, registrations: [] };
|
||
}
|
||
}
|
||
function persist(d) {
|
||
fs.writeFileSync(DATA, JSON.stringify(d, null, 2));
|
||
}
|
||
function readBody(req) {
|
||
return new Promise((resolve) => {
|
||
let s = "";
|
||
req.on("data", (c) => { s += c; if (s.length > 1e6) req.destroy(); });
|
||
req.on("end", () => { try { resolve(JSON.parse(s || "{}")); } catch (_) { resolve(null); } });
|
||
});
|
||
}
|
||
function json(res, code, obj) {
|
||
res.writeHead(code, { "Content-Type": "application/json; charset=utf-8" });
|
||
res.end(JSON.stringify(obj));
|
||
}
|
||
const MIME = {
|
||
".html": "text/html", ".css": "text/css", ".js": "application/javascript", ".json": "application/json",
|
||
".png": "image/png", ".jpg": "image/jpeg", ".svg": "image/svg+xml", ".ico": "image/x-icon", ".woff2": "font/woff2", ".woff": "font/woff", ".ttf": "font/ttf"
|
||
};
|
||
|
||
http.createServer(async (req, res) => {
|
||
const url = req.url.split("?")[0];
|
||
|
||
if (req.method === "GET" && url === "/api/registrations") {
|
||
return json(res, 200, db().registrations);
|
||
}
|
||
|
||
if (req.method === "POST" && url === "/api/registrations") {
|
||
const body = await readBody(req);
|
||
if (!body) return json(res, 400, { ok: false, error: "Некорректные данные" });
|
||
const name = String(body.name || "").trim().replace(/\s+/g, " ");
|
||
const email = String(body.email || "").trim().toLowerCase();
|
||
const phone = String(body.phone || "").trim();
|
||
if (!name || name.length < 3) return json(res, 400, { ok: false, error: "Укажите ФИО" });
|
||
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return json(res, 400, { ok: false, error: "Введите корректный адрес почты" });
|
||
if (phone.replace(/\D/g, "").length < 10) return json(res, 400, { ok: false, error: "Укажите телефон" });
|
||
const d = db();
|
||
if (d.registrations.some((r) => r.email === email)) {
|
||
return json(res, 409, { ok: false, error: "Заявка с этой почтой уже есть" });
|
||
}
|
||
const r = {
|
||
id: Date.now(),
|
||
name,
|
||
email,
|
||
phone,
|
||
department: String(body.department || "").trim(),
|
||
position: String(body.position || "").trim(),
|
||
role: String(body.role || "Сотрудник"),
|
||
track: String(body.track || "Все сессии"),
|
||
food: String(body.food || "Обычное"),
|
||
status: "Заявка",
|
||
createdAt: new Date().toISOString()
|
||
};
|
||
d.registrations.push(r);
|
||
persist(d);
|
||
return json(res, 200, { ok: true, registration: r });
|
||
}
|
||
|
||
if (req.method === "PATCH" && /^\/api\/registrations\/\d+$/.test(url)) {
|
||
const id = Number(url.split("/").pop());
|
||
const body = await readBody(req);
|
||
if (!body) return json(res, 400, { ok: false, error: "Некорректные данные" });
|
||
const d = db();
|
||
const r = d.registrations.find((x) => x.id === id);
|
||
if (!r) return json(res, 404, { ok: false, error: "Заявка не найдена" });
|
||
if ("status" in body) r.status = String(body.status || "Заявка");
|
||
const note = String(body.note == null ? "" : body.note).trim();
|
||
r.note = note;
|
||
persist(d);
|
||
return json(res, 200, { ok: true, registration: r });
|
||
}
|
||
|
||
let file = url === "/" ? "index.html" : url;
|
||
file = file.replace(/^\/+/, "");
|
||
const full = path.normalize(path.join(__dirname, file));
|
||
if (!full.startsWith(__dirname)) return json(res, 403, { ok: false, error: "Forbidden" });
|
||
if (fs.existsSync(full) && fs.statSync(full).isFile()) {
|
||
res.writeHead(200, { "Content-Type": (MIME[path.extname(full)] || "application/octet-stream") + "; charset=utf-8" });
|
||
return res.end(fs.readFileSync(full));
|
||
}
|
||
return json(res, 404, { ok: false, error: "Not found" });
|
||
}).listen(PORT, () => console.log("Сервер на порту " + PORT));
|