454 lines
22 KiB
HTML
454 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" dir="ltr">
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
|
|
<title>My Pantry - Groups</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(177 156 217 / 30%); /* Outline color */
|
|
background-color: rgb(177 156 217 / 30%); /* Fill color */
|
|
}
|
|
header, main, footer, body {
|
|
padding-left: 300px;
|
|
}
|
|
|
|
@media only screen and (max-width : 992px) {
|
|
header, main, footer, body {
|
|
padding-left: 0;
|
|
}
|
|
}
|
|
.dropdown-disabled {
|
|
pointer-events: none;
|
|
opacity: 0.5; /* or your desired degree of transparency */
|
|
}
|
|
</style>
|
|
<!-- NAVBAR -->
|
|
<div class="navbar-fixed">
|
|
<nav class="purple lighten-4 text-black z-depth-0">
|
|
<div class="nav-wrapper">
|
|
<ul id="nav-mobile" class="left hide-on-med-and-down black-text">
|
|
<li><a class="dropdown-trigger black-text" data-target="dropdown1">Current Site > {{current_site}}<i class="material-icons right">arrow_drop_down</i></a></li>
|
|
<li><a href="/items" class="black-text">Site Items</a></li>
|
|
<li class="active"><a href="/groups" class="black-text">Site Groups</a></li>
|
|
<li><a href="/shopping-lists" class="black-text">Site Shopping Lists</a></li>
|
|
<li><a href="/receipts" class="black-text">Site Receipts</a></li>
|
|
</ul>
|
|
<ul class="right">
|
|
<li><a class="dropdown-trigger hide-on-med-and-down black-text" data-target="username_dropdown">{{username}}<i class="material-icons right">arrow_drop_down</i></a></li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
<ul id='dropdown1' class='dropdown-content'>
|
|
{% for site in sites %}
|
|
<li><button class="btn transparent black-text z-depth-0" onclick="changeSite('{{ site }}')">{{site}}</button></li>
|
|
{% endfor %}
|
|
</ul>
|
|
<ul id='username_dropdown' class='dropdown-content'>
|
|
<li><a href="/profile" class="hide-on-med-and-down black-text">Profile</a></li>
|
|
{% if system_admin == True %}
|
|
<li><a href="/admin" class="hide-on-med-and-down black-text">Administration</a></li>
|
|
{% endif %}
|
|
<li><a href="/logout" class="hide-on-med-and-down black-text">Logout</a></li>
|
|
</ul>
|
|
<body>
|
|
<div class="container section" style="padding-bottom: 72px;">
|
|
<div class="row">
|
|
<!-- menu button, search bar, filters button -->
|
|
<div class="row col s12">
|
|
<div class="col-s3">
|
|
<a href="#" data-target="slide-out" class="sidenav-trigger hide-on-large-only left"><i class="material-icons">menu</i></a>
|
|
</div>
|
|
<div class="col s6 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 Items" value="">
|
|
</div>
|
|
<div class="col s3">
|
|
<a class="btn waves-effect waves-light center-align right tooltipped purple lighten-4 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>
|
|
<div class="col s12 hide" id="filter_options" style="padding: 20px">
|
|
<!-- Set the number of items -->
|
|
<div class="row center">
|
|
<div class="col s12">
|
|
<p>Set Items Per Page</p>
|
|
</div>
|
|
<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 s6 m4 l2">
|
|
<label>
|
|
<input name="group1" type="radio" onclick="changeLimit(50)"/>
|
|
<span>50 items</span>
|
|
</label>
|
|
</div>
|
|
<div class="col s6 m4 l2">
|
|
<label>
|
|
<input name="group1" type="radio" onclick="changeLimit(75)"/>
|
|
<span>75 itesm</span>
|
|
</label>
|
|
</div>
|
|
<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 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 hand-pointer"><a class="purple lighten-4" 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="purple lighten-4" 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="purple lighten-4" 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="purple lighten-4" 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 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 modal-trigger" href="#modal1"><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>
|
|
|
|
<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 purple lighten-4">
|
|
<span>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. There is three pieces of key information needed in order to
|
|
create a group; a name, a type, and a basic description.
|
|
<br><br>There are two types of groups you can create:
|
|
<br><br>
|
|
<b>Plain</b> - This group has no other extra features beyond being a place to keep a bunch of items categorized.
|
|
<br><br>
|
|
<b>Calculated</b> - This group will act a a substitutive group. The QOH of each item will be calculated together for you and when added to a
|
|
recipe the group will act as if the items can be used in place of each other.
|
|
<br><br>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="col s12 m6 input-field p-2">
|
|
<input id="group_name" type="text" placeholder=" " maxlength="64">
|
|
<label for="group_name">Group Name</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 p-2">
|
|
<select id="group_type">
|
|
<option value="plain" selected>Plain Group</option>
|
|
<option value="calculated">Calculated</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>
|
|
let current_page = 1
|
|
let end_page = 10
|
|
let limit = 50
|
|
let filter_state = "hidden"
|
|
let site = {{ current_site|tojson }}
|
|
|
|
|
|
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() {
|
|
var elems = document.querySelectorAll('.dropdown-trigger');
|
|
var instances = M.Dropdown.init(elems, {
|
|
alignment: 'right',
|
|
});
|
|
});
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
update_list()
|
|
});
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var elems = document.querySelectorAll('.modal');
|
|
var instances = M.Modal.init(elems, {
|
|
// specify options here
|
|
});
|
|
M.AutoInit();
|
|
});
|
|
|
|
async function changeSite(new_site){
|
|
console.log(`current_site: ${site}`)
|
|
console.log(`new site: ${new_site}`)
|
|
site = new_site
|
|
console.log(`current_site: ${site}`)
|
|
const url = new URL('/changeSite', window.location.origin);
|
|
url.searchParams.append('site', site)
|
|
await fetch(url)
|
|
location.reload();
|
|
}
|
|
|
|
function update_list(){
|
|
if (current_page === 1){
|
|
document.getElementById('back').classList.add("disabled")
|
|
document.getElementById('back').classList.remove("waves-effect")
|
|
document.getElementById('first').classList.add("disabled")
|
|
document.getElementById('first').classList.remove("waves-effect")
|
|
|
|
} else {
|
|
document.getElementById('back').classList.remove("disabled")
|
|
document.getElementById('back').classList.add("waves-effect")
|
|
document.getElementById('first').classList.remove("disabled")
|
|
document.getElementById('first').classList.add("waves-effect")
|
|
};
|
|
|
|
const url = new URL('/getGroups', window.location.origin);
|
|
url.searchParams.append('page', current_page);
|
|
url.searchParams.append('limit', limit);
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
|
|
end_page = parseInt(data.end)
|
|
if (current_page === end_page){
|
|
document.getElementById('forward').classList.add("disabled")
|
|
document.getElementById('forward').classList.remove("waves-effect")
|
|
document.getElementById('last').classList.add("disabled")
|
|
document.getElementById('last').classList.remove("waves-effect")
|
|
|
|
} else {
|
|
document.getElementById('forward').classList.remove("disabled")
|
|
document.getElementById('forward').classList.add("waves-effect")
|
|
document.getElementById('last').classList.remove("disabled")
|
|
document.getElementById('last').classList.add("waves-effect")
|
|
};
|
|
|
|
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.groups.forEach(item => {
|
|
let qty = item[5]
|
|
let roundedQty = qty.toFixed(2)
|
|
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; align-items: center;"
|
|
if(item[4] == 'calculated'){
|
|
header.innerHTML = `<i class='material-symbols-outlined'>fastfood</i>${item[1]}
|
|
<span class="badge purple lighten-4 black-text text-darken-2 z-depth-0" style="border-radius: 5px;">QOH: ${roundedQty}</span>`
|
|
} else {
|
|
header.innerHTML = `<i class='material-symbols-outlined'>fastfood</i>${item[1]}`
|
|
}
|
|
|
|
var body = document.createElement('div')
|
|
body.classList.add("collapsible-body")
|
|
body.style = "box-shadow: none !important; background: rgb(177 156 217 / 10%); border: 1px solid rgb(177 156 217 / 30%); border-radius: 0px 0px 10px 10px;"
|
|
|
|
var description = document.createElement('div')
|
|
description.classList.add("col")
|
|
description.classList.add("s12")
|
|
|
|
var span_desc = document.createElement('span')
|
|
span_desc.innerHTML = `<span>${item[2]}</span><div class="divider s12" style="margin-bottom: 5px; margin-top: 5px;"></div>`
|
|
description.appendChild(span_desc)
|
|
|
|
var items_table = document.createElement('table')
|
|
items_table.classList.add("striped")
|
|
items_table.classList.add("hide-on-small-only")
|
|
|
|
|
|
var table_header = document.createElement('thead')
|
|
table_header.innerHTML = `<th>Barcode</th><th>Item Name</th><th>QOH</th>`
|
|
|
|
var table_body = document.createElement('tbody')
|
|
console.log(item[3])
|
|
let items = item[3]
|
|
for (let i=0; i < items.length; i++){
|
|
console.log(items[i])
|
|
var table_row = document.createElement('tr')
|
|
table_row.innerHTML = `
|
|
<td>${items[i][0]}</td>
|
|
<td>${items[i][1]}</td>
|
|
<td>${items[i][2]}</td>
|
|
`
|
|
table_body.appendChild(table_row)
|
|
}
|
|
|
|
items_table.append(table_header)
|
|
items_table.append(table_body)
|
|
|
|
description.appendChild(items_table)
|
|
|
|
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; padding-top:10px;">
|
|
<a class="btn right purple lighten-4 black-text text-darken-2 z-depth-0 tooltipped" data-position="bottom" data-tooltip="Edit Group" style="display: inline-flex; border-radius: 20px 10px 20px 10px;" href="/group/${item[0]}">
|
|
<i class='material-icons'>edit</i>
|
|
</a>
|
|
<a class="btn right purple lighten-4 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;" disabled>
|
|
<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)}`
|
|
})
|
|
|
|
|
|
};
|
|
|
|
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 => {
|
|
M.toast({text: `Adding ${name}: ${data.state}`});
|
|
})
|
|
update_list()
|
|
var elem = document.getElementById("modal1");
|
|
var instance = M.Modal.getInstance(elem);
|
|
instance.close()
|
|
};
|
|
|
|
function changeLimit(limit_value){
|
|
limit = limit_value
|
|
current_page = 1
|
|
update_list()
|
|
};
|
|
|
|
function hideFilters(){
|
|
if (filter_state == "hidden"){
|
|
document.getElementById("filter_options").classList.remove("hide");
|
|
filter_state = "shown";
|
|
} else {
|
|
document.getElementById("filter_options").classList.add("hide");
|
|
filter_state = "hidden";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('forward').addEventListener('click', () =>{
|
|
if (!(document.getElementById("forward").classList.contains("disabled"))){
|
|
current_page++
|
|
update_list();
|
|
};
|
|
});
|
|
|
|
document.getElementById('back').addEventListener('click', () =>{
|
|
if (!(document.getElementById("back").classList.contains("disabled"))){
|
|
current_page--
|
|
update_list();
|
|
}
|
|
});
|
|
|
|
document.getElementById('last').addEventListener('click', () =>{
|
|
if(!(document.getElementById("last").classList.contains("disabled"))){
|
|
current_page = end_page
|
|
update_list();
|
|
};
|
|
});
|
|
|
|
document.getElementById('first').addEventListener('click', () =>{
|
|
if (!(document.getElementById("first").classList.contains("disabled"))){
|
|
current_page = 1
|
|
update_list();
|
|
};
|
|
});
|
|
|
|
</script>
|
|
</html>
|
|
|