mirror of
https://github.com/FAUSheppy/oh-my-nemesis
synced 2025-12-06 23:11:35 +01:00
Initial (reset)
This commit is contained in:
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
*.swp
|
||||
*.txt
|
||||
*.ncsv
|
||||
*.out
|
||||
*.log
|
||||
*.zip
|
||||
|
||||
pass.secret
|
||||
|
||||
css/
|
||||
js/
|
||||
data/
|
||||
build/
|
||||
fontawesome/
|
||||
static/pictures/
|
||||
config/champions/
|
||||
|
||||
__pychache__/
|
||||
*.pyc
|
||||
|
||||
config/
|
||||
24
README.md
Normal file
24
README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Setup
|
||||
## Python
|
||||
|
||||
pip install -r req.txt
|
||||
|
||||
## CSS/JS/Assets
|
||||
Download the following into the `static/` directory.
|
||||
|
||||
- [bootstrap>=4.3](https://getbootstrap.com/docs/4.3/getting-started/download/)
|
||||
- [fontawesome-free](https://fontawesome.com) (unpacked directory must be called `fontawesome`)
|
||||
|
||||
## Directories
|
||||
|
||||
mkdir -p data/users/
|
||||
|
||||
## User-Schema
|
||||
|
||||
{
|
||||
name : "name of user",
|
||||
accounts : [ "list", "of", "account", "names" ],
|
||||
single : "true/false, depending if user has team",
|
||||
selectedChampions: ["list of champions", "this user can play"]
|
||||
allowedFeatures: ["list of allowed features", "or empty list to allow all"]
|
||||
}
|
||||
32
composition_builder.py
Normal file
32
composition_builder.py
Normal file
@@ -0,0 +1,32 @@
|
||||
class Composition:
|
||||
def __init__(self, name):
|
||||
self.goodAgainst = []
|
||||
self.badAgainst = []
|
||||
self.name = name
|
||||
|
||||
def isGoodAgainst(self, compositions):
|
||||
self.goodAgainst = compositions
|
||||
|
||||
def isBadAgainst(self, compositions):
|
||||
self.badAgainst = Composition
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.name == other.name
|
||||
|
||||
ATTACK = Composition("ATTACK")
|
||||
PROTECT = Composition("PROTECT")
|
||||
CATCH = Composition("CATCH")
|
||||
SIEGE = Composition("SIEGE")
|
||||
SPLIT = Composition("SPLIT")
|
||||
|
||||
ATTACK.isGoodAgainst([SPLIT, SIEGE])
|
||||
PROTECT.isGoodAgainst([CATCH, ATTACK])
|
||||
CATCH.isGoodAgainst([ATTACK, SPLIT])
|
||||
SIEGE.isGoodAgainst([PROTECT, CATCH])
|
||||
SPLIT.isGoodAgainst([SIEGE, PROTECT])
|
||||
|
||||
ATTACK.isBadAgainst([CATCH, PROTECT])
|
||||
PROTECT.isBadAgainst([SPLIT, SIEGE])
|
||||
CATCH.isBadAgainst([SIEGE, PROTECT])
|
||||
SIEGE.isBadAgainst([ATTACK, SPLIT])
|
||||
SPLIT.isBadAgainst([CATCH, ATTACK])
|
||||
55
database.py
Normal file
55
database.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import json
|
||||
import os
|
||||
import usermanagement
|
||||
import flask_login as fl
|
||||
|
||||
userDb = {
|
||||
"sheppy" : { "password" : "" }
|
||||
}
|
||||
|
||||
DEAULT_DIR = "data/"
|
||||
def saveTable(tableId, jsonData):
|
||||
with open(DEAULT_DIR + tableId + ".json" , "w") as f:
|
||||
print(jsonData)
|
||||
f.write(json.dumps(jsonData))
|
||||
|
||||
def loadTable(tableId):
|
||||
with open(DEAULT_DIR + tableId + ".json") as f:
|
||||
return json.loads(f.read())
|
||||
|
||||
def teamChampSelectAdd(teamid, champ, role):
|
||||
path = "config/teams/{}/roles/{}.json".format(teamid, role)
|
||||
if not os.path.isfile(path):
|
||||
with open(path, "w") as f:
|
||||
f.write('{ "champions": [%s]] }' % champ)
|
||||
else:
|
||||
data = None
|
||||
with open(path, "r") as f:
|
||||
data = json.loads(f.read())
|
||||
if champ not in data["champions"]:
|
||||
data["champions"] += [champ]
|
||||
with open(path, "w") as f:
|
||||
f.write(json.dumps(data))
|
||||
|
||||
def teamChampSelectRemove(teamid, champ, role):
|
||||
path = "config/teams/{}/roles/{}.json".format(teamid, role)
|
||||
if not os.path.isfile(path):
|
||||
raise ValueError("No information about this role exists, so nothing can be removed.")
|
||||
else:
|
||||
data = None
|
||||
with open(path, "r") as f:
|
||||
data = json.loads(f.read())
|
||||
data["champions"].remove(champ)
|
||||
with open(path, "w") as f:
|
||||
f.write(json.dumps(data))
|
||||
|
||||
def getUserByFlaskLoginId(flId):
|
||||
if not flId.is_active:
|
||||
return None
|
||||
return usermanagement.User(flId)
|
||||
|
||||
def safeCheckLogin(username, password):
|
||||
return usermanagement.User(username)
|
||||
|
||||
def getUserByName(name):
|
||||
return usermanagement.User(name)
|
||||
74
entities/CellContainer.py
Normal file
74
entities/CellContainer.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import flask
|
||||
class CellContainer:
|
||||
|
||||
def __init__(self, tableConfig):
|
||||
|
||||
self.columns = tableConfig.get("columns")
|
||||
self.rows = tableConfig["rows"]
|
||||
self.headerRow = tableConfig["header-row"]
|
||||
if not self.columns:
|
||||
self.columns = len(self.headerRow)
|
||||
self.headerColumn = tableConfig["header-column"]
|
||||
self.currentCellId = 0
|
||||
self.contents = tableConfig.get("contents")
|
||||
self.colors = tableConfig.get("colors")
|
||||
self.help = tableConfig.get("help")
|
||||
|
||||
self.hasHeaderColumn = bool(tableConfig.get("hasHeaderColumn"))
|
||||
self.hasHeaderRow = bool(tableConfig.get("hasHeaderRow"))
|
||||
|
||||
def setContents(self, contents):
|
||||
self.contents = contents
|
||||
|
||||
def getView(self):
|
||||
innerHTML = ""
|
||||
startAtRow = 0
|
||||
if self.headerRow or self.hasHeaderRow:
|
||||
innerHTML += flask.Markup(flask.render_template("entities/row.html", cells=self.getHeaderRow()))
|
||||
startAtRow = 1
|
||||
for rowNr in range(startAtRow, self.rows):
|
||||
innerHTML += flask.Markup(flask.render_template("entities/row.html", cells=self.getRowHTML(rowNr)))
|
||||
return flask.Markup(flask.render_template("entities/table.html", tableContent=innerHTML))
|
||||
|
||||
def getHeaderRow(self):
|
||||
rowHTML = ""
|
||||
array = None
|
||||
if self.contents:
|
||||
array = self.contents[:self.columns]
|
||||
else:
|
||||
array = self.headerRow
|
||||
for rowStr in array:
|
||||
rowHTML += flask.Markup(flask.render_template("entities/cell.html",
|
||||
cellId=self.currentCellId, classes="cell header", cellContent=rowStr))
|
||||
self.currentCellId += 1
|
||||
return rowHTML
|
||||
|
||||
def getCellWidth(self):
|
||||
return "{:.2f}%".format(100/self.columns)
|
||||
|
||||
def getRowHTML(self, curRow):
|
||||
'''Get HTML for individual rows'''
|
||||
|
||||
rowHTML = ""
|
||||
for col in range(0, self.columns):
|
||||
|
||||
# handle header fields in rows #
|
||||
classes = ["cell"]
|
||||
cellContent = ""
|
||||
cellColor = ""
|
||||
if self.headerColumn and col == 0:
|
||||
classes += ["header"]
|
||||
cellContent = self.headerColumn[curRow]
|
||||
elif self.hasHeaderColumn and col == 0:
|
||||
classes += ["header"]
|
||||
if self.contents:
|
||||
cellContent = self.contents[curRow*self.columns+col]
|
||||
if self.colors:
|
||||
cellColor = self.colors[curRow*self.columns+col]
|
||||
|
||||
# add single cell #
|
||||
rowHTML += flask.Markup(flask.render_template("entities/cell.html", cellId=self.currentCellId, cellContent=cellContent, classes=" ".join(classes), enableEdit=True, cellColor=cellColor))
|
||||
self.currentCellId += 1
|
||||
|
||||
# return HTML for row #
|
||||
return rowHTML
|
||||
72
jsonConfig.py
Normal file
72
jsonConfig.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import re
|
||||
import os
|
||||
import json
|
||||
import types
|
||||
|
||||
def readJsonFile(filename):
|
||||
'''Return a single json file as a dictionary object'''
|
||||
|
||||
with open(filename) as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def readJsonDir(basedir):
|
||||
'''Return an array of dictionary objects in a directory'''
|
||||
|
||||
# important safety check #
|
||||
udata = basedir.encode("utf-8")
|
||||
asciidata = udata.decode("ascii", "ignore")
|
||||
if re.match(r'^[\w-]+$', asciidata) or basedir != asciidata:
|
||||
raise RuntimeError("Unsafe path")
|
||||
|
||||
# load json files from projects/ dir #
|
||||
jsonDictList = []
|
||||
for root, dirs, files in os.walk(basedir):
|
||||
root = dirs
|
||||
dirs = root
|
||||
for filename in files:
|
||||
if filename.endswith(".json"):
|
||||
jsonDictList += [readJsonFile(os.path.join(basedir, filename))]
|
||||
|
||||
return jsonDictList
|
||||
|
||||
|
||||
def priceSection(section):
|
||||
'''Get a prices sections by it's identifier'''
|
||||
|
||||
prices = readJsonDir(os.path.join("config/prices/", section))
|
||||
allFeatures = []
|
||||
for p in prices:
|
||||
allFeatures += p["features"]
|
||||
for p in prices:
|
||||
p["disabledFeatures"] = set(allFeatures) - set(p["features"])
|
||||
return prices
|
||||
|
||||
def pricesSections():
|
||||
return [ priceSection("section-1"), priceSection("section-2")]
|
||||
|
||||
def mainConfig():
|
||||
'''Get main configuration'''
|
||||
|
||||
ret = types.SimpleNamespace()
|
||||
ret.__dict__.update(readJsonFile("config/config.json"))
|
||||
return ret
|
||||
|
||||
def services():
|
||||
'''Get Services configuration'''
|
||||
|
||||
return readJsonDir("config/services/")
|
||||
|
||||
def getOfferById(strId):
|
||||
'''Get an offer in prices sections by it's id'''
|
||||
|
||||
d1 = readJsonDir("config/prices/section-1")
|
||||
d2 = readJsonDir("config/prices/section-1")
|
||||
for el in d1 + d2:
|
||||
if el.get(strId):
|
||||
return el
|
||||
return None
|
||||
|
||||
def champs():
|
||||
'''Read champ directory and return a list of champions'''
|
||||
return [ x["name"] for x in readJsonDir("config/champions/")]
|
||||
20
pages_api.py
Normal file
20
pages_api.py
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import flask
|
||||
import smtplib
|
||||
|
||||
import jsonConfig as jc
|
||||
|
||||
pagesApi = flask.Blueprint('simple_page', __name__, template_folder='templates')
|
||||
|
||||
@pagesApi.route("/contact-api", methods=['POST'])
|
||||
def contactAPI():
|
||||
|
||||
email = flask.request.form["email"]
|
||||
name = flask.request.form["name"]
|
||||
subject = "Subject: {} ({})\n\n".format(flask.request.form["subject"], name)
|
||||
message = subject + flask.request.form["message"]
|
||||
smtpTarget = smtplib.SMTP(jc.mainConfig().smtp)
|
||||
smtpTarget.sendmail(email, jc.mainConfig().target_email , message)
|
||||
smtpTarget.quit()
|
||||
|
||||
return flask.redirect("/thanks")
|
||||
29
pages_loginmanagement.py
Normal file
29
pages_loginmanagement.py
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
import flask
|
||||
import flask_login as fl
|
||||
import database as db
|
||||
import jsonConfig as jc
|
||||
|
||||
pagesLoginManagement = flask.Blueprint('pagesLoginManagement', __name__, template_folder='templates')
|
||||
|
||||
@pagesLoginManagement.route("/login", methods=['GET', 'POST'])
|
||||
def login():
|
||||
if flask.request.method == 'POST':
|
||||
username = flask.request.form['username']
|
||||
password = flask.request.form['password']
|
||||
print(username, password)
|
||||
acceptedUser = db.safeCheckLogin(username, password)
|
||||
if acceptedUser:
|
||||
fl.login_user(acceptedUser)
|
||||
return flask.redirect(flask.url_for("standardPages.dashboard"))
|
||||
else:
|
||||
return flask.abort(401)
|
||||
else:
|
||||
return flask.render_template("standard/login.html",
|
||||
config=jc.mainConfig())
|
||||
|
||||
@pagesLoginManagement.route("/logout")
|
||||
@fl.login_required
|
||||
def logout():
|
||||
fl.logout_user()
|
||||
return flask.redirect("/")
|
||||
73
pages_standard.py
Normal file
73
pages_standard.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import database as db
|
||||
import jsonConfig as jc
|
||||
import flask
|
||||
import flask_login as fl
|
||||
import os
|
||||
|
||||
standardPages = flask.Blueprint('standardPages', __name__, template_folder='templates')
|
||||
@standardPages.route('/')
|
||||
def index():
|
||||
'''Landing page/index page/root page'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/index.html",
|
||||
services=jc.services(),
|
||||
pricesSections=jc.pricesSections(),
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
|
||||
@standardPages.route("/dashboard")
|
||||
@fl.login_required
|
||||
def dashboard():
|
||||
'''Logged in user dashboard'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/user_dashboard.html",
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
|
||||
@standardPages.route("/shop")
|
||||
def shop():
|
||||
'''Shop to buy shit'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/shop.html",
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
|
||||
@standardPages.route("/about")
|
||||
def about():
|
||||
'''About Page'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/about.html",
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
|
||||
@standardPages.route("/impressum")
|
||||
def impressum():
|
||||
'''About Page'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/impressum.html",
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
|
||||
@standardPages.route("/contact")
|
||||
def contact():
|
||||
'''Contact Page'''
|
||||
|
||||
offer = jc.getOfferById(flask.request.args.get("offerId"))
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
|
||||
return flask.render_template("standard/contact.html",
|
||||
conf=jc.mainConfig(),
|
||||
currentUser=user, selectedOffer=offer)
|
||||
|
||||
@standardPages.route("/thanks")
|
||||
def thanks():
|
||||
'''Post Contact thanks page'''
|
||||
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("standard/thanks.html", config=jc.mainConfig(),
|
||||
currentUser=user)
|
||||
46
server.py
Executable file
46
server.py
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import flask
|
||||
import flask_login as fl
|
||||
import argparse
|
||||
|
||||
from pages_standard import standardPages
|
||||
from pages_api import pagesApi
|
||||
from subpages_dashboard import subpagesDashboard
|
||||
from pages_loginmanagement import pagesLoginManagement
|
||||
|
||||
import database as db
|
||||
|
||||
app = flask.Flask("OH-MY-Nemesis")
|
||||
app.secret_key = 'super secret key'
|
||||
app.config['SESSION_TYPE'] = 'filesystem'
|
||||
loginManager = fl.LoginManager()
|
||||
|
||||
@loginManager.user_loader
|
||||
def load_user(userName):
|
||||
'''Setup the user/login manager'''
|
||||
return db.getUserByName(userName)
|
||||
|
||||
#@app.route('/static/<path:path>')
|
||||
#def static(path):
|
||||
# '''Configure sending of static files'''
|
||||
# return flask.send_from_directory('static', path)
|
||||
|
||||
@app.before_first_request
|
||||
def init():
|
||||
'''Do nessesary initialization jobs'''
|
||||
loginManager.init_app(app)
|
||||
app.register_blueprint(standardPages)
|
||||
app.register_blueprint(pagesApi)
|
||||
app.register_blueprint(subpagesDashboard)
|
||||
app.register_blueprint(pagesLoginManagement)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='None',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('--interface', default="localhost",
|
||||
help='Interface on which flask (this server) will take requests on')
|
||||
parser.add_argument('--port', default="5000",
|
||||
help='Port on which flask (this server) will take requests on')
|
||||
args = parser.parse_args()
|
||||
app.run(host=args.interface, port=args.port)
|
||||
48
static/contact.js
Normal file
48
static/contact.js
Normal file
@@ -0,0 +1,48 @@
|
||||
function submitContactForm(){
|
||||
|
||||
/* check input fields */
|
||||
mailField = document.getElementById("email")
|
||||
messageField = document.getElementById("message")
|
||||
|
||||
if(mailField.value == ""){
|
||||
alert("Bitte geben Sie einen Kontakt an unter dem wir Sie erreichen können!")
|
||||
return
|
||||
}
|
||||
|
||||
if(messageField.value == ""){
|
||||
alert("Nachricht ist leer!")
|
||||
return
|
||||
}
|
||||
|
||||
/* show the waiting dialog */
|
||||
dialog = document.getElementById("waiting-dialog")
|
||||
dialog.style.disply = "block"
|
||||
setMainBackgroundOpacity(0.5)
|
||||
|
||||
/* submit the form */
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/contact-api");
|
||||
xhr.onload = formSubmitFinished
|
||||
formData = new FormData(document.getElementById("contact-form"));
|
||||
xhr.send(formData);
|
||||
|
||||
}
|
||||
|
||||
function formSubmitFinished(event){
|
||||
if(event.target.status < 200 || event.target.status >= 300){
|
||||
showErrorMessage(event.target); // blocking
|
||||
setMainBackgroundOpacity(1)
|
||||
}else{
|
||||
window.location.href = "/thanks"
|
||||
}
|
||||
}
|
||||
|
||||
function setMainBackgroundOpacity(opacity){
|
||||
mainContainer = document.getElementById("main-container")
|
||||
mainContainer.style.opacity = opacity
|
||||
}
|
||||
|
||||
function showErrorMessage(target){
|
||||
console.log(target)
|
||||
alert("Error: " + target.statusText)
|
||||
}
|
||||
BIN
static/defaultFavicon.ico
Normal file
BIN
static/defaultFavicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
64
static/login.css
Normal file
64
static/login.css
Normal file
@@ -0,0 +1,64 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Numans');
|
||||
|
||||
html,body{
|
||||
/*background-image: url('http://getwallpapers.com/wallpaper/full/a/5/d/544750.jpg');*/
|
||||
background-color: green !important;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
height: 100%;
|
||||
font-family: 'Numans', sans-serif;
|
||||
}
|
||||
|
||||
.container{
|
||||
height: 100%;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.card{
|
||||
height: 370px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
width: 400px;
|
||||
background-color: rgba(0,0,0,0.5) !important;
|
||||
}
|
||||
|
||||
.card-header h3{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.social_icon{
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: -45px;
|
||||
}
|
||||
|
||||
.input-group-prepend span{
|
||||
width: 50px;
|
||||
background-color: #FFC312;
|
||||
color: black;
|
||||
border:0 !important;
|
||||
}
|
||||
|
||||
input:focus{
|
||||
outline: 0 0 0 0 !important;
|
||||
box-shadow: 0 0 0 0 !important;
|
||||
}
|
||||
|
||||
.login_btn{
|
||||
color: black;
|
||||
background-color: rgb(255, 195, 18) !important;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.login_btn:hover{
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.links{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.links a{
|
||||
margin-left: 4px;
|
||||
}
|
||||
105
static/site.css
Normal file
105
static/site.css
Normal file
@@ -0,0 +1,105 @@
|
||||
.eyecatcher {
|
||||
height: 100vh;
|
||||
min-height: 500px;
|
||||
/* background-image: url('/static/pictures/test.png'); */
|
||||
background: cyan;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* pricing */
|
||||
section.pricing {
|
||||
background: #007bff;
|
||||
background: linear-gradient(to right, #0062E6, #33AEFF);
|
||||
}
|
||||
|
||||
.pricing .card {
|
||||
border: none;
|
||||
border-radius: 1rem;
|
||||
transition: all 0.2s;
|
||||
box-shadow: 0 0.5rem 1rem 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.pricing hr {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.pricing .card-title {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: .1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pricing .card-price {
|
||||
font-size: 3rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.pricing .card-price .period {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.pricing ul li {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pricing .text-muted {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.pricing .btn {
|
||||
font-size: 80%;
|
||||
border-radius: 5rem;
|
||||
letter-spacing: .1rem;
|
||||
font-weight: bold;
|
||||
padding: 1rem;
|
||||
opacity: 0.7;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.bg-special{
|
||||
background-color: #eae9e9;
|
||||
}
|
||||
|
||||
.hover-to-75:hover *{
|
||||
opacity: 0.75;
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.footer-el{
|
||||
float: left;
|
||||
color: rgba(255,255,255,.5);
|
||||
}
|
||||
|
||||
/* Hover Effects on Card */
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.pricing .card:hover {
|
||||
margin-top: -.25rem;
|
||||
margin-bottom: .25rem;
|
||||
box-shadow: 0 0.5rem 1rem 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.pricing .card:hover .btn {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.special-header{
|
||||
font-weight: 900 !important;
|
||||
color: rgba(255,255,255,.9);
|
||||
font-size: 6vw;
|
||||
}
|
||||
|
||||
.special-sub-header{
|
||||
font-weight: bold;
|
||||
color: rgba(255,255,255,.5);
|
||||
font-size: 4rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pic-disabled{
|
||||
opacity: 0.6;
|
||||
background-color: black;
|
||||
}
|
||||
47
static/table.css
Normal file
47
static/table.css
Normal file
@@ -0,0 +1,47 @@
|
||||
body{
|
||||
background: #161618;
|
||||
}
|
||||
table{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td{
|
||||
border-style: groove;
|
||||
border-width: 2px;
|
||||
border-color: antiquewhite;
|
||||
background-color: #f5f7f6;
|
||||
}
|
||||
.header{
|
||||
background: lightcyan !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hidden{
|
||||
display: none;
|
||||
}
|
||||
.information{
|
||||
margin-top: 8px;
|
||||
font-style: italic;
|
||||
color: #f5f7f6;
|
||||
}
|
||||
button{
|
||||
height: 40px;
|
||||
width: 30%;
|
||||
margin: 20px;
|
||||
border: transparent;
|
||||
border-radius: 20px;
|
||||
background: aqua;
|
||||
font-weight: bold;
|
||||
transition-duration: 0.3s;
|
||||
|
||||
}
|
||||
button:hover {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
.color-cell{
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
.color-cell:hover{
|
||||
opacity: 0.75;
|
||||
}
|
||||
152
static/table.js
Normal file
152
static/table.js
Normal file
@@ -0,0 +1,152 @@
|
||||
var currentCellSelected = null
|
||||
|
||||
|
||||
var colors = ["rgb(245, 247, 246)", "indianred", "coral", "orange", "yellow", "cyan", "lightgreen", "rgb(75, 140, 72)", "rgb(35, 110, 31)"]
|
||||
var words = ["", "Awefull", "Worse", "Bad", "Normal", "Praticed", "Decent", "Good", "Perfect"]
|
||||
|
||||
|
||||
function cellOnClickListener(element){
|
||||
updateSelectedCell(element)
|
||||
}
|
||||
|
||||
function colorCellOnClickListener(element){
|
||||
if(currentCellSelected){
|
||||
currentCellSelected.style.background = element.style.background
|
||||
}
|
||||
}
|
||||
|
||||
function updateSelectedCell(cell){
|
||||
if(currentCellSelected && currentCellSelected.id != cell.id){
|
||||
currentCellSelected.style.borderColor = ""
|
||||
currentCellSelected.blur()
|
||||
}
|
||||
currentCellSelected = cell
|
||||
if(cell){
|
||||
cell.style.borderColor = "blue"
|
||||
}
|
||||
}
|
||||
|
||||
function updateBackgroundForCell(cell, indexMod){
|
||||
if(!cell.style.background){
|
||||
cell.style.background = colors[0];
|
||||
}
|
||||
|
||||
/* firefox hack */
|
||||
var bcolor = cell.style.background
|
||||
if(bcolor.indexOf(") ")>0){
|
||||
bcolor = bcolor.split(") ")[0] + ")"
|
||||
}else if(bcolor.indexOf(" ") && bcolor.indexOf("rgb") == -1){
|
||||
bcolor = bcolor.split(" ")[0]
|
||||
}
|
||||
|
||||
console.log(bcolor)
|
||||
newColor = colors.indexOf(bcolor) + indexMod + colors.length
|
||||
cell.style.background = colors[newColor % colors.length]
|
||||
}
|
||||
|
||||
function addWindowListeners(){
|
||||
var colorContent = ""
|
||||
var i
|
||||
for(i = 1; i < colors.length; i++){
|
||||
var colorCell = '<td class="cell color-cell" onclick="colorCellOnClickListener(this)" '
|
||||
+ 'style="border-style: none; background: '
|
||||
+ colors[i] + '">' + words[i] + '</td>\n'
|
||||
colorContent += colorCell
|
||||
}
|
||||
document.getElementById("colorExplanation").innerHTML = colorContent
|
||||
|
||||
document.body.addEventListener('keyup', (e) => {
|
||||
if(!currentCellSelected){
|
||||
updateSelectedCell(document.getElementById("0"))
|
||||
}
|
||||
|
||||
var cols = document.getElementById('table').rows[0].cells.length
|
||||
var rows = document.getElementById('table').rows.length
|
||||
var id = parseInt(currentCellSelected.id)
|
||||
|
||||
if(e.code === "ArrowUp" && document.activeElement == document.body){
|
||||
var targetId = Math.max(id-cols, 0)
|
||||
updateSelectedCell(document.getElementById(targetId))
|
||||
e.preventDefault()
|
||||
}else if(e.code === "ArrowDown" && document.activeElement == document.body){
|
||||
var targetId = Math.min(id+cols, cols*rows)
|
||||
updateSelectedCell(document.getElementById(targetId))
|
||||
e.preventDefault()
|
||||
}else if(e.code === "ArrowLeft" && document.activeElement == document.body){
|
||||
var targetId = Math.max(id-1, 0)
|
||||
updateSelectedCell(document.getElementById(targetId))
|
||||
e.preventDefault()
|
||||
}else if(e.code === "ArrowRight" && document.activeElement == document.body){
|
||||
var targetId = Math.min(id+1, cols*rows)
|
||||
updateSelectedCell(document.getElementById(targetId))
|
||||
e.preventDefault()
|
||||
}else if(e.code === "Escape"){
|
||||
updateSelectedCell(null)
|
||||
e.preventDefault()
|
||||
}else if(e.code === "ShiftLeft"){
|
||||
updateBackgroundForCell(currentCellSelected, +1)
|
||||
e.preventDefault()
|
||||
}else if(e.code === "ControlLeft"){
|
||||
updateBackgroundForCell(currentCellSelected, -1)
|
||||
e.preventDefault()
|
||||
}else if(e.code === "Enter"){
|
||||
if(document.activeElement != document.body){
|
||||
// document.activeElement.blur()
|
||||
}else{
|
||||
if(currentCellSelected){
|
||||
currentCellSelected.focus()
|
||||
}
|
||||
}
|
||||
e.preventDefault()
|
||||
}else if(e.code === "Tab"){
|
||||
if(document.activeElement != document.body){
|
||||
document.activeElement.blur()
|
||||
}
|
||||
|
||||
if(currentCellSelected){
|
||||
var targetId = Math.min(id+1, cols*rows)
|
||||
updateSelectedCell(document.getElementById(targetId))
|
||||
}
|
||||
e.preventDefault()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveToServer(){
|
||||
var contents = []
|
||||
var colors = []
|
||||
|
||||
for(let el of document.getElementsByClassName("cell")){
|
||||
if(!el.id){
|
||||
/* filter color cells */
|
||||
continue
|
||||
}
|
||||
contents = contents.concat(el.innerText)
|
||||
colors = colors.concat(el.style.background)
|
||||
}
|
||||
|
||||
var cols = document.getElementById('table').rows[0].cells.length
|
||||
var rows = document.getElementById('table').rows.length
|
||||
var hasHeaderColumn = document.getElementById("hasHeaderColumn").innerText
|
||||
var hasHeaderRow = document.getElementById("hasHeaderRow").innerText
|
||||
var dict = { contents:contents, colors:colors, rows:rows, cols:cols,
|
||||
hasHeaderRow:hasHeaderRow, hasHeaderColumn:hasHeaderColumn };
|
||||
var json = JSON.stringify(dict);
|
||||
|
||||
var tableId = document.getElementById("tableId").innerText
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onload = function() {
|
||||
if (xhttp.status != 204) {
|
||||
alert("Transmission failed!?!")
|
||||
}else{
|
||||
window.location.href = "/table?id=" + tableId
|
||||
}
|
||||
}
|
||||
|
||||
xhttp.open("POST", "/save?id=" + tableId, true);
|
||||
xhttp.setRequestHeader('Content-Type', 'application/json');
|
||||
xhttp.send(json)
|
||||
}
|
||||
|
||||
window.onload = addWindowListeners
|
||||
49
static/team_champselect.js
Normal file
49
static/team_champselect.js
Normal file
@@ -0,0 +1,49 @@
|
||||
function saveToServer(){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
|
||||
champ = "Atrox"
|
||||
position = "Top"
|
||||
affinity = "5"
|
||||
|
||||
req = "/save?type=teamChampSelect" + "&champ=" + cahmp
|
||||
+ "&position=" + position
|
||||
+ "&affinity=" + affinity
|
||||
xhttp.open("POST", req, true);
|
||||
//xhttp.setRequestHeader('Content-Type', 'application/json');
|
||||
xhttp.send(json)
|
||||
}
|
||||
|
||||
|
||||
function addChamp(selectorId, role){
|
||||
champ = document.getElementById(selectorId).value
|
||||
url = window.location.href + "?" + "role=" + role +
|
||||
"&" + "champ=" + champ +
|
||||
"&" + "action=" + "add"
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
referrerPolicy: 'strict-origin'
|
||||
}
|
||||
).then(window.location.reload());
|
||||
}
|
||||
|
||||
|
||||
function removeChamp(champ, role){
|
||||
url = window.location.href + "?" + "role=" + role +
|
||||
"&" + "champ=" + champ +
|
||||
"&" + "action=" + "remove"
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
referrerPolicy: 'strict-origin'
|
||||
}
|
||||
).then(window.location.reload());
|
||||
}
|
||||
96
subpages_dashboard.py
Normal file
96
subpages_dashboard.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import jsonConfig as jc
|
||||
import flask
|
||||
import flask_login as fl
|
||||
import database as db
|
||||
import collections
|
||||
import os
|
||||
|
||||
subpagesDashboard = flask.Blueprint('subpagesDashboard', __name__, template_folder='templates')
|
||||
|
||||
@subpagesDashboard.route("/dashboard/self-analysis")
|
||||
@fl.login_required
|
||||
def selfMatchHistory():
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("dashboardSubpages/self_analysis.html",
|
||||
config=jc.mainConfig(),
|
||||
currentUser=user,
|
||||
champs=jc.champs())
|
||||
|
||||
@subpagesDashboard.route("/dashboard/self_matchups")
|
||||
@fl.login_required
|
||||
def selfMatchups():
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("dashboardSubpages/self_matchups.html",
|
||||
config=jc.mainConfig(), currentUser=user, champs=jc.champs())
|
||||
|
||||
@subpagesDashboard.route("/dashboard/team-match-history")
|
||||
@fl.login_required
|
||||
def teamMatchHistory():
|
||||
user = db.getUserByFlaskLoginId(fl.current_user)
|
||||
return flask.render_template("dashboardSubpages/subpage_team_history.html",
|
||||
config=jc.mainConfig(), currentUser=user, champs=jc.champs())
|
||||
|
||||
@subpagesDashboard.route("/team_champselect", methods=['GET', 'POST'])
|
||||
@fl.login_required
|
||||
def teamChampSelect():
|
||||
teamid = "example"
|
||||
|
||||
roles = collections.OrderedDict()
|
||||
roles["Top"] = None
|
||||
roles["Jungle"] = None
|
||||
roles["Mid"] = None
|
||||
roles["Bottom"] = None
|
||||
roles["Support"] = None
|
||||
|
||||
if flask.request.method == "POST":
|
||||
role = flask.request.args.get("role")
|
||||
champ = flask.request.args.get("champ")
|
||||
action = flask.request.args.get("action")
|
||||
|
||||
if action == "remove":
|
||||
db.teamChampSelectRemove(teamid, champ, role)
|
||||
elif action == "add":
|
||||
db.teamChampSelectAdd(teamid, champ, role)
|
||||
else:
|
||||
flask.abort(500)
|
||||
|
||||
return ("", 204)
|
||||
|
||||
|
||||
|
||||
for key in roles:
|
||||
path = "config/teams/{}/roles/{}.json".format(teamid, key)
|
||||
if not os.path.isfile(path):
|
||||
with open(path, "w") as f:
|
||||
f.write('{ "champions": [] }')
|
||||
roles[key] = jc.readJsonFile(path)
|
||||
|
||||
allChampions = jc.readJsonDir("config/champions")
|
||||
|
||||
return flask.render_template("team_champselect.html", roles=roles,
|
||||
allChampions=allChampions, config=jc.readJsonFile("config/config.json"), currentUser=fl.current_user)
|
||||
|
||||
@subpagesDashboard.route("/team_composition_overview")
|
||||
@fl.login_required
|
||||
def teamCompositionOverview():
|
||||
username = fl.current_user
|
||||
user = jc.readJsonFile(os.path.join("data/users/", "{}.json".format(username)))
|
||||
teamComps = jc.readJsonDir(os.path.join("config/teams/{}/compositions/".format("example")))
|
||||
return flask.render_template("team_composition_overview.html", config=jc.readJsonFile("config/config.json"), currentUser=fl.current_user,
|
||||
userInDatabase=user, teamComps=teamComps)
|
||||
|
||||
@subpagesDashboard.route("/team_composition_single")
|
||||
@fl.login_required
|
||||
def teamCompositionSingle():
|
||||
roles = collections.OrderedDict()
|
||||
roles["Top"] = None
|
||||
roles["Jungle"] = None
|
||||
roles["Mid"] = None
|
||||
roles["Bottom"] = None
|
||||
roles["Support"] = None
|
||||
allChampions = jc.readJsonDir("config/champions")
|
||||
return flask.render_template("team_composition_single.html", roles=roles,
|
||||
teamChamps=allChampions,
|
||||
config=jc.readJsonFile("config/config.json"),
|
||||
currentUser=fl.current_user)
|
||||
|
||||
21
templates/dashboardSubpages/matchhistory.html
Normal file
21
templates/dashboardSubpages/matchhistory.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
<main role="main">
|
||||
<!-- day | Game Nr | Role | played | against | side | result
|
||||
| day time | duoque? | kda | notes -->
|
||||
|
||||
</main>
|
||||
</body>
|
||||
36
templates/dashboardSubpages/self_analysis.html
Normal file
36
templates/dashboardSubpages/self_analysis.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
|
||||
<div role="main" class="p-5">
|
||||
<div class="row mb-3">
|
||||
<button id="save">Save All</button>
|
||||
</div>
|
||||
<div class="row border border-secondary p-2 mb-2">
|
||||
{% for m_entry in currentUser.selfAnalysisEntries %}
|
||||
{% include "partials/self-analysis-obj.html" %}
|
||||
{% endfor %}
|
||||
{% include "partials/self-analysis-obj.html" %}
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<button class="btn-primary">Add Match</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'partials/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
36
templates/dashboardSubpages/self_matchups.html
Normal file
36
templates/dashboardSubpages/self_matchups.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
|
||||
<div role="main" class="p-5">
|
||||
<div class="row mb-3">
|
||||
<button id="save">Save All</button>
|
||||
</div>
|
||||
<div class="border border-secondary p-2 mb-2">
|
||||
{% for m_entry in currentUser.matchupEntris %}
|
||||
{% include "partials/matchup-single-champ.html" %}
|
||||
{% endfor %}
|
||||
{% include "partials/matchup-single-champ.html" %}
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<button class="btn-primary">Add new Champ you play</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-5"></div>
|
||||
{% include 'partials/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
85
templates/dashboardSubpages/subpage_solo_improvement.html
Normal file
85
templates/dashboardSubpages/subpage_solo_improvement.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<main role="main">
|
||||
|
||||
<header class="eyecatcher">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center">
|
||||
<h1 class="font-weight-light">{{ config["main-title"] }}</h1>
|
||||
<p class="lead">{{ config["subtitle"] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Services -->
|
||||
<div class="container pt-3">
|
||||
<div class="row">
|
||||
{% for card in services %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<img class="card-img-top" src="static/pictures/{{ card["picture"] }}">
|
||||
<div class="card-body">
|
||||
<h2>{{ card["headline"] }}</h2>
|
||||
<p>{{ card["description"] }}</p>
|
||||
<p><a class="btn btn-secondary" href="{{ card["primary-link"] }}" role="button">Read More »</a></p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prices -->
|
||||
{% for prices in pricesSections %}
|
||||
<section class="pricing py-5 mb-5"" style="background-color: chartreuse;">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{% for card in prices %}
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-5 mb-lg-0">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-muted text-uppercase text-center">{{ card["header"] }}</h5>
|
||||
<h6 class="card-price text-center">{{ card["price"] }}€<span class="period">{{ card["period"] }}</span></h6>
|
||||
<hr>
|
||||
<ul class="fa-ul">
|
||||
{% for feature in card["features"] %}
|
||||
<li><span class="fa-li"><i class="fas fa-check"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
{% for feature in card["disabledFeatures"] %}
|
||||
<li class="text-muted"><span class="fa-li"><i class="fas fa-times"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="/contact?offerId={{ card["config-id"] }}" class="btn btn-block btn-primary text-uppercase">Contact Me</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
{% include 'footer.html' %}
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
35
templates/dashboardSubpages/subpage_team_history.html
Normal file
35
templates/dashboardSubpages/subpage_team_history.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
|
||||
<div role="main" class="p-5">
|
||||
<div class="row mb-3">
|
||||
<button id="save">Save All</button>
|
||||
</div>
|
||||
{% for m_entry in currentUser.matchhistoryEntries %}
|
||||
{% include "partials/matchhistory-analysis-team-obj.html" %}
|
||||
{% endfor %}
|
||||
{% include "partials/matchhistory-analysis-team-obj.html" %}
|
||||
<div class="row mt-3">
|
||||
<button class="btn-primary">Add Match</div>
|
||||
</div>
|
||||
<div class="pb-3"></div>
|
||||
</div>
|
||||
|
||||
{% include 'partials/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
85
templates/dashboardSubpages/subpage_team_improvement.html
Normal file
85
templates/dashboardSubpages/subpage_team_improvement.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<main role="main">
|
||||
|
||||
<header class="eyecatcher">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center">
|
||||
<h1 class="font-weight-light">{{ config["main-title"] }}</h1>
|
||||
<p class="lead">{{ config["subtitle"] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Services -->
|
||||
<div class="container pt-3">
|
||||
<div class="row">
|
||||
{% for card in services %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<img class="card-img-top" src="static/pictures/{{ card["picture"] }}">
|
||||
<div class="card-body">
|
||||
<h2>{{ card["headline"] }}</h2>
|
||||
<p>{{ card["description"] }}</p>
|
||||
<p><a class="btn btn-secondary" href="{{ card["primary-link"] }}" role="button">Read More »</a></p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prices -->
|
||||
{% for prices in pricesSections %}
|
||||
<section class="pricing py-5 mb-5"" style="background-color: chartreuse;">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{% for card in prices %}
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-5 mb-lg-0">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-muted text-uppercase text-center">{{ card["header"] }}</h5>
|
||||
<h6 class="card-price text-center">{{ card["price"] }}€<span class="period">{{ card["period"] }}</span></h6>
|
||||
<hr>
|
||||
<ul class="fa-ul">
|
||||
{% for feature in card["features"] %}
|
||||
<li><span class="fa-li"><i class="fas fa-check"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
{% for feature in card["disabledFeatures"] %}
|
||||
<li class="text-muted"><span class="fa-li"><i class="fas fa-times"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="/contact?offerId={{ card["config-id"] }}" class="btn btn-block btn-primary text-uppercase">Contact Me</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
{% include 'footer.html' %}
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
2
templates/entities/cell.html
Normal file
2
templates/entities/cell.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<td onclick="cellOnClickListener(this)" id="{{ cellId }}" {% if enableEdit %} contenteditable='true' {% endif %} class="{{ classes }}" {% if cellColor %}style="background: {{ cellColor }};"{% endif %}>{{ cellContent }}</td>
|
||||
|
||||
4
templates/entities/row.html
Normal file
4
templates/entities/row.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<tr>
|
||||
{{ cells }}
|
||||
</tr>
|
||||
|
||||
3
templates/entities/table.html
Normal file
3
templates/entities/table.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<table id="table">
|
||||
{{ tableContent }}
|
||||
</table>
|
||||
42
templates/entities/tableBody.html
Normal file
42
templates/entities/tableBody.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Basic Table</title>
|
||||
<link rel="shortcut icon" href="/static/defaultFavicon.ico">
|
||||
<link rel=stylesheet href="/static/table.css">
|
||||
<script defer src="/static/table.js"></script>
|
||||
<style>
|
||||
{% if cellWidth %}
|
||||
.cell{
|
||||
width: {{ cellWidth }};
|
||||
}
|
||||
{% endif %}
|
||||
</style>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
<body class="pt-5 mt-5">
|
||||
{% include 'navbar.html' %}
|
||||
<div class="hidden" id="tableId">{{ tableId }}</div>
|
||||
<div class="hidden" id="hasHeaderColumn">{{ hasHeaderColumn }}</div>
|
||||
<div class="hidden" id="hasHeaderRow">{{ hasHeaderRow }}</div>
|
||||
|
||||
{% if helpRow %}
|
||||
{{ helpRow }} {% if champion %} {{ champion}} {% endif %}
|
||||
{% else %}
|
||||
<table>
|
||||
<tr id="colorExplanation">
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
<div class="information">
|
||||
Left CTRL or SHIFT to change color of selected cell (or press the desired color with the cell selected)
|
||||
</div>
|
||||
<br>
|
||||
{{ body }}
|
||||
<div style="text-align: center">
|
||||
<button onclick=saveToServer()>Save</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
6
templates/partials/champ-selector-dropdown.html
Normal file
6
templates/partials/champ-selector-dropdown.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
{% for c in champs %}
|
||||
<option value="{{ c }}">{{ c }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
3
templates/partials/footer.html
Normal file
3
templates/partials/footer.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="footer-copyright text-center py-3 fixed-bottom bg-dark">
|
||||
<a class="col-sm footer-el" href="/impressum">Impressum/Datenschutz</a>
|
||||
</div>
|
||||
10
templates/partials/header.html
Normal file
10
templates/partials/header.html
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
<link rel="shortcut icon" href="/static/defaultFavicon.ico">
|
||||
<meta name="author" content="Yannik Schmidt">
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/static/site.css" rel="stylesheet">
|
||||
<link href="/static/fontawesome/css/all.css" rel="stylesheet">
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.js"></script>
|
||||
136
templates/partials/matchhistory-analysis-team-obj.html
Normal file
136
templates/partials/matchhistory-analysis-team-obj.html
Normal file
@@ -0,0 +1,136 @@
|
||||
<div class="p-3 row border border-secondary">
|
||||
{% set positions = [ "Top", "Jgl", "Mid", "Bot", "Sup" ] %}
|
||||
{% set gameTypes = [ "Leauge", "Tournament", "Scrim", "Normal", "Flex" ] %}
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>Game Type</h2>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
{% for gt in gameTypes %}
|
||||
<option value="{{ gt }}">{{ gt }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Our Team</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% for p in positions %}
|
||||
<div id="{{ p }}" class="col">
|
||||
<h4>{{ p }}</h4>
|
||||
{% include "partials/champ-selector-dropdown.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-5 pb-5">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Enemy Team</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% for p in positions %}
|
||||
<div id="{{ p }}" class="col">
|
||||
<h4>{{ p }}</h4>
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
{% for champs in champs %}
|
||||
<option value="{{ r }}">{{ r }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-5 pb-5">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>My Side</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="red">Red</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<h3>Result</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
<option value="w">Win</option>
|
||||
<option value="l">Lose</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>KDA</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
<option value="0">2</option>
|
||||
<option value="1">3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
<option value="0">2</option>
|
||||
<option value="1">3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
<option value="0">2</option>
|
||||
<option value="1">3</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Feedback</h3>
|
||||
<textarea class="w-100"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<h3>Feedback to Matchup</h3>
|
||||
<textarea class="w-100"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
49
templates/partials/matchup-single-champ.html
Normal file
49
templates/partials/matchup-single-champ.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="row mb-5">
|
||||
<div class="col">
|
||||
<h4>Champion</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
{% include "partials/champ-selector-dropdown.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>Matchups</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{% include "partials/champ-selector-dropdown.html" %}
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>Difficulty<option>
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<textarea class="w-100"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="btn-primary">+</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="border border-secondary my-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
49
templates/partials/navbar.html
Normal file
49
templates/partials/navbar.html
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">PH</a>
|
||||
</li>
|
||||
</nav>
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarMain" aria-controls="navbarMain" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarMain">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-nowrap" href="/about">About Me</a>
|
||||
</li>
|
||||
<!--<li class="nav-item">
|
||||
<a class="nav-link" href="/vod-reviews">Reviews</a>
|
||||
</li>-->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/shop">Shop</a>
|
||||
</li>
|
||||
|
||||
{% if currentUser %}
|
||||
<li class="nav-item" style="width: max-content !important;">
|
||||
<a class="nav-link" href="/dashboard">Dashboard</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
<ul class="navbar-nav mr-auto w-100 ml-auto justify-content-end">
|
||||
{% if currentUser %}
|
||||
<li class="nav-item navbar-brand">
|
||||
{{ currentUser }}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/logout">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/login">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
1
templates/partials/paypal-button.html
Normal file
1
templates/partials/paypal-button.html
Normal file
@@ -0,0 +1 @@
|
||||
<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_s-xclick"><input type="hidden" name="hosted_button_id" value="7EB72EVQ74634"><table><tr><td><input type="hidden" name="on0" value="Type">Type</td></tr><tr><td><select name="os0"><option value="VoD Review">VoD Review €10,00 EUR</option><option value="Coaching">Coaching €15,00 EUR</option><option value="Coaching x10">Coaching x10 €100,00 EUR</option></select> </td></tr></table><input type="hidden" name="currency_code" value="EUR"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"><img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"></form>
|
||||
16
templates/partials/self-analysis-obj.html
Normal file
16
templates/partials/self-analysis-obj.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="row border-secondary">
|
||||
{% set types = [ "Pre Game", "Early Game", "Ganks", "Counterjungling", "Mid Game", "Late Game", "All Game" ] %}
|
||||
{% set ratings = [ "Good", "Decent", "Practiced", "Normal", "Bad", "Worse" ] %}
|
||||
{% for t in types %}
|
||||
<div id="{{ t }}" class="col">
|
||||
<h3>{{ t }}</h3>
|
||||
<textarea style="width: 100%;"></textarea>
|
||||
<select class="browser-default custom-select">
|
||||
<option selected>...</option>
|
||||
{% for r in ratings %}
|
||||
<option value="{{ r }}">{{ r }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
20
templates/special/team_calendar.html
Normal file
20
templates/special/team_calendar.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
<main role="main">
|
||||
<!-- Selector für Teammitglieder wenn Teamcpt -->
|
||||
<!-- TODO when team has time -->
|
||||
</main>
|
||||
</body>
|
||||
59
templates/special/team_champselect.html
Normal file
59
templates/special/team_champselect.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
|
||||
<script src="/static/team_champselect.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
<main role="main" class="m-5">
|
||||
<!-- Selector für Teammitglieder wenn Teamcpt -->
|
||||
<!-- SELECTION -->
|
||||
<div style="margin-top: 100px !important;"></div>
|
||||
<div class="row" id="selection-row">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-selection">
|
||||
<div class="text-sm-left role-info m1">{{ key }}</div></br>
|
||||
<select id="{{ key }}-affinity-selector" class="selectpicker" data-live-search="true">
|
||||
{% for x in range(0,6) %}
|
||||
<option>{{ x }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select id="{{ key }}-selector" class="selectpicker" data-live-search="true">
|
||||
{% for champ in allChampions %}
|
||||
<option>{{ champ["name"] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button id="{{ key }}-selector-button" type="button" onClick="addChamp('{{ key }}-selector', '{{ key }}')" class="btn btn-primary add-btn">Add</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- SLECTED CHAMPIONS -->
|
||||
<div class="row" id="selection-row" style="min-height: 400px;">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-champs">
|
||||
{% for champ in roles[key].champions %}
|
||||
<div class="mt-3 mb-3" style="background-color: green; width: 100%; clear: both;">
|
||||
<div class="mr-2" style="float: left;">AF_PLACEHDR</div>
|
||||
<div style="float: left;">{{ champ }}</div>
|
||||
<button style="float: right;" type="button" onClick="removeChamp('{{ champ }}', '{{ key }}')" class="ml-3 btn btn-primary">Remove</button>
|
||||
</div></br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</select>
|
||||
</main>
|
||||
</body>
|
||||
50
templates/special/team_composition.html
Normal file
50
templates/special/team_composition.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
{% for x in range(1, 10) %}
|
||||
<main role="main" class="m-5">
|
||||
<!-- Selector für Teammitglieder wenn Teamcpt -->
|
||||
<!-- SELECTION -->
|
||||
<div style="margin-top: 100px !important;"></div>
|
||||
<div class="row" id="selection-row">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-selection">
|
||||
<select id="{{ key }}-selector" class="selectpicker" data-live-search="true">
|
||||
{% for champ in teamChamps %}
|
||||
<option>{{ champ["name"] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button id="{{ key }}-selector-button" type="button" class="btn btn-primary">Add</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- SLECTED CHAMPIONS -->
|
||||
<div class="row" id="selection-row" style="min-height: 400px;">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-champs">
|
||||
{% for champ in roles[key].champions %}
|
||||
<p>{{ champ }}</p> <button type="button" class="btn">Remove</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</select>
|
||||
</main>
|
||||
{% endfor %}
|
||||
</body>
|
||||
43
templates/special/team_composition_overview.html
Normal file
43
templates/special/team_composition_overview.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
<main role="main">
|
||||
|
||||
<!-- Services -->
|
||||
<div class="container pt-5 my-5">
|
||||
<div class="row">
|
||||
{% for comp in teamComps %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-body">
|
||||
<h2>{{ comp["name"] }}</h2>
|
||||
<p>{{ comp["Description"] }}</p>
|
||||
<p><a class="btn btn-secondary" href="/team_composition_single?id={{ comp['config-id'] }}" role="button">Open »</a></p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
<button type="button" onClick="createNewTeam()" class="ml-3 btn btn-primary">Create New Team</button>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
52
templates/special/team_composition_single.html
Normal file
52
templates/special/team_composition_single.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
|
||||
|
||||
<script src="/static/team_champselect.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<main role="main" class="m-5">
|
||||
<!-- Selector für Teammitglieder wenn Teamcpt -->
|
||||
<!-- SELECTION -->
|
||||
<div style="margin-top: 100px !important;"></div>
|
||||
<div class="row" id="selection-row">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-selection">
|
||||
<div class="text-sm-left role-info m1">{{ key }}</div></br>
|
||||
<select id="{{ key }}-selector" class="selectpicker" data-live-search="true">
|
||||
{% for champ in teamChamps %}
|
||||
<option>{{ champ["name"] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button id="{{ key }}-selector-button" type="button" onClick="addChamp('{{ key }}-selector', '{{ key }}')" class="btn btn-primary">Add</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- SLECTED CHAMPIONS -->
|
||||
<div class="row" id="selection-row" style="min-height: 400px;">
|
||||
{% for key in roles.keys() %}
|
||||
<div class="col-sm {% if loop.index % 2 == 0 %} bg-light {% else %} bg-secondary {% endif %}" id="{{ key }}-champs">
|
||||
{% for champ in roles[key].champions %}
|
||||
<p>{{ champ }}</p> <button type="button" onClick="removeChamp('{{ champ }}', '{{ key }}')" class="btn">Remove</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</select>
|
||||
</main>
|
||||
</body>
|
||||
21
templates/special/team_matchhistory.html
Normal file
21
templates/special/team_matchhistory.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Select the roles you can play for the team">
|
||||
<title>Champ Selection</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'default-includes.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'navbar.html' %}
|
||||
<main role="main">
|
||||
<!-- day | Game Nr | Role | played | against | side | result
|
||||
| day time | duoque? | kda | notes -->
|
||||
|
||||
</main>
|
||||
</body>
|
||||
38
templates/standard/about.html
Normal file
38
templates/standard/about.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
|
||||
<script src="/static/contact.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-secondary">
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div class="container mt-5 mb-5">
|
||||
<div class="row impressum mt-5">
|
||||
<div class="col text-min-dimensions">
|
||||
<h2>Nemesis</h2>
|
||||
<h4>Coach</h4>
|
||||
<p>
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
</p>
|
||||
</div>
|
||||
<div class="col image-min-dimensions">
|
||||
<img class="img-responsive w-100 image-max-dimensions" src="https://esports-erlangen.de/picture/nemesis_euw.jpg?scalex=1280&scaley=960"></img>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "partials/footer.html" %}
|
||||
</body>
|
||||
</html>
|
||||
85
templates/standard/contact.html
Normal file
85
templates/standard/contact.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
|
||||
<script src="/static/contact.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-secondary">
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div id="main-container" class="container" style="margin-top: 4vw;">
|
||||
<section class="mb-4">
|
||||
<h2 class="text-color-special h1-responsive font-weight-bold my-4">
|
||||
{{ conf['CONTACT_HEADLINE'] }}
|
||||
</h2>
|
||||
<p class="text-center w-responsive mx-auto mb-5"> </p>
|
||||
<div class="row">
|
||||
<div class="col-md-9 mb-md-0 mb-5">
|
||||
<form id="contact-form" name="contact-form">
|
||||
<!-- action="contact-api" method="POST" enctype='application/json'> -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mt-2">
|
||||
<div class="md-form mb-0">
|
||||
<input placeholder="{{ conf['CONTACT_PLACEHOLDER_NAME'] }}"
|
||||
type="text" id="name" name="name" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mt-2">
|
||||
<div class="md-form mb-0">
|
||||
<input type="text" id="email" name="email" class="form-control"
|
||||
placeholder="{{ conf['CONTACT_PLACEHOLDER_EMAIL'] }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="md-form mb-0">
|
||||
<input type="text" id="subject" name="subject" class="form-control"
|
||||
placeholder="{{ conf['CONTACT_PLACEHOLDER_SUBJECT'] }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="md-form">
|
||||
<textarea type="text" id="message" name="message" rows="10"
|
||||
placeholder="{{ conf['CONTACT_PLACEHOLDER_TEXTAREA'] }}"
|
||||
class="form-control md-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="text-center text-md-left mt-4">
|
||||
<a class="btn btn-light w-50" onclick="submitContactForm()">Absenden</a>
|
||||
</div>
|
||||
<div class="status"></div>
|
||||
</div>
|
||||
|
||||
<div class="border p-3 col-md-3 text-center bg-special">
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li><i class="fas fa-envelope mt-4 fa-2x"></i>
|
||||
<p>Wir freuen uns auf Ihre Nachricht!</p>
|
||||
{% if conf['CONTACT_EMAIL'] %}
|
||||
<hr>
|
||||
<p>Natürlich können Sie uns auch direkt per Mail kontaktieren.</p></br>
|
||||
<a type="button" class="btn btn-light p-3 w-75"
|
||||
href="mailto:{{ conf['CONTACT_EMAIL'] }}">{{ conf['CONTACT_EMAIL'] }}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% include "partials/footer.html" %}
|
||||
</body>
|
||||
</html>
|
||||
61
templates/standard/impressum.html
Normal file
61
templates/standard/impressum.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div class="navbar navbar-default"></div>
|
||||
<div class="container mt-5">
|
||||
<div class="row impressum">
|
||||
<div class="col-lg-12">
|
||||
<h1>Impressum</h1>
|
||||
<h4><b>{{ config["company-name"] }}</b></h4>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<p>Adresse<br/>{{ config["company-street"] }}<br/>{{ config["company-postal"] }}</p>
|
||||
<p>Telefon<br/>{{ config["company-phone"] }}</p>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<p>E-Mail<br/><a href="mailto:{{ config["company-mail"] }}">{{ config["company-mail"] }}</a></p>
|
||||
<p>Verantwortlicher<br/>{{ config["company-responsible"] }}</p>
|
||||
{{ config["company-freetext"] }}
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
Other Legal BS
|
||||
</div>
|
||||
</div>
|
||||
<div class=mt-5></div>
|
||||
<h1>Haftung für Inhalte</h1>
|
||||
<p>
|
||||
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
|
||||
</p>
|
||||
<h1>Haftung für Links</h1>
|
||||
<p>
|
||||
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h1>Datenschutz</h1>
|
||||
<p>
|
||||
Die Nutzung unserer Webseite ist in der Regel ohne Angabe personenbezogener Daten möglich. Soweit auf unseren Seiten personenbezogene Daten (beispielsweise Name, Anschrift oder eMail-Adressen) erhoben werden, erfolgt dies, soweit möglich, stets auf freiwilliger Basis. Diese Daten werden ohne Ihre ausdrückliche Zustimmung nicht an Dritte weitergegeben. Wir weisen darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich. Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.
|
||||
</p>
|
||||
<h1>Externe Inhalte</h1>
|
||||
<p>
|
||||
Externe Inhalte erforden eine Zustimmung des Nutzers, sollte der Nutzer der Einbindung
|
||||
dieser Inhalte zustimmen, ist er sich bewusst, dass für diese Inhalte die
|
||||
Datenschutzbestimmungen des jeweiligen Drittanbieters gelten.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class=pb-5></div>
|
||||
<div class=pb-5></div>
|
||||
|
||||
{% include 'partials/footer.html' %}
|
||||
</html>
|
||||
88
templates/standard/index.html
Normal file
88
templates/standard/index.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="League of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
|
||||
<main role="main" class="bg-special">
|
||||
|
||||
<header class="eyecatcher" style="background-image: url(https://blog.atlantishq.de/lolproplay_by_Clement_Grandjean_CCSA_licensed.jpg);">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 col-sm-12 text-center">
|
||||
<h1 class="special-header">{{ config["main-title"] }}</h1>
|
||||
<p class="lead special-sub-header">{{ config["subtitle"] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Services -->
|
||||
<div class="container pt-3">
|
||||
<div class="row">
|
||||
{% for card in services %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<img class="card-img-top" src="static/pictures/{{ card["picture"] }}">
|
||||
<div class="card-body">
|
||||
<h3>{{ card["headline"] }}</h3>
|
||||
<p>{{ card["description"] }}</p>
|
||||
<!--
|
||||
<p><a class="btn btn-secondary" href="{{ card["primary-link"] }}" role="button">Read More »</a></p>
|
||||
-->
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prices -->
|
||||
{% for prices in pricesSections %}
|
||||
<section class="pricing py-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{% for card in prices %}
|
||||
<div class="col-lg-4 pb-3">
|
||||
<div class="card mb-lg-0">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-muted text-uppercase text-center">{{ card["header"] }}</h5>
|
||||
<h6 class="card-price text-center">{{ card["price"] }}€<span class="period">{{ card["period"] }}</span></h6>
|
||||
<hr>
|
||||
<ul class="fa-ul">
|
||||
{% for feature in card["features"] %}
|
||||
<li><span class="fa-li"><i class="fas fa-check"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
{% for feature in card["disabledFeatures"] %}
|
||||
<li class="text-muted"><span class="fa-li"><i class="fas fa-times"></i></span>{{ feature }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="/contact?offerId={{ card["config-id"] }}" class="btn btn-block btn-primary text-uppercase">Contact Me</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
<div class="pb-5"></div>
|
||||
</main>
|
||||
|
||||
{% include 'partials/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
56
templates/standard/login.html
Normal file
56
templates/standard/login.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<link rel=stylesheet href="/static/login.css">
|
||||
<title>Nemesis Coaching</title>
|
||||
{% include 'partials/header.html' %}
|
||||
|
||||
</head>
|
||||
|
||||
<body style="background-image: url(https://blog.atlantishq.de/lolproplay_by_Clement_Grandjean_CCSA_licensed.jpg);">
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div class="container">
|
||||
<div class="d-flex justify-content-center h-100">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Sign In</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="input-group form-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="username" placeholder="username">
|
||||
|
||||
</div>
|
||||
<div class="input-group form-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" name="password" placeholder="password">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Login" class="btn float-right login_btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="d-flex justify-content-center links mb-2">
|
||||
{{ config["login-help"] }}
|
||||
</div>
|
||||
<div class="d-flex justify-content-center links">
|
||||
<a class="btn btn-block btn-primary text-uppercase" href="/contact">{{ config["login-help-action"] }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "partials/footer.html" %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
80
templates/standard/shop.html
Normal file
80
templates/standard/shop.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
|
||||
<script src="/static/contact.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-secondary">
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div class="container mt-5 mb-5">
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<div class="col image-min-dimensions">
|
||||
<img class="img-responsive w-100 image-max-dimensions"
|
||||
src="https://esports-erlangen.de/picture/nemesis_euw.jpg"></img>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-5 col text-min-dimensions">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>VoD Review</h2>
|
||||
<h4>Review eines deiner Spiele als VoD</h4>
|
||||
<p>
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{% include "partials/paypal-button.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- example ##################### example -->
|
||||
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<div class="col image-min-dimensions">
|
||||
<img class="img-responsive w-100 image-max-dimensions"
|
||||
src="https://esports-erlangen.de/picture/nemesis_euw.jpg"></img>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-5 col text-min-dimensions">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>Live Coaching</h2>
|
||||
<h4>Live im discord blablabla</h4>
|
||||
<p>
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
Nemesis is bad Nemesis is bad
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{% include "partials/paypal-button.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- example ##################### example -->
|
||||
|
||||
</div>
|
||||
<div class=pb-4></div>
|
||||
{% include "partials/footer.html" %}
|
||||
</body>
|
||||
</html>
|
||||
31
templates/standard/thanks.html
Normal file
31
templates/standard/thanks.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'partials/navbar.html' %}
|
||||
<div class="jumbotron text-center">
|
||||
<h1 class="display-3">Thank You!</h1>
|
||||
<p class="lead"><strong>Your contact request has been send!</strong> We will answer you as soon as possible.</p>
|
||||
<hr>
|
||||
<p>
|
||||
Still having trouble? <a href="/contact">Contact us</a>
|
||||
</p>
|
||||
<p class="lead">
|
||||
<a class="btn btn-primary btn-sm" href="/" role="button">Return to Homepage</a>
|
||||
</p>
|
||||
</div>
|
||||
{% include 'partials/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
77
templates/standard/user_dashboard.html
Normal file
77
templates/standard/user_dashboard.html
Normal file
@@ -0,0 +1,77 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Leauge of Legends Coaching">
|
||||
<title>Nemesis Coaching</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
{% include 'partials/header.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'partials/navbar.html' %}
|
||||
<main role="main">
|
||||
|
||||
<!-- Services -->
|
||||
<div class="container pt-1 my-5">
|
||||
{% if currentUser.single %}
|
||||
<div class="row p-2 border border-secondary">
|
||||
<div id="myaccounts" class="w-50">
|
||||
<h3>Accounts:</h3>
|
||||
{% for acc in currentUser.accounts %}
|
||||
{{ acc }}<br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id=mychamps class="w-50 float-left">
|
||||
<h3>Champions:</h3>
|
||||
{% for c in currentUser.selectedChampions %}
|
||||
<div id="championName">{{ c }}</div>
|
||||
{% endfor %}
|
||||
<div id="championSelector"></div>
|
||||
<div id="roleSelector"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3 p-2 border border-secondary">
|
||||
<div class="col-sm">
|
||||
<button class="btn-primary" id="addAccount">Add Account</button>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<button class="btn-primary" id="addChampion">Add Champion</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
{% for table in currentUser.allowedFeatures() %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<img class="card-img-top {% if table['disabled'] %}pic-disabled{% endif %}
|
||||
" src="static/pictures/{{ table["picture"] }}">
|
||||
<div class="card-body">
|
||||
<h2>{{ table["title"] }}</h2>
|
||||
<p>{{ table["description"] }}</p>
|
||||
{% if table.get("href") %}
|
||||
<p><a class="btn btn-secondary" href="{{ table["href"] }}" role="button">Open »</a></p>
|
||||
{% else %}
|
||||
<p><a class="btn btn-secondary {% if table['disabled'] %}disabled{% endif %}"
|
||||
href="/table?table={{ table['config-identifier'] }}"
|
||||
role="button">Open »</a></p>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'partials/footer.html' %}
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
31
usermanagement.py
Normal file
31
usermanagement.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import flask_login as fl
|
||||
import jsonConfig as jc
|
||||
|
||||
class User(fl.UserMixin):
|
||||
|
||||
def __init__(self, name):
|
||||
self.id = name
|
||||
self.name = "user" + str(id)
|
||||
self.password = self.name + "_secret"
|
||||
self.single = True
|
||||
self.accounts = ["Sheppy", "TheArmCommander"]
|
||||
self.selectedChampions = ["Lulu", "Aatrox", "Brand"]
|
||||
self.matchhistoryEntries = []
|
||||
|
||||
def __repr__(self):
|
||||
return self.id
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
def allowedFeatures(self):
|
||||
'''Dynamicly return the features this user is allowed to use'''
|
||||
|
||||
allFeatures = jc.readJsonDir("config/tables/")
|
||||
allowedFeatures = []
|
||||
if not allowedFeatures:
|
||||
allowedFeatures = allFeatures
|
||||
else:
|
||||
allowedFeatures = filter(lambda x: x["title"] in allowedFeatures,
|
||||
allFeatures)
|
||||
return sorted(allowedFeatures, key=lambda x: x["title"])
|
||||
Reference in New Issue
Block a user