init
This commit is contained in:
105
app.py
Normal file
105
app.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
from flask import Flask, render_template, request, redirect, session, jsonify
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.secret_key = "supersecretkey"
|
||||||
|
|
||||||
|
DB = "database.db"
|
||||||
|
|
||||||
|
# ---------------- DATABASE ----------------
|
||||||
|
def get_db():
|
||||||
|
conn = sqlite3.connect(DB)
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
return conn
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
conn = get_db()
|
||||||
|
conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS toner (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
quantity INTEGER NOT NULL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username TEXT,
|
||||||
|
password TEXT
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# ---------------- ROUTES ----------------
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def index():
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
@app.route("/api/toner")
|
||||||
|
def get_toner():
|
||||||
|
conn = get_db()
|
||||||
|
toner = conn.execute("SELECT * FROM toner").fetchall()
|
||||||
|
return jsonify([dict(row) for row in toner])
|
||||||
|
|
||||||
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
|
def login():
|
||||||
|
if request.method == "POST":
|
||||||
|
user = request.form["username"]
|
||||||
|
pw = request.form["password"]
|
||||||
|
|
||||||
|
conn = get_db()
|
||||||
|
result = conn.execute(
|
||||||
|
"SELECT * FROM users WHERE username=? AND password=?",
|
||||||
|
(user, pw)
|
||||||
|
).fetchone()
|
||||||
|
|
||||||
|
if result:
|
||||||
|
session["user"] = user
|
||||||
|
return redirect("/admin")
|
||||||
|
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
|
@app.route("/admin")
|
||||||
|
def admin():
|
||||||
|
if "user" not in session:
|
||||||
|
return redirect("/login")
|
||||||
|
return render_template("admin.html")
|
||||||
|
|
||||||
|
@app.route("/api/add", methods=["POST"])
|
||||||
|
def add_item():
|
||||||
|
if "user" not in session:
|
||||||
|
return "Unauthorized", 401
|
||||||
|
|
||||||
|
data = request.json
|
||||||
|
conn = get_db()
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO toner (name, quantity) VALUES (?, ?)",
|
||||||
|
(data["name"], data["quantity"])
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
@app.route("/api/update", methods=["POST"])
|
||||||
|
def update_item():
|
||||||
|
if "user" not in session:
|
||||||
|
return "Unauthorized", 401
|
||||||
|
|
||||||
|
data = request.json
|
||||||
|
conn = get_db()
|
||||||
|
conn.execute(
|
||||||
|
"UPDATE toner SET quantity=? WHERE id=?",
|
||||||
|
(data["quantity"], data["id"])
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
@app.route("/logout")
|
||||||
|
def logout():
|
||||||
|
session.clear()
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# ---------------- RUN ----------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
init_db()
|
||||||
|
app.run(debug=True)
|
||||||
BIN
database.db
Normal file
BIN
database.db
Normal file
Binary file not shown.
50
static/script.js
Normal file
50
static/script.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
async function loadInventory() {
|
||||||
|
const res = await fetch('/api/toner');
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
const table = document.getElementById("inventory") || document.getElementById("adminInventory");
|
||||||
|
table.innerHTML = "";
|
||||||
|
|
||||||
|
data.forEach(item => {
|
||||||
|
const row = document.createElement("tr");
|
||||||
|
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${item.name}</td>
|
||||||
|
<td>
|
||||||
|
<input value="${item.quantity}" id="qty-${item.id}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button onclick="updateItem(${item.id})">Save</button>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
table.appendChild(row);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addItem() {
|
||||||
|
const name = document.getElementById("name").value;
|
||||||
|
const qty = document.getElementById("qty").value;
|
||||||
|
|
||||||
|
await fetch("/api/add", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: JSON.stringify({name: name, quantity: qty})
|
||||||
|
});
|
||||||
|
|
||||||
|
loadInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateItem(id) {
|
||||||
|
const qty = document.getElementById(`qty-${id}`).value;
|
||||||
|
|
||||||
|
await fetch("/api/update", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: JSON.stringify({id: id, quantity: qty})
|
||||||
|
});
|
||||||
|
|
||||||
|
loadInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = loadInventory;
|
||||||
22
templates/admin.html
Normal file
22
templates/admin.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<h1>Admin Panel</h1>
|
||||||
|
|
||||||
|
<h3>Add Toner</h3>
|
||||||
|
<input id="name" placeholder="Toner Name">
|
||||||
|
<input id="qty" type="number" placeholder="Quantity">
|
||||||
|
<button onclick="addItem()">Add</button>
|
||||||
|
|
||||||
|
<h3>Update Inventory</h3>
|
||||||
|
<table border="1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Update</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="adminInventory"></tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<a href="/logout">Logout</a>
|
||||||
|
|
||||||
|
<script src="/static/script.js"></script>
|
||||||
20
templates/index.html
Normal file
20
templates/index.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Toner Inventory</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Toner Inventory</h1>
|
||||||
|
<table border="1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="inventory"></tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script src="/static/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
6
templates/login.html
Normal file
6
templates/login.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<form method="POST">
|
||||||
|
<h2>Admin Login</h2>
|
||||||
|
<input name="username" placeholder="Username" required>
|
||||||
|
<input name="password" type="password" placeholder="Password" required>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
Reference in New Issue
Block a user