This commit is contained in:
2024-12-26 21:46:13 -05:00
parent 37eb7eebe8
commit 70f434cae3
5 changed files with 60 additions and 32 deletions

View File

@@ -229,7 +229,6 @@ app.get('/editcamp', requireSuperUser, (req,res) => {
const parts=t.split("-"); const parts=t.split("-");
const cname=parts[0]; const cname=parts[0];
const tnum=Number(parts[1]); const tnum=Number(parts[1]);
console.log("Cname: ",cname," campname ",campname," tnum ",tnum);
if (cname==campname) { if (cname==campname) {
edit.tickets[t]={}; edit.tickets[t]={};
edit.tickets[t].owner=tickets[t].owner; edit.tickets[t].owner=tickets[t].owner;
@@ -237,12 +236,21 @@ app.get('/editcamp', requireSuperUser, (req,res) => {
edit.tickets[t].status=tickets[t].status; edit.tickets[t].status=tickets[t].status;
} }
} }
console.log("Edit is ",edit);
return res.render("editcamp",edit); return res.render("editcamp",edit);
}) })
app.get('/manytickets', requireLogin, (req,res) => {
let username=req.session.username;
const edit={ username:req.session.username, tickets: {} };
for (const t in tickets) if (tickets[t].owner==username && tickets[t].status=="i") {
edit.tickets[t]={};
edit.tickets[t].offered=tickets[t].offered;
}
return res.render("manytickets",edit);
})
app.get('/mytickets',requireLogin, (req,res)=> {
app.get('/mytickets',requireLogin, async (req,res)=> {
let username=req.session.username; let username=req.session.username;
let claimed=0; let claimed=0;
let owned=0; let owned=0;
@@ -259,10 +267,30 @@ app.get('/mytickets',requireLogin, (req,res)=> {
} }
} }
if (owned==0) return res.render("message",{ username:username, message:"You have no unused tickets" }); 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 if (owned==1) {
const hash0=crypto.createHash('sha256');
const hash1=hash0.update(theticket+QRSalt);
const hash=hash1.digest("base64").slice(0,6);
const dataURL=await QRCode.toDataURL('localhost:3000/useticket?t='+theticket+'&h='+hashQR(theticket,username));
return res.render("oneticket",{ username:username, ticket:theticket, offered:tickets[theticket].offered, qrcode:dataURL });
}
else return res.render("manytickets",edit); else return res.render("manytickets",edit);
}); });
app.post('/mytickets',requireLogin, async (req,res)=> {
let username=req.session.username;
let theticket=req.body.ticket;
let offered=req.body.offered;
if (tickets[theticket].owner==username && tickets[theticket].status=="i") {
tickets[theticket].offered=offered;
}
const hash0=crypto.createHash('sha256');
const hash1=hash0.update(theticket+QRSalt);
const hash=hash1.digest("base64").slice(0,6);
const dataURL=await QRCode.toDataURL('localhost:3000/useticket?t='+theticket+'&h='+hashQR(theticket,username));
return res.render("oneticket", { username:username, ticket:theticket, offered:tickets[theticket].offered, qrcode:dataURL });
});
// Big Kahuna // Big Kahuna
// If you have zero tickets, show something saying that // If you have zero tickets, show something saying that
// For each ticket owned, display options to offer it, use it, or (eventually) pay for it. // For each ticket owned, display options to offer it, use it, or (eventually) pay for it.
@@ -283,7 +311,7 @@ app.get('/transfer', requireLogin, async (req,res) => {
edit.tickets[t]={}; edit.tickets[t]={};
edit.tickets[t].owner=tickets[t].owner; edit.tickets[t].owner=tickets[t].owner;
edit.tickets[t].offered=tickets[t].offered; edit.tickets[t].offered=tickets[t].offered;
edit.tickets[t].used=tickets[t].used; edit.tickets[t].used=tickets[t].status=="u";
} }
return res.render("transfer",edit); return res.render("transfer",edit);
} }
@@ -303,12 +331,6 @@ app.get('/transfer', requireLogin, async (req,res) => {
if (cat=="complex") return res.render('transfer',simpledata); if (cat=="complex") return res.render('transfer',simpledata);
}) })
app.post("/toggle", requireSuperUser, (req,res) => {
const ticket=req.body.ticket;
const isChecked = req.body.checked;
tickets[ticket].used=isChecked;
res.json({ message: 'Checkbox state received', checked: isChecked });
})
app.post("/changestatus", requireSuperUser, (req,res) => { app.post("/changestatus", requireSuperUser, (req,res) => {
const ticket=req.body.ticket; const ticket=req.body.ticket;
@@ -322,7 +344,8 @@ app.post("/updateoffered", requireLogin, (req,res) => {
const ticket=req.body.ticket; const ticket=req.body.ticket;
const offered=req.body.offered; const offered=req.body.offered;
if (tickets[ticket].owner!=req.session.username) res.status(500).send("Ticket "+ticket+" owned by someone else"); if (tickets[ticket].owner!=req.session.username) res.status(500).send("Ticket "+ticket+" owned by someone else");
else if (tickets[ticket].used) res.status(500).send("Ticket "+ticket+" has already been used"); else if (tickets[ticket].status=="u") res.status(500).send("Ticket "+ticket+" has already been used");
else if (tickets[ticket].status=="r") res.status(500).send("Ticket "+ticket+" was revoked");
else { else {
tickets[ticket].offered=offered; tickets[ticket].offered=offered;
res.json({ message: 'Updated owner of '+ticket+' to '+offered }); res.json({ message: 'Updated owner of '+ticket+' to '+offered });
@@ -344,10 +367,10 @@ app.get("/useticket",(req,res) => {
let ticket=req.t; let ticket=req.t;
let hash=req.h; let hash=req.h;
if (hashQR(ticket,req.session.username)!=hash) res.status(500).send("Ticket "+ticket+" was transferred to "+tickets[ticket].username); if (hashQR(ticket,req.session.username)!=hash) res.status(500).send("Ticket "+ticket+" was transferred to "+tickets[ticket].username);
else if (tickets[ticket].used) res.status(500).send("Ticket "+ticket+" has already been used."); else if (tickets[ticket].status!="i") res.status(500).send("Ticket "+ticket+" has already been used.");
else { else {
tickets[ticket].used=new Date().toISOString(); tickets[ticket].status="u";
res.send("<h1>Welcome, "+tickets[ticket].username+" to Falls on Fire! Ticket "+ticket+" has now been used.</h1>"); res.send("<h1>Welcome, "+tickets[ticket].owner+" to Falls on Fire! Ticket "+ticket+" has now been used.</h1>");
} }
}) })

View File

@@ -24,8 +24,7 @@
.qrcode-image { .qrcode-image {
object-fit: contain; object-fit: contain;
width: 80%; /* Adjust as needed */ grid-column:2;
height: 80%;
} }
/* Close button */ /* Close button */
@@ -37,24 +36,25 @@
cursor: pointer; cursor: pointer;
} }
.grid {
}
/* General Reset */ /* General Reset */
body { body {
margin: 0; margin: 0;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
display: flex; /* Ensure the body uses a flex container */ display: grid;
grid-template-columns: 1fr 3fr;
height: 100vh; /* Full viewport height */ height: 100vh; /* Full viewport height */
} }
/* Sidebar (Nav Links) */ /* Sidebar (Nav Links) */
.nav-links { .nav-links {
width: 250px; /* Set a fixed width for the sidebar */
background-color: #f4f4f4; /* Light gray background */ background-color: #f4f4f4; /* Light gray background */
padding: 20px; padding: 20px;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); /* Add a slight shadow for separation */ box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); /* Add a slight shadow for separation */
display: flex; grid-column: 1;
flex-direction: column; /* Ensure items stack vertically */
justify-content: flex-start; /* Optional: adjust spacing of items */
min-height: 100vh; /* Stretch to full viewport height */ min-height: 100vh; /* Stretch to full viewport height */
} }
@@ -77,6 +77,7 @@ body {
} }
.content { .content {
grid-column: 2;
flex-grow: 1; /* Allow content to fill the remaining space */ flex-grow: 1; /* Allow content to fill the remaining space */
padding: 20px; padding: 20px;
} }

View File

@@ -4,7 +4,7 @@
<title>Camps</title> <title>Camps</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
</head> </head>
<body> <body class="grid">
<%- include('partials/nav') %> <%- include('partials/nav') %>
<form id="editor" method="post"> <form id="editor" method="post">
<table border="1"> <table border="1">

View File

@@ -4,7 +4,7 @@
<title>Edit Camp</title> <title>Edit Camp</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
</head> </head>
<body> <body class="grid">
<%- include('partials/nav') %> <%- include('partials/nav') %>
<div id="QRShow" class="modal"> <div id="QRShow" class="modal">
<div id="QRBackground" class="modal-content"> <div id="QRBackground" class="modal-content">

View File

@@ -4,14 +4,18 @@
<title>Your Ticket</title> <title>Your Ticket</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
</head> </head>
<%- include('partials/nav') %>
<body> <body>
<form id="editor"> <%- include('partials/nav') %>
Transfer Ticket: <div class="content">
<input type="edit" placeholder="yourfriend@xyz.com" value="<%=offered%>" id="offered"> To use <%=ticket%>, scan this QR Code:<br>
<button id="Submit" type="button">Transfer</button> <img class="qrcode-image" width=300 height=300 src="<%=qrcode%>" alt="QR Code">
<form id="editor" method="POST">
Or transfer <%=ticket%> to:<br>
<input type="hidden" name="ticket" value="<%=ticket%>">
<input type="email" placeholder="yourfriend@xyz.com" value="<%=offered%>" name="offered">
<button id="Submit" type="submit">Transfer</button>
<br> <br>
</form> </form>
<img width=300 height=300 src="https://via.placeholder.com/150" alt="Placeholder Image"> </div>
</body> </body>
</html> </html>