Skip to content

Announcement banner / Expandable Server data sysem #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .replit
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

hidden = [".config", ".editorconfig", ".gitattributes", ".gitignore", ".gitnore", ".github"]
run = "npm run start"

[[hints]]
regex = "Error \\[ERR_REQUIRE_ESM\\]"
message = "We see that you are using require(...) inside your code. We currently do not support this syntax. Please use 'import' instead when using external modules. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)"

[nix]
channel = "stable-22_05"

[env]
XDG_CONFIG_HOME = "/home/runner/.config"
PATH = "/home/runner/$REPL_SLUG/.config/npm/node_global/bin:/home/runner/$REPL_SLUG/node_modules/.bin"
npm_config_prefix = "/home/runner/$REPL_SLUG/.config/npm/node_global"

[gitHubImport]
requiredFiles = [".replit", "replit.nix", ".config"]

[packager]
language = "nodejs"

[packager.features]
packageSearch = true
guessImports = true
enabledForHosting = false

[unitTest]
language = "nodejs"

[debugger]
support = true

[debugger.interactive]
transport = "localhost:0"
startCommand = [ "dap-node" ]

[debugger.interactive.initializeMessage]
command = "initialize"
type = "request"

[debugger.interactive.initializeMessage.arguments]
clientID = "replit"
clientName = "replit.com"
columnsStartAt1 = true
linesStartAt1 = true
locale = "en-us"
pathFormat = "path"
supportsInvalidatedEvent = true
supportsProgressReporting = true
supportsRunInTerminalRequest = true
supportsVariablePaging = true
supportsVariableType = true

[debugger.interactive.launchMessage]
command = "launch"
type = "request"

[debugger.interactive.launchMessage.arguments]
args = []
console = "externalTerminal"
cwd = "."
environment = []
pauseForSourceMap = false
program = "./index.js"
request = "launch"
sourceMaps = true
stopOnEntry = false
type = "pwa-node"

[languages]

[languages.javascript]
pattern = "**/{*.js,*.jsx,*.ts,*.tsx}"

[languages.javascript.languageServer]
start = "typescript-language-server --stdio"
8 changes: 8 additions & 0 deletions data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"announcement": {
"content": "Hey, lookat that! It's a new Aspine update! You probably don't care, but for the two people that <i>do</i> care, you can check out the change logs by scrolling down in the <a onclick='openTab(\"information\");'>info tab</a>. These announcements will show up every once in a while, informing you of any upcoming events, school news, or anything else.<br>- The Aspine Devs<span style=\"float: right; font-size: 10px; margin-top: 15px;\">P.S. Admins, to edit the announcement, go to the super secret admin tab</span>",
"content-type": "html",
"shown": true
},
"note for dev team": "this system is expandable, feel free to use this file for additional features"
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"express-session": "^1.17.1",
"file-saver": "^2.0.5",
"fs-extra": "^9.1.0",
"fullcalendar": "^5.11.3",
"jquery": "^3.6.0",
"jsdom": "^16.5.2",
"marked": "^4.0.10",
Expand Down
42 changes: 42 additions & 0 deletions public/adminTab.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<div id="admin" class="tabcontent">
<details>
<summary>Server Data</summary>
<textarea id="data-input" style="width: 100%; height: 300px;">unable to get server data</textarea>
<div style="border-style: outset; color: var(--black); cursor: pointer; width: 200px;" id="data-update-button">Save to Server</div>
</details>

<!-- tremble before my bad code -->
<script>

async function getData() {
let response = await fetch('serverdata');
return response.json();
}

getData().then((data) => {
document.getElementById('data-input').value = JSON.stringify(data, null, 2);
});

// post function
async function postData(data) {
var response = await fetch(location.origin + '/serverdata', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
return response.json(); // parses JSON response into native JavaScript objects
}

document.getElementById('data-update-button').addEventListener('click', () => {
try {
jsonToPost = JSON.parse(document.getElementById('data-input').value);
if (window.confirm("Are you sure you want to change this? This cannot be undone.")) {
postData(jsonToPost);
location.reload();
}
} catch(err) {
window.alert(err.stack);
}
});
</script>
</div>
12 changes: 12 additions & 0 deletions public/css/home.css
Original file line number Diff line number Diff line change
Expand Up @@ -1404,3 +1404,15 @@ hr {
font-size: 16px;
font-family: 'Poppins-Regular';
}

#announcement-banner {
display: inline-block;
text-align: left;
width: 98%;
padding: 1em;
margin-bottom: 0.5em;
border-radius: 16px;
color: var(--black);
background: var(--white);
border: 2px solid var(--green);
}
11 changes: 9 additions & 2 deletions public/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ <h4 id="title" onclick="openTab('grades')">Aspine</h4>
</label>
</div>

<div id="announcement-banner" style="display: none;">
<h3>ANNOUNCEMENT
<span class="close" title="go away" onclick="this.parentElement.parentElement.style.display = 'none';">&times;</span>
</h3>
</div>

<!-- SIDENAV STUFF -->
<div id="sidenav">
<!-- switch-exempt makes the switch out of navbar pass over this -->
Expand All @@ -85,7 +91,7 @@ <h4 id="title" onclick="openTab('grades')">Aspine</h4>
</button>
<hr/>
</div>

<div class="tab">
<button class="tablinks hide switch-exempt" onclick="openSideNav()" id="hamburger_button"><i class="fa fa-bars"></i></button>
<button class="tablinks active" onclick="openTab('grades'); closeSideNav()" id="grades_open">Grades</button>
Expand Down Expand Up @@ -120,7 +126,7 @@ <h4 id="title" onclick="openTab('grades')">Aspine</h4>
</select>
</div>
</div>

<!--
<div id="loader" class="modal" style="background-color: rgba(0,0,0,0.0); padding-top: 300px; display: inline-block;">
<div id="loader_modal_content" class="model-content" style=" width: 500px; height: 150px; margin: auto;">
Expand Down Expand Up @@ -491,6 +497,7 @@ <h2 class="info-header">GPA Type and Switching Quarters</h2>
</p>
</div>
</div>
<!-- hidden tab -->
<p>Aspine version: <span id="version">(loading&hellip;)</span></p>
<script>
window.addEventListener('DOMContentLoaded', () => {
Expand Down
25 changes: 25 additions & 0 deletions public/js/extraFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -806,3 +806,28 @@ let isAccessible = function(term, includedTerms) {
reason: reason
};
}


window.getData = async function() {
let response = await fetch('serverdata');
return response.json();
}

getData().then((data) => {
let announcement = data.announcement;

let banner = document.getElementById("announcement-banner");
banner.json = JSON.parse(JSON.stringify(announcement));
// check if announcement exists
if ((announcement.content != null) && announcement.shown) {
// show announcement banner
banner.style.display = 'inline-block';
if (announcement.contentType == 'text') {
for (let textPart of announcement.content.split("\n")) {
banner.appendChild(document.createTextNode(textPart));
}
} else {
banner.innerHTML += announcement.content;
}
}
});
8 changes: 8 additions & 0 deletions replit.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ pkgs }: {
deps = [
pkgs.nodejs-16_x
pkgs.nodePackages.typescript-language-server
pkgs.yarn
pkgs.replitPackages.jest
];
}
44 changes: 43 additions & 1 deletion serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const changelog = marked(
const schedule = TOML.parse(
fs.readFileSync(__dirname + '/public/schedule.toml')
);
// environment variable, someone deal with this
const admins = JSON.parse(process.env['admins']).map(function (username) {
return username.toString();
});

program
.version(version)
Expand Down Expand Up @@ -195,7 +199,19 @@ app.post('/pdf', async (req, res) => {

app.get('/', async (req, res) => {
if (req.session.username || req.session.nologin) {
res.sendFile(__dirname + '/public/home.html');
if (admins.includes(req.session.username)) {
// edited home page for admins
let adminTab = fs.readFileSync(__dirname + '/public/adminTab.html', "utf8");
let homeHTML = fs.readFileSync(__dirname + '/public/home.html', "utf8");

// fear my bad code
homeHTML = homeHTML.replace("<!-- hidden tab -->", adminTab);
homeHTML = homeHTML.replace("Info</button>", 'Info</button>\n<button class="tablinks" onclick="openTab(\'admin\'); closeSideNav()" id="admin_open">Admin</button>');
res.end(homeHTML);
} else {
res.sendFile(__dirname + '/public/home.html');
}

} else {
res.redirect('/login');
}
Expand Down Expand Up @@ -227,6 +243,32 @@ app.get('/logout', async (req, res) => {
res.redirect('/login');
});

app.get('/serverdata', async (req, res) => {
let serverData = JSON.parse(fs.readFileSync(__dirname + '/data.json'));
let responseData = {};
// maybe modify data before sending it
responseData = serverData;
res.status(200).send(responseData);
});

app.post('/serverdata', async (req, res) => {
if (admins.includes(req.session.username)) {
console.log("server data updated by " + req.session.username);
fs.writeFileSync(__dirname + '/data.json', JSON.stringify(req.body, null, "\t"));
res.sendStatus(200);
} else {
console.log(`attepmted server data update by ${req.session.username}, denied`);
res.sendStatus(403);
}
});

app.get('/admin', async (req, res) => {
if (admins.includes(req.session.username)) {
res.sendFile(__dirname + '/public/adminTab.html');
} else {
res.status(403).send("haha lol you arent admin L bozo<br>..or you're just not <a href=\"login\">logged in</a>");
}
});

app.use((req, res) => {
res.status(404);
Expand Down