mirror of https://github.com/me50/kukemuna.git
This commit is contained in:
commit
acbc5313f8
|
|
@ -0,0 +1,75 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from cs50 import SQL
|
||||||
|
from flask import Flask, flash, jsonify, redirect, render_template, request, session
|
||||||
|
|
||||||
|
# Configure application
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Ensure templates are auto-reloaded
|
||||||
|
app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||||
|
|
||||||
|
# Configure CS50 Library to use SQLite database
|
||||||
|
db = SQL("sqlite:///birthdays.db")
|
||||||
|
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def after_request(response):
|
||||||
|
"""Ensure responses aren't cached"""
|
||||||
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||||
|
response.headers["Expires"] = 0
|
||||||
|
response.headers["Pragma"] = "no-cache"
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/", methods=["GET", "POST"])
|
||||||
|
def index():
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Add the user's entry into the database
|
||||||
|
name = request.form.get("name")
|
||||||
|
if not name:
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
day = request.form.get("day")
|
||||||
|
if not day:
|
||||||
|
return redirect("/")
|
||||||
|
try:
|
||||||
|
day = int(day)
|
||||||
|
except ValueError:
|
||||||
|
return redirect("/")
|
||||||
|
if day < 1 or day > 31:
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
month = request.form.get("month")
|
||||||
|
if not month:
|
||||||
|
return redirect("/")
|
||||||
|
try:
|
||||||
|
month = int(month)
|
||||||
|
except ValueError:
|
||||||
|
return redirect("/")
|
||||||
|
if month < 1 or month > 12:
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
db.execute("INSERT INTO birthdays(name, day, month) VALUES(?, ?, ?)", name, day ,month)
|
||||||
|
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Display the entries in the database on index.html
|
||||||
|
bdays = db.execute("SELECT * FROM birthdays")
|
||||||
|
return render_template("index.html", bdays=bdays)
|
||||||
|
|
||||||
|
# Remove single entry
|
||||||
|
@app.route("/remove", methods=["POST"])
|
||||||
|
def remove():
|
||||||
|
bday_id = request.form.get("id")
|
||||||
|
db.execute("DELETE FROM birthdays WHERE ID=?", bday_id)
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# Remove all entries
|
||||||
|
@app.route("/remove_all", methods=["POST"])
|
||||||
|
def remove_all():
|
||||||
|
db.execute("DELETE FROM birthdays")
|
||||||
|
return redirect("/")
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,83 @@
|
||||||
|
body {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #212529;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
text-align: center;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #477bff;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
padding-left: 2rem;
|
||||||
|
padding-right: 2rem;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
transition: color 2s ease-in-out, background-color 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input[type="submit"] {
|
||||||
|
background-color: #d9edff;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
text-align: center;
|
||||||
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], input[type="number"] {
|
||||||
|
line-height: 1.8;
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]:hover, input[type="number"]:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
transition: color 2s ease-in-out, background-color 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
background-color: transparent;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th,
|
||||||
|
table td {
|
||||||
|
padding: 0.75rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-of-type(odd) {
|
||||||
|
background-color: rgb(179, 208, 255, 0.3)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap" rel="stylesheet">
|
||||||
|
<link href="/static/styles.css" rel="stylesheet">
|
||||||
|
<title>Birthdays</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>Birthdays</h1>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="section">
|
||||||
|
|
||||||
|
<h2>Add a Birthday</h2>
|
||||||
|
<!-- Create a form for users to submit a name, a day, and a month -->
|
||||||
|
<form action="/" method="POST">
|
||||||
|
<input autocomplete="off" autofocus name="name" placeholder="Name" type="text">
|
||||||
|
<input autocomplete="off" autofocus name="day" placeholder="Day" type="number">
|
||||||
|
<input autocomplete="off" autofocus name="month" placeholder="Month" type="number">
|
||||||
|
<input type="submit" value="Add Birthday">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
|
||||||
|
<h2>All Birthdays</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Birthday</th>
|
||||||
|
<th>
|
||||||
|
<form action="/remove_all" method="POST">
|
||||||
|
<input type="submit" value="Remove all">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- TODO: Loop through the database entries to display them in this table -->
|
||||||
|
{% for bday in bdays %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ bday.name }}</td>
|
||||||
|
<td>{{ bday.day }}.{{ bday.month }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="/remove" method="POST">
|
||||||
|
<input type="hidden" name="id" value="{{ bday.id }}">
|
||||||
|
<input type="submit" value="Remove">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue