diff --git a/http_root/css/site.css b/http_root/css/site.css index a89de1c..c731386 100644 --- a/http_root/css/site.css +++ b/http_root/css/site.css @@ -44,7 +44,7 @@ input[type=textarea] { height: 150px; } -input[type=submit] { +button { /* remove default behavior */ appearance: none; -webkit-appearance: none; diff --git a/http_views/events.pug b/http_views/events.pug index fc85554..c259389 100644 --- a/http_views/events.pug +++ b/http_views/events.pug @@ -3,23 +3,42 @@ extends layout.pug block content h1 Welcome to D&D Vault Bot + script. + event=!{JSON.stringify(event)} + async function setEvent() { + console.log('setEvent fired: '+event.guildID); + event.title=document.getElementById('event-info').value; + event.dm=document.getElementById('event-dm').value; + event.duration_hours=document.getElementById('event-duration_hours').value; + event.number_player_slots=document.getElementById('event-number_player_slots').value; + event.campaign=document.getElementById('event-campaign').value; + event.description=document.getElementById('event-description').value; + event.date_time=new Date(document.getElementById('event-date').value+'T'+document.getElementById('event-time').value); + try { + const jsonResponse = await postData('#{Config.httpServerURL}/events/set', event); + document.getElementById('event-info').innerHTML='Updated!'; + } catch (error) { + document.getElementById('event-info').innerHTML='Error: '+error.message; + } + } .thebody - form(action=`${Config.httpServerURL}/events/set`, method="POST") + div(id="event-info") + form p | Title: - input(type='text' name='title' placeholder='Title', value=`${event?event.title:''}`) + input(type='text' name='title' id='event-title' placeholder='Title', value=`${event&&event.title?event.title:''}`) | DM/GM: - input(type='text' name='dm' placeholder='DM/GM', value=`${event?event.dm:''}`) + input(type='text' name='dm' id='event-dm' placeholder='DM/GM', value=`${event&&event.dm?event.dm:''}`) | Duration (in hours): - input(type='text' name='duration_hours' placeholder='Duration (in hours)', value=`${event?event.duration_hours:''}`) + input(type='text' name='duration_hours' id='event-duration_hours' placeholder='Duration (in hours)', value=`${event&&event.duration_hours?event.duration_hours:''}`) | Start (Date): - input(type='date' name='date', value=`${event?event.date_time.toISOString().substring(0,10):''}`) + input(type='date' name='date' id='event-date' value=`${event?event.date_time.toISOString().substring(0,10):''}`) | Start (Time): - input(type='time' name='time', value=`${event?event.date_time.toISOString().substring(11,16):''}`) + input(type='time' name='time' id='event-time' value=`${event?event.date_time.toISOString().substring(11,16):''}`) | Number of Players: - input(type='text' name='number_player_slots' placeholder='Number of Players', value=`${event?event.number_player_slots:''}`) + input(type='text' name='number_player_slots' id='event-number_player_slots' placeholder='Number of Players', value=`${event&&event.number_player_slots?event.number_player_slots:''}`) | Campaign: - input(type='text' name='campaign' placeholder='Campaign', value=`${event?event.campaign:''}`) + input(type='text' name='campaign' id='event-campaign' placeholder='Campaign', value=`${event&&event.campaign?event.campaign:''}`) | Description: - input(type='textarea' name='description' placeholder='Description', value=`${event?event.description:''}`) - input(type='submit' value='Submit') \ No newline at end of file + input(type='textarea' name='description' id='event-description' placeholder='Description', value=`${event&&event.description?event.description:''}`) + button(type='button' onclick='setEvent();') Save \ No newline at end of file diff --git a/http_views/includes/head.pug b/http_views/includes/head.pug index 9605dc0..c2750eb 100644 --- a/http_views/includes/head.pug +++ b/http_views/includes/head.pug @@ -3,5 +3,26 @@ head title D&D Vault - #{title} link(rel='stylesheet' href='/css/site.css' type='text/css') link(rel="icon" href="/animated_favicon.gif" type="image/gif") - + script. + // POST method implementation: + async function postData(url = '', data = {}) { + // Default options are marked with * + const response = await fetch(url, { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify(data) // body data type must match "Content-Type" header + }); + if (response.status != 200) { + throw new Error('Error talking with backend: '+response.statusText); + } + return response.json(); // parses JSON response into native JavaScript objects + } //- script(src='/js/examples.js') diff --git a/index.js b/index.js index 3e0f6f1..a139df1 100644 --- a/index.js +++ b/index.js @@ -61,6 +61,7 @@ const ROUTE_CALENDAR = "/calendar"; const ROUTE_TIMEZONES = "/timezones"; const ROUTE_TIMEZONESSET = "/timezones/set"; const ROUTE_EVENTS = "/events"; +const ROUTE_EVENTSSET = "/events/set"; let app = express(); @@ -124,9 +125,56 @@ let server = app .get(ROUTE_ROOT, function (request, response) { response.render('index', { title: 'Home', Config: Config, discordMe: request.session.discordMe }); }) + .get(ROUTE_CALENDAR, async (request, response) => { + try { + console.log('serving ' + ROUTE_CALENDAR); + const requestUrl = new URL(request.url, `${request.protocol}://${request.headers.host}`); + let userID = requestUrl.searchParams.get('userID'); + const excludeGuild = requestUrl.searchParams.get('exclude') ? requestUrl.searchParams.get('exclude').split(',') : []; + if (!userID && request.session.discordMe) { + // console.log(`have discordMe, setting userID`); + userID = request.session.discordMe.id; + } + if (!userID) { + // console.log(`don't have userID, redirecting to discord to login`); + request.query.destination = ROUTE_CALENDAR; + response.redirect(url.format({ + pathname: grant.config.discord.prefix + "/discord", + query: request.query, + })); + } else { + // console.log(`have userid, heading to handleCalendarRequest`); + let responseContent = await calendar.handleCalendarRequest(userID, excludeGuild); + response.setHeader('Content-Type', 'text/calendar'); + response.end(responseContent); + } + } catch (error) { + console.error(error.message); + response.setHeader('Content-Type', 'text/html'); + response.status(500); + response.end(error.message); + } + }) + .use(async function (request, response, next) { + console.log('in middleware, ensuring user is logged in'); + let desiredDestination = request.path; + // console.log('desiredDestination ' + desiredDestination); + if (!request.session.discordMe) { + console.log(`user is _not_ logged in, redirecting`); + request.query.destination = desiredDestination; + response.redirect(url.format({ + pathname: grant.config.discord.prefix + "/discord", + query: request.query, + })); + } else { + console.log(`${request.session.discordMe.username} user is logged in`); + next(); + } + }) .get(ROUTE_TIMEZONESSET, async function (request, response) { try { console.log('serving ' + ROUTE_TIMEZONESSET); + //@todo can remove if (!request.session.discordMe) { console.log(`User not authenticated.`); response.json({ status: 'false' }); @@ -155,6 +203,7 @@ let server = app .get(ROUTE_TIMEZONES, function (request, response) { try { console.log('serving ' + ROUTE_TIMEZONES); + //@todo can remove if (!request.session.discordMe) { request.query.destination = ROUTE_TIMEZONES; response.redirect(url.format({ @@ -177,6 +226,7 @@ let server = app .get(ROUTE_EVENTS, async function (request, response) { try { console.log('serving ' + ROUTE_EVENTS); + //@todo can remove if (!request.session.discordMe) { request.query.destination = ROUTE_EVENTS; response.redirect(url.format({ @@ -200,35 +250,8 @@ let server = app response.end(error.message); } }) - .get(ROUTE_CALENDAR, async (request, response) => { - try { - console.log('serving ' + ROUTE_CALENDAR); - const requestUrl = new URL(request.url, `${request.protocol}://${request.headers.host}`); - let userID = requestUrl.searchParams.get('userID'); - const excludeGuild = requestUrl.searchParams.get('exclude') ? requestUrl.searchParams.get('exclude').split(',') : []; - if (!userID && request.session.discordMe) { - // console.log(`have discordMe, setting userID`); - userID = request.session.discordMe.id; - } - if (!userID) { - // console.log(`don't have userID, redirecting to discord to login`); - request.query.destination = ROUTE_CALENDAR; - response.redirect(url.format({ - pathname: grant.config.discord.prefix + "/discord", - query: request.query, - })); - } else { - // console.log(`have userid, heading to handleCalendarRequest`); - let responseContent = await calendar.handleCalendarRequest(userID, excludeGuild); - response.setHeader('Content-Type', 'text/calendar'); - response.end(responseContent); - } - } catch (error) { - console.error(error.message); - response.setHeader('Content-Type', 'text/html'); - response.status(500); - response.end(error.message); - } + .get(ROUTE_EVENTSSET, async (request, resposne) => { + }) .listen(Config.httpServerPort);