forked from Dniel97/artemis
HUGE WebUI overhaul
- Removed ugly styles in header - Properly implemented Bootstrap's NavBar - Added username to session
This commit is contained in:
parent
08927db100
commit
c51103aaf5
155
core/frontend.py
155
core/frontend.py
@ -18,22 +18,26 @@ from core.data import Data
|
||||
|
||||
|
||||
class IUserSession(Interface):
|
||||
userId = Attribute("User's ID")
|
||||
user_id = Attribute("User's ID")
|
||||
username = Attribute("User's username")
|
||||
current_ip = Attribute("User's current ip address")
|
||||
permissions = Attribute("User's permission level")
|
||||
|
||||
|
||||
class PermissionOffset(Enum):
|
||||
USER = 0 # Regular user
|
||||
USERMOD = 1 # Can moderate other users
|
||||
ACMOD = 2 # Can add arcades and cabs
|
||||
SYSADMIN = 3 # Can change settings
|
||||
USER = 0 # Regular user
|
||||
USERMOD = 1 # Can moderate other users
|
||||
ACMOD = 2 # Can add arcades and cabs
|
||||
SYSADMIN = 3 # Can change settings
|
||||
# 4 - 6 reserved for future use
|
||||
OWNER = 7 # Can do anything
|
||||
OWNER = 7 # Can do anything
|
||||
|
||||
|
||||
@implementer(IUserSession)
|
||||
class UserSession(object):
|
||||
def __init__(self, session):
|
||||
self.userId = 0
|
||||
self.user_id = 0
|
||||
self.username = None
|
||||
self.current_ip = "0.0.0.0"
|
||||
self.permissions = 0
|
||||
|
||||
@ -106,6 +110,7 @@ class FrontendServlet(resource.Resource):
|
||||
server_name=self.config.server.name,
|
||||
title=self.config.server.name,
|
||||
game_list=self.game_list,
|
||||
active_page="/",
|
||||
sesh=vars(IUserSession(request.getSession())),
|
||||
).encode("utf-16")
|
||||
|
||||
@ -134,7 +139,7 @@ class FE_Gate(FE_Base):
|
||||
|
||||
sesh = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if usr_sesh.userId > 0:
|
||||
if usr_sesh.user_id > 0:
|
||||
return redirectTo(b"/user", request)
|
||||
|
||||
if uri.startswith("/gate/create"):
|
||||
@ -153,6 +158,7 @@ class FE_Gate(FE_Base):
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | Login Gate",
|
||||
error=err,
|
||||
active_page="gate",
|
||||
sesh=vars(usr_sesh),
|
||||
).encode("utf-16")
|
||||
|
||||
@ -161,7 +167,7 @@ class FE_Gate(FE_Base):
|
||||
ip = Utils.get_ip_addr(request)
|
||||
|
||||
if uri == "/gate/gate.login":
|
||||
access_code: str = request.args[b"access_code"][0].decode()
|
||||
access_code: str = request.args[b"access-code"][0].decode()
|
||||
passwd: bytes = request.args[b"passwd"][0]
|
||||
if passwd == b"":
|
||||
passwd = None
|
||||
@ -187,9 +193,10 @@ class FE_Gate(FE_Base):
|
||||
|
||||
sesh = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
usr_sesh.userId = uid
|
||||
usr_sesh.user_id = uid
|
||||
usr_sesh.username = user["username"]
|
||||
usr_sesh.current_ip = ip
|
||||
usr_sesh.permissions = user['permissions']
|
||||
usr_sesh.permissions = user["permissions"]
|
||||
|
||||
return redirectTo(b"/user", request)
|
||||
|
||||
@ -228,20 +235,23 @@ class FE_Gate(FE_Base):
|
||||
card = self.data.card.get_card_by_access_code(ac)
|
||||
if card is None:
|
||||
return redirectTo(b"/gate?e=1", request)
|
||||
|
||||
user = self.data.user.get_user(card['user'])
|
||||
|
||||
user = self.data.user.get_user(card["user"])
|
||||
if user is None:
|
||||
self.logger.warning(f"Card {ac} exists with no/invalid associated user ID {card['user']}")
|
||||
self.logger.warning(
|
||||
f"Card {ac} exists with no/invalid associated user ID {card['user']}"
|
||||
)
|
||||
return redirectTo(b"/gate?e=0", request)
|
||||
|
||||
if user['password'] is not None:
|
||||
if user["password"] is not None:
|
||||
return redirectTo(b"/gate?e=1", request)
|
||||
|
||||
template = self.environment.get_template("core/frontend/gate/create.jinja")
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | Create User",
|
||||
code=ac,
|
||||
sesh={"userId": 0, "permissions": 0},
|
||||
active_page="gate",
|
||||
sesh={"user_id": 0, "permissions": 0},
|
||||
).encode("utf-16")
|
||||
|
||||
|
||||
@ -252,48 +262,51 @@ class FE_User(FE_Base):
|
||||
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if usr_sesh.userId == 0:
|
||||
if usr_sesh.user_id == 0:
|
||||
return redirectTo(b"/gate", request)
|
||||
|
||||
|
||||
m = re.match("\/user\/(\d*)", uri)
|
||||
|
||||
if m is not None:
|
||||
|
||||
if m is not None:
|
||||
usrid = m.group(1)
|
||||
if usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value or not usrid == usr_sesh.userId:
|
||||
if (
|
||||
usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value
|
||||
or not usrid == usr_sesh.user_id
|
||||
):
|
||||
return redirectTo(b"/user", request)
|
||||
|
||||
|
||||
else:
|
||||
usrid = usr_sesh.userId
|
||||
|
||||
usrid = usr_sesh.user_id
|
||||
|
||||
user = self.data.user.get_user(usrid)
|
||||
if user is None:
|
||||
return redirectTo(b"/user", request)
|
||||
|
||||
|
||||
cards = self.data.card.get_user_cards(usrid)
|
||||
arcades = self.data.arcade.get_arcades_managed_by_user(usrid)
|
||||
|
||||
|
||||
card_data = []
|
||||
arcade_data = []
|
||||
|
||||
for c in cards:
|
||||
if c['is_locked']:
|
||||
status = 'Locked'
|
||||
elif c['is_banned']:
|
||||
status = 'Banned'
|
||||
for i, c in enumerate(cards):
|
||||
if c["is_locked"]:
|
||||
status = "Locked"
|
||||
elif c["is_banned"]:
|
||||
status = "Banned"
|
||||
else:
|
||||
status = 'Active'
|
||||
|
||||
card_data.append({'access_code': c['access_code'], 'status': status})
|
||||
|
||||
for a in arcades:
|
||||
arcade_data.append({'id': a['id'], 'name': a['name']})
|
||||
status = "Active"
|
||||
|
||||
card_data.append({"index": i+1, "access_code": c["access_code"], "status": status})
|
||||
|
||||
for i, a in enumerate(arcades):
|
||||
arcade_data.append({"index": i+1, "id": a["id"], "name": a["name"]})
|
||||
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | Account",
|
||||
sesh=vars(usr_sesh),
|
||||
cards=card_data,
|
||||
username=user['username'],
|
||||
arcades=arcade_data
|
||||
title=f"{self.core_config.server.name} | Account",
|
||||
sesh=vars(usr_sesh),
|
||||
cards=card_data,
|
||||
arcades=arcade_data,
|
||||
active_page="user",
|
||||
).encode("utf-16")
|
||||
|
||||
def render_POST(self, request: Request):
|
||||
@ -310,11 +323,16 @@ class FE_System(FE_Base):
|
||||
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if usr_sesh.userId == 0 or usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value:
|
||||
if (
|
||||
usr_sesh.user_id == 0
|
||||
or usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value
|
||||
):
|
||||
return redirectTo(b"/gate", request)
|
||||
|
||||
|
||||
if uri.startswith("/sys/lookup.user?"):
|
||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.user?", "")) # lop off the first bit
|
||||
uri_parse = parse.parse_qs(
|
||||
uri.replace("/sys/lookup.user?", "")
|
||||
) # lop off the first bit
|
||||
uid_search = uri_parse.get("usrId")
|
||||
email_search = uri_parse.get("usrEmail")
|
||||
uname_search = uri_parse.get("usrName")
|
||||
@ -335,7 +353,9 @@ class FE_System(FE_Base):
|
||||
usrlist.append(u._asdict())
|
||||
|
||||
elif uri.startswith("/sys/lookup.arcade?"):
|
||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.arcade?", "")) # lop off the first bit
|
||||
uri_parse = parse.parse_qs(
|
||||
uri.replace("/sys/lookup.arcade?", "")
|
||||
) # lop off the first bit
|
||||
ac_id_search = uri_parse.get("arcadeId")
|
||||
ac_name_search = uri_parse.get("arcadeName")
|
||||
ac_user_search = uri_parse.get("arcadeUser")
|
||||
@ -354,9 +374,11 @@ class FE_System(FE_Base):
|
||||
ul = self.data.arcade.get_arcades_managed_by_user(ac_user_search[0])
|
||||
for u in ul:
|
||||
aclist.append(u._asdict())
|
||||
|
||||
|
||||
elif uri.startswith("/sys/lookup.cab?"):
|
||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.cab?", "")) # lop off the first bit
|
||||
uri_parse = parse.parse_qs(
|
||||
uri.replace("/sys/lookup.cab?", "")
|
||||
) # lop off the first bit
|
||||
cab_id_search = uri_parse.get("cabId")
|
||||
cab_serial_search = uri_parse.get("cabSerial")
|
||||
cab_acid_search = uri_parse.get("cabAcId")
|
||||
@ -377,11 +399,12 @@ class FE_System(FE_Base):
|
||||
cablist.append(u._asdict())
|
||||
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | System",
|
||||
sesh=vars(usr_sesh),
|
||||
title=f"{self.core_config.server.name} | System",
|
||||
sesh=vars(usr_sesh),
|
||||
usrlist=usrlist,
|
||||
aclist=aclist,
|
||||
cablist=cablist,
|
||||
active_page="sys",
|
||||
).encode("utf-16")
|
||||
|
||||
|
||||
@ -403,31 +426,32 @@ class FE_Arcade(FE_Base):
|
||||
uri = request.uri.decode()
|
||||
template = self.environment.get_template("core/frontend/arcade/index.jinja")
|
||||
managed = []
|
||||
|
||||
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if usr_sesh.userId == 0:
|
||||
if usr_sesh.user_id == 0:
|
||||
return redirectTo(b"/gate", request)
|
||||
|
||||
|
||||
m = re.match("\/arcade\/(\d*)", uri)
|
||||
|
||||
|
||||
if m is not None:
|
||||
arcadeid = m.group(1)
|
||||
perms = self.data.arcade.get_manager_permissions(usr_sesh.userId, arcadeid)
|
||||
perms = self.data.arcade.get_manager_permissions(usr_sesh.user_id, arcadeid)
|
||||
arcade = self.data.arcade.get_arcade(arcadeid)
|
||||
|
||||
if perms is None:
|
||||
perms = 0
|
||||
|
||||
|
||||
else:
|
||||
return redirectTo(b"/user", request)
|
||||
|
||||
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | Arcade",
|
||||
title=f"{self.core_config.server.name} | Arcade",
|
||||
sesh=vars(usr_sesh),
|
||||
error=0,
|
||||
perms=perms,
|
||||
arcade=arcade._asdict()
|
||||
arcade=arcade._asdict(),
|
||||
active_page="arcade",
|
||||
).encode("utf-16")
|
||||
|
||||
|
||||
@ -435,15 +459,16 @@ class FE_Machine(FE_Base):
|
||||
def render_GET(self, request: Request):
|
||||
uri = request.uri.decode()
|
||||
template = self.environment.get_template("core/frontend/machine/index.jinja")
|
||||
|
||||
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if usr_sesh.userId == 0:
|
||||
if usr_sesh.user_id == 0:
|
||||
return redirectTo(b"/gate", request)
|
||||
|
||||
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | Machine",
|
||||
sesh=vars(usr_sesh),
|
||||
title=f"{self.core_config.server.name} | Machine",
|
||||
sesh=vars(usr_sesh),
|
||||
arcade={},
|
||||
error=0,
|
||||
).encode("utf-16")
|
||||
active_page="machine",
|
||||
).encode("utf-16")
|
||||
|
@ -1,24 +1,44 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Create User</h1>
|
||||
<form id="create" style="max-width: 240px; min-width: 10%;" action="/gate/gate.create" method="post">
|
||||
<div class="form-group row">
|
||||
<label for="access_code">Card Access Code</label><br>
|
||||
<input class="form-control" name="access_code" id="access_code" type="text" placeholder="00000000000000000000" value={{ code }} maxlength="20" readonly>
|
||||
<div class="row justify-content-md-center form-signin">
|
||||
<div class="col col-lg-4">
|
||||
<form id="create" action="/gate/gate.create" method="post">
|
||||
<h1 class="h3 mb-3 fw-normal">Sign-up</h1>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input class="form-control" name="access-code" id="access-code" type="text"
|
||||
placeholder="00000000000000000000" value={{ code }} maxlength="20" required>
|
||||
<label for="access-code">Access Code*</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" name="username" id="username" placeholder="username">
|
||||
<label for="username">Username*</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="email" class="form-control" name="email" id="email" placeholder="example@example.com">
|
||||
<label for="email">E-Mail*</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password" class="form-control" name="passwd" id="passwd" placeholder="Password">
|
||||
<label for="passwd">Password*</label>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="form-check text-start my-3">
|
||||
<input class="form-check-input" type="checkbox" value="remember-me" id="remember-me">
|
||||
<label class="form-check-label" for="remember-me">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="alert alert-warning" role="alert">
|
||||
If you have not registered a card with this server, you cannot create a WebUI account!
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary w-100 py-2" type="submit">Sign-up</button>
|
||||
<!-- <p class="mt-5 mb-3 text-body-secondary">© 2023 ARTEMiS</p>-->
|
||||
</form>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="username">Username</label><br>
|
||||
<input id="username" class="form-control" name="username" type="text" placeholder="username">
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="email">Email</label><br>
|
||||
<input id="email" class="form-control" name="email" type="email" placeholder="example@example.com">
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="passwd">Password</label><br>
|
||||
<input id="passwd" class="form-control" name="passwd" type="password" placeholder="password">
|
||||
</div>
|
||||
<p></p>
|
||||
<input id="submit" class="btn btn-primary" style="display: block; margin: 0 auto;" type="submit" value="Create">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock content %}
|
@ -1,32 +1,52 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Gate</h1>
|
||||
{% include "core/frontend/widgets/err_banner.jinja" %}
|
||||
<style>
|
||||
/* Chrome, Safari, Edge, Opera */
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
.form-signin input[type="text"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
</style>
|
||||
<form id="login" style="max-width: 240px; min-width: 10%;" action="/gate/gate.login" method="post">
|
||||
<div class="form-group row">
|
||||
<label for="access_code">Card Access Code</label><br>
|
||||
<input form="login" class="form-control" name="access_code" id="access_code" type="number" placeholder="00000000000000000000" maxlength="20" required>
|
||||
<div class="row justify-content-md-center form-signin">
|
||||
<div class="col col-lg-4">
|
||||
<form id="login" action="/gate/gate.login" method="post">
|
||||
<h1 class="h3 mb-3 fw-normal">Login</h1>
|
||||
|
||||
{% include "core/frontend/widgets/err_banner.jinja" %}
|
||||
|
||||
<div class="form-floating">
|
||||
<input form="login" class="form-control" name="access-code" id="access-code" type="text"
|
||||
placeholder="00000000000000000000" maxlength="20" required>
|
||||
<label for="access-code">Access Code</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input form="login" type="password" class="form-control" name="passwd" id="passwd" placeholder="Password">
|
||||
<label for="passwd">Password</label>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="form-check text-start my-3">
|
||||
<input class="form-check-input" type="checkbox" value="remember-me" id="remember-me">
|
||||
<label class="form-check-label" for="remember-me">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="alert alert-info" role="alert">
|
||||
To register for the WebUI, type in the <strong>access code</strong> of your card, as shown in a game, and leave the
|
||||
password field blank.
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
|
||||
<!-- <p class="mt-5 mb-3 text-body-secondary">© 2023 ARTEMiS</p>-->
|
||||
</form>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="passwd">Password</label><br>
|
||||
<input id="passwd" class="form-control" name="passwd" type="password" placeholder="password">
|
||||
</div>
|
||||
<p></p>
|
||||
<input id="submit" class="btn btn-primary" style="display: block; margin: 0 auto;" form="login" type="submit" value="Login">
|
||||
</form>
|
||||
<h6>*To register for the webui, type in the access code of your card, as shown in a game, and leave the password field blank.</h6>
|
||||
<h6>*If you have not registered a card with this server, you cannot create a webui account.</h6>
|
||||
</div>
|
||||
{% endblock content %}
|
@ -1,88 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: #181a1b !important;
|
||||
margin: 10px;
|
||||
}
|
||||
html {
|
||||
color-scheme: dark !important;
|
||||
}
|
||||
html, body, input, textarea, select, button, dialog {
|
||||
background-color: #181a1b;
|
||||
}
|
||||
html, body, input, textarea, select, button {
|
||||
border-color: #736b5e;
|
||||
color: #e8e6e3;
|
||||
}
|
||||
a {
|
||||
color: #3391ff;
|
||||
}
|
||||
table {
|
||||
border-color: #545b5e;
|
||||
}
|
||||
::placeholder {
|
||||
color: #b2aba1;
|
||||
}
|
||||
input:-webkit-autofill,
|
||||
textarea:-webkit-autofill,
|
||||
select:-webkit-autofill {
|
||||
background-color: #404400 !important;
|
||||
color: #e8e6e3 !important;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
background-color: #202324;
|
||||
color: #aba499;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #454a4d;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #575e62;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background-color: #484e51;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: #181a1b;
|
||||
}
|
||||
* {
|
||||
scrollbar-color: #454a4d #202324;
|
||||
}
|
||||
::selection {
|
||||
background-color: #004daa !important;
|
||||
color: #e8e6e3 !important;
|
||||
}
|
||||
::-moz-selection {
|
||||
background-color: #004daa !important;
|
||||
color: #e8e6e3 !important;
|
||||
}
|
||||
input[type="text"], input[type="text"]:focus, input[type="password"], input[type="password"]:focus, input[type="email"], input[type="email"]:focus {
|
||||
background-color: #202324 !important;
|
||||
color: #e8e6e3;
|
||||
}
|
||||
form {
|
||||
outline: 1px solid grey;
|
||||
padding: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.err-banner {
|
||||
background-color: #AA0000;
|
||||
padding: 20px;
|
||||
margin-bottom: 10px;
|
||||
width: 15%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ title }}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include "core/frontend/widgets/topbar.jinja" %}
|
||||
{% block content %}
|
||||
<h1>{{ server_name }}</h1>
|
||||
{% endblock content %}
|
||||
</body>
|
||||
<div class="container">
|
||||
{% block content %}
|
||||
<h1>{{ server_name }}</h1>
|
||||
{% endblock content %}
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,41 +1,126 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Management for {{ username }}</h1>
|
||||
<h2>Cards <button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#card_add">Add</button></h2>
|
||||
<ul style="font-size: 20px;">
|
||||
{% for c in cards %}
|
||||
<li>{{ c.access_code }}: {{ c.status }} {% if c.status == 'Active'%}<button class="btn-warning btn">Lock</button>{% elif c.status == 'Locked' %}<button class="btn-warning btn">Unlock</button>{% endif %} <button class="btn-danger btn">Delete</button></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h1>{{ sesh["username"] }}'s Account</h1>
|
||||
|
||||
{% if arcades is defined %}
|
||||
<h2>Arcades</h2>
|
||||
<ul style="font-size: 20px;">
|
||||
{% for a in arcades %}
|
||||
<li><a href=/arcade/{{ a.id }}>{{ a.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div class="modal fade" id="card_add" tabindex="-1" aria-labelledby="card_add_label" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="card_add_label">Add Card</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
HOW TO:<br>
|
||||
Scan your card on any networked game and press the "View Access Code" button (varies by game) and enter the 20 digit code below.<br>
|
||||
!!FOR AMUSEIC CARDS: DO NOT ENTER THE CODE SHOWN ON THE BACK OF THE CARD ITSELF OR IT WILL NOT WORK!!
|
||||
<p /><label for="card_add_frm_access_code">Access Code: </label><input id="card_add_frm_access_code" maxlength="20" type="text" required>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary">Add</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">Cards</h3>
|
||||
<!--<h4 class="card-subtitle mb-2 text-body-secondary">Card subtitle</h4>-->
|
||||
<p class="card-text">All aime cards are listed here for the given user.</p>
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#card-add" class="btn btn-primary mb-3">Add Card</a>
|
||||
{% if cards is defined and cards|length > 0 %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Access Code</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in cards %}
|
||||
<tr class="align-middle">
|
||||
<th scope="row">{{ c.index }}</th>
|
||||
<td>{{ c.access_code }}</td>
|
||||
<td>
|
||||
{% if c.status == 'Active'%}
|
||||
<span class="badge rounded-pill text-bg-success">Active</span>
|
||||
{% elif c.status == 'Locked' %}
|
||||
<span class="badge rounded-pill text-bg-warning">Locked</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if c.status == 'Active'%}
|
||||
<button type="button" class="btn btn-warning btn-sm">Lock</i></button>
|
||||
{% elif c.status == 'Locked' %}
|
||||
<button type="button" class="btn btn-success btn-sm">Unlock</i></button>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-danger btn-sm">Delete</i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning" role="alert">
|
||||
You have no cards registered to your account. Please add one.
|
||||
</div>
|
||||
{% endif %}
|
||||
<!--<a href="#" data-bs-toggle="modal" data-bs-target="#card-add" class="card-link">Add Card</a>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">Arcades</h3>
|
||||
<!--<h4 class="card-subtitle mb-2 text-body-secondary">Card subtitle</h4>-->
|
||||
<p class="card-text">All arcades connected to the given account are listed here.</p>
|
||||
{% if arcades is defined and arcades|length > 0 %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in arcades %}
|
||||
<tr class="align-middle clickable-row" data-href=/arcade/{{ a.id }}>
|
||||
<th scope="row">{{ a.index }}</th>
|
||||
<td>{{ a.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info" role="alert">
|
||||
You have no arcades connected to your account.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="card-add" tabindex="-1" aria-labelledby="card-add-label" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="card-add-label">Add Card</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h3 class="fs-5">How to:</h3>
|
||||
Scan your card on any networked game and press the "View Access Code" button (varies by game) and enter
|
||||
the 20
|
||||
digit code below.
|
||||
<hr>
|
||||
FOR AMUSE IC CARDS: DO NOT ENTER THE CODE SHOWN ON THE BACK OF THE CARD ITSELF OR IT WILL NOT WORK!
|
||||
<form>
|
||||
<div class="form-floating mt-3">
|
||||
<label for="access-code" class="col-form-label">Access Code</label>
|
||||
<input maxlength="20" type="text" required pattern="[0-9]{20}" class="form-control"
|
||||
id="access-code">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
@ -1,6 +1,5 @@
|
||||
{% if error > 0 %}
|
||||
<div class="err-banner">
|
||||
<h3>Error</h3>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{% if error == 1 %}
|
||||
Card not registered, or wrong password
|
||||
{% elif error == 2 %}
|
||||
|
@ -1,21 +1,56 @@
|
||||
<div style="background: #333; color: #f9f9f9; width: 10%; height: 50px; line-height: 50px; text-align: center; float: left;">
|
||||
Navigation
|
||||
</div>
|
||||
<div style="background: #333; color: #f9f9f9; width: 80%; height: 50px; line-height: 50px; padding-left: 10px; float: left;">
|
||||
<a href=/><button class="btn btn-primary">Home</button></a>
|
||||
{% for game in game_list %}
|
||||
<a href=/game/{{ game.url }}><button class="btn btn-success">{{ game.name }}</button></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div style="background: #333; color: #f9f9f9; width: 10%; height: 50px; line-height: 50px; text-align: center; float: left;">
|
||||
{% if sesh is defined and sesh["permissions"] >= 2 %}
|
||||
<a href="/sys"><button class="btn btn-primary">System</button></a>
|
||||
{% endif %}
|
||||
{% if sesh is defined and sesh["userId"] > 0 %}
|
||||
<a href="/user"><button class="btn btn-primary">Account</button></a>
|
||||
{% else %}
|
||||
<a href="/gate"><button class="btn btn-primary">Gate</button></a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<nav class="p-3 mb-3 navbar navbar-expand-lg bg-body-tertiary" aria-label="Thirteenth navbar example">
|
||||
<div class="container">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample11"
|
||||
aria-controls="navbarsExample11" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse d-lg-flex" id="navbarsExample11">
|
||||
<a class="navbar-brand col-lg-3 me-0" href= />ARTEMiS</a>
|
||||
<ul class="navbar-nav col-lg-6 justify-content-lg-center nav-pills">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if active_page == '/' %}active{% endif %}" aria-current="page" href= />Home</a>
|
||||
</li>
|
||||
{% for game in game_list %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if active_page == game.url %}active{% endif %}" href=/game/{{ game.url }}>{{ game.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<!--
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">Dropdown</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
<div class="d-lg-flex col-lg-3 justify-content-lg-end">
|
||||
{% if sesh is defined and sesh["user_id"] > 0 %}
|
||||
<div class="btn-group dropdown">
|
||||
<a href="#" class="d-block link-body-emphasis text-decoration-none dropdown-toggle"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ sesh["username"] }}
|
||||
</a>
|
||||
<ul class="dropdown-menu text-small">
|
||||
{% if sesh["permissions"] >= 2 %}
|
||||
<li><a class="dropdown-item {% if active_page == 'sys' %}active{% endif %}" href="/sys">System</a></li>
|
||||
{% endif %}
|
||||
<li><a class="dropdown-item" href="#">Settings</a></li>
|
||||
<li><a class="dropdown-item {% if active_page == 'user' %}active{% endif %}" href="/user">Account</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="#">Sign out</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% else %}
|
||||
<a href="/gate"><button class="btn {% if active_page == 'gate' %}btn-primary{% else %}btn-outline-primary{% endif %}">Login</button></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
@ -22,7 +22,7 @@ class PokkenFrontend(FE_Base):
|
||||
self.game_cfg.update(
|
||||
yaml.safe_load(open(f"{cfg_dir}/{PokkenConstants.CONFIG_NAME}"))
|
||||
)
|
||||
self.nav_name = "Pokken"
|
||||
self.nav_name = "Pokkén"
|
||||
|
||||
def render_GET(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
@ -35,5 +35,6 @@ class PokkenFrontend(FE_Base):
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh)
|
||||
sesh=vars(usr_sesh),
|
||||
active_page="pokken",
|
||||
).encode("utf-16")
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Pokken</h1>
|
||||
<h1>Pokkén</h1>
|
||||
{% endblock content %}
|
@ -22,7 +22,7 @@ class WaccaFrontend(FE_Base):
|
||||
self.game_cfg.update(
|
||||
yaml.safe_load(open(f"{cfg_dir}/{WaccaConstants.CONFIG_NAME}"))
|
||||
)
|
||||
self.nav_name = "Wacca"
|
||||
self.nav_name = "WACCA"
|
||||
|
||||
def render_GET(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
@ -30,9 +30,10 @@ class WaccaFrontend(FE_Base):
|
||||
)
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
|
||||
|
||||
return template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh)
|
||||
sesh=vars(usr_sesh),
|
||||
active_page="wacca",
|
||||
).encode("utf-16")
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Wacca</h1>
|
||||
<h1>WACCA</h1>
|
||||
{% endblock content %}
|
Loading…
Reference in New Issue
Block a user