diff --git a/package.json b/package.json
index 779b2bb..68f54b2 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@nextui-org/react": "^2.2.10",
"@tanstack/react-query": "^5.27.5",
+ "country-region-data": "^3.0.0",
"framer-motion": "^11.0.12",
"ky": "^1.2.2",
"luxon": "^3.4.4",
diff --git a/src/app/results/SearchPage.tsx b/src/app/results/SearchPage.tsx
index 95ca165..ad86e71 100644
--- a/src/app/results/SearchPage.tsx
+++ b/src/app/results/SearchPage.tsx
@@ -11,7 +11,9 @@ export const SearchPage: Component = () => {
return (
<>
-
+
+
+
>
);
};
diff --git a/src/app/trending/RegionSwitcher.tsx b/src/app/trending/RegionSwitcher.tsx
new file mode 100644
index 0000000..44dffe3
--- /dev/null
+++ b/src/app/trending/RegionSwitcher.tsx
@@ -0,0 +1,33 @@
+"use client";
+
+import { Component } from "@/typings/component";
+import { Region } from "@/utils/getRegionCodes";
+
+import { Autocomplete, AutocompleteItem } from "@nextui-org/autocomplete";
+import { useRouter } from "next/navigation";
+
+export const RegionSwitcher: Component<{
+ regions: Region[];
+ currentRegion: Region | null;
+}> = ({ currentRegion, regions }) => {
+ const router = useRouter();
+
+ return (
+ {
+ if (typeof key === "string" && key.length != 0)
+ return router.push(`/trending?region=${key}`);
+ }}
+ className="max-w-xs"
+ >
+ {(item) => (
+ {item.name}
+ )}
+
+ );
+};
diff --git a/src/app/trending/Trending.tsx b/src/app/trending/Trending.tsx
index b0e20fe..6bc8c50 100644
--- a/src/app/trending/Trending.tsx
+++ b/src/app/trending/Trending.tsx
@@ -5,47 +5,95 @@ import { useClient } from "@/hooks/useClient";
import { useQuery } from "@tanstack/react-query";
import { Button } from "@nextui-org/button";
-import { CircularProgress } from "@nextui-org/progress";
import { Spacer } from "@nextui-org/spacer";
import { VideoCard } from "./VideoCard";
+import { LoadingPage } from "@/components/LoadingPage";
+import { useSearchParams } from "next/navigation";
+import { useMemo } from "react";
+import getRegionCodes from "@/utils/getRegionCodes";
+import { RegionSwitcher } from "./RegionSwitcher";
+import { defaultRegion } from "@/constants";
export const Trending: Component = ({}) => {
const client = useClient();
- const { isLoading, error, refetch, data } = useQuery({
- queryKey: ["trending"],
- queryFn: () => client.getTrending("NL")
+ const searchParams = useSearchParams();
+ const validRegions = useMemo(() => getRegionCodes(), []);
+
+ const specifiedRegion =
+ searchParams.get("region")?.toUpperCase() ?? defaultRegion;
+
+ const [region, regionError] = useMemo(() => {
+ const foundRegion = validRegions.find(
+ (validRegion) => validRegion.code === specifiedRegion
+ );
+
+ if (foundRegion === undefined)
+ return [null, new Error(`Region \`${specifiedRegion}\` is invalid`)];
+
+ return [foundRegion, null];
+ }, [specifiedRegion, validRegions]);
+
+ const {
+ isLoading,
+ error: fetchError,
+ refetch,
+ data
+ } = useQuery({
+ queryKey: ["trending", region],
+ queryFn: () => {
+ if (region === null) return;
+
+ return client.getTrending(region.code);
+ },
+ enabled: regionError === null
});
+ const noDataError = useMemo(() => {
+ if (data && data.length === 0)
+ return new Error(
+ `Could not find any trending video's in region \`${region?.name}\``
+ );
+
+ return null;
+ }, [data]);
+
+ const error: Error | null = regionError ?? fetchError ?? noDataError ?? null;
+
return (
-
- {isLoading && !data && (
-
-
-
- )}
- {error && (
-
-
-
- An error occurred loading the trending page
-
-
{error.toString()}
-
-
+ <>
+ {isLoading && !data &&
}
+ {!isLoading && (
+
+
+
+
+
Trending
+ {error && (
+
+
+
+ An error occurred loading the trending page
+
+ {error.toString()}
+
+
+
+
+ )}
+ {data && error === null && (
+
+ {data.map((video) => (
+
+ ))}
+
+ )}
)}
- {data && (
-
- {data.map((video) => (
-
- ))}
-
- )}
-
+ >
);
};
diff --git a/src/app/trending/VideoCard.tsx b/src/app/trending/VideoCard.tsx
index b0d1290..da7800c 100644
--- a/src/app/trending/VideoCard.tsx
+++ b/src/app/trending/VideoCard.tsx
@@ -10,9 +10,17 @@ import formatDuration from "@/utils/formatDuration";
export const VideoCard: Component<{ data: TrendingVideo }> = ({
data: video
}) => {
+ const handleContextMenu = () => {};
+
return (
-
+ {
+ e.preventDefault();
+ handleContextMenu();
+ }}
+ >
-
+ }>
+
+
>
);
}
diff --git a/src/components/LoadingPage.tsx b/src/components/LoadingPage.tsx
new file mode 100644
index 0000000..d0f9187
--- /dev/null
+++ b/src/components/LoadingPage.tsx
@@ -0,0 +1,12 @@
+"use client";
+
+import { Component } from "@/typings/component";
+import { CircularProgress } from "@nextui-org/progress";
+
+export const LoadingPage: Component = () => {
+ return (
+
+
+
+ );
+};
diff --git a/src/components/Search.tsx b/src/components/Search.tsx
index e799786..212713b 100644
--- a/src/components/Search.tsx
+++ b/src/components/Search.tsx
@@ -12,7 +12,7 @@ export const Search: Component<{ initialQueryValue?: string }> = ({
}) => {
const client = useClient();
- const [searchQuery, setSearchQuery] = useState(initialQueryValue ?? "");
+ const [searchQuery, setSearchQuery] = useState("");
const [searchQueryDebounced] = useDebounce(searchQuery, 500);
@@ -23,8 +23,6 @@ export const Search: Component<{ initialQueryValue?: string }> = ({
});
const handleSubmit: FormEventHandler = (e) => {
- // e.preventDefault();
-
console.log(searchQuery);
};
diff --git a/src/constants.ts b/src/constants.ts
new file mode 100644
index 0000000..b302473
--- /dev/null
+++ b/src/constants.ts
@@ -0,0 +1 @@
+export const defaultRegion = "US" as const;
diff --git a/src/utils/getRegionCodes.ts b/src/utils/getRegionCodes.ts
new file mode 100644
index 0000000..1bfa20f
--- /dev/null
+++ b/src/utils/getRegionCodes.ts
@@ -0,0 +1,15 @@
+import { allCountries } from "country-region-data";
+
+export interface Region {
+ code: string;
+ name: string;
+}
+
+const getRegionCodes = (): Region[] => {
+ return allCountries.map((country) => ({
+ name: country[0],
+ code: country[1]
+ }));
+};
+
+export default getRegionCodes;
diff --git a/yarn.lock b/yarn.lock
index 7eddb01..81b82cf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3676,6 +3676,11 @@ core-js-compat@^3.31.0, core-js-compat@^3.34.0:
dependencies:
browserslist "^4.22.3"
+country-region-data@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/country-region-data/-/country-region-data-3.0.0.tgz#9251cff57c22e450cbe96a7e50a3a23362d4304a"
+ integrity sha512-jpZwc6coXayi3aAv2HHTC9vhwRJB2zdur+coBlIZo1IVMonzylRR4Asf5j7evtUzdZPODdHrJ8CzEFK6MGUAgg==
+
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"