import {Component , Output, EventEmitter} from '@angular/core';
import { NgForm } from '@angular/forms';
import {Need} from '../../models/Need';
import {CupboardService} from '../../services/cupboard.service';
import { UsersService } from '../../services/users.service';
import { userType } from '../../models/User';
import {AuthService} from '../../services/auth.service';
import {catchError, of} from 'rxjs';
interface sortAlgo {
(a: Need,b: Need): number;
}
// sort functions
const sortByName: sortAlgo = (a: Need, b: Need): number => {
if(a.name.toLocaleLowerCase() < b.name.toLocaleLowerCase()) {
return -1;
}
return 1;
}
const sortByGoal: sortAlgo = (a: Need, b: Need): number => {
if(a.maxGoal == b.maxGoal) {
return sortByName(a,b);
}
else if(a.maxGoal > b.maxGoal) {
return -1;
}
return 1;
}
const sortByCompletion: sortAlgo = (a: Need, b: Need): number => {
if(a.current == b.current) {
return sortByGoal(a,b);
}
else if(a.current > b.current) {
return -1;
}
return 1;
}
const sortByPriority: sortAlgo = (a: Need, b: Need): number => {
if(a.urgent == b.urgent) {
return sortByGoal(a,b);
}
else if(a.urgent && !b.urgent) {
return -1;
}
return 1;
}
const sortByLocation: sortAlgo = (a: Need, b: Need): number => {
if(a.location.toLocaleLowerCase() < b.location.toLocaleLowerCase()) {
return -1;
}
return 1;
}
@Component({
selector: 'app-need-list',
standalone: false,
templateUrl: './need-list.component.html',
styleUrl: './need-list.component.css'
})
export class NeedListComponent {
selectedNeed: Need | null = null;
needs: Need[] = [];
searchResults: Need[] = [];
sortMode: 'Ascending' | 'Descending' = 'Ascending'
currentSortAlgo: sortAlgo = sortByPriority;
sortSelection: string = 'sortByPriority';
SortingAlgoArrays: {func:sortAlgo,name:string, display:string[]}[] = [
{func:sortByPriority,name:"sortByPriority", display:["Highest Priority", "Lowest Priority"]},
{func:sortByName,name:"sortByName", display:["Name (A to Z)", "Name (Z to A)"]},
{func:sortByLocation,name:"sortByLocation", display:["Location (A to Z)", "Location (Z to A)"]},
{func:sortByCompletion,name:"sortByCompletion", display:["Most Completed", "Least Completed"]},
{func:sortByGoal,name:"sortByGoal", display:["Largest Maximum Goal", "Smallest Maximum Goal"]},
];
@Output() currentNeed = new EventEmitter<Need>();
constructor(
private cupboardService: CupboardService,
private usersService: UsersService,
private authService: AuthService
) {}
refresh() {
this.cupboardService.getNeeds().subscribe(n => {
if (this.sortMode == 'Ascending') {
this.needs = n.sort(this.currentSortAlgo);
} else {
this.needs = n.sort(this.currentSortAlgo).reverse();
}
this.searchResults = this.needs;
});
const form = document.getElementById('search-form') as HTMLFormElement;
form.reset();
this.search(null);
}
ngOnInit(): void {
this.refresh()
}
changeSortMode(form : any) {
if (this.sortMode == 'Ascending'){
this.sortMode = 'Descending'
} else {
this.sortMode = 'Ascending'
}
this.search(form)
}
private searchDelay: any;
async search(form: any) {
//wait .25 seconds before searching but cancel if another search is made during the wait to prevent too many api calls
//remove previous search if it exists
if (this.searchDelay) {
clearTimeout(this.searchDelay);
}
if (form) {
this.searchDelay = setTimeout(() => {
if (form) {
//sorting based on algo selected
this.SortingAlgoArrays.forEach(algo => {
if(algo.name === this.sortSelection) {
this.currentSortAlgo = algo.func;
console.log("changed sorting algorithm to: ", algo.name + this.sortMode)
return
}
});
const currentSearchValue = form.search; //latest value of the search
this.cupboardService.searchNeeds(currentSearchValue).subscribe((n) => {
if (this.sortMode == 'Ascending') {
this.searchResults = n.sort(this.currentSortAlgo);
} else {
this.searchResults = n.sort(this.currentSortAlgo).reverse();
}
console.log(currentSearchValue, this.searchResults);
});
}
}, 250);
} else {
//user has cleared the search bar, we can skip the timeout for a 1/4 second faster response
//clear timeout to stop pending search
clearTimeout(this.searchDelay);
this.searchResults = this.needs;
}
}
delete(id : number) {
this.cupboardService.deleteNeed(id).subscribe(() => {
this.needs = this.needs.filter(n => n.id !== id)
})
this.refresh();
}
isManager() {
const type = this.authService.getCurrentUser()?.type;
return type === ("MANAGER" as unknown as userType);
}
isHelper() {
const type = this.authService.getCurrentUser()?.type;
return type === ("HELPER" as unknown as userType);
}
changeText(id : number, text : string) {
const span = document.getElementById('hover-status-label-' + id);
if (span) {
span.innerHTML = ' ' + text;
}
}
add(need: Need) {
const currentUser = this.authService.getCurrentUser();
//console.log("get current user in angular:", currentUser)
if (currentUser) {
if (!currentUser.basket.includes(need.id)) {
currentUser.basket.push(need.id);
this.usersService.updateUser(currentUser)
.pipe(catchError((err, _) => {
console.error(err);
return of();
}))
.subscribe(() => {
this.usersService.refreshBasket();
});
} else {
window.alert("This need is already in your basket!")
}
}
}
back() {
this.searchResults = this.needs;
}
select(need : Need) {
//emit value
this.currentNeed.emit(need);
if (this.selectedNeed) {
//revert already selected need to previous style
console.log(need.id);
let button = document.getElementById('need-button-' + this.selectedNeed.id);
if (button) {
console.log(button)
button.style.background = 'lightgray';
button.style.marginLeft = '0%';
button.style.width = '98%';
}
button = document.getElementById('need-edit-button-' + this.selectedNeed.id);
if (button) {
button.style.visibility = 'visible';
}
}
//change selected need to selected style
this.selectedNeed = need;
let button = document.getElementById('need-button-' + need.id);
if (button) {
button.style.background = 'white';
button.style.marginLeft = '4%';
button.style.width = '100%';
}
button = document.getElementById('need-edit-button-' + need.id);
if (button) {
button.style.visibility = 'hidden';
}
}
}
function not(location: string) {
throw new Error('Function not implemented.');
}