List states

master
Eirik Th S 2021-06-05 17:31:34 +02:00
parent 86b00423e1
commit 8a656b93e1
7 changed files with 130 additions and 20 deletions

View File

@ -51,6 +51,15 @@ body {
height: 20px;
width: 20px;
}
.iconWrapper .page-link {
padding: 0.35rem 0.4rem;
}
.iconWrapper li img {
margin: 0;
}
.iconWrapper li.active img {
filter: invert(100%);
}
.card-columns .card {
display: inline-block;
@ -96,6 +105,9 @@ body.dollars span.price::after {
.itemAmountWrapper {
clear: both;
}
.itemAmountText {
font-size: 0.9rem;
}
.itemAmount.itemAmountBtn {
-webkit-appearance: none;
-moz-appearance: textfield;

4
icon/basket2.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-basket2" viewBox="0 0 16 16">
<path d="M4 10a1 1 0 0 1 2 0v2a1 1 0 0 1-2 0v-2zm3 0a1 1 0 0 1 2 0v2a1 1 0 0 1-2 0v-2zm3 0a1 1 0 1 1 2 0v2a1 1 0 0 1-2 0v-2z"/>
<path d="M5.757 1.071a.5.5 0 0 1 .172.686L3.383 6h9.234L10.07 1.757a.5.5 0 1 1 .858-.514L13.783 6H15.5a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-.623l-1.844 6.456a.75.75 0 0 1-.722.544H3.69a.75.75 0 0 1-.722-.544L1.123 8H.5a.5.5 0 0 1-.5-.5v-1A.5.5 0 0 1 .5 6h1.717L5.07 1.243a.5.5 0 0 1 .686-.172zM2.163 8l1.714 6h8.246l1.714-6H2.163z"/>
</svg>

After

Width:  |  Height:  |  Size: 600 B

3
icon/check-all.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-all" viewBox="0 0 16 16">
<path d="M8.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L2.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093L8.95 4.992a.252.252 0 0 1 .02-.022zm-.92 5.14.92.92a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 1 0-1.091-1.028L9.477 9.417l-.485-.486-.943 1.179z"/>
</svg>

After

Width:  |  Height:  |  Size: 409 B

3
icon/list-check.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-check" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zM3.854 2.146a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 3.293l1.146-1.147a.5.5 0 0 1 .708 0zm0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 7.293l1.146-1.147a.5.5 0 0 1 .708 0zm0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 0 1 .708-.708l.146.147 1.146-1.147a.5.5 0 0 1 .708 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 709 B

View File

@ -142,6 +142,19 @@ if(!empty($data) && isset($user_id)){
returns($db->error,1);
}
else if($data['plan'] == "setState"){
if(($temp = checkArgs(array("storeID"=>@$data['storeID'], "state"=>@$data['state']))) !== true){
returns("Missing a value: $temp", 1);
}
if( setState($data['storeID'], $data['state']) ){
returns();
}
returns($db->error, 1);
}
else if($data['plan'] == 'spaces'){
$spaces = [];
$getOwnedSpacesSQL = "SELECT space_id, space_name, owner_id userid FROM plan_space s WHERE s.owner_id = $user_id;";
@ -418,3 +431,16 @@ function setItemAmount($storeID, $itemID, $newAmount = 1){
return false;
}
function setState($storeID, $newState){
global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'";
$setStateSQL = "UPDATE plan_store SET state = '$newState' WHERE plan_store_id = ($verifyUserOwnershipSQL);";
if($db->query($setStateSQL)){
return true;
}
return false;
}

View File

@ -1,9 +1,9 @@
/*jshint sub:true, esversion: 6, -W083 */
class Store {
constructor(title, storeID) {
constructor(title, storeID, state) {
this.items = [];
this.state = 'unlocked'; // states: unlocked/locked
this.state = state || 'planning'; // states: planning/shopping/closed
let storeNum = $(".store").length+1;
this.title = title || "Store "+storeNum;
@ -12,13 +12,20 @@ class Store {
let html = "";
html += "<div class='card store' style='width: 25rem; max-width: 90vw;'>";
html += " <div class='card-header'>"+this.title+"</div>";
html += " <div class='iconWrapper' style='float: left;'><img src='../icon/unlock.svg' class='lockStore ariaButton' alt='Lock the store' tabindex=0 role='button' /></div>";
html += " <div class='iconWrapper' style='float: left; margin-top: -35px; margin-left: 1px;'>";
html += " <nav aria-label='State changer'><ul class='pagination'>";
html += " <li class='page-item planningState "+(this.state === 'planning'?"active":"")+"'><span class='page-link'><img src='../icon/list-check.svg' class='ariaButton' alt='Planning state' title='Planning state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " <li class='page-item shoppingState "+(this.state === 'shopping'?"active":"")+"'><span class='page-link'><img src='../icon/basket2.svg' class='ariaButton' alt='Shopping state' title='Shopping state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " <li class='page-item closedState "+(this.state === 'closed'?"active":"")+"'><span class='page-link'><img src='../icon/check-all.svg' class='ariaButton' alt='Closed state' title='Closed state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " </ul></nav>";
html += " </div>";
html += " <div class='iconWrapper'>";
html += " <img src='../icon/pencil-square.svg' class='editStoreName ariaButton' alt='edit name' data-toggle='tooltip' title='Edit store name' tabindex=0 role='button' />";
// html += " <img src='../icon/filter-square.svg' class='sortItems ariaButton' alt='sort items' data-toggle='tooltip' title='Sort items by appearance in store' tabindex=0 role='button' />";
html += " <img src='../icon/x-circle.svg' class='removeStore ariaButton' alt='remove store' data-toggle='tooltip' title='Remove store' tabindex=0 role='button' />";
html += " </div>";
html += " <div class='card-body'>";
html += " <div class='draggable' style='width: 100%; height: 10px; border-width: 1px;'></div> <ul class='list-group list-group-flush'>";
html += " <div class='draggable' style='width: 100%; height: 10px; border-width: 1px;'></div> <ul class='list-group list-group-flush storeItems'>";
html += " <li class='list-group-item emptyList'>No items added</li>";
html += " </ul>";
@ -57,6 +64,25 @@ class Store {
});
this.selector.find('.iconWrapper .page-item').on('click', ev=>{
console.log(ev);
this.selector.find('.page-item.active').removeClass('active');
$(ev.currentTarget).addClass('active');
if($(ev.currentTarget).hasClass('planningState')){
this.setState('planning');
}
else if($(ev.currentTarget).hasClass('shoppingState')){
this.setState('shopping');
}
else if($(ev.currentTarget).hasClass('closedState')){
this.setState('closed');
}
});
/**
this.selector.find('.lockStore').tooltip({title: 'Lock Store'});
this.selector.find('.lockStore').on('click', ev => {
let lockIcon = $(ev.target);
@ -72,7 +98,7 @@ class Store {
lockIcon.tooltip({title: 'Lock Store'});
lockIcon.tooltip('show');
}
});
});*/
this.selector.find('.editStoreName').one('click', ev => { this.editNameFn(ev); });
@ -86,21 +112,39 @@ class Store {
}
lockStore(){
if(this.state === "unlocked"){
this.state = "locked";
this.selector.find('.itemAmountWrapper').slideUp(200);
this.selector.find('.addItemFormWrapper').slideUp(200);
// this.selector.find('.remItem').hide();
if(this.state === "planning"){
this.setState("shopping");
return 1;
}
this.state = "unlocked";
this.selector.find('.itemAmountWrapper').slideDown(200);
this.selector.find('.addItemFormWrapper').slideDown(200);
// this.selector.find('.remItem').show();
this.setState("planning");
return 0;
}
setState(state){
switch (state){
case "planning":
this.state = "planning";
this.selector.find('.itemAmountButtons').slideDown(200);
this.selector.find('.itemAmountText').slideUp(200);
this.selector.find('.addItemFormWrapper').slideDown(200);
break;
case "shopping":
this.state = "shopping";
this.selector.find('.itemAmountButtons').slideUp(200);
this.selector.find('.itemAmountText:not(.oneItem)').slideDown(200);
this.selector.find('.addItemFormWrapper').slideUp(200);
break;
case "closed":
this.state = "closed";
break;
}
ajaxReq({ plan: 'setState', storeID: this.storeID, state: this.state });
}
editNameFn(ev){
if(ev.type === 'click'){
@ -178,8 +222,11 @@ class Store {
html += "<li class='list-group-item draggable' id='item_"+itemID+"' data-itemid='"+itemID+"' draggable='true'>";
html += " <span style='float: left;'>"+text+"</span>";
html += " <div class='priceWrapper'><span class='price'>"+(price*amount).toFixed(2)+"</span>";
html += "<img src='../icon/dash-circle.svg' alt='Remove item' class='remItem ariaButton' data-itemID='"+itemID+"' data-price='"+price+"' style='margin-right: 3px;' tabindex='0' role='button'></div>";
html += " <span class='itemAmountWrapper' style='float: left; padding: 0 10px;'>";
html += " <div class='input-group'>";
html += " <div class='input-group itemAmountButtons'>";
html += " <button class='btn btn-outline-danger itemAmountBtn' type='button'>-</button>";
html += " <input class='form-control itemAmount itemAmountBtn' type='number' value='"+amount+"' min='0' max='99' aria-label='Amount of item' >";
if(price !== 0) {
@ -187,13 +234,14 @@ class Store {
}
html += " <button class='btn btn-outline-success itemAmountBtn' type='button'>+</button>";
html += " </div>";
html += " <div class='itemAmountText "+(amount <= 1?"oneItem":"")+"' style='display: none;'>";
html += " Amount: <span class='itemAmount' style='padding-left: 10px;'>"+amount+"</span>x <span class='price'>" + price.toFixed(2) + "</span>";
html += " </div>";
html += " </span>";
html += " <div class='priceWrapper'><span class='price'>"+(price*amount).toFixed(2)+"</span>";
html += "<img src='../icon/dash-circle.svg' alt='Remove item' class='remItem ariaButton' data-itemID='"+itemID+"' data-price='"+price+"' style='margin-right: 3px;' tabindex='0' role='button'></div>";
html += "</li>";
this.selector.find("ul").append(html);
this.selector.find("ul.storeItems").append(html);
this.selector.find(".emptyList").hide();
this.verify();
return true;
@ -207,12 +255,15 @@ class Store {
remItem(pos, itemID, price){
let that = this;
if(this.state === "planning"){
return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price })
.done(json => {
// console.log("remItem return:", json);
return that.remItemHtml(itemID);
});
}
}
remItemHtml(itemID){
@ -288,6 +339,16 @@ class Store {
if(newValue > 0 && newValue < 100){
amountElem.val(newValue);
that.setItemAmount(itemid, newValue);
let textAmountElem = $(this).parent().parent().find('.itemAmountText');
textAmountElem.find('.itemAmount').html(newValue);
if(newValue === 1){
textAmountElem.addClass('oneItem');
}
else {
textAmountElem.removeClass('oneItem');
}
}
});

View File

@ -41,6 +41,7 @@ CREATE OR REPLACE TABLE plan_store (
`space_id` INT NOT NULL,
`name` varchar(100) NOT NULL,
`created` DATETIME default current_timestamp() NOT NULL,
`state` ENUM('planning', 'shopping', 'closed') default 'planning',
PRIMARY KEY (plan_store_id),
CONSTRAINT plan_store_user_FK FOREIGN KEY (`space_id`) REFERENCES `plan_space`(`space_id`)
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;