From 189c651941064a889867815e08bb5b9680554e73 Mon Sep 17 00:00:00 2001 From: Guus van Meerveld Date: Fri, 5 Apr 2024 21:04:38 +0200 Subject: [PATCH] restructured youtube paths, added search modal --- src/app/(youtube)/SearchModal.tsx | 54 ++++++++++++++ src/app/(youtube)/layout.tsx | 14 ++++ src/app/{ => (youtube)}/results/ErrorPage.tsx | 0 .../{ => (youtube)}/results/SearchPage.tsx | 6 +- .../results/SearchPageBody/Channel.tsx | 0 .../SearchPageBody/LoadingNextPage.tsx | 0 .../results/SearchPageBody/Playlist.tsx | 0 .../results/SearchPageBody/Video.tsx | 0 .../results/SearchPageBody/constants.ts | 0 .../results/SearchPageBody/index.tsx | 0 src/app/{ => (youtube)}/results/page.tsx | 4 +- .../trending/RegionSwitcher.tsx | 0 src/app/{ => (youtube)}/trending/Trending.tsx | 0 src/app/{ => (youtube)}/trending/page.tsx | 0 src/app/{ => (youtube)}/watch/Comments.tsx | 0 src/app/{ => (youtube)}/watch/Description.tsx | 0 .../watch/HighlightRenderer.tsx | 0 .../{ => (youtube)}/watch/Player/index.tsx | 0 src/app/{ => (youtube)}/watch/Related.tsx | 0 src/app/{ => (youtube)}/watch/Watch.tsx | 0 src/app/{ => (youtube)}/watch/page.tsx | 0 src/app/results/SearchPageHeader.tsx | 37 ---------- .../results => components/Search}/Filter.tsx | 0 .../{Search.tsx => Search/Input.tsx} | 74 +++++++++---------- src/components/Search/index.tsx | 41 ++++++++++ src/hooks/useSearch.ts | 4 +- 26 files changed, 150 insertions(+), 84 deletions(-) create mode 100644 src/app/(youtube)/SearchModal.tsx create mode 100644 src/app/(youtube)/layout.tsx rename src/app/{ => (youtube)}/results/ErrorPage.tsx (100%) rename src/app/{ => (youtube)}/results/SearchPage.tsx (83%) rename src/app/{ => (youtube)}/results/SearchPageBody/Channel.tsx (100%) rename src/app/{ => (youtube)}/results/SearchPageBody/LoadingNextPage.tsx (100%) rename src/app/{ => (youtube)}/results/SearchPageBody/Playlist.tsx (100%) rename src/app/{ => (youtube)}/results/SearchPageBody/Video.tsx (100%) rename src/app/{ => (youtube)}/results/SearchPageBody/constants.ts (100%) rename src/app/{ => (youtube)}/results/SearchPageBody/index.tsx (100%) rename src/app/{ => (youtube)}/results/page.tsx (81%) rename src/app/{ => (youtube)}/trending/RegionSwitcher.tsx (100%) rename src/app/{ => (youtube)}/trending/Trending.tsx (100%) rename src/app/{ => (youtube)}/trending/page.tsx (100%) rename src/app/{ => (youtube)}/watch/Comments.tsx (100%) rename src/app/{ => (youtube)}/watch/Description.tsx (100%) rename src/app/{ => (youtube)}/watch/HighlightRenderer.tsx (100%) rename src/app/{ => (youtube)}/watch/Player/index.tsx (100%) rename src/app/{ => (youtube)}/watch/Related.tsx (100%) rename src/app/{ => (youtube)}/watch/Watch.tsx (100%) rename src/app/{ => (youtube)}/watch/page.tsx (100%) delete mode 100644 src/app/results/SearchPageHeader.tsx rename src/{app/results => components/Search}/Filter.tsx (100%) rename src/components/{Search.tsx => Search/Input.tsx} (50%) create mode 100644 src/components/Search/index.tsx diff --git a/src/app/(youtube)/SearchModal.tsx b/src/app/(youtube)/SearchModal.tsx new file mode 100644 index 0000000..be23282 --- /dev/null +++ b/src/app/(youtube)/SearchModal.tsx @@ -0,0 +1,54 @@ +"use client"; + +import { Button } from "@nextui-org/react"; +import { FC, useState } from "react"; +import { useHotkeys } from "react-hotkeys-hook"; + +import { + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader +} from "@nextui-org/modal"; + +import { Search } from "@/components/Search"; + +export const SearchModal: FC = () => { + const [isOpen, setOpen] = useState(false); + + useHotkeys( + "ctrl+k", + () => { + setOpen(true); + }, + { preventDefault: true } + ); + + return ( + { + setOpen(isOpen); + }} + size="2xl" + > + + {(onClose) => ( + <> + Search + + onClose()} /> + + + + + + + )} + + + ); +}; diff --git a/src/app/(youtube)/layout.tsx b/src/app/(youtube)/layout.tsx new file mode 100644 index 0000000..b325b56 --- /dev/null +++ b/src/app/(youtube)/layout.tsx @@ -0,0 +1,14 @@ +import { SearchModal } from "./SearchModal"; + +import { Component } from "@/typings/component"; + +const YoutubeLayout: Component = ({ children }) => { + return ( + <> + {children} + + + ); +}; + +export default YoutubeLayout; diff --git a/src/app/results/ErrorPage.tsx b/src/app/(youtube)/results/ErrorPage.tsx similarity index 100% rename from src/app/results/ErrorPage.tsx rename to src/app/(youtube)/results/ErrorPage.tsx diff --git a/src/app/results/SearchPage.tsx b/src/app/(youtube)/results/SearchPage.tsx similarity index 83% rename from src/app/results/SearchPage.tsx rename to src/app/(youtube)/results/SearchPage.tsx index da92e59..0814d53 100644 --- a/src/app/results/SearchPage.tsx +++ b/src/app/(youtube)/results/SearchPage.tsx @@ -6,9 +6,9 @@ import { FC, useMemo } from "react"; import { SearchType, SearchTypeModel } from "@/client/typings/search/options"; import { Container } from "@/components/Container"; +import { Search } from "@/components/Search"; import { SearchPageBody } from "./SearchPageBody"; -import { SearchPageHeader } from "./SearchPageHeader"; export const SearchPage: FC = () => { const searchParams = useSearchParams(); @@ -16,7 +16,7 @@ export const SearchPage: FC = () => { const query = useMemo(() => { const param = searchParams.get("search_query"); - if (param === null || param.length === null) return; + if (param === null || param.length === 0) return; return param; }, [searchParams]); @@ -34,7 +34,7 @@ export const SearchPage: FC = () => { return ( <> - + {query && } diff --git a/src/app/results/SearchPageBody/Channel.tsx b/src/app/(youtube)/results/SearchPageBody/Channel.tsx similarity index 100% rename from src/app/results/SearchPageBody/Channel.tsx rename to src/app/(youtube)/results/SearchPageBody/Channel.tsx diff --git a/src/app/results/SearchPageBody/LoadingNextPage.tsx b/src/app/(youtube)/results/SearchPageBody/LoadingNextPage.tsx similarity index 100% rename from src/app/results/SearchPageBody/LoadingNextPage.tsx rename to src/app/(youtube)/results/SearchPageBody/LoadingNextPage.tsx diff --git a/src/app/results/SearchPageBody/Playlist.tsx b/src/app/(youtube)/results/SearchPageBody/Playlist.tsx similarity index 100% rename from src/app/results/SearchPageBody/Playlist.tsx rename to src/app/(youtube)/results/SearchPageBody/Playlist.tsx diff --git a/src/app/results/SearchPageBody/Video.tsx b/src/app/(youtube)/results/SearchPageBody/Video.tsx similarity index 100% rename from src/app/results/SearchPageBody/Video.tsx rename to src/app/(youtube)/results/SearchPageBody/Video.tsx diff --git a/src/app/results/SearchPageBody/constants.ts b/src/app/(youtube)/results/SearchPageBody/constants.ts similarity index 100% rename from src/app/results/SearchPageBody/constants.ts rename to src/app/(youtube)/results/SearchPageBody/constants.ts diff --git a/src/app/results/SearchPageBody/index.tsx b/src/app/(youtube)/results/SearchPageBody/index.tsx similarity index 100% rename from src/app/results/SearchPageBody/index.tsx rename to src/app/(youtube)/results/SearchPageBody/index.tsx diff --git a/src/app/results/page.tsx b/src/app/(youtube)/results/page.tsx similarity index 81% rename from src/app/results/page.tsx rename to src/app/(youtube)/results/page.tsx index 74f42e5..5749800 100644 --- a/src/app/results/page.tsx +++ b/src/app/(youtube)/results/page.tsx @@ -2,9 +2,9 @@ import { NextPage } from "next"; import { Suspense } from "react"; import { Container } from "@/components/Container"; +import { Search } from "@/components/Search"; import { SearchPage } from "./SearchPage"; -import { SearchPageHeader } from "./SearchPageHeader"; const Page: NextPage = () => { return ( @@ -12,7 +12,7 @@ const Page: NextPage = () => { - + } > diff --git a/src/app/trending/RegionSwitcher.tsx b/src/app/(youtube)/trending/RegionSwitcher.tsx similarity index 100% rename from src/app/trending/RegionSwitcher.tsx rename to src/app/(youtube)/trending/RegionSwitcher.tsx diff --git a/src/app/trending/Trending.tsx b/src/app/(youtube)/trending/Trending.tsx similarity index 100% rename from src/app/trending/Trending.tsx rename to src/app/(youtube)/trending/Trending.tsx diff --git a/src/app/trending/page.tsx b/src/app/(youtube)/trending/page.tsx similarity index 100% rename from src/app/trending/page.tsx rename to src/app/(youtube)/trending/page.tsx diff --git a/src/app/watch/Comments.tsx b/src/app/(youtube)/watch/Comments.tsx similarity index 100% rename from src/app/watch/Comments.tsx rename to src/app/(youtube)/watch/Comments.tsx diff --git a/src/app/watch/Description.tsx b/src/app/(youtube)/watch/Description.tsx similarity index 100% rename from src/app/watch/Description.tsx rename to src/app/(youtube)/watch/Description.tsx diff --git a/src/app/watch/HighlightRenderer.tsx b/src/app/(youtube)/watch/HighlightRenderer.tsx similarity index 100% rename from src/app/watch/HighlightRenderer.tsx rename to src/app/(youtube)/watch/HighlightRenderer.tsx diff --git a/src/app/watch/Player/index.tsx b/src/app/(youtube)/watch/Player/index.tsx similarity index 100% rename from src/app/watch/Player/index.tsx rename to src/app/(youtube)/watch/Player/index.tsx diff --git a/src/app/watch/Related.tsx b/src/app/(youtube)/watch/Related.tsx similarity index 100% rename from src/app/watch/Related.tsx rename to src/app/(youtube)/watch/Related.tsx diff --git a/src/app/watch/Watch.tsx b/src/app/(youtube)/watch/Watch.tsx similarity index 100% rename from src/app/watch/Watch.tsx rename to src/app/(youtube)/watch/Watch.tsx diff --git a/src/app/watch/page.tsx b/src/app/(youtube)/watch/page.tsx similarity index 100% rename from src/app/watch/page.tsx rename to src/app/(youtube)/watch/page.tsx diff --git a/src/app/results/SearchPageHeader.tsx b/src/app/results/SearchPageHeader.tsx deleted file mode 100644 index 8bb9a2b..0000000 --- a/src/app/results/SearchPageHeader.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client"; - -import { FC } from "react"; - -import { useSearch } from "@/hooks/useSearch"; - -import { SearchType } from "@/client/typings/search/options"; - -import { Search as SearchInput } from "@/components/Search"; - -import { Filter } from "./Filter"; - -export const SearchPageHeader: FC<{ - query?: string; - filter?: SearchType; -}> = ({ query, filter }) => { - const searchFor = useSearch(); - - const searchForQuery = (query: string): void => { - searchFor(query, filter); - }; - - const searchWithFilter = (filter: SearchType): void => { - if (query) searchFor(query, filter); - }; - - return ( -
-
- -
-
- -
-
- ); -}; diff --git a/src/app/results/Filter.tsx b/src/components/Search/Filter.tsx similarity index 100% rename from src/app/results/Filter.tsx rename to src/components/Search/Filter.tsx diff --git a/src/components/Search.tsx b/src/components/Search/Input.tsx similarity index 50% rename from src/components/Search.tsx rename to src/components/Search/Input.tsx index 9cc0989..ee1463b 100644 --- a/src/components/Search.tsx +++ b/src/components/Search/Input.tsx @@ -10,7 +10,7 @@ import { Autocomplete, AutocompleteItem } from "@nextui-org/autocomplete"; import { useClient } from "@/hooks/useClient"; -export const Search: FC<{ +export const Input: FC<{ query?: string; setQuery: (query: string) => void; }> = ({ setQuery, query }) => { @@ -29,10 +29,6 @@ export const Search: FC<{ } }); - const submit = (query: string): void => { - setQuery(query); - }; - const suggestions = useMemo( () => data?.map((suggestion) => ({ @@ -43,41 +39,39 @@ export const Search: FC<{ ); return ( -
submit(searchQuery)}> - { - if (e.key === "Enter") { - submit(searchQuery); - } - }} - startContent={} - defaultItems={suggestions} - onSelectionChange={(key) => { - if (key === null) return; + { + if (e.key === "Enter") { + setQuery(searchQuery); + } + }} + startContent={} + defaultItems={suggestions} + onSelectionChange={(key) => { + if (key === null) return; - setSearchQuery(key.toString()); - submit(key.toString()); - }} - errorMessage={error !== null ? error.toString() : ""} - isInvalid={error !== null} - required - type="text" - label="Search" - variant="bordered" - placeholder="Search for videos" - > - {(suggestion) => ( - - {suggestion.label} - - )} - - + setSearchQuery(key.toString()); + setQuery(key.toString()); + }} + errorMessage={error !== null ? error.toString() : ""} + isInvalid={error !== null} + required + type="text" + label="Search" + variant="bordered" + placeholder="Search for videos" + > + {(suggestion) => ( + + {suggestion.label} + + )} +
); }; diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx new file mode 100644 index 0000000..0d6fd55 --- /dev/null +++ b/src/components/Search/index.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { FC } from "react"; + +import { useSearch } from "@/hooks/useSearch"; + +import { SearchType } from "@/client/typings/search/options"; + +import { Filter } from "./Filter"; +import { Input } from "./Input"; + +export const Search: FC<{ + query?: string; + filter?: SearchType; + onSearch?: (query: string, filter: SearchType) => void; +}> = ({ query = "", filter = "all", onSearch }) => { + const searchFor = useSearch(); + + const searchForQuery = (query: string): void => { + searchFor(query, filter); + if (onSearch) onSearch(query, filter); + }; + + const searchWithFilter = (filter: SearchType): void => { + searchFor(query, filter); + if (onSearch) onSearch(query, filter); + }; + + return ( +
+
+
+ +
+
+ +
+
+
+ ); +}; diff --git a/src/hooks/useSearch.ts b/src/hooks/useSearch.ts index 3de5a9d..edf485c 100644 --- a/src/hooks/useSearch.ts +++ b/src/hooks/useSearch.ts @@ -4,10 +4,10 @@ import { SearchType } from "@/client/typings/search/options"; const searchPathname = "/results"; -export const useSearch = (): ((query: string, filter?: SearchType) => void) => { +export const useSearch = (): ((query: string, filter: SearchType) => void) => { const router = useRouter(); - return (query, filter = "all") => { + return (query, filter) => { const params = new URLSearchParams(); params.set("search_query", query);