From 1ff61bf91dc8cef51387734393e6bfad9d3d331f Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 18 Mar 2022 12:37:39 -0400 Subject: [PATCH] adding in stuff to make search work but still testing and stuff --- packages/api/index.ts | 2 + packages/api/middleware/auth.ts | 1 + packages/api/routes/search.ts | 40 ++++++++++++ packages/api/services/user.service.ts | 26 ++++++++ packages/core/responses/search.response.ts | 12 ++++ packages/desktop/src/controller/index.tsx | 32 ++++++++-- packages/desktop/src/controller/recoil.tsx | 5 ++ .../src/pages/Home/conversations/index.tsx | 41 ++++++++++++ .../desktop/src/pages/Home/header/index.tsx | 35 ++++++++++ packages/desktop/src/pages/Home/index.tsx | 64 +++---------------- .../desktop/src/pages/Home/search/index.tsx | 24 +++++++ packages/desktop/src/pages/Login/index.tsx | 7 +- 12 files changed, 225 insertions(+), 64 deletions(-) create mode 100644 packages/api/routes/search.ts create mode 100644 packages/core/responses/search.response.ts create mode 100644 packages/desktop/src/pages/Home/conversations/index.tsx create mode 100644 packages/desktop/src/pages/Home/header/index.tsx create mode 100644 packages/desktop/src/pages/Home/search/index.tsx diff --git a/packages/api/index.ts b/packages/api/index.ts index 026f03f..c2eb253 100644 --- a/packages/api/index.ts +++ b/packages/api/index.ts @@ -3,6 +3,7 @@ import express, { Application, Request, Response } from "express"; import { NextFunction } from "express"; import { connectToDatabase } from "./services/database.service"; import cors from "cors"; +import getSearchRoutes from "./routes/search"; import getUserRoutes from "./routes/user"; const app = express(); @@ -19,6 +20,7 @@ app.get("/", (req: Request, res: Response) => { }); app.use("/api/users", getUserRoutes()); +app.use("/api/search", getSearchRoutes()); app.listen(5000, () => console.log("Example app is listening on port 5000.")); diff --git a/packages/api/middleware/auth.ts b/packages/api/middleware/auth.ts index a338b9a..2fce164 100644 --- a/packages/api/middleware/auth.ts +++ b/packages/api/middleware/auth.ts @@ -29,6 +29,7 @@ export const authCheck = async ( next(); } catch (error) { + console.log(error); res.status(401).send("unauthorized"); } }; diff --git a/packages/api/routes/search.ts b/packages/api/routes/search.ts new file mode 100644 index 0000000..9238296 --- /dev/null +++ b/packages/api/routes/search.ts @@ -0,0 +1,40 @@ +import express, { Application, Request, Response } from "express"; + +import SearchResponse from "@nirvana/core/responses/search.response"; +import { User } from "@nirvana/core/models"; +import { UserService } from "../services/user.service"; +import { authCheck } from "../middleware/auth"; + +export default function getSearchRoutes() { + const router = express.Router(); + + router.use(express.json()); + + // get user details based on id token + router.get("/", authCheck, handleSearch); + + return router; +} + +async function handleSearch(req: Request, res: Response) { + try { + const { query } = req.query; + + if (!query) { + res.status(400).send("No search query provided!"); + return; + } + + // text search on users + const users: User[] | null = await UserService.getUsersLikeEmailAndName( + query as string + ); + + const resObj = new SearchResponse(users ?? []); + + res.send(resObj); + } catch (error) { + console.log(error); + res.status(500).send(`something went wrong`); + } +} diff --git a/packages/api/services/user.service.ts b/packages/api/services/user.service.ts index f57a13e..747280c 100644 --- a/packages/api/services/user.service.ts +++ b/packages/api/services/user.service.ts @@ -31,6 +31,32 @@ export class UserService { return null; } + static async getUsersLikeEmailAndName(searchQuery: string) { + // based on index defined in Mongo atlas + const query = { + $search: { + index: "default", + text: { + query: searchQuery, + path: { + wildcard: "*", + }, + }, + }, + }; + + // const res = await collections.users?.find(query).toArray(); + + const res = await collections.users?.aggregate([query]).toArray(); + + // exists + if (res?.length) { + return res as User[]; + } + + return null; + } + static async createUserIfNotExists(newUser: User) { const exists = (await collections.users?.findOne({ email: newUser.email })) ?._id; diff --git a/packages/core/responses/search.response.ts b/packages/core/responses/search.response.ts new file mode 100644 index 0000000..ab534d2 --- /dev/null +++ b/packages/core/responses/search.response.ts @@ -0,0 +1,12 @@ +import { User } from "@nirvana/core/models"; + +/** + * Full results from the global search + */ +export default class SearchResponse { + // all friends/contacts matching search + contacts?: User[]; + + // all public users + constructor(public users: User[]) {} +} diff --git a/packages/desktop/src/controller/index.tsx b/packages/desktop/src/controller/index.tsx index af25bfd..b409191 100644 --- a/packages/desktop/src/controller/index.tsx +++ b/packages/desktop/src/controller/index.tsx @@ -1,16 +1,14 @@ +import { $authTokens, $searchQuery } from "./recoil"; import { useMutation, useQuery } from "react-query"; -import { $authTokens } from "./recoil"; +import SearchResponse from "@nirvana/core/responses/search.response"; import { User } from "@nirvana/core/models"; import axios from "axios"; import { nirvanaApi } from "./nirvanaApi"; import { queryClient } from "../nirvanaApp"; import { useRecoilValue } from "recoil"; -export enum Querytypes { - GET_USER_DETAILS = "GET_USER_DETAILS", -} - +// =========== API export const localHost = "http://localhost:5000/api"; const getUserDetails = async ( @@ -22,6 +20,20 @@ const getUserDetails = async ( }); }; +const search = async ( + idToken: string, + searchQuery: string +): Promise => { + return await axios.get(localHost + `/search?query=${searchQuery}`, { + headers: { Authorization: idToken }, + }); +}; + +// ====== QUERIES +export enum Querytypes { + GET_USER_DETAILS = "GET_USER_DETAILS", + GET_SEARCH_RESULTS = "GET_SEARCH_RESULTS", +} export function useGetUserDetails() { const authTokens = useRecoilValue($authTokens); @@ -34,6 +46,16 @@ export function useGetUserDetails() { ); } +export function useSearch() { + const authTokens = useRecoilValue($authTokens); + const searchQuery = useRecoilValue($searchQuery); + + return useQuery(Querytypes.GET_SEARCH_RESULTS, () => + search(authTokens.idToken, searchQuery) + ); +} + +// =========== MUTATIONS export function useCreateUser() { return useMutation(nirvanaApi.user.createUser, { onSettled: (data, error) => { diff --git a/packages/desktop/src/controller/recoil.tsx b/packages/desktop/src/controller/recoil.tsx index a9f4f36..63aaaee 100644 --- a/packages/desktop/src/controller/recoil.tsx +++ b/packages/desktop/src/controller/recoil.tsx @@ -8,3 +8,8 @@ export const $authTokens = atom<{ key: "AUTH_TOKENS", // unique ID (with respect to other atoms/selectors) default: null, // default value (aka initial value) }); + +export const $searchQuery = atom({ + key: "SEARCH_QUERY", + default: "", +}); diff --git a/packages/desktop/src/pages/Home/conversations/index.tsx b/packages/desktop/src/pages/Home/conversations/index.tsx new file mode 100644 index 0000000..dd8e3aa --- /dev/null +++ b/packages/desktop/src/pages/Home/conversations/index.tsx @@ -0,0 +1,41 @@ +import { + Add, + CardGiftcardRounded, + ContactsRounded, + LinkRounded, + PushPinRounded, +} from "@mui/icons-material"; + +export default function Conversations() { + return ( + <> + {/* actions navbar */} +
+ + + + + + + + + + + + + + +
+ + {/* pinned conversations */} +
+ + + + Pinned + + +
+ + ); +} diff --git a/packages/desktop/src/pages/Home/header/index.tsx b/packages/desktop/src/pages/Home/header/index.tsx new file mode 100644 index 0000000..fda4fd9 --- /dev/null +++ b/packages/desktop/src/pages/Home/header/index.tsx @@ -0,0 +1,35 @@ +import Logo, { LogoType } from "../../../components/Logo"; + +import { $searchQuery } from "../../../controller/recoil"; +import { useGetUserDetails } from "../../../controller/index"; +import { useRecoilState } from "recoil"; + +export default function Header() { + const { data: user } = useGetUserDetails(); + const [searchQuery, setSearchQuery] = useRecoilState($searchQuery); + + return ( +
+ + setSearchQuery(e.target.value)} + /> + + + + + cannot find + + +
+ ); +} diff --git a/packages/desktop/src/pages/Home/index.tsx b/packages/desktop/src/pages/Home/index.tsx index 76dc148..44e3c75 100644 --- a/packages/desktop/src/pages/Home/index.tsx +++ b/packages/desktop/src/pages/Home/index.tsx @@ -1,69 +1,23 @@ -import { - Add, - CardGiftcardRounded, - ContactsRounded, - LinkRounded, - PushPinRounded, -} from "@mui/icons-material"; import Logo, { LogoType } from "../../components/Logo"; +import { $searchQuery } from "../../controller/recoil"; +import Conversations from "./conversations"; +import Header from "./header"; +import Search from "./search"; import { useEffect } from "react"; -import { useGetUserDetails } from "../../controller/index"; +import { useGetUserDetails } from "../../controller/"; +import { useRecoilValue } from "recoil"; export default function Home() { const { data: user } = useGetUserDetails(); + const searchQuery = useRecoilValue($searchQuery); return (
{/* header */} -
- - +
- - - - cannot find - - -
- - {/* actions navbar */} -
- - - - - - - - - - - - - - -
- - {/* pinned conversations */} -
- - - - Pinned - - -
+ {searchQuery ? : }
); } diff --git a/packages/desktop/src/pages/Home/search/index.tsx b/packages/desktop/src/pages/Home/search/index.tsx new file mode 100644 index 0000000..58cc334 --- /dev/null +++ b/packages/desktop/src/pages/Home/search/index.tsx @@ -0,0 +1,24 @@ +import { $searchQuery } from "../../../controller/recoil"; +import { useEffect } from "react"; +import { useSearch } from "../../../controller"; + +export default function Search() { + const { data: searchResultsResponse, isLoading, isError } = useSearch(); + useEffect(() => {}, []); + + if (!searchResultsResponse?.users) { + return ( + + no results. please try someone's email or name. + + ); + } + + return ( +
+ {searchResultsResponse.users?.map((user) => { + return {user.name}; + })} +
+ ); +} diff --git a/packages/desktop/src/pages/Login/index.tsx b/packages/desktop/src/pages/Login/index.tsx index 4c6afe0..ab48509 100644 --- a/packages/desktop/src/pages/Login/index.tsx +++ b/packages/desktop/src/pages/Login/index.tsx @@ -11,6 +11,7 @@ import { useSetRecoilState } from "recoil"; export default function Login({ onReady }: { onReady: Function }) { const setAuthTokens = useSetRecoilState($authTokens); + const [isLoading, setIsLoading] = useState(false); const continueAuth = () => { setIsLoading(true); @@ -26,6 +27,8 @@ export default function Login({ onReady }: { onReady: Function }) { }) => { setAuthTokens(tokens); + console.log(tokens.idToken); + onReady(); }; @@ -34,8 +37,6 @@ export default function Login({ onReady }: { onReady: Function }) { window.electronAPI.store .get(STORE_ITEMS.AUTH_TOKENS) .then((tokensFromStore: any) => { - console.log(tokensFromStore); - if (tokensFromStore) { setIsLoading(true); @@ -68,8 +69,6 @@ export default function Login({ onReady }: { onReady: Function }) { // }; }, []); - const [isLoading, setIsLoading] = useState(false); - return (