This commit is contained in:
2024-12-26 00:33:23 -05:00
parent 2ad92eb7fd
commit 37eb7eebe8
11 changed files with 475 additions and 132 deletions

View File

@@ -23,8 +23,10 @@ const QRSalt="!SaltyMagic5392370662";
// + Issue Tickets
// + Transfer Tickets Complicated page. (One ticket: static with transfer and QR code. Multi: buttons to transfer or show QR code)
// Split Transfer into admin (change owner, unused/used/cancelled pulldown) and public (no Used column) versions
// Claim Tickets
// + Use Ticket
// Claim One Claims, displays QRCode, and allows transfer with a single button.
// Claim Many Claims, but then displays tickets line by line with update and QRCode functionality
// Edit Regex based ticket list. Allows changing Owner, Offered, Used (Dropdown).
//
// ToDo, Later
// + Use a templating engine
@@ -56,12 +58,13 @@ const users = { "teppy@egenesis.com" : { password: hashPW("x6321872X.1"),
"fallsonfire@gmail.com" : { password: hashPW("indiantreeonfire"), superuser:false }
};
const tickets = { "habitat-1" : { owner: "teppy@egenesis.com" , offered: "", paid: 0.00, used: false },
"habitat-2" : { owner: "teppy@egenesis.com" , offered: "", paid: 0.00 },
"habitat-3" : { owner: "ginachen94@gmail.com", offered: "teppy@egenesis.com", paid: 0.00 },
"habitat-4" : { owner: "teppy@egenesis.com" , offered: "noahstern00@gmail.com", paid: 0.00 },
"habitat-5" : { owner: "teppy@egenesis.com" , offered: "", paid: 0.00, used: true },
"habitat-6" : { owner: "teppy@egenesis.com" , offered: "", paid: 0.00 },
// Status can be "i"=issued, "u"=used, "r"=revoked"
const tickets = { "habitat-1" : { owner: "teppyx@egenesis.com" , offered: "", paid: 0.00, status:"i" },
"habitat-2" : { owner: "teppyx@egenesis.com" , offered: "", paid: 0.00, status:"u" },
"habitat-3" : { owner: "ginachen94@gmail.com", offered: "teppyx@egenesis.com", paid: 0.00, status:"i" },
"habitat-4" : { owner: "teppyx@egenesis.com" , offered: "noahstern00@gmail.com", paid: 0.00, status:"i" },
"habitat-5" : { owner: "teppyx@egenesis.com" , offered: "", paid: 0.00, status:"r" },
"habitat-6" : { owner: "teppyx@egenesis.com" , offered: "", paid: 0.00, status:"i" },
};
const camps = { "habitat": { leader: "teppy@egenesis.com", lastid:6 } };
@@ -82,6 +85,7 @@ app.use(session({
// Middleware to protect routes
function requireLogin(req, res, next) {
if (req.session.username) return next();
req.session.returnTo=req.originalUrl;
return res.redirect('/login');
}
@@ -139,7 +143,7 @@ function categorizeTickets(username) {
let offering=0;
let simpleoffered=0;
let thet="";
for (const t in tickets) if (!tickets[t].used) {
for (const t in tickets) if (tickets[t].status=="i") {
if (tickets[t].owner==username && tickets[t].offered=="") simpleowner+=1;
else if (tickets[t].owner==username && tickets[t].offered!=username) offering+=1;
else if (tickets[t].owner!=username && tickets[t].offered==username) simpleoffered+=1;
@@ -164,16 +168,30 @@ app.get('/camps',requireSuperUser, (req,res) => {
}
for (const t in tickets) {
const parts=t.split("-");
const campname=parts[0];
const campname=parts[0];
const ticketnum=Number(parts[1]);
// camplist[campname]??={ leader:"", issued:0, claimed:0, used:0 };
camplist[campname].issued+=1;
if (tickets[t].owner!="") camplist[campname].claimed+=1;
if (tickets[t].used) camplist[campname].used+=1;
if (tickets[t].status!="r") {
camplist[campname].issued+=1;
if (tickets[t].owner!="") camplist[campname].claimed+=1;
if (tickets[t].status=="u") camplist[campname].used+=1;
}
}
return res.render("camps",{ username:"Teppy", camps:camplist });
return res.render("camps",{ username:req.session.username, camps:camplist });
})
app.post("/camps",requireSuperUser,(req,res) => {
console.log("New camp: ");
const campname=req.body.campname;
const leader=req.body.leader;
const qty=Number(req.body.qty);
camps[campname]??={ leader:leader, lastid:0 };
for (let i=0; i<qty; i++) {
camps[campname].lastid+=1;
tickets[campname+'-'+camps[campname].lastid]={ owner: "", offered: leader, status:"i" };
}
return res.redirect("/camps");
})
app.get('/issue', requireSuperUser, (req,res) => {
const camplist={};
@@ -182,26 +200,68 @@ app.get('/issue', requireSuperUser, (req,res) => {
const campname=parts[0];
const ticketnum=Number(parts[1]);
camplist[campname]??={ issued:0, claimed:0, used:0 };
camplist[campname].issued+=1;
if (tickets[t].owner!="") camplist[campname].claimed+=1;
if (tickets[t].used) camplist[campname].used+=1;
if (tickets[t].status!="r") {
camplist[campname].issued+=1;
if (tickets[t].owner!="") camplist[campname].claimed+=1;
if (tickets[t].status=="u") camplist[campname].used+=1;
}
}
return res.render("issue",{ username:"Teppy", camps:camplist });
return res.render("issue",{ camps:camplist });
})
app.post("/camps",(req,res) => {
const campname=req.body.campname;
const email=req.body.email;
const qty=Number(req.body.qty);
console.log("New camp: ",campname);
camps[campname]??={ leader:leader, lastid:0 };
for (let i=0; i<qty; i++) {
camps[campname].lastid+=1;
tickets[campname+'-'+camps[campname].lastid]={ owner: "", offered: email, used:false };
app.get('/camplead', requireLogin, (req,res) => {
let username=req.session.username;
const edit={ tickets: {} };
for (const t in tickets) if (tickets[t].owner==username) {
edit.tickets[t]={};
edit.tickets[t].owner=tickets[t].owner;
edit.tickets[t].offered=tickets[t].offered;
}
return res.redirect("/camps");
return res.render("camplead",edit);
})
app.get('/editcamp', requireSuperUser, (req,res) => {
let campname=req.query.campname;
const edit={ username:req.session.username, tickets: {} };
for (const t in tickets) {
const parts=t.split("-");
const cname=parts[0];
const tnum=Number(parts[1]);
console.log("Cname: ",cname," campname ",campname," tnum ",tnum);
if (cname==campname) {
edit.tickets[t]={};
edit.tickets[t].owner=tickets[t].owner;
edit.tickets[t].offered=tickets[t].offered;
edit.tickets[t].status=tickets[t].status;
}
}
console.log("Edit is ",edit);
return res.render("editcamp",edit);
})
app.get('/mytickets',requireLogin, (req,res)=> {
let username=req.session.username;
let claimed=0;
let owned=0;
let theticket="";
const edit={ username:req.session.username, tickets: {} };
for (const t in tickets) {
if (tickets[t].status=="i" && tickets[t].offered==username) { claimed++; tickets[t].owner=username; tickets[t].offered=""; }
if (tickets[t].status=="i" && tickets[t].owner==username) {
owned++;
if (owned==1) theticket=t; else theticket="";
edit.tickets[t]={};
edit.tickets[t].owner=tickets[t].owner;
edit.tickets[t].offered=tickets[t].offered;
}
}
if (owned==0) return res.render("message",{ username:username, message:"You have no unused tickets" });
else if (owned==1) return res.render("oneticket",{ username:username, ticket:theticket, offered:tickets[theticket].offered });
else return res.render("manytickets",edit);
});
// Big Kahuna
// If you have zero tickets, show something saying that
@@ -247,11 +307,18 @@ app.post("/toggle", requireSuperUser, (req,res) => {
const ticket=req.body.ticket;
const isChecked = req.body.checked;
tickets[ticket].used=isChecked;
// Perform any server-side logic here
res.json({ message: 'Checkbox state received', checked: isChecked });
})
app.post("/changestatus", requireSuperUser, (req,res) => {
const ticket=req.body.ticket;
console.log("Changestatus ",ticket);
tickets[ticket].status=req.body.status;
res.json({ message: 'Status received', status: req.body.status });
})
app.post("/updateoffered", requireLogin, (req,res) => {
console.log("UpdateOffered being rubn");
const ticket=req.body.ticket;
const offered=req.body.offered;
if (tickets[ticket].owner!=req.session.username) res.status(500).send("Ticket "+ticket+" owned by someone else");
@@ -263,6 +330,16 @@ app.post("/updateoffered", requireLogin, (req,res) => {
})
app.post("/updateticketsu", requireSuperUser, (req,res) => {
const ticket=req.body.ticket;
const owner=req.body.owner;
const offered=req.body.offered;
tickets[ticket].owner=req.body.owner;
tickets[ticket].offered=req.body.offered;
res.json({ message: 'Updated '+ticket });
})
app.get("/useticket",(req,res) => {
let ticket=req.t;
let hash=req.h;
@@ -445,6 +522,13 @@ app.post('/qrcode',requireLogin,async (req,res) => {
return res.send({ owner:tickets[ticket].owner, qrcode: URL });
})
app.post('/qrcodesu',requireSuperUser,async (req,res) => {
const username=req.session.username;
const ticket=req.body.ticket;
const URL=await QRCode.toDataURL('localhost:3000/useticket?t='+ticket+'&h='+hashQR(ticket,username));
return res.send({ owner:tickets[ticket].owner, qrcode: URL });
})
// Protected routes
app.get('/products', requireLogin, (req, res) => {
res.send(`