Sfoglia il codice sorgente

wip

* basics of user management, card navigation, pass additions, etc.
abetusk 5 anni fa
parent
commit
884d56f27d

+ 47 - 1
main/app/routes.py

@@ -19,7 +19,8 @@ def favicon():
 def api_user():
   field_names = [ "username", "first_name", "last_name",
                   "email", "phone", "address", "city", "state", "zip",
-                  "shipping_name", "shipping_address", "shipping_address",
+                  "shipping_name", "shipping_address", "shipping_city",
+                  "shipping_state", "shipping_country_code", "shipping_country_name",
                   "shipping_zip", "password"];
 
   args = request.args
@@ -88,6 +89,42 @@ def api_card():
 
   return jsonify(res)
 
+@app.route("/api/v1/Pass")
+def api_pass():
+  field_names = [ "logical_card_id",
+                 "nrides_orig", "nrides_remain",
+                 "nday_orig", "nday_expiration",
+                 "rule", "issued", "firstused", "lastused"]
+
+  args = request.args
+  res = {}
+
+  print("api.pass args:", args)
+
+  if 'action' in args:
+    if args['action'] == 'add':
+      api_req = { "action":"add", "function":"Pass" }
+      for f in field_names:
+        if f in args:
+          api_req[f] = args[f]
+
+      print("avpi/v1/Pass send:", api_req)
+
+      res = api.Request(api_req)
+
+      print("got:...", res)
+    elif args['action'] == 'update':
+
+      api_req = { "action":"update", "function":"Pass" }
+      if "user_pass_id" in args:
+        api_req["user_pass_id"] = args["user_pass_id"]
+
+      print("avpi/v1/Pass.update send:", api_req)
+
+      res = api.Request(api_req)
+
+  return jsonify(res)
+
 @app.route("/api/v1/CardInfo")
 def api_card_info():
 
@@ -107,6 +144,15 @@ def api_card_info():
       res = api.Request(api_req)
 
       print("got:...", res)
+  else:
+    api_req = { "function":"CardInfo" }
+    search_fields = ["logical_card_id"]
+    for sf in search_fields:
+      if sf in args:
+        api_req[sf] = args[sf]
+    res = api.Request(api_req)
+
+    print("got:...", res)
 
   return jsonify(res)
 

+ 332 - 15
main/app/static/js/popufare_admin.js

@@ -23,7 +23,10 @@ function _redirect(rel_str) {
 
 function _fill_input_field(fid, fdata) {
   var ele = document.getElementById(fid);
-  if (ele) { ele.value = fdata; }
+  if (ele) {
+    if (ele.nodeName === "DIV") { ele.innerHTML = fdata; }
+    else                        { ele.value = fdata; }
+  }
 }
 
 function _get_input_field(fid) {
@@ -32,21 +35,172 @@ function _get_input_field(fid) {
   return null;
 }
 
+function _get_select(fid) {
+  var ele = document.getElementById(fid);
+  if (ele) {
+    return ele.options[ele.selectedIndex].value;
+  }
+  return null;
+}
+
+function _create_pass_row(dat) {
+  var pass_table = document.getElementById("manage_card:list_passes");
+
+  while (pass_table.firstChild) {
+    pass_table.removeChild(pass_table.lastChild);
+  }
+
+  var row = document.createElement("div");
+  row.classList.add("row");
+  row.classList.add("rowpop");
+  row.classList.add("row-shade");
+
+  var fields_width = [1,1,1,1,2,2,2,2];
+  var fields = ["x", "Type", "Original", "Remain", "Exp.", "Issued", "First Used", "Last Used"];
+  for (var idx=0; idx<fields.length; idx++) {
+    var cell = document.createElement("div");
+    cell.innerHTML = fields[idx];
+    cell.classList.add("col-" + fields_width[idx]);
+    row.appendChild(cell);
+  }
+  pass_table.appendChild(row);
+
+  for (var idx=0; idx<dat["pass"].length; idx++) {
+    var pass_data = dat["pass"][idx];
+
+    var pass_type = "unk";
+    var pass_rule = pass_data["rule"];
+    var pass_orig = "";
+    var pass_remain = "";
+    var pass_exp = "";
+    if (pass_rule.search(/NRIDE/) >= 0) {
+      pass_type = "NRide";
+      pass_orig = pass_data["nrides_orig"];
+      pass_remain = pass_data["nrides_remain"];
+      pass_exp = "";
+    }
+    else if (pass_rule.search(/NDAY/) >= 0) {
+      pass_type = "NDay";
+      pass_orig = pass_data["nday_orig"];
+      pass_remain = "";
+      pass_exp = pass_data["nday_expiration"];
+    }
+    else {
+      pass_type = "Other";
+    }
+
+    var pass_firstused = "";
+    var pass_lastused = "";
+    if ( (typeof pass_data["firstused"] !== "undefined") &&
+         (pass_data["firstused"]) ) {
+      pass_firstused = pass_data["firstused"];
+    }
+
+    if ( (typeof pass_data["lastused"] !== "undefined") &&
+         (pass_data["lastused"]) ) {
+      pass_lastused = pass_data["lastused"];
+    }
+
+    row = document.createElement("div");
+    row.classList.add("row");
+    row.classList.add("rowpop");
+    if ((idx%2)==1) {
+      row.classList.add("row-shade");
+    }
+
+    var cell = document.createElement("div");
+    cell.innerHTML = "x";
+    cell.classList.add("col-" + fields_width[0]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_type;
+    cell.classList.add("col-" + fields_width[1]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_orig;
+    cell.classList.add("col-" + fields_width[2]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_remain;
+    cell.classList.add("col-" + fields_width[3]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_exp;
+    cell.classList.add("col-" + fields_width[4]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_data["issued"];
+    cell.classList.add("col-" + fields_width[5]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_firstused;
+    cell.classList.add("col-" + fields_width[6]);
+    row.appendChild(cell);
+
+    cell = document.createElement("div");
+    cell.innerHTML = pass_lastused;
+    cell.classList.add("col-" + fields_width[7]);
+    row.appendChild(cell);
+
+    pass_table.appendChild(row);
+
+  }
+}
+
 function manage_card_find_fill(data) {
   var fields = [ "logical_card_id", "group", "mag_token", "rfid_token"];
 
+  console.log("manage_card_find_fill:", data);
+
   for (var idx=0; idx<fields.length; idx++) {
     if (fields[idx] in data) {
       _fill_input_field("manage_card:" + fields[idx], data[fields[idx]])
     }
   }
 
+  if ("user" in data) {
+    for (_key in data["user"]) {
+      _fill_input_field("manage_card:" + _key, data["user"][_key]);
+    }
+  }
+
+  if ("pass" in data) {
+    _create_pass_row(data);
+  }
+
+
+  window.history.replaceState({}, document.title, "/manage_card");
+
+}
+
+function manage_card_find_cardid() {
+  var cardid = _get_input_field("manage_card:logical_card_id");
+  console.log("??", cardid);
+  api_req({"api_function":"CardInfo", "ui_function":"manage_card.find", "data": [ ["action","search"], ["logical_card_id",cardid] ] });
 }
 
+function manage_card_find_magstripe() {
+  var mag = _get_input_field("manage_card:mag_token");
+  api_req({"api_function":"CardInfo", "ui_function":"manage_card.find", "data": [ ["action","search"],["mag_token",mag] ] });
+}
+
+function manage_card_find_rfid() {
+  var rfid = _get_input_field("manage_card:rfid_token");
+  api_req({"api_function":"CardInfo", "ui_function":"manage_card.find", "data": [ ["action","search"],["rfid_token",rfid] ] });
+}
+
+
 function manage_user_find_fill(data) {
   var fields = [ "userid", "username", "first_name", "last_name",
                  "email", "phone", "address", "city", "state", "zip",
-                 "shipping_name", "shipping_city", "shipping_address",
+                 "shipping_name", "shipping_city", "shipping_state", "shipping_address",
+                 "shipping_country_code", "shipping_country_name",
                  "shipping_zip", "password"];
 
   if ("user" in data) {
@@ -134,11 +288,18 @@ function api_resp(xhr,extra) {
       var dat = JSON.parse(xhr.responseText);
 
       if (extra["ui_function"] === "manage_card.find") {
+
+        console.log("manage_card.find", dat);
+
         if (("cards"in dat) &&
             (dat.cards.length>0)) {
           manage_card_find_fill(dat.cards[0]);
         }
       }
+      else if (extra["ui_function"] === "manage_card.update") {
+        var cardid = _get_input_field("manage_card:logical_card_id");
+        api_req({"api_function":"CardInfo", "ui_function":"manage_card.find", "data":[["logical_card_id",cardid]]});
+      }
 
       else if (extra["ui_function"] === "create_user.finish") {
         _redirect( "manage_user?" + "action=get&userid=" + dat["userid"])
@@ -149,9 +310,18 @@ function api_resp(xhr,extra) {
         manage_user_find_fill(dat);
       }
       else if (extra["ui_function"] === "manage_user.update") {
-        console.log("manage_user.update resp:", dat)
+        var userid = _get_input_field("manage_user:userid");
+
+        console.log("manage_user.update resp:", dat);
+
+        // After we've associated the card to the user, re-get user information to re-fill
+        // page
+        //
+        api_req({"api_function":"UserInfo", "ui_function":"manage_user.find", "data":[["userid",userid]]});
       }
 
+      //else if (extra["ui_function"] === "manage_card.find") { manage_card_find_fill(dat); }
+
     }
     else {
       console.log("xhr error:", xhr);
@@ -186,9 +356,117 @@ function api_req(ctx) {
 
 }
 
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+
+function manage_card_redirect_manage_user() {
+  var userid = _get_input_field("manage_card:userid");
+  _redirect( "manage_user?" + "action=get&userid=" + userid);
+}
+
+function manage_card_reissue() {
+  var cardid = _get_input_field("manage_card:logical_card_id");
+  _redirect( "reissue?" + "action=get&logical_card_id=" + userid);
+}
+
+function manage_card_add_pass(pass_type) {
+  //var cardid = _get_input_field("manage_card:logical_card_id");
+
+  console.log("manage_card_add_pass:", cardid, pass_type);
+  var dat = {
+    "api_function":"Pass",
+    "ui_function":"manage_card.update",
+    "data": [
+      ["logical_card_id",cardid],
+      ["nrides_orig", 3],
+      ["nrides_remain", 2],
+      ["nday_orig", 5],
+      ["rule", "ORIG-NRIDE"]
+    ]};
+  api_req(dat);
+}
+
+function manage_card_add_pass_nride() {
+  var cardid = _get_input_field("manage_card:logical_card_id");
+  var nrides_orig = _get_input_field("manage_card:pass_nride_other");
+
+  if (nrides_orig.length == 0) {
+    nrides_orig = _get_select("manage_card:pass_nride_orig");
+  }
+
+  var rule = "ORG";
+  rule += "-" + _get_select("manage_card:pass_nride_type");
+  rule += "-" + _get_select("manage_card:pass_nride_region");
+
+  var api_data = {
+    "api_function":"Pass",
+    "ui_function":"manage_card.update",
+    "data" : [
+      ["action","add"],
+      ["logical_card_id" , cardid],
+      ["nrides_orig" , nrides_orig],
+      ["nrides_remain" , nrides_orig],
+      ["rule" , rule]
+    ]
+  };
+
+  console.log(">>nride++", api_data);
+  api_req(api_data);
+}
+
+function manage_card_add_pass_nday() {
+  var cardid = _get_input_field("manage_card:logical_card_id");
+  var nday_orig = _get_input_field("manage_card:pass_nday_other");
+
+  if (nday_orig.length == 0) {
+    nday_orig = _get_select("manage_card:pass_nday_orig");
+  }
+
+  var rule = "ORG";
+  rule += "-" + _get_select("manage_card:pass_nday_type");
+  rule += "-" + _get_select("manage_card:pass_nday_region");
+
+  var api_data = {
+    "api_function":"Pass",
+    "ui_function":"manage_card.update",
+    "data" : [
+      ["action","add"],
+      ["logical_card_id" , cardid],
+      ["nday_orig" , nday_orig],
+      ["rule" , rule]
+    ]
+  };
+
+  console.log(">>nday++", api_data);
+  api_req(api_data);
+}
+
+function manage_card_add_pass_other() {
+}
+
+function manage_card_delete_pass(passid) {
+  var cardid = _get_input_field("manage_card:logical_card_id");
+
+  var dat = {
+    "api_function":"Pass",
+    "ui_function":"manage_card.update",
+    "data": [
+      ["action", "deactivate"],
+      ["logical_card_id",cardid],
+      ["user_pass_id", passid]
+    ]};
+  api_req(dat);
+}
+
+// --------------------------------------
+// --------------------------------------
+
+
 function manage_user_find_userid() {
-  var ele = document.getElementById("manage_user:userid");
-  var userid = ele.value;
+  var userid = _get_input_field("manage_user:userid");
   api_req({"api_function":"UserInfo", "ui_function":"manage_user.find", "data": [ ["userid",userid] ] });
 }
 
@@ -205,7 +483,7 @@ function manage_user_associate_card(data) {
   var ele = document.getElementById("manage_user:logical_card_id");
   var cardid = ele.value;
 
-  var req_dat = { "api_function":"Card", "ui_function":"create_user.update",
+  var req_dat = { "api_function":"Card", "ui_function":"manage_user.update",
                   "data": [
                     ["action","update"],
                     ["userid", userid],
@@ -216,13 +494,18 @@ function manage_user_associate_card(data) {
   
 }
 
+// --------------------------------------
+// --------------------------------------
 
 
 function create_user_process_button() {
   var val_names = ["username", "first_name", "last_name",
                    "email", "phone", "address", "city", "state", "zip",
-                   "shipping_name", "shipping_city", "shipping_address",
-                   "shipping_zip", "password"];
+                   "shipping_name", "shipping_address",
+                   "shipping_city", "shipping_state",
+                   "shipping_country_code", "shipping_country_name",
+                   "shipping_zip",
+                   "password"];
   var req_dat = { "api_function":"User", "ui_function":"create_user.finish",
                   "data":[ ["action","add"]] };
   for (var idx=0; idx<val_names.length; idx++) {
@@ -235,14 +518,23 @@ function create_user_process_button() {
   api_req(req_dat);
 }
 
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+// --------------------------------------
+
+
 function admin_api_init() {
   var ele;
-
   var _func = location.pathname.substring(1);
 
-  if (_func === "creat_user") {
-    ele = document.getElementById("create_user:button_create");
-    if (ele) { ele.onclick = create_user_process_button; }
+  console.log("...init", _func);
+  console.log(window.location.search);
+  var _h = _param2hash(window.location.search);
+
+  if (_func === "create_user") {
+    _attach_button("create_user:button_create", create_user_process_button);
   }
 
   else if (_func === "manage_user") {
@@ -250,10 +542,35 @@ function admin_api_init() {
     _attach_button( "manage_user:button_lookup_username", manage_user_find_username);
     _attach_button( "manage_user:button_associate_card", manage_user_associate_card);
 
-    console.log(window.location.search);
-    var _h = _param2hash(window.location.search);
     if ("userid" in _h) {
-      api_req({"api_function":"User", "ui_function":"manage_user.find", "data":[["action","get"],["userid",_h["userid"]]]});
+      console.log("sending manage_user.find request");
+      api_req({"api_function":"UserInfo", "ui_function":"manage_user.find", "data":[["userid",_h["userid"]]]});
+    }
+  }
+
+  else if (_func === "manage_card") {
+    _attach_button( "manage_card:button_lookup_logical_card_id", manage_card_find_cardid);
+    _attach_button( "manage_card:button_lookup_mag_token", manage_card_find_magstripe);
+    _attach_button( "manage_card:button_lookup_rfid_token", manage_card_find_rfid);
+
+    _attach_button( "manage_card:button_manage_user", manage_card_redirect_manage_user);
+    _attach_button( "manage_card:button_reissue", manage_card_reissue);
+    _attach_button( "manage_card:button_add_pass_nride", manage_card_add_pass_nride);
+    _attach_button( "manage_card:button_add_pass_nday", manage_card_add_pass_nday);
+    _attach_button( "manage_card:button_add_pass_other", manage_card_add_pass_other);
+    _attach_button( "manage_card:button_delete_pass", manage_card_delete_pass);
+
+
+    if ("logical_card_id" in _h) {
+      console.log("sending manage_card.find request");
+      api_req({
+        "api_function":"CardInfo",
+        "ui_function":"manage_card.find",
+        "data": [
+          ["action","search"],
+          ["logical_card_id",_h["logical_card_id"] ]
+        ]
+      });
     }
   }
 

+ 12 - 0
main/app/templates/create_user.html

@@ -91,6 +91,18 @@
               <div class='col-2'> </div>
             </div>
 
+            <div class='row rowpop '>
+              <div class='col-4'> Shipping Country Code</div>
+              <div class='col-6'> <input id='create_user:shipping_country_code' type='text' class='form-control form-control-sm' placeholder=''> </div>
+              <div class='col-2'> </div>
+            </div>
+
+            <div class='row rowpop row-shade'>
+              <div class='col-4'> Shipping Country </div>
+              <div class='col-6'> <input id='create_user:shipping_country_name' type='text' class='form-control form-control-sm' placeholder=''> </div>
+              <div class='col-2'> </div>
+            </div>
+
             <div class='row rowpop '>
               <div class='col-4'> Shipping ZIP </div>
               <div class='col-6'> <input id='create_user:shipping_zip' type='text' class='form-control form-control-sm' placeholder=''> </div>

+ 89 - 71
main/app/templates/manage_card.html

@@ -24,7 +24,7 @@
                 <input id='manage_card:logical_card_id' type='text' class='form-control form-control-sm' placeholder=''>
               </div>
               <div class='col-2'> 
-                <button id='manage_card:button_find_logical_card_id' type='button' class='btn btn-secondary btn-sm'>Find</button>
+                <button id='manage_card:button_lookup_logical_card_id' type='button' class='btn btn-secondary btn-sm'>Find</button>
               </div>
             </div>
 
@@ -48,7 +48,7 @@
                 <input id='manage_card:mag_token' type='text' class='form-control form-control-sm' placeholder=''>
               </div>
               <div class='col-2' >
-                <button type='button' class='btn btn-secondary btn-sm '>Find</button>
+                <button id='manage_card:button_lookup_mag_token' type='button' class='btn btn-secondary btn-sm '>Find</button>
               </div>
             </div>
 
@@ -58,7 +58,7 @@
                 <input id='manage_card:rfid_token' type='text' class='form-control form-control-sm' placeholder=''>
               </div>
               <div class='col-2 '>
-                <button type='button' class='btn btn-secondary btn-sm'>Find</button>
+                <button id='manage_card:button_lookup_rfid_token' type='button' class='btn btn-secondary btn-sm'>Find</button>
               </div>
             </div>
 
@@ -99,6 +99,8 @@
           <!-- and the other half is devoted to user specific information (associated with the card) -->
           <div class='col-5'>
 
+            <input id='manage_card:userid' type='hidden' >
+
             <div class='row row-shade rowpop'>
               <div class='col-5'> Username </div>
               <div id='manage_card:username' class='col-7'> jdoey112 </div>
@@ -150,10 +152,18 @@
               <div id='manage_card:group' class='col-7'> General </div>
             </div>
 
+            <div class='row'>
+              <div class='col-5'>
+                <button id='manage_card:button_manage_user' type='button' class='btn btn-secondary btn-sm'>Manage User</button>
+              </div>
+            </div>
+
           </div>
 
+
         </div>
 
+        <br>
         <br>
         <br>
 
@@ -177,9 +187,9 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>Adult</option>
-                <option>Half</option>
+              <select id='manage_card:pass_nride_type' class='custom-select'>
+                <option value='NRIDE'>Adult</option>
+                <option value='NRIDEH'>Half</option>
               </select>
             </div>
 
@@ -188,9 +198,9 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>Region 0</option>
-                <option>Region 1</option>
+              <select id='manage_card:pass_nride_region' class='custom-select'>
+                <option value='ZON0'>Region 0</option>
+                <option value='ZON1'>Region 1</option>
               </select>
             </div>
 
@@ -199,12 +209,12 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>1</option>
-                <option>2</option>
-                <option>5</option>
-                <option>10</option>
-                <option>25</option>
+              <select id='manage_card:pass_nride_orig' class='custom-select'>
+                <option value='1'>1</option>
+                <option value='2'>2</option>
+                <option value='5'>5</option>
+                <option value='10'>10</option>
+                <option value='25'>25</option>
               </select>
             </div>
 
@@ -216,12 +226,12 @@
               <div class='input-group-prepend'>
                 <span class='input-group-text'>Other</span>
               </div>
-              <input type='text' class='form-control form-control-sm' placeholder=''>
+              <input id='manage_card:pass_nride_other' type='text' class='form-control form-control-sm' placeholder=''>
             </div>
           </div>
 
           <div class='col-1'>
-            <button type='button' class='btn btn-secondary btn-sm'>Add</button>
+            <button id='manage_card:button_add_pass_nride' type='button' class='btn btn-secondary btn-sm'>Add</button>
           </div>
 
         </div>
@@ -231,9 +241,9 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>Adult</option>
-                <option>Half</option>
+              <select id='manage_card:pass_nday_type' class='custom-select'>
+                <option value='NDAY'>Adult</option>
+                <option value='NDAYH'>Half</option>
               </select>
             </div>
 
@@ -242,9 +252,9 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>Region 0</option>
-                <option>Region 1</option>
+              <select id='manage_card:pass_nday_region' class='custom-select'>
+                <option value='ZON0'>Region 0</option>
+                <option value='ZON1'>Region 1</option>
               </select>
             </div>
 
@@ -253,12 +263,12 @@
           <div class='col-2'>
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>1</option>
-                <option>2</option>
-                <option>5</option>
-                <option>10</option>
-                <option>25</option>
+              <select id='manage_card:pass_nday_orig' class='custom-select'>
+                <option value='1'>1</option>
+                <option value='2'>2</option>
+                <option value='5'>5</option>
+                <option value='10'>10</option>
+                <option value='25'>25</option>
               </select>
             </div>
 
@@ -269,13 +279,13 @@
               <div class='input-group-prepend'>
                 <span class='input-group-text'>Other</span>
               </div>
-              <input type='text' class='form-control form-control-sm' placeholder=''>
+              <input id='manage_card:pass_nday_other' type='text' class='form-control form-control-sm' placeholder=''>
             </div>
 
           </div>
 
           <div class='col-1'>
-            <button type='button' class='btn btn-secondary btn-sm'>Add</button>
+            <button id='manage_card:button_add_pass_nday' type='button' class='btn btn-secondary btn-sm'>Add</button>
           </div>
 
         </div>
@@ -285,17 +295,17 @@
           <div class='col-9'> 
 
             <div class='input-group input-group-sm mb-3'>
-              <select class='custom-select'>
-                <option>Custom Pass 0</option>
-                <option>Custom Pass 1</option>
-                <option>Custom Pass 2</option>
+              <select id='manage_card:pass_other' class='custom-select'>
+                <option id='TEST-ORG-OTHER'>Custom Pass 0</option>
+                <option id='TEST-ORG-OTHER1'>Custom Pass 1</option>
+                <option id='TEST-ORG-OTHER2'>Custom Pass 2</option>
               </select>
             </div>
 
           </div>
 
           <div class='col-1'>
-            <button type='button' class='btn btn-secondary btn-sm'>Add</button>
+            <button id='manage_card:button_add_pass_other' type='button' class='btn btn-secondary btn-sm'>Add</button>
           </div>
 
         </div>
@@ -308,46 +318,54 @@
 
 
         <!-- pre-existing pass management where they can be re-ordered and deleted -->
-        <div class='row row-shade rowpop'>
-          <div class='col-3'>
-            <button type='button' class='btn btn-secondary btn-sm'>check / uncheck all</button>
+        <div class='row'>
+
+          <div id='manage_card:list_passes_buttons' class='col-12'>
+            <div class='row row-shade rowpop'>
+              <div class='col-3'>
+                <button type='button' class='btn btn-secondary btn-sm'>check / uncheck all</button>
+              </div>
+              <div class='col-7'> </div>
+              <div class='col-2'> <button type='button' class='btn btn-secondary btn-sm'>delete</button> </div>
+            </div>
           </div>
-          <div class='col-7'> </div>
-          <div class='col-2'> <button type='button' class='btn btn-secondary btn-sm'>delete</button> </div>
-        </div>
 
-        <div class='row row-shade rowpop' >
-          <div class='col-1'> Type </div>
-          <div class='col-1'> Original </div>
-          <div class='col-1'> Remain </div>
-          <div class='col-2'> Exp. </div>
-          <div class='col-2'> Issued </div>
-          <div class='col-2'> First Used </div>
-          <div class='col-3'> Last Used </div>
-        </div>
+          <div id='manage_card:list_passes' class='col-12'>
 
-        <div class='row rowpop' >
-          <div class='col-1'> NRide </div>
-          <div class='col-1'> 5 </div>
-          <div class='col-1'> 3 </div>
-          <div class='col-2'> -  </div>
-          <div class='col-2'> 2020-01-20 </div>
-          <div class='col-2'> 2020-01-20 </div>
-          <div class='col-3'> 2020-01-25 13:10 </div>
-        </div>
+            <div class='row row-shade rowpop' >
+              <div class='col-1'> Type </div>
+              <div class='col-1'> Original </div>
+              <div class='col-1'> Remain </div>
+              <div class='col-2'> Exp. </div>
+              <div class='col-2'> Issued </div>
+              <div class='col-2'> First Used </div>
+              <div class='col-3'> Last Used </div>
+            </div>
 
-        <div class='row rowpop' >
-          <div class='col-1'> NDay </div>
-          <div class='col-1'> 10 </div>
-          <div class='col-1'> 2 </div>
-          <div class='col-2'> 2020-04-01 </div>
-          <div class='col-2'> 2020-01-20 </div>
-          <div class='col-2'> 2020-01-20 </div>
-          <div class='col-3'> 2020-01-25 13:10 </div>
-        </div>
+            <div class='row rowpop' >
+              <div class='col-1'> NRide </div>
+              <div class='col-1'> 5 </div>
+              <div class='col-1'> 3 </div>
+              <div class='col-2'> -  </div>
+              <div class='col-2'> 2020-01-20 </div>
+              <div class='col-2'> 2020-01-20 </div>
+              <div class='col-3'> 2020-01-25 13:10 </div>
+            </div>
+
+            <div class='row rowpop' >
+              <div class='col-1'> NDay </div>
+              <div class='col-1'> 10 </div>
+              <div class='col-1'> 2 </div>
+              <div class='col-2'> 2020-04-01 </div>
+              <div class='col-2'> 2020-01-20 </div>
+              <div class='col-2'> 2020-01-20 </div>
+              <div class='col-3'> 2020-01-25 13:10 </div>
+            </div>
 
-      <!-- end of col-10 -->
-      </div>
+          </div>
+
+        <!-- end of col-12 -->
+        </div>
 
       <!-- side padding -->
       <div class='col-2'> </div>

+ 12 - 0
main/app/templates/manage_user.html

@@ -103,6 +103,18 @@
               <div class='col-2'> </div>
             </div>
 
+            <div class='row rowpop row-shade'>
+              <div class='col-4'> Country Code </div>
+              <div class='col-6'> <input id='manage_user:shipping_country_code' type='text' class='form-control form-control-sm' placeholder=''> </div>
+              <div class='col-2'> </div>
+            </div>
+
+            <div class='row rowpop'>
+              <div class='col-4'> Country Name</div>
+              <div class='col-6'> <input id='manage_user:shipping_country_name' type='text' class='form-control form-control-sm' placeholder=''> </div>
+              <div class='col-2'> </div>
+            </div>
+
             <div class='row rowpop row-shade'>
               <div class='col-4'> Shipping ZIP </div>
               <div class='col-6'> <input id='manage_user:shipping_zip' type='text' class='form-control form-control-sm' placeholder=''> </div>

+ 2 - 0
main/main.py

@@ -2,6 +2,8 @@
 #
 
 from app import app
+import logging
+logging.basicConfig(level=logging.DEBUG)
 
 if __name__ == '__main__':
   app.run()