Implement searching via categories

This commit is contained in:
Stedoss 2022-10-31 23:04:14 +00:00
parent 96f409c8d8
commit 82376af904
7 changed files with 56 additions and 10 deletions

View File

@ -15,9 +15,10 @@ public class VenueController : ControllerBase
}
[HttpGet]
public async Task<IActionResult> GetAll()
public async Task<IActionResult> GetVenues([FromQuery] string[]? categories = null, [FromQuery] string[]? tags = null)
{
var venues = await _venueService.GetAllVenues();
var venues = await _venueService.GetFilteredVenues(null, categories);
return Ok(venues);
}

View File

@ -6,4 +6,5 @@ public interface IVenueService
{
public Task<IEnumerable<Venue>> GetAllVenues();
public Task<Venue?> GetVenue(int venueId);
public Task<IEnumerable<Venue>> GetFilteredVenues(string[]? tags = null, string[]? categories = null);
}

View File

@ -29,4 +29,21 @@ public class VenueService : IVenueService
.Include(v => v.Tags)
.SingleOrDefaultAsync(v => v.Id == venueId);
}
public async Task<IEnumerable<Venue>> GetFilteredVenues(string[]? tags = null, string[]? categories = null)
{
var venues = _context.Venues
.Include(v => v.Category)
.Include(v => v.Tags);
IQueryable<Venue> filteredVenues = venues;
if (categories is { Length: > 0 })
{
filteredVenues = venues.Where(v => categories.Contains(v.Category.Name));
}
return await filteredVenues.ToListAsync();
}
}

View File

@ -1,10 +1,13 @@
import { TCategory, TTag, TVenue } from "./types";
import { ArrayToArrayUrlParams } from "./helpers";
import { TCategory, TTag, TVenue, TVenueFilters } from "./types";
export class API {
constructor(private baseAPIUrl: string) {}
getVenues = async (): Promise<TVenue[]> => {
const response = await fetch(`${this.baseAPIUrl}/venue`);
getVenues = async (venueFilters: TVenueFilters | null): Promise<TVenue[]> => {
const categoriesParams = ArrayToArrayUrlParams("categories", venueFilters?.categories.map((c) => c.name) ?? []);
const response = await fetch(`${this.baseAPIUrl}/venue${categoriesParams}`);
console.log(`calling ${this.baseAPIUrl}/venue${categoriesParams}`);
return await response.json();
}

View File

@ -0,0 +1,12 @@
export function ArrayToArrayUrlParams(paramName: string, params: string[], isFirstParam: boolean = true): string {
if (params.length === 0) {
return "";
}
let paramString = isFirstParam ? "?" : "&";
params.forEach((param) => {
paramString += `${paramName}=${param}&`;
});
return paramString.slice(0, -1);
}

View File

@ -28,3 +28,8 @@ export type TVenue = {
starsValue: number;
tags: TTag[];
}
export type TVenueFilters = {
tags: TTag[];
categories: TCategory[];
}

View File

@ -1,22 +1,29 @@
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { useEffect, useState } from "react";
import { DropdownFilter } from "../components/dropdown-filter";
import { VenueGrid } from "../components/venue-grid";
import { API } from "../lib/api";
import { Environment } from "../lib/environment";
import { TCategory, TTag, TVenue } from "../lib/types";
import { TCategory, TTag, TVenue, TVenueFilters } from "../lib/types";
export function Index() {
const [filteredTags, setFilteredTags] = useState<TTag[]>([]);
const [filteredCategories, setFilteredCategories] = useState<TCategory[]>([]);
const api = new API(Environment.BaseAPIUrl);
const { data: venueData } = useQuery<TVenue[], Error>(["venues"], api.getVenues);
const queryClient = useQueryClient();
const { data: venueData } = useQuery<TVenue[], Error>(["venues", filteredCategories], () => api.getVenues({categories: filteredCategories, tags: filteredTags}));
const { data: categoryData } = useQuery<TCategory[], Error>(["categories"], api.getCategories);
const { data: tagData } = useQuery<TTag[], Error>(["tags"], api.getTags);
const [filteredTags, setFilteredTags] = useState<TTag[]>([]);
const [filteredCategories, setFilteredCategories] = useState<TCategory[]>([]);
// useEffect(() => {
// console.log("useeffect called!");
// queryClient.invalidateQueries(["venues"]);
// }, [filteredCategories]);
return(
<>