From 6f7d04829daa2b2a27538bed96c6cd0640c40790 Mon Sep 17 00:00:00 2001 From: wixarm Date: Sun, 1 Feb 2026 10:47:38 +0330 Subject: [PATCH] ad: transactions province filter --- index.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index d1c961f..07f00e6 100644 --- a/index.js +++ b/index.js @@ -1084,6 +1084,7 @@ app.get("/all-payments/data", requireAllPaymentsAuth, async (req, res) => { let dateTo = (req.query.dateTo || "").trim(); if (dateFrom && !dateTo) dateTo = dateFrom; const search = (req.query.search || "").trim(); + const province = (req.query.province || "").trim(); if (dateFrom || dateTo) { console.log("all-payments/data date filter:", { dateFrom, dateTo }); @@ -1106,6 +1107,25 @@ app.get("/all-payments/data", requireAllPaymentsAuth, async (req, res) => { } } + if (province) { + const code = String(province).trim(); + const prefixRegex = new RegExp("^" + escapeRegex(code)); + filter.$and = filter.$and || []; + filter.$and.push({ + $or: [ + { provincecode: prefixRegex }, + { + $expr: { + $regexMatch: { + input: { $toString: "$provincecode" }, + regex: "^" + escapeRegex(code), + }, + }, + }, + ], + }); + } + if (search) { filter.$or = [ { amountRaw: new RegExp(escapeRegex(search), "i") }, @@ -1113,6 +1133,13 @@ app.get("/all-payments/data", requireAllPaymentsAuth, async (req, res) => { { provincecode: new RegExp(escapeRegex(search), "i") }, { resNum: new RegExp(escapeRegex(search), "i") }, ]; + // Province name filter: match search text against province names (e.g. همدان, تست) + Object.keys(PROVINCE_NAMES).forEach((code) => { + if (PROVINCE_NAMES[code].indexOf(search) !== -1) { + filter.$or.push({ provincecode: code }); + filter.$or.push({ provincecode: parseInt(code, 10) }); + } + }); if (!isNaN(parseInt(search, 10))) { filter.$or.push({ amount: parseInt(search, 10) }); } @@ -1250,7 +1277,9 @@ app.get("/all-payments", async (req, res) => { * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Inter', -apple-system, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; padding: 24px; line-height: 1.5; } .page { max-width: 1200px; margin: 0 auto; } - h1 { font-size: 1.75rem; font-weight: 700; margin-bottom: 24px; letter-spacing: -0.02em; } + .page-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 24px; } + .page-header h1 { font-size: 1.75rem; font-weight: 700; margin: 0; letter-spacing: -0.02em; } + .header-actions { display: flex; gap: 10px; align-items: center; } .toolbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: 20px; } .filters { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; flex: 1; } .filter-group { display: flex; align-items: center; gap: 8px; } @@ -1261,6 +1290,11 @@ app.get("/all-payments", async (req, res) => { } input[type="text"]:focus, input[type="date"]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(99,102,241,0.2); } input[type="text"]::placeholder { color: var(--text-muted); } + select { + background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); + color: var(--text); padding: 10px 14px; font-size: 0.875rem; min-width: 140px; cursor: pointer; + } + select:focus { outline: none; border-color: var(--primary); } .btn { border: none; border-radius: var(--radius-sm); padding: 10px 18px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.15s, opacity 0.15s; } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .btn-primary { background: var(--primary); color: #fff; } @@ -1295,7 +1329,13 @@ app.get("/all-payments", async (req, res) => {
-

همه پرداخت‌ها

+
@@ -1309,12 +1349,19 @@ app.get("/all-payments", async (req, res) => {
- + + +
+
+
- -
@@ -1328,7 +1375,7 @@ app.get("/all-payments", async (req, res) => {