Commit de09435c authored by Geovanny's avatar Geovanny

My units page is done

parent 4323eed6
......@@ -38,6 +38,19 @@ userModel.getUserUnits = async(id) => {
return data;
}
userModel.getUserUnitsInverse = async(id) => {
const sql_txt = `SELECT u.*, 0 as unit_level, 0 as elite_flg
FROM units as u
LEFT JOIN (SELECT u.id as uid
FROM users as us
LEFT JOIN users_units as uu ON us.id = uu.user_id
LEFT JOIN units as u ON uu.unit_id = u.id
WHERE us.id = ? ORDER BY u.name ASC) as e ON e.uid = u.id
WHERE e.uid IS NULL;`
const data = await db.con.query(sql_txt, [id]);
return data;
}
userModel.getUserUnit = async(id, term) =>{
const unit_id = parseInt(term, 10);
if(isNaN(unit_id)){
......@@ -139,7 +152,6 @@ userModel.registerUser = async (username, password) =>{
userModel.loginUser = async (username, password) =>{
const hashPassword = await crypto.hash(password);
console.log(username, hashPassword)
const sql_text = 'SELECT id, username from users WHERE username = ? AND password = ?';
const data = await db.con.query(sql_text, [username, hashPassword]);
......
......@@ -43,7 +43,6 @@ router.post('/login', async (context, next) =>{
if(!user){
throw Error('No user found')
}
console.log(user);
context.session.user_id = user.id;
context.response.body = {username: user.username};
context.status = 200;
......@@ -117,6 +116,20 @@ authRouter.get('/units', async (context, next) => {
}
});
authRouter.get('/units-inverse', async (context, next) => {
try{
const data = await userModel.getUserUnitsInverse(context.session.user_id);
if(data.length===1 && data[0].id===null){
throw Error('No Units Found')
}
context.response.body = {units: data};
context.status = 200;
}catch(error){
console.log(error)
context.throw(400, 'No Units Found');
}
});
authRouter.get('/unit/:term', async (context, next) =>{
try{
const data = await userModel.getUserUnit(context.session.user_id, context.params.term)
......@@ -134,7 +147,8 @@ authRouter.post('/unit', async (context, next) => {
if(!body.unit_id){
throw Error('No Unit Id To assign')
}
await userModel.assignUserUnit(context.session.user_id, body.unit_id, body.unit_level);
console.log(body)
await userModel.assignUserUnit(context.session.user_id, body.unit_id, body);
context.status = 204;
}catch(error){
console.log(error);
......
import Sync from "./sync.js"
class MyUnitsController{
constructor(view){
this.view = view;
this.data =[];
this.sync = new Sync();
this.view.addEventListener("unit_tab_change", () => this.getMyUnits())
this.view.addEventListener("add_tab_change", () => this.getUnitsToAdd())
this.view.addEventListener("row_click", (event) => this.changeUnitDetail(event.detail));
this.view.addEventListener("add_unit", (event) => this.addUnit(event.detail));
this.view.addEventListener("modify_unit", (event) => this.modifyUnit(event.detail));
this.getMyUnits();
}
async addUnit(data){
try{
await this.sync.addUnit(data);
alert('Insertion Successful');
this.view.unitAdded();
}catch(error){
console.log(error);
alert('Insertion to update')
}
}
async modifyUnit(data){
try{
await this.sync.modifyUnit(data);
alert('Update Successful')
this.view.unitModified();
}catch(error){
console.log(error);
alert('Failed to update')
}
}
changeUnitDetail(index){
this.view.changeUnitDetail(this.data[index]);
}
async getMyUnits(){
this.data = [];
try{
this.data = (await this.sync.getMyUnits()).units;
}catch(error){
console.log(error);
// alert('Failed to get units')
}
this.view.drawTable(this.data);
}
async getUnitsToAdd(){
this.data = [];
try{
this.data = (await this.sync.getUnitsToAdd()).units;
}catch(error){
console.log(error);
// alert('Failed to get units')
}
this.view.drawTable(this.data);
}
}
export default MyUnitsController;
\ No newline at end of file
class UnitDetailView extends EventTarget{
constructor(){
super();
this.unit = {};
this.element = document.querySelector("unit-detail");
this.fields = {
img : this.element.querySelector(".unit-img"),
name : this.element.querySelector(".unit-name"),
level_input : this.element.querySelector("#level-input"),
elite_input : this.element.querySelector("#elite-ckb"),
button : this.element.querySelector(".unit-button")
}
this.disableInput()
this.fields.button.addEventListener("click", (event) =>{
this.dispatchEvent(new CustomEvent("submit_detail", {detail: this.unit}))
});
this.fields.level_input.addEventListener("input", () =>{
this.unit.unit_level = this.fields.level_input.value;
})
this.fields.elite_input.addEventListener("change", () =>{
this.unit.elite_flg = this.fields.elite_input.checked;
})
}
changeUnit(unit){
this.unit = unit;
if(!this.unit){
this.disableInput();
}else{
this.enableInput();
this.refresh();
}
}
refresh(){
if(this.unit.img){
this.fields.img.src = this.unit.img;
}
this.fields.name.innerText = this.unit.name;
this.fields.level_input.value = this.unit.unit_level;
this.fields.elite_input.checked = this.unit.elite_flg;
}
clean(){
this.fields.img.src = "";
this.fields.name.innerText = "---";
this.fields.level_input.value = 0;
this.fields.elite_input.checked = false;
}
enableInput(){
this.fields.level_input.disabled = false;
this.fields.elite_input.disabled = false;
this.fields.button.disabled = false;
}
disableInput(){
this.fields.level_input.disabled = true;
this.fields.elite_input.disabled = true;
this.fields.button.disabled = true;
}
}
export default UnitDetailView;
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf8"/>
<script src="sugar.js"></script>
<script>Sugar.extend()</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script src="./myunits/module.js" type="module"></script>
<link rel="stylesheet" href="./stylesheets/main.css"/>
</head>
<body>
<nav-placeholder></nav-placeholder>
<script src="/navbar/navbar.js"></script>
<table-component>
<table-wrapper>
<div class="tab tab2">
<button id="my_units" class="tablinks active">My Units</button>
<button id="add_units" class="tablinks">Units to Add</button>
</div>
<table id="units-table" class="display" style="max-width: 500px;"></table>
</table-wrapper>
<unit-detail>
<image class="unit-img"></image>
<div class="unit-name">
---
</div>
<div class="unit-level">
<p>Unit Level:</p>
<input id="level-input" type="number"/>
<p>Elite:</p>
<input id="elite-ckb" type="checkbox"/>
</div>
<div class="unit-button">
<button class="unit-button">Submit</button>
</div>
</unit-detail>
</table-component>
</body>
</html>
import MyUnitsView from "./view.js";
import MyUnitsController from "./controller.js";
if(!document.cookie){
location.replace("/login")
}else{
new MyUnitsController(new MyUnitsView);
}
\ No newline at end of file
class Sync{
async getMyUnits(){
const response = await fetch('/api/user/units');
if(!response.ok){
throw Error('Failed to get units')
}
const response_data = await response.json();
return response_data;
}
async getUnitsToAdd(){
const response = await fetch('/api/user/units-inverse');
if(!response.ok){
throw Error('Failed to get units')
}
const response_data = await response.json();
return response_data;
}
async addUnit(data){
const response = await fetch('/api/user/unit', {
method: "POST",
body: JSON.stringify({unit_id: data.id, unit_level: data.unit_level}),
headers: {
'Content-Type': 'application/json'
}
})
}
async modifyUnit(data){
const response = await fetch(`/api/user/unit/${data.id}`, {
method: "PUT",
body: JSON.stringify({unit_id: data.id, unit_level: data.unit_level}),
headers: {
'Content-Type': 'application/json'
}
})
}
}
export default Sync;
\ No newline at end of file
import UnitTableView from "../units/view.js";
import UnitDetailView from "./detail_view.js"
const unit_columns =[
{title: "ID", term: "id"},
{title: "Name", term: "name"},
{title: "Unit Type", term: "unit_type"},
{title: "Stars", term: "stars"},
{title: "HP", term:"hp"},
{title: "PAP", term:"pap"},
{title: "PD", term:"pd"},
{title: "SAP", term:"sap"},
{title: "SD", term:"sd"},
{title: "BAP", term:"bap"},
{title: "BD", term:"bd"},
{title: "PDF", term:"pdf"},
{title: "SDF", term:"sdf"},
{title: "BDF", term:"bdf"},
{title: "Leadership", term:"ld"},
{title: "Hero Level", term:"hl"},
{title: "Speed", term:"speed"},
{title: "Unit Range", term:"unit_range"},
{title: "Ammo", term:"ammo"},
{title: "Labour", term:"labour"},
{title: "Unit Level", term:"unit_level"},
{title: "Elite", term:"elite_flg"}
]
class MyUnitView extends EventTarget{
constructor(){
super();
this.my_units_add = document.querySelector("#my_units");
this.add_units = document.querySelector("#add_units");
this.unit_table_view = new UnitTableView(unit_columns);
this.unit_detail_view = new UnitDetailView();
this.my_units_tab = true;
this.my_units_add.addEventListener("click", (event) =>{
this.changeTab(event.currentTarget);
this.dispatchEvent(new CustomEvent("unit_tab_change"))
})
this.add_units.addEventListener("click", () =>{
this.changeTab(event.currentTarget);
this.dispatchEvent(new CustomEvent("add_tab_change"))
})
this.unit_table_view.addEventListener("row_click", (event) =>{
this.dispatchEvent(new CustomEvent("row_click", {detail: event.detail}));
})
this.unit_detail_view.addEventListener("submit_detail", (event) =>{
if(this.my_units_tab){
this.dispatchEvent(new CustomEvent("modify_unit", {detail: event.detail}));
}else{
this.dispatchEvent(new CustomEvent("add_unit", {detail: event.detail}));
}
})
}
changeTab(tab){
var i, tablinks;
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
this.my_units_tab = !this.my_units_tab;
tab.className += " active";
}
drawTable(data){
this.unit_table_view.drawTable(data);
}
changeUnitDetail(data){
this.unit_detail_view.changeUnit(data);
}
unitAdded(){
this.unit_detail_view.clean();
this.dispatchEvent(new CustomEvent("add_tab_change"))
}
unitModified(){
this.dispatchEvent(new CustomEvent("unit_tab_change"))
}
}
export default MyUnitView;
\ No newline at end of file
......@@ -7,7 +7,7 @@
<p>Unit</p>
<div class="dropdown-content">
<a href="/units">All Units</a>
<a>My Units</a>
<a href="/myunits">My Units</a>
</div>
</div>
<div class="dropdown">
......
......@@ -15,5 +15,6 @@ body{
}
content-body{
margin-top: 50px;
grid-area: content;
}
\ No newline at end of file
......@@ -27,8 +27,72 @@ table.dataTable.display tbody tr.even{
}
.dataTables_wrapper{
margin-top: 50px;
padding: 10px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.tab2{
text-align: center;
}
table-component{
margin-top: 50px;
grid-area: content;
grid-template:
"table details"
/1fr 200px
;
}
table-wrapper{
grid-area: table;
width: 100%;
display: inline-block;
}
unit-detail{
grid-area: details;
text-align: center;
position: relative;
display: inline-block;
background-color: rgb(27, 27, 27);
height: 600px;
width: 500px;
left: 50%;
margin-top: 50px;
margin-left: -250px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding-top: 20px;
}
.unit-img{
width: 300px;
height: 400px;
background-color: white;
}
.unit-name{
padding-top: 10px;
font-size: 25px;
display: block;
}
.unit-level{
height: 50px;
display: block;
p{
font-size: 15px;
display: inline;
}
}
.unit-elite{
display: inline-block;
}
.unit-button{
display: inline;
button{
left:50%;
text-align: center;
}
}
\ No newline at end of file
......@@ -195,12 +195,76 @@ table.dataTable.display tbody tr.even .sorting_1 {
}
.dataTables_wrapper {
margin-top: 50px;
padding: 10px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.tab2 {
text-align: center;
}
table-component {
margin-top: 50px;
grid-area: content;
grid-template: "table details"/1fr 200px;
}
table-wrapper {
grid-area: table;
width: 100%;
display: inline-block;
}
unit-detail {
grid-area: details;
text-align: center;
position: relative;
display: inline-block;
background-color: #1b1b1b;
height: 600px;
width: 500px;
left: 50%;
margin-top: 50px;
margin-left: -250px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
padding-top: 20px;
}
.unit-img {
width: 300px;
height: 400px;
background-color: white;
}
.unit-name {
padding-top: 10px;
font-size: 25px;
display: block;
}
.unit-level {
height: 50px;
display: block;
}
.unit-level p {
font-size: 15px;
display: inline;
}
.unit-elite {
display: inline-block;
}
.unit-button {
display: inline;
}
.unit-button button {
left: 50%;
text-align: center;
}
body {
font-family: monospace;
background-color: #313131;
......@@ -210,6 +274,7 @@ body {
}
content-body {
margin-top: 50px;
grid-area: content;
}
......
{"version":3,"sourceRoot":"","sources":["../fontawesome/font_awesome.scss","../sass/navbar.scss","../sass/login.scss","../sass/unit.scss","../sass/main.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAmBF;EACI;IAAK;;EACP;IAAO;;;AC1CX;EACI;EACA;EACA;EACA,eACI;EAGJ;;;AAGJ;EAEI;;AACA;EACI;EACA;EAEA;EACA;;;AAIR;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;;AAIR;EACI;;AACA;EACI;;;AAIR;EACI;EACA;EACA;;AACA;EACI;EACA;;;AAIR;EACI;;;AAKA;EACI;;AAEJ;EACI;;;AChFR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EAEA;;AAEA;EACI;EACA;;;AAIN;AACF;EACI;EAEA;EACA;EACA;EACA;EACA;;;AAGF;AACF;EACI;;;AAGF;AACF;EACI;;;AAGF;AACF;EACI;EACA;EACA;EACA;;;AAGJ;EACI;AAA0B;;;AAG9B;AACA;EACI;IAAM;;EACN;IAAI;;;AC3DR;EACI;EACA;;;AAGJ;EACI;;;AAEJ;EACI;;AAEA;EACI;;;AAKR;EACI;;AACA;EACI;;;AAGR;EACI;;;AAGJ;EACI;EACA;EACA;EACA;;;AC3BJ;EACI;EACA;EACA;EACA;EACA,eACI;;;AAKR;EACI","file":"main.css"}
\ No newline at end of file
{"version":3,"sourceRoot":"","sources":["../fontawesome/font_awesome.scss","../sass/navbar.scss","../sass/login.scss","../sass/unit.scss","../sass/main.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAmBF;EACI;IAAK;;EACP;IAAO;;;AC1CX;EACI;EACA;EACA;EACA,eACI;EAGJ;;;AAGJ;EAEI;;AACA;EACI;EACA;EAEA;EACA;;;AAIR;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;;AAIR;EACI;;AACA;EACI;;;AAIR;EACI;EACA;EACA;;AACA;EACI;EACA;;;AAIR;EACI;;;AAKA;EACI;;AAEJ;EACI;;;AChFR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EAEA;;AAEA;EACI;EACA;;;AAIN;AACF;EACI;EAEA;EACA;EACA;EACA;EACA;;;AAGF;AACF;EACI;;;AAGF;AACF;EACI;;;AAGF;AACF;EACI;EACA;EACA;EACA;;;AAGJ;EACI;AAA0B;;;AAG9B;AACA;EACI;IAAM;;EACN;IAAI;;;AC3DR;EACI;EACA;;;AAGJ;EACI;;;AAEJ;EACI;;AAEA;EACI;;;AAKR;EACI;;AACA;EACI;;;AAGR;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EAEA,eACI;;;AAKR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;;AACA;EACI;EACA;;;AAGR;EACI;;;AAEJ;EACI;;AACA;EACI;EACA;;;AC1FR;EACI;EACA;EACA;EACA;EACA,eACI;;;AAKR;EACI;EACA","file":"main.css"}
\ No newline at end of file
......@@ -26,10 +26,74 @@ table.dataTable.display tbody tr.even .sorting_1 {
}
.dataTables_wrapper {
margin-top: 50px;
padding: 10px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.tab2 {
text-align: center;
}
table-component {
margin-top: 50px;
grid-area: content;
grid-template: "table details"/1fr 200px;
}
table-wrapper {
grid-area: table;
width: 100%;
display: inline-block;
}
unit-detail {
grid-area: details;
text-align: center;
position: relative;
display: inline-block;
background-color: #1b1b1b;
height: 600px;
width: 500px;
left: 50%;
margin-top: 50px;
margin-left: -250px;
outline: 1px black solid;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
padding-top: 20px;
}
.unit-img {
width: 300px;
height: 400px;
background-color: white;
}
.unit-name {
padding-top: 10px;
font-size: 25px;
display: block;
}
.unit-level {
height: 50px;
display: block;
}
.unit-level p {
font-size: 15px;
display: inline;
}
.unit-elite {
display: inline-block;
}
.unit-button {
display: inline;
}
.unit-button button {
left: 50%;
text-align: center;
}
/*# sourceMappingURL=unit.css.map */
{"version":3,"sourceRoot":"","sources":["../sass/unit.scss"],"names":[],"mappings":"AACA;EACI;EACA;;;AAGJ;EACI;;;AAEJ;EACI;;AAEA;EACI;;;AAKR;EACI;;AACA;EACI;;;AAGR;EACI;;;AAGJ;EACI;EACA;EACA;EACA","file":"unit.css"}
\ No newline at end of file
{"version":3,"sourceRoot":"","sources":["../sass/unit.scss"],"names":[],"mappings":"AACA;EACI;EACA;;;AAGJ;EACI;;;AAEJ;EACI;;AAEA;EACI;;;AAKR;EACI;;AACA;EACI;;;AAGR;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EAEA,eACI;;;AAKR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;;AACA;EACI;EACA;;;AAGR;EACI;;;AAEJ;EACI;;AACA;EACI;EACA","file":"unit.css"}
\ No newline at end of file
......@@ -19,27 +19,5 @@
<table id="units-table" class="display" style="width: 100%;">
</table>
</content-body>
<script>
function changeTab(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>
const columns =[
{title: "ID"},
{title: "Name"},
{title: "Unit Type"},
{title: "Stars"},
{title: "HP"},
{title: "PAP"},
{title: "PD"},
{title: "SA"},
{title: "SD"},
{title: "BAP"},
{title: "BD"},
{title: "PDF"},
{title: "SDF"},
{title: "BDF"},
{title: "Leadership"},
{title: "Hero Level"},
{title: "Speed"},
{title: "Unit Range"},
{title: "Ammo"},
{title: "Labour"},
const default_columns =[
{title: "ID", term: "id"},
{title: "Name", term: "name"},
{title: "Unit Type", term: "unit_type"},
{title: "Stars", term: "stars"},
{title: "HP", term:"hp"},
{title: "PAP", term:"pap"},
{title: "PD", term:"pd"},
{title: "SAP", term:"sap"},
{title: "SD", term:"sd"},
{title: "BAP", term:"bap"},
{title: "BD", term:"bd"},
{title: "PDF", term:"pdf"},
{title: "SDF", term:"sdf"},
{title: "BDF", term:"bdf"},
{title: "Leadership", term:"ld"},