Skip to content

Commit

Permalink
implement search and filter in trips page
Browse files Browse the repository at this point in the history
  • Loading branch information
derGraph committed Dec 31, 2024
1 parent f045b4b commit 644463b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 22 deletions.
22 changes: 22 additions & 0 deletions src/routes/api/Locations/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { prisma } from "$lib/server/prisma";
import { error } from "@sveltejs/kit";

export async function GET(event) {
try{
let responseData = await prisma.location.findMany({
where: {
}
});
return new Response(JSON.stringify(responseData));
} catch (error_message) {
if (error_message instanceof Error) {
error(404, {
message: error_message.message
});
} else {
error(500, {
message: 'ERROR'
});
}
}
}
1 change: 0 additions & 1 deletion src/routes/api/Trips/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export async function GET(event: {
if(username == null){
responseData = await prisma.trip.findMany({
where:{
deleted: deleted,
OR: [{
crew: {
some: {
Expand Down
92 changes: 71 additions & 21 deletions src/routes/trips/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,54 @@
import errorStore from "$lib/errorStore";
import { onMount } from "svelte";
import { parseVisibility } from "$lib/visibility";
import type { User } from "@prisma/client";
import type { User, Location, Trip } from "@prisma/client";
import { parseDate, parseRadioButton } from "$lib/functions.js";
import SearchBar from "$lib/searchBar.svelte";
import { filter } from "@skeletonlabs/skeleton";
let tableArr: any[] = $state([]);
let allTrips: any[] = $state([]);
let totalLength = $state(0);
let totalSailedLength = $state(0);
let totalMotoredLength = $state(0);
let showDeletedTrips = $state(false);
let showMyTrips = $state(false);
let showLocationSearch = $state(false);
let filterLocations: String[] = $state([]);
let { data } = $props();
onMount(()=>{
reloadTable();
});
function applyTripFilter(){
tableArr = allTrips.filter(trip => {
// If locations array is empty, consider all locations
const locationMatch = filterLocations.length === 0 || trip.location.some((loc: { name: String; }) => filterLocations.includes(loc.name));
// If showDeletedTrips is false, only include trips that are not deleted
const deletionMatch = showDeletedTrips || !trip.deleted;
// If showMyTrips is false, include all trips; otherwise, filter by the user's trips
const isMyTrip =
!showMyTrips ||
trip.crew.some((crewMember: { username: string | undefined; }) => crewMember.username === data.user?.username) ||
trip.skipperName === data.user?.username;
// Combine all conditions
return locationMatch && deletionMatch && isMyTrip;
});
}
function reloadTable(){
fetch('/api/Trips').then(async (response)=>{
if (!response.ok) {
$errorStore = response;
return;
}
tableArr = await response.json();
tableArr = tableArr.filter((trip:{length_sail:Number, length_motor:Number, skipperName:String|null, crew:User[]})=>{
if(trip.skipperName == data.user?.username){
// is Skipper
totalLength += Number(trip.length_sail)+Number(trip.length_motor);
totalSailedLength += Number(trip.length_sail);
totalMotoredLength += Number(trip.length_motor);
return true;
}
if((trip.crew.map((member)=>{return member.username})).includes(data.user!.username)){
// is Crew;
totalLength += Number(trip.length_sail)+Number(trip.length_motor);
totalSailedLength += Number(trip.length_sail);
totalMotoredLength += Number(trip.length_motor);
return true;
}
return false;
});
allTrips = await response.json();
applyTripFilter();
});
}
Expand All @@ -54,6 +61,14 @@
return crewHtml.replace(/. $/, "");
}
function parseLocation(locationData:Location[]){
let parsedLocation = "";
for(let location of locationData){
parsedLocation += location.name;
}
return parsedLocation;
}
async function selectActiveTrip(tripId:string){
let result;
if(tripId != data.user?.activeTripId){
Expand All @@ -74,20 +89,53 @@
window.location.assign("/trips/edit/"+(await result.json()).id);
}
}
async function getLocations(){
let locationList:String[] = [];
let result = await fetch("/api/Locations");
if (!result.ok){
errorStore.set(result);
}else{
let json = await result.json();
for(let location of json){
locationList.push(location.name);
}
}
return locationList;
}
async function addLocationTerm(location: String) {
if(!filterLocations.includes(location)){
filterLocations.push(location);
applyTripFilter();
}
}
</script>

<div class="md:container md:mx-auto pb-3 h-full rounded table-container">
<div class="flex flex-row my-1 flex-wrap">
<button type="button" onclick={()=>{if(showMyTrips){showDeletedTrips=false} showMyTrips = !showMyTrips}} class="btn btn-md variant-ghost mr-2">
<button type="button" onclick={()=>{if(showMyTrips){showDeletedTrips=false} showMyTrips = !showMyTrips; applyTripFilter()}} class="btn btn-md variant-ghost mr-2">
<span class="material-symbols-outlined">{#if showMyTrips}check_box{:else}check_box_outline_blank{/if}</span>
my Trips
</button>
<button type="button" onclick={()=>{if(!showDeletedTrips){showMyTrips=true} showDeletedTrips = !showDeletedTrips}} class="btn btn-md variant-ghost-error">
<button type="button" onclick={()=>{if(!showDeletedTrips){showMyTrips=true} showDeletedTrips = !showDeletedTrips; applyTripFilter()}} class="btn btn-md variant-ghost-error mr-4">
<span class="material-symbols-outlined">{#if showDeletedTrips}check_box{:else}check_box_outline_blank{/if}</span>
deleted Trips
</button>
<spacer class="flex-1"></spacer>
<button type="button" onclick={()=>{showLocationSearch = !showLocationSearch}} class="btn btn-md variant-ghost mr-2">
<span class="material-symbols-outlined">search</span>
search for Location
</button>
<SearchBar bind:displayed = {showLocationSearch} getList={getLocations} onSelected={addLocationTerm}></SearchBar>
{#each filterLocations as filterLocation}
<button type="button" onclick={()=>{filterLocations = filterLocations.filter(e => e !== filterLocation); applyTripFilter()}} class="btn btn-md variant-ghost-tertiary mr-2">
<span class="material-symbols-outlined">close</span>
{filterLocation}
</button>
{/each}
<spacer class="flex-1"></spacer>
<button type="button" onclick={()=>{addTrip()}} class="btn btn-md variant-ghost-success"><span class="material-symbols-outlined">add</span>add Trip</button>
</div>
<table class="text-wrap table table-hover">
Expand All @@ -98,6 +146,7 @@
<th>Start Date</th>
<th>End Date</th>
<th>Distance</th>
<th>Location</th>
<th>Skipper</th>
<th>Crew</th>
<th>Visibilty</th>
Expand All @@ -111,6 +160,7 @@
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{parseDate(row.startPoint)}</td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{parseDate(row.endPoint)}</td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{((Number(row.length_sail) + Number(row.length_motor))/1853).toFixed(0)} NM<div class="hidden group-hover:block"><span class="!text-xs material-symbols-outlined">sailing</span>{(Number(row.length_sail)/1853).toFixed(0)} <span class="!text-xs material-symbols-outlined">mode_heat</span>{(Number(row.length_motor)/1853).toFixed(0)}</div></td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{parseLocation(row.location)}</td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{row.skipperName}</td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{parseCrew(row.crew)}</td>
<td onclick={()=>{window.location.href='/trips/'+row.id}} class="!align-middle">{parseVisibility(row.visibility)}</td>
Expand Down

0 comments on commit 644463b

Please sign in to comment.