Commit 798b419d by tdgiang

Add date-range filter, stats strip, search, and form validation to admin transactions UI

Adds GET /admin index redirect, createdAt date-range filtering on the
transactions list with a stat strip (total/success/pending/revenue) and
client-side search, plus inline validation and quick amount chips on the
new-transaction form.
Co-Authored-By: 's avatarClaude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KPzWwuTEeX2vXGXvyGn4q
parent de551724
......@@ -209,6 +209,14 @@ exports.listTransactions = function (req, res) {
filter.createdByUsername = String(req.query.staff);
}
var fromDate = moment(String(req.query.fromDate || ""), "YYYY-MM-DD", true);
var toDate = moment(String(req.query.toDate || ""), "YYYY-MM-DD", true);
if (fromDate.isValid() || toDate.isValid()) {
filter.createdAt = {};
if (fromDate.isValid()) filter.createdAt.$gte = fromDate.startOf("day").toDate();
if (toDate.isValid()) filter.createdAt.$lte = toDate.endOf("day").toDate();
}
function render(staffOptions) {
AdminTransaction.find(filter)
.sort({ createdAt: -1 })
......@@ -222,6 +230,7 @@ exports.listTransactions = function (req, res) {
var transactions = list.map(function (tx) {
return {
merTrxId: tx.merTrxId,
merTrxIdShort: tx.merTrxId.split("_").pop(),
customerName: tx.customerName,
customerPhone: tx.customerPhone,
amount: tx.amount,
......@@ -243,6 +252,8 @@ exports.listTransactions = function (req, res) {
username: req.session.username,
staffOptions: staffOptions || [],
selectedStaff: req.query.staff || "",
selectedFromDate: fromDate.isValid() ? fromDate.format("YYYY-MM-DD") : "",
selectedToDate: toDate.isValid() ? toDate.format("YYYY-MM-DD") : "",
});
});
}
......
......@@ -10,6 +10,13 @@ var MIN_PASSWORD_LENGTH = 8;
// timing responses cannot tell "no such user" apart from "wrong password".
var DUMMY_HASH = "$2b$10$v5huvbowopyU7O11oK7ykeCMpvpEJCt4.y9cv8kZ.7liCwdYEY8sS";
exports.index = function (req, res) {
if (req.session && req.session.userId) {
return res.redirect("/admin/transactions");
}
return res.redirect("/admin/login");
};
exports.loginForm = function (req, res) {
res.render("admin/login", { error: null });
};
......
......@@ -6,6 +6,8 @@ module.exports = function (app) {
var requireAdmin = require("../middlewares/requireAdmin");
var loginRateLimit = require("../middlewares/loginRateLimit");
app.route("/admin").get(adminAuth.index);
app.route("/admin/login")
.get(adminAuth.loginForm)
.post(loginRateLimit, adminAuth.login);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment