feat: Add promo codes
All checks were successful
Build Docker / Build Image (push) Successful in 21s

This commit is contained in:
2024-02-15 11:58:22 +11:00
parent 9b7089fe7c
commit f5f4addd74
10 changed files with 476 additions and 26 deletions

2
.gitignore vendored
View File

@@ -6,3 +6,5 @@ __pycache__/
used.json used.json
payments.json payments.json
promo.json

22
account.py Normal file
View File

@@ -0,0 +1,22 @@
import os
import dotenv
import random
dotenv.load_dotenv()
EMAIL = os.getenv('LOGIN_EMAIL')
PASSWORD = os.getenv('LOGIN_PASSWORD')
tokens = []
def login(email, password):
if email == EMAIL and password == PASSWORD:
token = str(random.randint(100000, 999999))
tokens.append(token)
return token
return False
def token(token):
if token in tokens:
return True
return False

View File

@@ -29,6 +29,10 @@ else:
with open(path+'used.json', 'w') as f: with open(path+'used.json', 'w') as f:
json.dump(used, f, indent=4) json.dump(used, f, indent=4)
if not os.path.exists(path+'promo.json'):
with open(path+'promo.json', 'w') as f:
json.dump([], f, indent=4)
HNSaddress = os.getenv('ADDRESS') HNSaddress = os.getenv('ADDRESS')
names = { names = {
@@ -37,7 +41,7 @@ names = {
} }
def generate_payment(name,email,mobile,address,country,cart,hns): def generate_payment(name,email,mobile,address,country,cart,hns,promo=False):
# Generate a payment object # Generate a payment object
payment_id = generate_payment_id() payment_id = generate_payment_id()
if payment_id == "ERROR": if payment_id == "ERROR":
@@ -50,6 +54,11 @@ def generate_payment(name,email,mobile,address,country,cart,hns):
if item['name'] in names: if item['name'] in names:
item['name'] = names[item['name']] item['name'] = names[item['name']]
if promo:
promo = promo["id"]
usePromo(promo)
payment = { payment = {
"name": name, "name": name,
"email": email, "email": email,
@@ -59,6 +68,7 @@ def generate_payment(name,email,mobile,address,country,cart,hns):
"hns": hns, "hns": hns,
"ID": finalPrice, "ID": finalPrice,
"cart": cart, "cart": cart,
"promo": promo,
"status": "Pending" "status": "Pending"
} }
finalPriceDolarydoo = float(finalPrice) * 1000000 finalPriceDolarydoo = float(finalPrice) * 1000000
@@ -135,6 +145,68 @@ def generate_payment_id():
if id > 99: if id > 99:
return "ERROR" return "ERROR"
def getPromo(code):
with open(path+'promo.json', 'r') as f:
promos = json.load(f)
for promo in promos:
if promo['id'] == code:
return promo
return False
def getPromos():
with open(path+'promo.json', 'r') as f:
promos = json.load(f)
return promos
def addPromo(id, constant, percent, uses):
with open(path+'promo.json', 'r') as f:
promos = json.load(f)
for promo in promos:
if promo['id'] == id:
return False
promos.append({
"id": id,
"constant": constant,
"percent": percent,
"uses": uses
})
with open(path+'promo.json', 'w') as f:
json.dump(promos, f, indent=4)
return True
def deletePromo(id):
with open(path+'promo.json', 'r') as f:
promos = json.load(f)
for promo in promos:
if promo['id'] == id:
promos.remove(promo)
with open(path+'promo.json', 'w') as f:
json.dump(promos, f, indent=4)
return True
return False
def usePromo(id):
with open(path+'promo.json', 'r') as f:
promos = json.load(f)
for promo in promos:
if promo['id'] == id:
if promo['uses'] == "1":
promos.remove(promo)
elif promo['uses'] == "-1":
return True
uses = int(promo['uses'])
uses -= 1
promo['uses'] = str(uses)
with open(path+'promo.json', 'w') as f:
json.dump(promos, f, indent=4)
return True
if __name__ == '__main__': if __name__ == '__main__':
for i in range(10): for i in range(10):
generate_payment('Test', 'test@email.com', '123 Test St', [ generate_payment('Test', 'test@email.com', '123 Test St', [

View File

@@ -68,7 +68,7 @@ def cart_total(cert):
price = prices[path] price = prices[path]
else: else:
name = path name = path
image = "tech/image2.jpg" image = "pins/pack1.jpg"
price = 45 price = 45
hns = usdToHNS(price, True) hns = usdToHNS(price, True)
@@ -122,7 +122,7 @@ def usdToHNS(usd, returnInt=False):
return hns return hns
def total_usd(cert): def total_usd(cert,promo):
total = 0 total = 0
for item in cert: for item in cert:
path = item['name'] path = item['name']
@@ -130,18 +130,33 @@ def total_usd(cert):
total += prices[path] * int(item['quantity']) total += prices[path] * int(item['quantity'])
else: else:
total += 45 * int(item['quantity']) total += 45 * int(item['quantity'])
if promo:
if promo["constant"]:
total -= int(promo["constant"])
else:
total = total - (total * int(promo["percent"]) / 100)
return total return total
def total_hns(cert, returnInt=False): def total_hns(cert, promo, returnInt=False):
total = 0 total = total_usd(cert, promo)
for item in cert: total = usdToHNS(total,True)
path = item['name']
if path in prices:
total += usdToHNS(prices[path],True) * int(item['quantity'])
else:
total += usdToHNS(45,True) * int(item['quantity'])
if returnInt: if returnInt:
return int(total) return int(total)
total ="{:,}".format(total) total ="{:,}".format(total)
return total return total
def promoList(promo):
html = '<ul class="list-group">'
for item in promo:
discount = 0
if item['constant']:
discount = "$"+item['constant']
else:
discount = item['percent'] + '%'
html += f'<li class="list-group-item"><span>Code: {item["id"]} | {discount} off (Uses Left {item["uses"]})</span><a class="btn btn-primary align-right" role="button" href="/promo/delete/{item["id"]}">Delete</a></li>'
html += '</ul>'
return html

127
server.py
View File

@@ -7,6 +7,7 @@ import json
import render import render
import payments import payments
import threading import threading
import account
app = Flask(__name__) app = Flask(__name__)
dotenv.load_dotenv() dotenv.load_dotenv()
@@ -170,13 +171,41 @@ def cart():
else: else:
cart = '[]' cart = '[]'
promo_message = ''
if 'promo' in cookies:
promo = cookies['promo']
else:
promo = ''
cart = json.loads(cart) cart = json.loads(cart)
cartHtml = render.cart(cart) cartHtml = render.cart(cart)
total_usd = render.total_usd(cart) if promo != '':
total_hns = render.total_hns(cart) promo = payments.getPromo(promo)
if not promo:
promo_message = 'Invalid promo code'
promo = ''
else:
promo_message = f'Promo code {promo["id"]} applied'
return render_template('cart.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) total_usd = render.total_usd(cart,promo)
total_hns = render.total_hns(cart,promo)
promoCode = ''
if promo:
promoCode = promo["id"]
else:
total_usd = render.total_usd(cart, False)
total_hns = render.total_hns(cart, False)
promoCode = ''
return render_template('cart.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns,promo=promoCode, promo_message=promo_message)
@app.route('/cart/promo', methods=['POST'])
def cart_promo():
data = request.form
response = make_response(redirect('/cart'))
response.set_cookie('promo', data['promo'])
return response
@app.route('/payment') @app.route('/payment')
def payment(): def payment():
@@ -194,8 +223,17 @@ def payment():
cart = json.loads(cart) cart = json.loads(cart)
cartHtml = render.cart_total(cart) cartHtml = render.cart_total(cart)
total_usd = render.total_usd(cart) if 'promo' in cookies:
total_hns = render.total_hns(cart) promo = cookies['promo']
promo = payments.getPromo(promo)
total_usd = render.total_usd(cart,promo)
total_hns = render.total_hns(cart,promo)
else:
promo = ''
total_usd = render.total_usd(cart, False)
total_hns = render.total_hns(cart, False)
return render_template('payment.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) return render_template('payment.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns)
@@ -212,8 +250,16 @@ def payment_post():
return redirect('/cart') return redirect('/cart')
cart = json.loads(cart) cart = json.loads(cart)
total_usd = render.total_usd(cart) if 'promo' in cookies:
total_hns = render.total_hns(cart) promo = cookies['promo']
promo = payments.getPromo(promo)
total_usd = render.total_usd(cart,promo)
total_hns = render.total_hns(cart,promo)
else:
promo = False
total_usd = render.total_usd(cart, False)
total_hns = render.total_hns(cart, False)
data = request.form data = request.form
if 'email' in data: if 'email' in data:
@@ -242,15 +288,13 @@ def payment_post():
cartHtml = render.cart_total(cart) cartHtml = render.cart_total(cart)
if email == '' or address == '' or name == '' or country == '' or mobile == '': if email == '' or address == '' or name == '' or country == '' or mobile == '':
return render_template('payment.html', error='Please fill all fields', return render_template('payment.html', error='Please fill all fields',
email=email, address=address, name=name, mobile=mobile, country=country, email=email, address=address, name=name, mobile=mobile, country=country,
cart=cartHtml, total_usd=total_usd, total_hns=total_hns) cart=cartHtml, total_usd=total_usd, total_hns=total_hns)
# All good, check out # All good, check out
payment = payments.generate_payment(name, email, mobile,address,country, cart, render.total_hns(cart, True)) payment = payments.generate_payment(name, email, mobile,address,country, cart, render.total_hns(cart, promo,True), promo)
if payment == False: if payment == False:
return render_template('payment.html', error='There was an error processing your payment', email=email, address=address, name=name, return render_template('payment.html', error='There was an error processing your payment', email=email, address=address, name=name,
@@ -265,9 +309,67 @@ def payment_post():
responce = make_response(render_template('payment_info.html',cart=cartHtml, total_hns=finalPrice,address=HNSaddress, year=datetime.datetime.now().year, qr=qr)) responce = make_response(render_template('payment_info.html',cart=cartHtml, total_hns=finalPrice,address=HNSaddress, year=datetime.datetime.now().year, qr=qr))
responce.set_cookie('cart', '[]') responce.set_cookie('cart', '[]')
return responce return responce
# Promo routes
@app.route('/promo')
def promo():
year = datetime.datetime.now().year
# Check user is logged in
token = request.cookies.get('token')
if not token:
return redirect('/login')
if not account.token(token):
return redirect('/login')
promos = payments.getPromos()
promos = render.promoList(promos)
return render_template('promo.html', year=year, promos=promos)
@app.route('/promo', methods=['POST'])
def promo_post():
data = request.form
token = request.cookies.get('token')
if not token:
return redirect('/login')
if not account.token(token):
return redirect('/login')
id = data['code']
constant = data['constant']
percent = data['percent']
uses = data['uses']
payments.addPromo(id, constant, percent, uses)
return redirect('/promo')
@app.route('/promo/delete/<path:path>')
def promo_delete(path):
token = request.cookies.get('token')
if not token:
return redirect('/login')
if not account.token(token):
return redirect('/login')
payments.deletePromo(path)
return redirect('/promo')
@app.route('/login', methods=['POST'])
def login():
data = request.form
token = account.login(data['email'], data['password'])
if token:
response = make_response(redirect('/promo'))
response.set_cookie('token', token)
return response
return redirect('/login')
# Main routes # Main routes
@app.route('/') @app.route('/')
def index(): def index():
@@ -305,7 +407,4 @@ def check_payments():
payments.check_payments() payments.check_payments()
if __name__ == '__main__': if __name__ == '__main__':
# Set timer for payments
repeat_check_payments()
app.run(debug=True, port=5000, host='0.0.0.0') app.run(debug=True, port=5000, host='0.0.0.0')

View File

@@ -39,3 +39,13 @@
text-decoration: none; text-decoration: none;
} }
.align-right {
position: absolute;
right: 1px;
top: 1px;
}
.price {
font-size: medium !important;
}

View File

@@ -77,6 +77,7 @@
<div class="col-md-12 col-lg-4"> <div class="col-md-12 col-lg-4">
<div class="bg-body-tertiary summary"> <div class="bg-body-tertiary summary">
<h3>Summary</h3> <h3>Summary</h3>
<form style="margin-bottom: 25px;" method="post" action="/cart/promo"><label class="form-label" for="promo">Promo Code</label><input class="form-control" type="text" placeholder="Promo Code" name="promo" value="{{promo}}"><span>{{promo_message}}</span></form>
<h4 class="border-primary-subtle" style="border-color: var(--bs-primary-border-subtle);"><span class="text">Total USD</span><span class="price">US${{total_usd}}</span></h4> <h4 class="border-primary-subtle" style="border-color: var(--bs-primary-border-subtle);"><span class="text">Total USD</span><span class="price">US${{total_usd}}</span></h4>
<h4><span class="text">Total</span><span class="price">{{total_hns}} HNS</span></h4><a class="btn btn-primary btn-lg d-block w-100" role="button" href="/payment">Checkout</a> <h4><span class="text">Total</span><span class="price">{{total_hns}} HNS</span></h4><a class="btn btn-primary btn-lg d-block w-100" role="button" href="/payment">Checkout</a>
</div> </div>

109
templates/login.html Normal file
View File

@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html data-bs-theme="dark" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Login - HNSAU</title>
<meta name="theme-color" content="#ffffff">
<link rel="canonical" href="https://hns.au/login">
<meta property="og:url" content="https://hns.au/login">
<meta name="twitter:image" content="https://hns.au/assets/img/HNSAUbanner.png">
<meta name="twitter:description" content="The home of Australians using the decentralized web, built on Handshake.">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:description" content="The home of Australians using the decentralized web, built on Handshake.">
<meta name="description" content="Handshake Australia">
<meta property="og:title" content="HNS AU">
<meta property="og:type" content="website">
<meta name="twitter:title" content="HNS AU">
<meta property="og:image" content="https://hns.au/assets/img/HNSAUbanner.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:400,400i,700,700i,600,600i&amp;display=swap">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.css">
<link rel="stylesheet" href="/assets/css/vanilla-zoom.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '8']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body>
<nav class="navbar navbar-expand-lg fixed-top bg-dark clean-navbar navbar-light" data-bs-theme="dark">
<div class="container-fluid"><a class="navbar-brand logo" href="/" style="width: 50%;"><img src="/assets/img/favicon.png" style="height: 50px;margin-right: 10px;">HNSAU</a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-1"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/blog">Blog</a></li>
<li class="nav-item"><a class="nav-link" href="/links">Links</a></li>
<li class="nav-item"><a class="nav-link" href="/about">About Us</a></li>
<li class="nav-item"><a class="nav-link" href="https://domains.hns.au">Domains</a></li>
<li class="nav-item"><a class="nav-link" href="/pins">Pins</a></li>
<li class="nav-item"><a class="nav-link" href="/contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<main class="page login-page">
<section class="clean-block clean-form dark">
<div class="container">
<div class="block-heading">
<h2 class="text-info">Log In</h2>
</div>
<form method="post">
<div class="mb-3"><label class="form-label" for="email">Email</label><input class="form-control item" type="email" id="email" data-bs-theme="light" name="email"></div>
<div class="mb-3"><label class="form-label" for="password">Password</label><input class="form-control" type="password" id="password" data-bs-theme="light" name="password"></div><button class="btn btn-primary" type="submit">Log In</button>
</form>
</div>
</section>
</main>
<footer class="page-footer dark">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Get started</h5>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/links">Links</a></li>
<li><a href="/domains" target="_blank">Domains</a></li>
</ul>
</div>
<div class="col-sm-3">
<h5>Contact</h5>
<ul>
<li><a href="https://discord.gg/WJ6vpjuQv5" target="_blank">Discord</a></li>
<li><a href="/email" target="_blank">Email</a></li>
<li><a href="/about">About Us</a></li>
</ul>
</div>
</div>
</div>
<div class="footer-copyright">
<p>© {{year}} Handshake AU</p>
</div>
</footer>
<script src="/assets/bootstrap/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.js"></script>
<script src="/assets/js/vanilla-zoom.js"></script>
<script src="/assets/js/theme.js"></script>
</body>
</html>

114
templates/promo.html Normal file
View File

@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html data-bs-theme="dark" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Login - HNSAU</title>
<meta name="theme-color" content="#ffffff">
<link rel="canonical" href="https://hns.au/promo">
<meta property="og:url" content="https://hns.au/promo">
<meta name="twitter:image" content="https://hns.au/assets/img/HNSAUbanner.png">
<meta name="twitter:description" content="The home of Australians using the decentralized web, built on Handshake.">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:description" content="The home of Australians using the decentralized web, built on Handshake.">
<meta name="description" content="Handshake Australia">
<meta property="og:title" content="HNS AU">
<meta property="og:type" content="website">
<meta name="twitter:title" content="HNS AU">
<meta property="og:image" content="https://hns.au/assets/img/HNSAUbanner.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:400,400i,700,700i,600,600i&amp;display=swap">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.css">
<link rel="stylesheet" href="/assets/css/vanilla-zoom.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '8']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body>
<nav class="navbar navbar-expand-lg fixed-top bg-dark clean-navbar navbar-light" data-bs-theme="dark">
<div class="container-fluid"><a class="navbar-brand logo" href="/" style="width: 50%;"><img src="/assets/img/favicon.png" style="height: 50px;margin-right: 10px;">HNSAU</a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-1"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/blog">Blog</a></li>
<li class="nav-item"><a class="nav-link" href="/links">Links</a></li>
<li class="nav-item"><a class="nav-link" href="/about">About Us</a></li>
<li class="nav-item"><a class="nav-link" href="https://domains.hns.au">Domains</a></li>
<li class="nav-item"><a class="nav-link" href="/pins">Pins</a></li>
<li class="nav-item"><a class="nav-link" href="/contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<main class="page login-page">
<section class="clean-block clean-form dark">
<div class="container">
<div class="block-heading">
<h2 class="text-info">Create Promo Code</h2>
</div>
<form method="post">
<div style="margin-bottom: 16px;"><label class="form-label" for="code">Code</label><input class="form-control" type="text" data-bs-theme="light" name="code" placeholder="Promo Code"></div>
<div style="margin-bottom: 16px;"><label class="form-label" for="constant">US$ Off</label><input class="form-control" type="text" data-bs-theme="light" name="constant" placeholder="10"></div>
<div style="margin-bottom: 16px;"><label class="form-label" for="percent">% Off</label><input class="form-control" type="text" data-bs-theme="light" name="percent" placeholder="25"></div>
<div style="margin-bottom: 16px;"><label class="form-label" for="uses">Uses</label><input class="form-control" type="text" data-bs-theme="light" name="uses" placeholder="1"><span>Enter -1 for unlimited uses</span></div><button class="btn btn-primary" type="submit">Create</button>
</form>
</div>
<div style="margin: auto;margin-top: 25px;max-width: 700px;">
<h3 class="text-center">Existing Promo Codes</h3>{{promos | safe}}
</div>
</section>
</main>
<footer class="page-footer dark">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Get started</h5>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/links">Links</a></li>
<li><a href="/domains" target="_blank">Domains</a></li>
</ul>
</div>
<div class="col-sm-3">
<h5>Contact</h5>
<ul>
<li><a href="https://discord.gg/WJ6vpjuQv5" target="_blank">Discord</a></li>
<li><a href="/email" target="_blank">Email</a></li>
<li><a href="/about">About Us</a></li>
</ul>
</div>
</div>
</div>
<div class="footer-copyright">
<p>© {{year}} Handshake AU</p>
</div>
</footer>
<script src="/assets/bootstrap/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.js"></script>
<script src="/assets/js/vanilla-zoom.js"></script>
<script src="/assets/js/theme.js"></script>
</body>
</html>

View File

@@ -39,6 +39,9 @@
<url> <url>
<loc>https://hns.au/links</loc> <loc>https://hns.au/links</loc>
</url> </url>
<url>
<loc>https://hns.au/login</loc>
</url>
<url> <url>
<loc>https://hns.au/payment</loc> <loc>https://hns.au/payment</loc>
</url> </url>
@@ -48,6 +51,9 @@
<url> <url>
<loc>https://hns.au/pins</loc> <loc>https://hns.au/pins</loc>
</url> </url>
<url>
<loc>https://hns.au/promo</loc>
</url>
<url> <url>
<loc>https://hns.au/uv</loc> <loc>https://hns.au/uv</loc>
</url> </url>