Commit 445ba9bf authored by Geovanny's avatar Geovanny

House creation and update done

parent 6e88953c
......@@ -13,9 +13,14 @@ model.getAll = async () => {
return data;
}
model.getHouse = async() => {
// implement getting house details
throw Error('Not Implemented');
model.getHouse = async(house_id) => {
const sql_text = `SELECT h.*, u.username as liege_username
FROM houses as h
LEFT JOIN users as u on u.id = h.liege_id
WHERE h.id = ? LIMIT 1`;
const data = await db.con.query(sql_text, house_id);
return data[0];
}
model.insertHouse = async(body, liege_id) => {
......
......@@ -258,9 +258,10 @@ authRouter.delete('/leave-house', async (context, next) => {
}
});
router.get('/', async (context, next) => {
authRouter.get('/', async (context, next) => {
hasHouse(context);
try{
const data = await houseModel.getHouse();
const data = await houseModel.getHouse(context.user.house_id);
context.response.status = 200;
context.response.body = data;
}catch(error){
......@@ -288,13 +289,16 @@ authRouter.post('/', async (context, next) => {
});
authRouter.put('/:house_id', async (context, next) => {
console.log('asd')
checkHouse(context);
checkPermissions(context, HOUSE_ROLES.LIEGE)
try{
console.log('dsa')
const body = context.request.body;
if(!body){
throw Error('No params')
}
console.log(body)
await houseModel.modifyHouse(context.user.house_id, body);
context.response.status = 204;
}catch(error){
......
import Sync from "./sync.js";
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
class MyHouseController{
constructor(view){
......@@ -8,6 +34,10 @@ class MyHouseController{
this.permission_level = 1000;
this.members = [];
this.requests = [];
this.house = {};
this.view.addEventListener("create_house", (event) => this.createHouse(event.detail));
this.view.addEventListener("modify_house", (event) => this.modifyHouse(event.detail));
this.view.addEventListener("participation_attemp", (event) => this.attempParticipate(event.detail));
this.view.addEventListener("member_select", (event) => this.selectMember(event.detail));
this.view.addEventListener("modify_member_role", (event) => this.modifyMemberRole(event.detail.member_id, event.detail.role));
......@@ -20,6 +50,30 @@ class MyHouseController{
setInterval(() => {
this.refresh();
}, 10000);
this.view.updateViews(undefined);
}
async createHouse(house){
try{
await this.sync.createHouse(house);
alert('House Created');
this.refresh();
}catch(error){
console.log(error);
alert('Failed to Create House')
}
}
async modifyHouse(house){
try{
await this.sync.modifyHouse(house);
alert('House Modified');
this.refresh();
}catch(error){
console.log(error);
alert('Failed to Modify House')
}
}
async modifyMemberRole(member_id, role){
......@@ -45,6 +99,7 @@ class MyHouseController{
}
async refresh(){
this.getHouse();
this.getParticipation();
this.getMembers();
this.getPermissionLevel();
......@@ -139,6 +194,20 @@ class MyHouseController{
console.log(error);
}
}
async getHouse(){
try{
const house = await this.sync.getHouse();
if(!isEquivalent(this.house, house)){
this.house = house;
this.view.updateViews(house);
}
}catch(error){
this.house = {};
this.view.updateViews();
console.log(error);
}
}
}
export default MyHouseController;
\ No newline at end of file
class HouseView extends EventTarget{
constructor(element){
super();
this.element = element;
this.is_editing = false;
this.modify_btn = this.element.querySelector('#modify_btn');
this.create_btn = this.element.querySelector('#create_btn')
this.edit_btn = this.element.querySelector('#edit_btn');
this.title = this.element.querySelector('#title');
this.house = {};
this.display_fields = {
element: this.element.querySelector('#house_text'),
name: this.element.querySelector('#house_name'),
house_level: this.element.querySelector('#house_level'),
liege_name: this.element.querySelector('#liege_name'),
camp_location: this.element.querySelector('#camp_location'),
// members: this.element.querySelector('.members'),
}
this.edit_fields = {
element: this.element.querySelector('#house_edit'),
name: this.element.querySelector('input#house_name'),
house_level: this.element.querySelector('input#house_level'),
camp_location: this.element.querySelector('input#camp_location'),
// liege_name: this.element.querySelector('input.liege_name'),
// members: this.element.querySelector('input.members'),
}
this.edit_btn.addEventListener("click", () => {
this.toggleEdit();
});
this.create_btn.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("create_house", {detail: {
house_name: this.edit_fields.name.value,
house_level: this.edit_fields.house_level.value,
camp_location: this.edit_fields.camp_location.value,
}}))
});
this.modify_btn.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("modify_house", {detail: {
house_id: this.house.id,
house_name: this.edit_fields.name.value ? this.edit_fields.name.value : this.house.name,
house_level: this.edit_fields.house_level.value ? this.edit_fields.house_level.value : this.house.house_level,
camp_location: this.edit_fields.camp_location.value ? this.edit_fields.camp_location.name.value : this.house.camp_location,
}}))
});
}
selectHouse(house){
this.house = house;
this.toggleView();
}
toggleView(){
this.title.innerText = 'House';
this.refreshText();
this.hideEdit();
this.showText();
this.create_btn.style.display = "none";
}
updatePermissions(permission_level){
if(permission_level<2){
this.edit_btn.style.display = "";
}else{
this.edit_btn.style.display = "none";
}
}
toggleCreate(){
this.title.innerText = 'Create a House';
this.hideText();
this.showEdit();
this.edit_btn.style.display = "none";
this.modify_btn.style.display = "none";
this.create_btn.style.display = "";
}
toggleEdit(){
this.is_editing = !this.is_editing;
this.refresh();
}
refresh(){
if(this.is_editing){
this.hideText();
this.showEdit();
}else{
this.refreshText();
this.hideEdit();
this.showText();
}
}
refreshText(){
this.display_fields.name.innerText = `House Name: ${this.house.house_name}`;
this.display_fields.house_level.innerText = `House Level: ${this.house.house_level}`;
this.display_fields.liege_name.innerText = `Liege: ${this.house.liege_username}`;
this.display_fields.camp_location.innerText = `Camp Location: ${this.house.camp_location}`;
}
showText(){
this.display_fields.element.style.display = "";
}
hideText(){
this.display_fields.element.style.display = "none"
}
showEdit(){
this.edit_fields.element.style.display = "";
this.modify_btn.style.display = "";
}
hideEdit(){
this.edit_fields.element.style.display = "none";
this.modify_btn.style.display = "none";
}
}
export default HouseView;
\ No newline at end of file
......@@ -15,14 +15,44 @@
<nav-placeholder></nav-placeholder>
<script src="/navbar/navbar.js"></script>
<content-body id="my_house">
<div id="area_1">
<house-area>
<div class="table_header">
<p id="title" class="header_title">---</p>
<button id="modify_btn" class="modify_button one" style="display: none;">Update</button>
<button id="create_btn" class="add_button one" style="display: none;">Create</button>
<button id="edit_btn" class="two">Edit</button>
</div>
<div id="house_details">
<div id="house_text">
<span id="house_name">House Name: ---</span>
<span id="house_level">House Level: ---</span>
<span id="liege_name">Liege: ---</span>
<span id="camp_location">Camp Location: ---</span>
</div>
<div id="house_edit" style="display: none;">
<div>
<span>Name:&nbsp;</span>
<input id="house_name" type="text"/>
</div>
<div>
<span>House Level:&nbsp;</span>
<input id="house_level" type="number"/>
</div>
<div>
<span>Camp Location:&nbsp;</span>
<input id="camp_location" type="text"/>
</div>
</div>
</div>
</house-area>
<div id="area_1" style="display: none;">
<war-participation>
<table-wrapper>
<div class="table_header">
<span>Participation:</span>
<button id="yes">Yes</button>
<button id="no">No</button>
<button id="maybe">Maybe</button>
<p class="header_title">Participation:</p>
<button id="yes" class="one">Yes</button>
<button id="no" class="two">No</button>
<button id="maybe" class="three">Maybe</button>
</div>
<table id="data_table" class="display"></table>
</table-wrapper>
......@@ -31,7 +61,7 @@
<table-detail style="display: initial;">
<table-wrapper>
<div class="table_header">
<p>Members</p>
<p class="header_title">Members</p>
</div>
<table id="data_table" class="display"></table>
</table-wrapper>
......@@ -53,18 +83,19 @@
</table-detail>
</members-area>
</div>
<div id="area_2">
<requests-area style="display: none;">
<div id="area_2" style="display: none;">
<requests-area>
<div class="table_header">
<div class="title"><span>House</span></div>
<button id="reject">Reject</button>
<button id="accept">Accept</button>
<!-- <div class="title"><span>House</span></div> -->
<p class="header_title">House</p>
<button id="reject" class="one">Reject</button>
<button id="accept" class="two">Accept</button>
</div>
<table id="data_table" class="display"></table>
</requests-area>
<member-units style="display: none;">
<div class="table_header">
<div class="title"><span>Units</span></div>
<p class="header_title">Units</p>
</div>
<table id="data_table" class="display"></table>
</member-units>
......
class Sync{
async getHouse(){
const response = await fetch("/api/house/");
if(!response.ok){
throw Error('Failed to get requests');
}
const data = await response.json();
return data;
}
async createHouse(house){
const response = await fetch("/api/house", {
method: "POST",
body: JSON.stringify(house),
headers: {
'Content-Type': 'application/json'
}
});
if(!response.ok){
throw Error('Failed to Create House');
}
}
async modifyHouse(house){
const response = await fetch(`/api/house/${house.id}`, {
method: "PUT",
body: JSON.stringify(house),
headers: {
'Content-Type': 'application/json'
}
});
if(!response.ok){
throw Error('Failed to Modify House');
}
}
async getRequests(){
const response = await fetch("/api/house/requests");
......
import HouseView from "./house_view.js";
import ParticipationView from "./participation_view.js";
import MembersView from "./members_view.js";
import RequestsView from "./requests_view.js";
......@@ -8,15 +9,24 @@ class MyHouseController extends EventTarget{
constructor(){
super();
this.house_view = new HouseView(document.querySelector('house-area'));
this.participation_view = new ParticipationView(document.querySelector('war-participation'));
this.members_view = new MembersView(document.querySelector('members-area'));
this.requests_view = new RequestsView(document.querySelector('requests-area'));
this.member_units_view = new MemberUnitsView(document.querySelector('member-units'))
this.area_1 = document.querySelector('#area_1');
this.area_2 = document.querySelector('#area_2');
this.house_view.addEventListener("create_house", (event) => {
this.dispatchEvent(new CustomEvent("create_house", {detail: event.detail}));
});
this.house_view.addEventListener("modify_house", (event) => {
this.dispatchEvent(new CustomEvent("modify_house", {detail: event.detail}));
});
this.participation_view.addEventListener("participation_atempt", (event) => {
this.dispatchEvent(new CustomEvent("participation_attemp", {detail: event.detail}));
});
this.members_view.addEventListener("member_select", (event) => {
this.dispatchEvent(new CustomEvent("member_select", {detail: event.detail}));
});
......@@ -35,6 +45,9 @@ class MyHouseController extends EventTarget{
this.requests_view.addEventListener("reject_request", (event) => {
this.dispatchEvent(new CustomEvent("reject_request", {detail: event.detail}));
});
this.hideArea1();
this.hideArea2();
}
drawParticipationTable(data){
......@@ -62,13 +75,40 @@ class MyHouseController extends EventTarget{
updatePermissions(permission_level){
if(permission_level<2){
this.showArea2();
this.requests_view.show();
this.member_units_view.show();
}else{
this.hideArea2();
this.requests_view.hide();
this.member_units_view.hide();
}
this.members_view.updatePermissions(permission_level);
this.house_view.updatePermissions(permission_level);
}
updateViews(house){
if(!house){
this.hideArea1();
this.hideArea2();
this.house_view.toggleCreate();
}else{
this.showArea1();
this.house_view.selectHouse(house);
}
}
showArea1(){
this.area_1.style.display = "grid";
}
hideArea1(){
this.area_1.style.display = "none";
}
showArea2(){
this.area_2.style.display = "grid";
}
hideArea2(){
this.area_2.style.display = "none";
}
}
......
......@@ -33,10 +33,37 @@
#my_house{
display: grid;
grid-template:
"house_area" 150px
"area-1" 500px
"area-2" 500px
/1fr
;
house-area{
grid-area: house_area;
border: 2px solid black;
#house_details{
width: 100%;
height: 100px;
div{
display: flex;
height: 100%;
span{
margin: auto;
vertical-align: middle;
}
justify-content: space-evenly;
input{
margin: auto;
max-height: 50px;
}
}
}
}
#area_1{
display: grid;
grid-template:
......@@ -50,17 +77,17 @@
war-participation{
grid-area: war-participation;
padding: 10px;
.header_title{
margin-left: 10px;
text-align: left;
}
}
members-area{
grid-area: members;
padding: 10px;
// background-color: blue;
.table_header{
text-align: center;
font-size: 20px;
}
detail{
left: 50%;
height: 350px;
......@@ -129,6 +156,7 @@
}
member-units{
grid-area: member-units;
padding: 10px;
// background-color: green;
.table_header{
......@@ -144,10 +172,39 @@
}
}
.table_header{
text-align: right;
// $positions : 10px, 100px, 200px, 300px;
// @for $i from 1 through length($positions) {
// $pos: nth($positions, $i);
// button:nth-child(#{$i}){
// right: $pos;
// }
// }
$positions: (
"one": 10px,
"two": 110px,
"three": 210px,
"four": 310px
);
@each $starNo, $value in $positions{
button.#{$starNo} {
right: $value;
}
}
button{
color: rgb(204, 204, 204);
position: absolute;
top: 1px;
right: 10px;
}
}
}
.header_title{
text-align: center;
}
\ No newline at end of file
.table_header {
overflow: hidden;
// border: 1px solid #ccc;
position: relative;
background-color: #383838;
border: 1px solid #ccc;
border-bottom: none;
min-height: 50px;
button{
font-family: monospace;
font-size: 20px;
......@@ -108,16 +109,16 @@ detail{
text-align: center;
}
}
.add_button{
background-color: green !important;
border: 2px solid rgb(3, 102, 20);
}
.modify_button{
background-color: rgb(53, 53, 255) !important;
border: 2px solid rgb(4, 4, 124);
}
.delete_button{
background-color: red !important;
border: 2px solid rgb(83, 3, 3);
}
}
.add_button{
background-color: green !important;
border: 2px solid rgb(3, 102, 20);
}
.modify_button{
background-color: rgb(53, 53, 255) !important;
border: 2px solid rgb(4, 4, 124);
}
.delete_button{
background-color: red !important;
border: 2px solid rgb(83, 3, 3);
}
\ No newline at end of file
......@@ -29,7 +29,28 @@
#my_house {
display: grid;
grid-template: "area-1" 500px "area-2" 500px/1fr;
grid-template: "house_area" 150px "area-1" 500px "area-2" 500px/1fr;
}
#my_house house-area {
grid-area: house_area;
border: 2px solid black;
}
#my_house house-area #house_details {
width: 100%;
height: 100px;
}
#my_house house-area #house_details div {
display: flex;
height: 100%;
justify-content: space-evenly;
}
#my_house house-area #house_details div span {
margin: auto;
vertical-align: middle;
}
#my_house house-area #house_details div input {
margin: auto;
max-height: 50px;
}
#my_house #area_1 {
display: grid;
......@@ -43,14 +64,14 @@
grid-area: war-participation;
padding: 10px;
}
#my_house #area_1 war-participation .header_title {
margin-left: 10px;
text-align: left;
}
#my_house #area_1 members-area {
grid-area: members;
padding: 10px;
}
#my_house #area_1 members-area .table_header {
text-align: center;
font-size: 20px;
}
#my_house #area_1 members-area detail {
left: 50%;
height: 350px;
......@@ -105,6 +126,7 @@
}
#my_house #area_2 member-units {
grid-area: member-units;
padding: 10px;
}
#my_house #area_2 member-units .table_header .title {
text-align: left;
......@@ -117,8 +139,27 @@
#my_house .table_header {
text-align: right;
}
#my_house .table_header button.one {
right: 10px;
}
#my_house .table_header button.two {
right: 110px;
}
#my_house .table_header button.three {
right: 210px;
}
#my_house .table_header button.four {
right: 310px;
}
#my_house .table_header button {
color: #cccccc;
position: absolute;
top: 1px;
right: 10px;
}
.header_title {
text-align: center;
}
/*# sourceMappingURL=house.css.map */
{"version":3,"sourceRoot":"","sources":["../sass/house.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;;AAGA;EACI;;AACA;EACI;;AAGR;EACI;;AACA;EACI;;;AAMhB;EACI;EACA,eACI;;AAIJ;EACI;EACA,eACI;;AAGJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAGA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAIA;EACI;;AAKhB;EACI;EACA,eACI;;AAGJ;EACI;EACA;;AAII;EACI;;AACA;EACI;;AAGR;EACI;;AACA;EACI;;AAMR;EACI;EACA;;AACA;EACI;EACA;;AAIZ;EACI;;AAEJ;EACI;;AAGR;EACI;;AAII;EACI;EACA;;AACA;EACI;EACA;;AAOpB;EACI;;AACA;EACI","file":"house.css"}
\ No newline at end of file
{"version":3,"sourceRoot":"","sources":["../sass/house.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;;AAGA;EACI;;AACA;EACI;;AAGR;EACI;;AACA;EACI;;;AAMhB;EACI;EACA,eACI;;AAMJ;EACI;EACA;;AAEA;EAEI;EACA;;AACA;EACI;EACA;EAKA;;AAJA;EACI;EACA;;AAIJ;EACI;EACA;;AAMhB;EACI;EACA,eACI;;AAGJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEA;EACI;EACA;;AAGR;EACI;EACA;;AAGA;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAIA;EACI;;AAKhB;EACI;EACA,eACI;;AAGJ;EACI;EACA;;AAII;EACI;;AACA;EACI;;AAGR;EACI;;AACA;EACI;;AAMR;EACI;EACA;;AACA;EACI;EACA;;AAIZ;EACI;;AAEJ;EACI;;AAGR;EACI;EACA;;AAII;EACI;EACA;;AACA;EACI;EACA;;AAUpB;EACI;;AAgBI;EACI,OARI;;AAOR;EACI,OARI;;AAOR;EACI,OARI;;AAOR;EACI,OARI;;AAWZ;EACI;EACA;EACA;EACA;;;AAKZ;EACI","file":"house.css"}
\ No newline at end of file
......@@ -126,9 +126,11 @@ bar-user .dropdown:hover {