Add search

This commit is contained in:
Santiago Lo Coco 2023-12-07 14:40:11 -03:00
parent 3faa1cb12f
commit 047e580502
6 changed files with 76 additions and 16 deletions

View File

@ -73,8 +73,8 @@ interface FlightData {
count: number
}
export const fetchFlights = (origin: string | null, page: number | null): Promise<FlightData> => {
return instance.get("flights" + (origin ? "?origin=" + origin : "") + (page ? "?page=" + page : ""))
export const fetchFlights = (page: number | null, search: string | null): Promise<FlightData> => {
return instance.get("flights" + (page ? "?page=" + page : "") + (search ? (page ? "&" : "?") + "search=" + search : ""))
};
export const createFlight = (

View File

@ -5,6 +5,8 @@ import { Flight } from "../../Types";
import { useNavigate } from "react-router";
import useAuth from "../../useAuth";
import { useFetchSubscriptions } from "../../hooks/useFetchSubscriptions";
import { Button, Input, Space } from "antd";
import { SearchOutlined, CloseCircleOutlined } from '@ant-design/icons';
interface Props {
flights?: Flight[];
@ -12,9 +14,10 @@ interface Props {
export const Home: React.FC<Props> = (props) => {
const urlParams = new URLSearchParams(window.location.search);
const origin = urlParams.get('origin');
const initialPage = parseInt(urlParams.get('page') || '1', 10);
const { flights, count, error, isLoading, fetchData: refreshFlights } = useFetchFlights(origin, initialPage);
const query = urlParams.get('search');
const [searchQuery, setSearchQuery] = useState(query);
const { flights, count, error, isLoading, fetchData: refreshFlights } = useFetchFlights(initialPage, searchQuery);
const navigate = useNavigate()
const [currentPage, setCurrentPage] = useState(initialPage);
@ -25,6 +28,9 @@ export const Home: React.FC<Props> = (props) => {
useEffect(() => {
const newParams = new URLSearchParams(window.location.search);
newParams.set('page', currentPage.toString());
if (searchQuery && searchQuery.length != 0) {
newParams.set("search", searchQuery);
}
navigate(`?${newParams.toString()}`);
}, [currentPage, navigate]);
@ -52,6 +58,26 @@ export const Home: React.FC<Props> = (props) => {
return currentPage > 1 ? true : false
}
const handleSearchSubmit = (e: React.FormEvent | undefined) => {
let searchQueryValue = null
if (!!e) {
e.preventDefault();
const formData = new FormData(e.currentTarget as HTMLFormElement);
searchQueryValue = formData.get("searchInput") as string;
}
setSearchQuery(searchQueryValue)
const newParams = new URLSearchParams(window.location.search);
newParams.set('page', "1");
if (searchQueryValue && searchQueryValue.length != 0) {
newParams.set("search", searchQueryValue);
} else {
newParams.delete("search")
}
navigate(`?${newParams.toString()}`);
};
if (loading || isLoading) {
return <div>Loading...</div>;
}
@ -62,8 +88,33 @@ export const Home: React.FC<Props> = (props) => {
<div className="Box">
{isAirline ? <button name="CreateFlight" onClick={() => { navigate("/create-flight") }}>Create flight</button> : <></>}
{isAdmin ? <button onClick={() => { navigate("/create-airline") }}>Create airline user</button> : <></>}
<h2>Flights</h2>
<form onSubmit={handleSearchSubmit}>
<Space size={8} direction="horizontal">
{/* <h2>Flights</h2> */}
<div style={{ display: 'flex' }}>
<Input
type="text"
placeholder="Enter flight code"
name="searchInput"
defaultValue={searchQuery || ""}
style={{ borderRadius: 0 }}
/>
{searchQuery && (<Button
type="text"
onClick={() => handleSearchSubmit(undefined)}
style={{ border: 'none', backgroundColor: 'transparent', marginRight: '5px' }}
>
<CloseCircleOutlined style={{ color: 'gray' }} />
</Button>
)}
<Button type="primary" style={{ border: 'none', borderRadius: 0 }} htmlType="submit">
<SearchOutlined/>
</Button>
</div>
</Space>
</form>
<div className="Items" style={{ gridTemplateColumns: `repeat(${columns}, minmax(80px, 250px))` }}>
{flights.length == 0 && <p>No flights found!</p>}
{(props.flights ? props.flights : flights).map((f) => {
return <Card key={f.id} flight={f} user={user}
subscribed={subscriptions.some((i => i.flight_id === f.id))}
@ -73,7 +124,7 @@ export const Home: React.FC<Props> = (props) => {
</div>
<div>
{checkMinPage() && <button onClick={goToPrevPage}>Prev</button>}
<span> Page {currentPage} </span>
{flights.length != 0 && <span> Page {currentPage} </span>}
{checkMaxPage() && <button onClick={goToNextPage}>Next</button>}
</div>
</div>

View File

@ -1,9 +1,9 @@
import React, { useCallback, useEffect } from "react";
import { useCallback, useEffect } from "react";
import { useState } from "react";
import { User, Flight } from "../Types";
import { Flight } from "../Types";
import { fetchFlights } from "../Api";
export const useFetchFlights = (origin: string | null, page: number | null) => {
export const useFetchFlights = (page: number | null, search: string | null) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [flights, setFlights] = useState<Flight[]>([]);
@ -13,7 +13,7 @@ export const useFetchFlights = (origin: string | null, page: number | null) =>
setError(null);
setIsLoading(true)
fetchFlights(origin, page)
fetchFlights(page, search)
.then((data) => {
setCount(data.count)
setFlights(data.flights);
@ -25,7 +25,7 @@ export const useFetchFlights = (origin: string | null, page: number | null) =>
}
})
.finally(() => setIsLoading(false))
}, [origin, page]);
}, [page, search]);
useEffect(() => {
fetchData()

View File

@ -60,13 +60,16 @@ def get_flight_by_id(db: Session, flight_id: int):
return db.query(Flight).filter(Flight.id == flight_id).first()
def get_flights(db: Session, deleted, page: int = 1, limit: int = 8):
def get_flights(db: Session, deleted, search, page: int = 1, limit: int = 8):
if page <= 0:
page = 1
skip = (page - 1) * limit
condition = Flight.status != "Deleted" if not deleted else True
count = db.query(Flight).filter(condition).count()
return db.query(Flight).filter(condition).offset(skip).limit(limit).all(), count
conditions = [
Flight.status != "Deleted" if not deleted else True,
func.lower(Flight.flight_code).contains(search.lower()) if search else True,
]
count = db.query(Flight).filter(*conditions).count()
return db.query(Flight).filter(*conditions).offset(skip).limit(limit).all(), count
def create_flight(db: Session, flight: FlightPydantic):

View File

@ -87,6 +87,7 @@ def get_flights(
future: Optional[str] = None,
deleted: Optional[str] = None,
page: Optional[int] = 1,
search: Optional[str] = None,
db: Session = Depends(get_db),
):
if origin and lastUpdated:
@ -102,7 +103,9 @@ def get_flights(
db=db, destination=destination, future=future
)
else:
flights, count = flight_crud.get_flights(db=db, page=page, deleted=deleted)
flights, count = flight_crud.get_flights(
db=db, page=page, deleted=deleted, search=search
)
response.headers["X-Count"] = str(count)
if not flights:

View File

@ -71,6 +71,7 @@ async def get_flights(
lastUpdated: Optional[str] = None,
deleted: Optional[str] = None,
page: Optional[int] = 1,
search: Optional[str] = None,
future: Optional[str] = None,
):
query = {}
@ -84,6 +85,8 @@ async def get_flights(
query["future"] = future
if deleted:
query["deleted"] = deleted
if search:
query["search"] = search
if page:
query["page"] = page
request_id = req.state.request_id