From 9c905ceab9debebbbdbd3f83bc5c195497d08bcc Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 09 Oct 2021 12:26:53 +0100 Subject: [PATCH] Implement search results for users --- chartered-frontend/src/index.sass | 8 ++++++++ chartered-frontend/src/index.tsx | 6 ++++++ chartered-frontend/src/util.tsx | 3 ++- chartered-frontend/src/pages/Search.tsx | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chartered-frontend/src/sections/Nav.tsx | 40 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 123 insertions(+), 9 deletions(-) diff --git a/chartered-frontend/src/index.sass b/chartered-frontend/src/index.sass index 879e263..1697bf7 100644 --- a/chartered-frontend/src/index.sass +++ a/chartered-frontend/src/index.sass @@ -42,3 +42,11 @@ &::after content: "" border-top: 1px solid + +.navbar .form-control + transition: width 0.5s ease-in-out + width: 250px + + &:focus, &:not(:placeholder-shown) + width: 350px + diff --git a/chartered-frontend/src/index.tsx b/chartered-frontend/src/index.tsx index 140e9e5..4635203 100644 --- a/chartered-frontend/src/index.tsx +++ a/chartered-frontend/src/index.tsx @@ -23,6 +23,7 @@ import OrganisationView from "./pages/crate/OrganisationView"; import CreateOrganisation from "./pages/organisations/CreateOrganisation"; import User from "./pages/User"; +import Search from "./pages/Search"; function App() { return ( @@ -92,6 +93,11 @@ exact path="/organisations/create" component={() => } + /> + } /> diff --git a/chartered-frontend/src/util.tsx b/chartered-frontend/src/util.tsx index 2de96bd..93dfab4 100644 --- a/chartered-frontend/src/util.tsx +++ a/chartered-frontend/src/util.tsx @@ -24,6 +24,7 @@ React.useEffect(async () => { try { + setResponse(null); let res = await fetch(authenticatedEndpoint(auth, endpoint)); if (res.status == 401) { @@ -94,7 +95,7 @@ } else { return (
); diff --git a/chartered-frontend/src/pages/Search.tsx b/chartered-frontend/src/pages/Search.tsx new file mode 100644 index 0000000..f7048eb 100644 --- /dev/null +++ a/chartered-frontend/src/pages/Search.tsx @@ -1,0 +1,75 @@ +import React = require("react"); +import { useState, useEffect } from "react"; +import { Link, useHistory, useLocation } from "react-router-dom"; + +import Nav from "../sections/Nav"; +import { useAuth } from "../useAuth"; +import { authenticatedEndpoint, ProfilePicture, useAuthenticatedRequest } from "../util"; + +import { Plus } from "react-bootstrap-icons"; +import { LoadingSpinner } from "./Loading"; + +interface UsersSearchResponse { + users: UserSearchResponseUser[]; +} + +interface UserSearchResponseUser { + user_uuid: string; + display_name: string; + picture_url: string; +} + +export default function Search() { + const auth = useAuth(); + const location = useLocation(); + + const query = location.pathname === '/search' + ? new URLSearchParams(location.search).get("q") || "" + : ""; + + return ( +
+
+ ); +} + +function UsersResults({ query }: { query: string }) { + const auth = useAuth(); + + const { response: results, error } = + useAuthenticatedRequest({ + auth, + endpoint: "users/search?q=" + encodeURIComponent(query), + }, [query]); + + if (!results) { + return
+
+ {[0, 1, 2].map((i) => ( + + ))} +
+
+ } + + if (results?.users.length === 0) { + return <>; + } + + return
+
+ {results.users.map((user, i) => ( + + + + ))} +
+
; +}diff --git a/chartered-frontend/src/sections/Nav.tsx b/chartered-frontend/src/sections/Nav.tsx index fd4782b..b795532 100644 --- a/chartered-frontend/src/sections/Nav.tsx +++ a/chartered-frontend/src/sections/Nav.tsx @@ -1,17 +1,33 @@ import React = require("react"); +import { useHistory, useLocation } from "react-router-dom"; import { NavLink, Link } from "react-router-dom"; -import { BoxArrowRight } from "react-bootstrap-icons"; +import { BoxArrowRight, Search } from "react-bootstrap-icons"; import { useAuth } from "../useAuth"; export default function Nav() { const auth = useAuth(); + const history = useHistory(); + const location = useLocation(); const logout = async (e) => { e.preventDefault(); await auth.logout(); }; + const [search, setSearch] = React.useState( + location.pathname === '/search' + ? new URLSearchParams(location.search).get("q") || "" + : "" + ); + const submitSearchForm = (e) => { + e.preventDefault(); + + if (search != "") { + history.push(`/search?q=${encodeURIComponent(search)}`) + } + }; + return (