Lots of base additons
This commit is contained in:
parent
9a57fa7ad6
commit
f042c7ca82
Binary file not shown.
Binary file not shown.
BIN
__pycache__/webserver.cpython-312.pyc
Normal file
BIN
__pycache__/webserver.cpython-312.pyc
Normal file
Binary file not shown.
92
api.py
92
api.py
@ -4,12 +4,59 @@ from config import config
|
||||
|
||||
database_api= Blueprint('database_api', __name__)
|
||||
|
||||
|
||||
def paginate_with_params(cur, limit, offset, params):
|
||||
sql = f"SELECT * FROM main_items LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id"
|
||||
count = f"SELECT COUNT(*) FROM main_items LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id"
|
||||
# WHERE search_string LIKE '%{search_string}%'
|
||||
strings = []
|
||||
count_strings = []
|
||||
if params['search_string'] != "":
|
||||
s = params['search_string']
|
||||
strings.append(f" search_string LIKE '%{s}%'")
|
||||
count_strings.append(f" search_string LIKE '%{s}%'")
|
||||
|
||||
if params['view'] == 1:
|
||||
s = params['view']
|
||||
strings.append(f" main_logistics_info.quantity_on_hand <> 0.00")
|
||||
count_strings.append(f" main_logistics_info.quantity_on_hand <> 0.00")
|
||||
|
||||
|
||||
# LIMIT {limit} OFFSET {offset};"
|
||||
|
||||
if len(strings) > 0:
|
||||
sql = f"{sql} WHERE{" AND".join(strings)}"
|
||||
|
||||
if len(count_strings) > 0:
|
||||
count = f"{count} WHERE{" AND".join(count_strings)}"
|
||||
|
||||
sql = f"{sql} ORDER BY main_logistics_info.quantity_on_hand LIMIT {limit} OFFSET {offset};"
|
||||
count = f"{count};"
|
||||
print(count)
|
||||
print(sql)
|
||||
cur.execute(sql)
|
||||
pantry_inventory = cur.fetchall()
|
||||
cur.execute(count)
|
||||
count = cur.fetchone()[0]
|
||||
return pantry_inventory, count
|
||||
|
||||
def paginate_default(cur, limit, offset):
|
||||
sql = f"SELECT * FROM main_items LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id LIMIT %s OFFSET %s;"
|
||||
cur.execute(sql, (limit, offset))
|
||||
pantry_inventory = cur.fetchall()
|
||||
cur.execute("SELECT COUNT(*) FROM main_items;")
|
||||
count = cur.fetchone()[0]
|
||||
return pantry_inventory, count
|
||||
|
||||
|
||||
@database_api.route("/getItems")
|
||||
def pagninate_items():
|
||||
print("hello")
|
||||
page = int(request.args.get('page', 1))
|
||||
limit = int(request.args.get('limit', 10))
|
||||
search_string = str(request.args.get('search_text', ""))
|
||||
sort_order = int(request.args.get('sort_order', 1))
|
||||
view = int(request.args.get('view', 0))
|
||||
|
||||
offset = (page - 1) * limit
|
||||
|
||||
@ -20,26 +67,22 @@ def pagninate_items():
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
if search_string != "":
|
||||
sql = f"SELECT * FROM main_items LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id WHERE search_string LIKE '%{search_string}%' LIMIT {limit} OFFSET {offset};"
|
||||
cur.execute(sql)
|
||||
pantry_inventory = cur.fetchall()
|
||||
cur.execute(f"SELECT COUNT(*) FROM main_items WHERE search_string LIKE '%{search_string}%';")
|
||||
count = cur.fetchone()[0]
|
||||
else:
|
||||
sql = f"SELECT * FROM main_items LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id LIMIT %s OFFSET %s;"
|
||||
cur.execute(sql, (limit, offset))
|
||||
pantry_inventory = cur.fetchall()
|
||||
cur.execute("SELECT COUNT(*) FROM main_items;")
|
||||
count = cur.fetchone()[0]
|
||||
|
||||
print(sql)
|
||||
print(count, math.ceil(count/limit))
|
||||
|
||||
pantry_inventory, count = paginate_with_params(
|
||||
cur, limit, offset,
|
||||
{'search_string': search_string,
|
||||
'view': view}
|
||||
)
|
||||
except (Exception, psycopg2.DatabaseError) as error:
|
||||
print(error)
|
||||
|
||||
pantry_inventory = sorted(pantry_inventory, key=lambda x: x[2])
|
||||
if sort_order == 0:
|
||||
pantry_inventory = sorted(pantry_inventory, key=lambda x: x[1])
|
||||
|
||||
if sort_order == 1:
|
||||
pantry_inventory = sorted(pantry_inventory, key=lambda x: x[2])
|
||||
|
||||
if sort_order == 2:
|
||||
pantry_inventory = sorted(pantry_inventory, key=lambda x: x[18])
|
||||
|
||||
return jsonify({'items': pantry_inventory, "end": math.ceil(count/limit)})
|
||||
|
||||
@ -63,4 +106,17 @@ def get_item():
|
||||
except (Exception, psycopg2.DatabaseError) as error:
|
||||
print(error)
|
||||
|
||||
return render_template(f"item_page/index.html", item=item)
|
||||
return render_template(f"item_page/index.html", item=item)
|
||||
|
||||
@database_api.route("/addGroup")
|
||||
def addGroup():
|
||||
name = str(request.args.get('name', ""))
|
||||
description = str(request.args.get('description', ""))
|
||||
group_type = str(request.args.get('type', ""))
|
||||
|
||||
state = "FAILED"
|
||||
|
||||
if name or description or group_type == "":
|
||||
print("this is empty")
|
||||
|
||||
return jsonify({'state': state})
|
||||
16
main.py
16
main.py
@ -310,6 +310,11 @@ def delete_site(site_name):
|
||||
drop_table(f'sites/{site_name}/sql/drop/logistics_info.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/zones.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/locations.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/vendors.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/receipt_items.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/receipts.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/recipes.sql')
|
||||
drop_table(f'sites/{site_name}/sql/drop/shopping_lists.sql')
|
||||
|
||||
def create_site(site_name):
|
||||
|
||||
@ -326,6 +331,12 @@ def create_site(site_name):
|
||||
create_table(f'sites/{site_name}/sql/create/item.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/zones.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/locations.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/vendors.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/receipt_items.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/receipts.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/recipes.sql')
|
||||
create_table(f'sites/{site_name}/sql/create/shopping_lists.sql')
|
||||
|
||||
|
||||
sql = f"INSERT INTO {site_name}_zones(name) VALUES (%s) RETURNING id;"
|
||||
sqltwo = f"INSERT INTO {site_name}_locations(uuid, name, zone_id, items) VALUES (%s, %s, %s, %s);"
|
||||
@ -411,7 +422,8 @@ def parse_csv(path_to_csv):
|
||||
if line[0] != "id":
|
||||
payload["item_info"]["packaging"] = line[10]
|
||||
payload["item_info"]["uom"] = line[13]
|
||||
payload["item_info"]["cost"] = line[15]
|
||||
if line[15] != "":
|
||||
payload["item_info"]["cost"] = line[15]
|
||||
if line[17] != "None":
|
||||
payload["item_info"]["safety_stock"] = line[17]
|
||||
qty = float(line[30])
|
||||
@ -432,4 +444,4 @@ if __name__ == "__main__":
|
||||
for k, v in items.items():
|
||||
print(f"{k}: {v}")
|
||||
"""
|
||||
parse_csv(r"C:\\Users\\jadow\Downloads\\2024-10-02-Pantry.csv")
|
||||
parse_csv(r"C:\\Users\\jadow\\Documents\\code\\postgresql python\\postgresql-python\\2024-10-02-Pantry.csv")
|
||||
17
manage.py
17
manage.py
@ -6,6 +6,22 @@ Manage.py is where the databases and configuration is set up. Its a CLI for quic
|
||||
MyPantry App.
|
||||
"""
|
||||
|
||||
def rename_unique_sql(site_name):
|
||||
files = os.walk(f"sites/{site_name}/sql/unique")
|
||||
|
||||
sql_files = []
|
||||
for file in files:
|
||||
sql_files = file[2]
|
||||
|
||||
for file_name in sql_files:
|
||||
words = None
|
||||
with open(f"sites/{site_name}/sql/unique/{file_name}", "r") as file:
|
||||
words = file.read()
|
||||
words = words.replace("%sitename%", site_name)
|
||||
|
||||
with open(f"sites/{site_name}/sql/unique/{file_name}", "w") as file:
|
||||
file.write(words)
|
||||
|
||||
def rename_drop_sql(site_name):
|
||||
files = os.walk(f"sites/{site_name}/sql/drop")
|
||||
|
||||
@ -60,6 +76,7 @@ def create():
|
||||
shutil.copytree(f"sites/default/sql", f"sites/{site_name}/sql")
|
||||
rename_create_sql(site_name)
|
||||
rename_drop_sql(site_name)
|
||||
rename_unique_sql(site_name)
|
||||
|
||||
with open(f"sites/{site_name}/site.ini", "w+") as config:
|
||||
config.write(f"[site]\n")
|
||||
|
||||
@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS %sitename%_items(
|
||||
barcode VARCHAR(255) NOT NULL,
|
||||
item_name VARCHAR(255) NOT NULL,
|
||||
brand INTEGER,
|
||||
description TEXT;
|
||||
tags TEXT [],
|
||||
links JSONB,
|
||||
item_info_id INTEGER NOT NULL,
|
||||
|
||||
@ -6,4 +6,4 @@ CREATE TABLE IF NOT EXISTS %sitename%_receipt_items (
|
||||
qty FLOAT8 NOT NULL,
|
||||
data JSONB,
|
||||
status VARCHAR (64)
|
||||
)
|
||||
);
|
||||
@ -5,4 +5,4 @@ CREATE TABLE IF NOT EXISTS %sitename%_vendors (
|
||||
creation_date TIMESTAMP NOT NULL,
|
||||
created_by TIMESTAMP NOT NULL,
|
||||
phone_number VARCHAR(32)
|
||||
)
|
||||
);
|
||||
1
sites/default/sql/drop/receipt_items.sql
Normal file
1
sites/default/sql/drop/receipt_items.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE %sitename%_receipt_items CASCADE;
|
||||
1
sites/default/sql/drop/receipts.sql
Normal file
1
sites/default/sql/drop/receipts.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE %sitename%_receipts CASCADE;
|
||||
1
sites/default/sql/drop/recipes.sql
Normal file
1
sites/default/sql/drop/recipes.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE %sitename%_recipes CASCADE;
|
||||
1
sites/default/sql/drop/shopping_lists.sql
Normal file
1
sites/default/sql/drop/shopping_lists.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE %sitename%_shopping_lists CASCADE;
|
||||
1
sites/default/sql/drop/vendors.sql
Normal file
1
sites/default/sql/drop/vendors.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE %sitename%_vendors CASCADE;
|
||||
@ -9,36 +9,37 @@ WHERE %sitename%_items.id=%s;
|
||||
01 - barcode
|
||||
02 - item_name
|
||||
03 - brand (id)
|
||||
04 - tags
|
||||
05 - links
|
||||
06 - item_info_id
|
||||
07 - logistics_info_id
|
||||
08 - food_info_id
|
||||
09 - row_type
|
||||
10 - item_type
|
||||
11 - search_string
|
||||
12 - logistics_info_id
|
||||
13 - barcode
|
||||
14 - primary_location
|
||||
15 - auto_issue_location
|
||||
16 - dynamic_locations
|
||||
17 - location_data
|
||||
18 - quantity_on_hand
|
||||
19 - item_info_id
|
||||
20 - barcode
|
||||
21 - linked_items
|
||||
22 - shopping_lists
|
||||
23 - recipes
|
||||
24 - groups
|
||||
25 - packaging
|
||||
26 - uom
|
||||
27 - cost
|
||||
28 - safety_stock
|
||||
29 - lead_time_days
|
||||
30 - ai_pick
|
||||
31 - food_info_id
|
||||
32 - food_groups
|
||||
33 - ingrediants
|
||||
34 - nutrients
|
||||
35 - expires
|
||||
04 - description
|
||||
05 - tags
|
||||
06 - links
|
||||
07 - item_info_id
|
||||
08 - logistics_info_id
|
||||
09 - food_info_id
|
||||
10 - row_type
|
||||
11 - item_type
|
||||
12 - search_string
|
||||
13 - logistics_info_id
|
||||
14 - barcode
|
||||
15 - primary_location
|
||||
16 - auto_issue_location
|
||||
17 - dynamic_locations
|
||||
18 - location_data
|
||||
19 - quantity_on_hand
|
||||
20 - item_info_id
|
||||
21 - barcode
|
||||
22 - linked_items
|
||||
23 - shopping_lists
|
||||
24 - recipes
|
||||
25 - groups
|
||||
26 - packaging
|
||||
27 - uom
|
||||
28 - cost
|
||||
29 - safety_stock
|
||||
30 - lead_time_days
|
||||
31 - ai_pick
|
||||
32 - food_info_id
|
||||
33 - food_groups
|
||||
34 - ingrediants
|
||||
35 - nutrients
|
||||
36 - expires
|
||||
*/
|
||||
@ -1,6 +1,6 @@
|
||||
[site]
|
||||
site_name=main
|
||||
site_owner=jadowyne
|
||||
site_owner=
|
||||
email=
|
||||
|
||||
[defaults]
|
||||
|
||||
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS main_items(
|
||||
item_name VARCHAR(255) NOT NULL,
|
||||
brand INTEGER,
|
||||
tags TEXT [],
|
||||
links TEXT [],
|
||||
links JSONB,
|
||||
item_info_id INTEGER NOT NULL,
|
||||
logistics_info_id INTEGER NOT NULL,
|
||||
food_info_id INTEGER,
|
||||
|
||||
9
sites/main/sql/create/receipt_items.sql
Normal file
9
sites/main/sql/create/receipt_items.sql
Normal file
@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS main_receipt_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
barcode VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
qty FLOAT8 NOT NULL,
|
||||
data JSONB,
|
||||
status VARCHAR (64)
|
||||
);
|
||||
10
sites/main/sql/create/receipts.sql
Normal file
10
sites/main/sql/create/receipts.sql
Normal file
@ -0,0 +1,10 @@
|
||||
CREATE TABLE IF NOT EXISTS main_receipts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
receipt_id INTEGER NOT NULL,
|
||||
receipt_status VARCHAR (64) NOT NULL,
|
||||
date_submitted TIMESTAMP NOT NULL,
|
||||
submitted_by INTEGER NOT NULL,
|
||||
vendor_id INTEGER,
|
||||
files JSONB,
|
||||
UNIQUE(receipt_id)
|
||||
);
|
||||
12
sites/main/sql/create/recipes.sql
Normal file
12
sites/main/sql/create/recipes.sql
Normal file
@ -0,0 +1,12 @@
|
||||
CREATE TABLE IF NOT EXISTS main_recipes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR,
|
||||
author INTEGER,
|
||||
description TEXT,
|
||||
creation_date TIMESTAMP,
|
||||
custom_items JSONB,
|
||||
pantry_items JSONB,
|
||||
group_items JSONB,
|
||||
instructions TEXT [],
|
||||
picture_path TEXT
|
||||
);
|
||||
13
sites/main/sql/create/shopping_lists.sql
Normal file
13
sites/main/sql/create/shopping_lists.sql
Normal file
@ -0,0 +1,13 @@
|
||||
CREATE TABLE IF NOT EXISTS main_shopping_lists (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
pantry_items JSONB,
|
||||
custom_items JSONB,
|
||||
recipes JSONB,
|
||||
groups JSONB,
|
||||
author INTEGER,
|
||||
creation_date TIMESTAMP,
|
||||
type VARCHAR(64),
|
||||
UNIQUE(name)
|
||||
);
|
||||
8
sites/main/sql/create/vendors.sql
Normal file
8
sites/main/sql/create/vendors.sql
Normal file
@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS main_vendors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address VARCHAR(255),
|
||||
creation_date TIMESTAMP NOT NULL,
|
||||
created_by TIMESTAMP NOT NULL,
|
||||
phone_number VARCHAR(32)
|
||||
);
|
||||
1
sites/main/sql/drop/receipt_items.sql
Normal file
1
sites/main/sql/drop/receipt_items.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE main_receipt_items CASCADE;
|
||||
1
sites/main/sql/drop/receipts.sql
Normal file
1
sites/main/sql/drop/receipts.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE main_receipts CASCADE;
|
||||
1
sites/main/sql/drop/recipes.sql
Normal file
1
sites/main/sql/drop/recipes.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE main_recipes CASCADE;
|
||||
1
sites/main/sql/drop/shopping_lists.sql
Normal file
1
sites/main/sql/drop/shopping_lists.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE main_shopping_lists CASCADE;
|
||||
1
sites/main/sql/drop/vendors.sql
Normal file
1
sites/main/sql/drop/vendors.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE main_vendors CASCADE;
|
||||
@ -2,4 +2,43 @@ SELECT * FROM main_items
|
||||
LEFT JOIN main_logistics_info ON main_items.logistics_info_id = main_logistics_info.id
|
||||
LEFT JOIN main_item_info ON main_items.item_info_id = main_item_info.id
|
||||
LEFT JOIN main_food_info ON main_items.food_info_id = main_food_info.id
|
||||
WHERE main_items.id=%s;
|
||||
WHERE main_items.id=%s;
|
||||
|
||||
/*
|
||||
00 - item_id
|
||||
01 - barcode
|
||||
02 - item_name
|
||||
03 - brand (id)
|
||||
04 - tags
|
||||
05 - links
|
||||
06 - item_info_id
|
||||
07 - logistics_info_id
|
||||
08 - food_info_id
|
||||
09 - row_type
|
||||
10 - item_type
|
||||
11 - search_string
|
||||
12 - logistics_info_id
|
||||
13 - barcode
|
||||
14 - primary_location
|
||||
15 - auto_issue_location
|
||||
16 - dynamic_locations
|
||||
17 - location_data
|
||||
18 - quantity_on_hand
|
||||
19 - item_info_id
|
||||
20 - barcode
|
||||
21 - linked_items
|
||||
22 - shopping_lists
|
||||
23 - recipes
|
||||
24 - groups
|
||||
25 - packaging
|
||||
26 - uom
|
||||
27 - cost
|
||||
28 - safety_stock
|
||||
29 - lead_time_days
|
||||
30 - ai_pick
|
||||
31 - food_info_id
|
||||
32 - food_groups
|
||||
33 - ingrediants
|
||||
34 - nutrients
|
||||
35 - expires
|
||||
*/
|
||||
@ -4,78 +4,177 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
|
||||
<title>My Pantry</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@materializecss/materialize@2.0.3-alpha/dist/css/materialize.min.css" />
|
||||
<!-- Material Icons -->
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
||||
<!-- Material Symbols - Outlined Set -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
|
||||
<!-- Material Symbols - Rounded Set -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
|
||||
<!-- Material Symbols - Sharp Set -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/@materializecss/materialize@2.0.3-alpha/dist/js/materialize.min.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
.hand-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
[type="radio"]:checked + span:after {
|
||||
border: 2px solid rgb(0 128 0 / 30%); /* Outline color */
|
||||
background-color: rgb(0 128 0 / 30%); /* Fill color */
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div class="container section">
|
||||
<div class="container section" style="padding-bottom: 72px;">
|
||||
<div class="row">
|
||||
<div class="col s9 m6 offset-m3 input-field outlined align-center">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input style="border-radius: 20px; border: 1px solid #ccc;" id="search" name="search" type="search" placeholder="Search" value="">
|
||||
</div>
|
||||
<div class="col s3">
|
||||
<a class="btn waves-effect waves-light center-align right tooltipped" data-position="bottom" data-tooltip="Open up filter options." style="margin-top: 5px;" onclick="hideFilters()"><i class="material-icons">tune</i></a>
|
||||
<a class="btn waves-effect waves-light center-align right tooltipped green lighten-3 black-text text-darken-2 z-depth-0" data-position="bottom" data-tooltip="Open up filter options." style="margin-right: 5px; margin-top:0px; border-radius: 20px 10px 20px 10px;" onclick="hideFilters()"><i class="material-icons">tune</i></a>
|
||||
</div>
|
||||
<div class="col s12 hide" id="filter_options">
|
||||
<div class="row">
|
||||
<div class="col s12 hide" id="filter_options" style="padding: 20px">
|
||||
<!-- This is for basic views -->
|
||||
<div class="row center">
|
||||
<div class="col s12">
|
||||
<p>Change Views</p>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group3" type="radio" checked onclick="changeView(0)"/>
|
||||
<span>All</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group3" type="radio" onclick="changeView(1)"/>
|
||||
<span>Non Zero Items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s12 divider"></div>
|
||||
</div>
|
||||
<!-- This is for sorting values -->
|
||||
<div class="row center">
|
||||
<div class="col s12">
|
||||
<p>Sort Items By</p>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group2" type="radio" onclick="changeSort(0)"/>
|
||||
<span>Barcode</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group2" type="radio" checked onclick="changeSort(1)"/>
|
||||
<span>Item Name</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group2" type="radio" onclick="changeSort(2)"/>
|
||||
<span>Quantity on Hand</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s12 divider"></div>
|
||||
</div>
|
||||
<!-- Set the number of items -->
|
||||
<div class="row center">
|
||||
<div class="col s12">
|
||||
<p>Item Limit</p>
|
||||
<p>Set Items Per Page</p>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" checked onclick="changeLimit(25)"/>
|
||||
<span>25 items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" onclick="changeLimit(50)"/>
|
||||
<span>50 items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" onclick="changeLimit(75)"/>
|
||||
<span>75 itesm</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" onclick="changeLimit(100)"/>
|
||||
<span>100 items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" onclick="changeLimit(150)"/>
|
||||
<span>150 items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s6 m4 l2">
|
||||
<label>
|
||||
<input name="group1" type="radio" onclick="changeLimit(200)"/>
|
||||
<span>200 items</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s12 divider"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="collection" id="collection_list">
|
||||
<div class="col s12 z-depth-0">
|
||||
<div class="z-depth-0" id="cards">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 center" id="pagination_list">
|
||||
<ul class="pagination">
|
||||
<li id="first" class="waves-effect"><a><i class="material-icons">first_page</i></a></li>
|
||||
<li id="back" class="waves-effect"><a><i class="material-icons">chevron_left</i></a></li>
|
||||
<li id="current_page" class="flow-text">page_number</li>
|
||||
<li id="forward" class="waves-effect"><a><i class="material-icons">chevron_right</i></a></li>
|
||||
<li id="last" class="waves-effect"><a><i class="material-icons">last_page</i></a></li>
|
||||
<li id="first" class="waves-effect hand-pointer"><a class="green lighten-3" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px;"><i class="material-icons">first_page</i></a></li>
|
||||
<li id="back" class="waves-effect hand-pointer" ><a class="green lighten-3" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px;"><i class="material-icons">chevron_left</i></a></li>
|
||||
<li id="current_page" style="padding-top: 7px; padding-left: 5px; padding-right: 5px; font-size: 18px;">page_number</li>
|
||||
<li id="forward" class="waves-effect hand-pointer"><a class="green lighten-3" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px;"><i class="material-icons">chevron_right</i></a></li>
|
||||
<li id="last" class="waves-effect hand-pointer"><a class="green lighten-3" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px;"><i class="material-icons">last_page</i></a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed-action-btn">
|
||||
<a class="btn-floating btn-large">
|
||||
<i class="large material-icons">more_vert</i>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a class="btn-floating blue darken-1"><i class="material-icons">playlist_add</i></a></li>
|
||||
<li><a class="btn-floating green darken-1"><i class="material-icons">download</i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
let current_page = 1
|
||||
let end_page = 10
|
||||
let sort_order = 1
|
||||
let view = 0
|
||||
let limit = 50
|
||||
let filter_state = "hidden"
|
||||
let searchText = ""
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var elems = document.querySelectorAll('.collapsible');
|
||||
var instances = M.Collapsible.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var elems = document.querySelectorAll('.fixed-action-btn');
|
||||
var instances = M.FloatingActionButton.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
update_list()
|
||||
});
|
||||
@ -108,6 +207,10 @@
|
||||
url.searchParams.append('page', current_page);
|
||||
url.searchParams.append('limit', limit);
|
||||
url.searchParams.append('search_text', searchText);
|
||||
url.searchParams.append('sort_order', sort_order);
|
||||
url.searchParams.append('view', view);
|
||||
|
||||
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
@ -127,24 +230,79 @@
|
||||
document.getElementById('last').classList.add("waves-effect")
|
||||
};
|
||||
|
||||
const collection = document.getElementById('collection_list');
|
||||
collection.style = "border: 0px; gap: 12px;"
|
||||
while(collection.firstChild){
|
||||
collection.removeChild(collection.firstChild);
|
||||
}
|
||||
//<ul class="collapsible">
|
||||
// <li>
|
||||
// <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
|
||||
//<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
|
||||
// </li>
|
||||
|
||||
//</ul>
|
||||
|
||||
const cards = document.getElementById("cards")
|
||||
const dummy_div = document.createElement('div')
|
||||
const list_collapsible = document.createElement('ul')
|
||||
list_collapsible.classList.add("collapsible")
|
||||
list_collapsible.classList.add("popout")
|
||||
list_collapsible.style = "background: white;"
|
||||
|
||||
data.items.forEach(item => {
|
||||
const collection_item = document.createElement('a');
|
||||
collection_item.classList.add('collection-item');
|
||||
collection_item.classList.add('truncate');
|
||||
|
||||
|
||||
collection_item.href = `/getItem?id=${item[0]}`
|
||||
collection_item.style = "border-radius: 20px; border: 1px solid #ccc; margin-top: 5px;"
|
||||
let qty = item[18]
|
||||
let roundedQty = qty.toFixed(2)
|
||||
collection_item.innerHTML = `${item[2]}<span class="badge hide-on-small-only indigo lighten-4" style="border-radius: 20px;" data-badge-caption="">${roundedQty}</span>`;
|
||||
collection.appendChild(collection_item);
|
||||
})
|
||||
var list_item = document.createElement('li')
|
||||
list_item.classList.add("z-depth-0")
|
||||
list_item.style = "background: white;"
|
||||
|
||||
var header = document.createElement("div")
|
||||
header.classList.add("collapsible-header")
|
||||
header.style = "box-shadow: none !important; background: white; border: 1px solid rgb(150 150 150 / 30%); border-radius: 10px 10px 0px 0px;"
|
||||
header.innerHTML = `<i class='material-symbols-outlined'>grocery</i>${item[2]}
|
||||
<span class="badge green lighten-4 black-text text-darken-2 z-depth-0" style="border-radius: 5px;">Qty: ${roundedQty}</span>`
|
||||
|
||||
var body = document.createElement('div')
|
||||
body.classList.add("collapsible-body")
|
||||
body.style = "box-shadow: none !important; background: rgb(0 128 0 / 10%); border: 1px solid rgb(150 150 150 / 30%); border-radius: 0px 0px 10px 10px;"
|
||||
|
||||
var description = document.createElement('div')
|
||||
description.classList.add("col")
|
||||
description.classList.add("s12")
|
||||
description.innerHTML = `
|
||||
<span>Lorem ipsum dolor sit amet. This is a description for ${item[2]}</span>
|
||||
<div class="divider s12" style="margin-bottom: 5px; margin-top: 5px;"></div>`
|
||||
var button_group = document.createElement('div')
|
||||
button_group.classList.add("row")
|
||||
button_group.style = "margin-bottom: 0px; padding-bottom: 0px;"
|
||||
button_group.innerHTML = `
|
||||
<div class="col s12" style="align-items: center;">
|
||||
<a class="btn right green lighten-3 black-text text-darken-2 z-depth-0 tooltipped" data-position="bottom" data-tooltip="Edit Item" style="display: inline-flex; border-radius: 20px 10px 20px 10px;">
|
||||
<i class='material-icons'>edit</i>
|
||||
</a>
|
||||
<a class="btn right green lighten-3 black-text text-darken-2 z-depth-0 tooltipped" data-position="left" data-tooltip="Transactions" style="display: inline-flex; margin-right: 5px; margin-top:0px; border-radius: 20px 10px 20px 10px;">
|
||||
<i class='material-icons'>list_alt</i>
|
||||
</a>
|
||||
</div>`
|
||||
|
||||
body.appendChild(description)
|
||||
body.appendChild(button_group)
|
||||
|
||||
list_item.appendChild(header)
|
||||
list_item.appendChild(body)
|
||||
|
||||
list_collapsible.appendChild(list_item)
|
||||
});
|
||||
|
||||
dummy_div.appendChild(list_collapsible)
|
||||
|
||||
cards.innerHTML = dummy_div.innerHTML
|
||||
|
||||
var elems = document.querySelectorAll('.collapsible');
|
||||
var instances = M.Collapsible.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
var elems = document.querySelectorAll('.tooltipped');
|
||||
var instances = M.Tooltip.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
|
||||
document.getElementById("current_page").innerHTML = `${String(current_page)} / ${String(end_page)}`
|
||||
})
|
||||
|
||||
@ -157,6 +315,16 @@
|
||||
update_list()
|
||||
};
|
||||
|
||||
function changeSort(order){
|
||||
sort_order = order
|
||||
update_list()
|
||||
}
|
||||
|
||||
function changeView(view_num){
|
||||
view = view_num
|
||||
update_list()
|
||||
}
|
||||
|
||||
function hideFilters(){
|
||||
if (filter_state == "hidden"){
|
||||
document.getElementById("filter_options").classList.remove("hide");
|
||||
|
||||
108
templates/workshop.html
Normal file
108
templates/workshop.html
Normal file
@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
|
||||
<title>Workshop</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@materializecss/materialize@2.0.3-alpha/dist/css/materialize.min.css" />
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/@materializecss/materialize@2.0.3-alpha/dist/js/materialize.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="section">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="row">
|
||||
<div class="col s12 m9" style="background-color: whitesmoke;">
|
||||
<p class="flow-text" style="text-align: center; padding: 10px;"> Welcome to you personalized workshop, this is where you can add/create/modify
|
||||
alot of the items and functions in your site. These modals will walk you through what basic info you will need
|
||||
in order to further expand on your site.</p>
|
||||
</div>
|
||||
<div class="col s12 m3" style="background-color: aliceblue;">
|
||||
<div class="col s6 m6 m-2">
|
||||
<a class="btn elevated green modal-trigger" href="#modal1" style="width: 100%;">Add Group</a>
|
||||
</div>
|
||||
<div class="col s6 m6 m-2">
|
||||
<button class="btn elevated orange" style="width: 100%;">Add Item</button>
|
||||
</div>
|
||||
<div class="col s6 m6 m-2">
|
||||
<button class="btn elevated blue" style="width: 100%;">Add Shopping List</button>
|
||||
</div>
|
||||
<div class="col s6 m6 m-2">
|
||||
<button class="btn elevated purple" style="width: 100%;">Add Recipe</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal1" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Adding a Group...</h4>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel">
|
||||
<span class="blue-text">Groups are internal "grouping" of items that can be of the same type, tag, process, etc. The point of them is that you
|
||||
can keep track of all of one thing in a list for quick reference.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 input-field outlined p-2">
|
||||
<input id="group_name" type="text" placeholder=" " maxlength="64">
|
||||
<label for="group_name">Group Name</label>
|
||||
<!--<span class="supporting-text">Supporting Text</span>-->
|
||||
</div>
|
||||
<div class="input-field col s12 m6 p-2">
|
||||
<select id="group_type">
|
||||
<option value="plain" selected>Plain Group</option>
|
||||
<option value="exclusive">Exclusive Group</option>
|
||||
<option value="inclusive">Inclusive Group</option>
|
||||
</select>
|
||||
<label for="group_type">Group Type</label>
|
||||
</div>
|
||||
<div class="input-field col s12 p-2">
|
||||
<textarea id="group_description" class="materialize-textarea" placeholder="A short description for what this group represents..."></textarea>
|
||||
<label for="group_description">Group Description</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a onclick="addGroup()" class="waves-effect btn">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var elems = document.querySelectorAll('.modal');
|
||||
var instances = M.Modal.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var elems = document.querySelectorAll('select');
|
||||
var instances = M.FormSelect.init(elems, {
|
||||
// specify options here
|
||||
});
|
||||
});
|
||||
|
||||
function addGroup(){
|
||||
var name = document.getElementById("group_name").value
|
||||
var description = document.getElementById("group_description").value
|
||||
var type = document.getElementById("group_type").value
|
||||
|
||||
const url = new URL('/addGroup', window.location.origin);
|
||||
url.searchParams.append('name', name);
|
||||
url.searchParams.append('description', description);
|
||||
url.searchParams.append('type', type);
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
||||
@ -4,6 +4,9 @@ app = Flask(__name__)
|
||||
|
||||
app.register_blueprint(api.database_api)
|
||||
|
||||
@app.route("/workshop")
|
||||
def workshop():
|
||||
return render_template("workshop.html")
|
||||
|
||||
@app.route("/")
|
||||
def home():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user