diff --git a/app/analyze/page.tsx b/app/analyze/page.tsx index 921de21..c6da804 100644 --- a/app/analyze/page.tsx +++ b/app/analyze/page.tsx @@ -3,6 +3,8 @@ import * as React from 'react'; import Link from 'next/link'; +import { Balancer } from 'react-wrap-balancer'; + import { analyzeFoodImageAction } from '~/app/analyze/actions'; import { Header } from '~/components/header'; import { Icons } from '~/components/icons'; @@ -184,7 +186,7 @@ export default function AnalyzePage() { - Failed to Access Device Camera! + Failed to Access Device Camera! Please make sure you have granted access to your device camera diff --git a/app/providers.tsx b/app/providers.tsx index 8969fbe..e805b43 100644 --- a/app/providers.tsx +++ b/app/providers.tsx @@ -2,6 +2,8 @@ import * as React from 'react'; +import { Provider as ReactWrapBalancerProvider } from 'react-wrap-balancer'; + import { TooltipProvider } from '~/components/ui/tooltip'; interface ProvidersProps { @@ -9,5 +11,9 @@ interface ProvidersProps { } export function Providers({ children }: ProvidersProps) { - return {children}; + return ( + + {children} + + ); } diff --git a/app/search/not-found.tsx b/app/search/not-found.tsx deleted file mode 100644 index 9bf1b87..0000000 --- a/app/search/not-found.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Link from 'next/link'; - -import { Balancer } from 'react-wrap-balancer'; - -import { constant } from '~/app/search/constant'; -import { Icons } from '~/components/icons'; -import { Button } from '~/components/ui/button'; - -export default function Notfound() { - return ( -
-
- - -

{constant.notFound.title}

-

- {constant.notFound.description} -

- - -
-
- ); -} diff --git a/app/search/page.tsx b/app/search/page.tsx index 7c73b98..0b708db 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -1,10 +1,15 @@ import * as React from 'react'; import { Metadata } from 'next'; -import { notFound, redirect } from 'next/navigation'; +import Link from 'next/link'; +import { redirect } from 'next/navigation'; + +import { Balancer } from 'react-wrap-balancer'; import { constant } from '~/app/search/constant'; import { Header } from '~/components/header'; +import { Icons } from '~/components/icons'; import { RecipeCard } from '~/components/recipe-card'; +import { Button } from '~/components/ui/button'; import { spoonacular } from '~/lib/spoonacular'; import { getRecipeImageById } from '~/lib/utils'; @@ -24,11 +29,18 @@ export async function generateMetadata({ return { title: constant.notFound.title, description: constant.notFound.description, + openGraph: { + title: constant.notFound.title, + description: constant.notFound.description, + }, }; } return { title: `Search results for ${searchParams.q}`, + openGraph: { + title: `Search results for ${searchParams.q}`, + }, }; } catch (error) { return {}; @@ -40,7 +52,29 @@ export default async function SearchPage({ searchParams }: SearchPageProps) { const recipes = await spoonacular.searchRecipesByQuery(searchParams.q); - if (recipes.length === 0) return notFound(); + // related to this issue https://github.com/edwintantawi/foodsery/issues/5 + // if the search result is empty, we will show a not found page here + // instead of using not-found.tsx page + if (recipes.length === 0) { + return ( +
+
+ + +

{constant.notFound.title}

+

+ {constant.notFound.description} +

+ + +
+
+ ); + } return (
diff --git a/components/header.tsx b/components/header.tsx index a713425..1e58190 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -1,7 +1,5 @@ import * as React from 'react'; -import { Balancer } from 'react-wrap-balancer'; - interface HeaderProps { title: string; subTitle: React.ReactNode; @@ -10,12 +8,8 @@ interface HeaderProps { export function Header({ title, subTitle }: HeaderProps) { return (
-

- {title} -

-

- {subTitle} -

+

{title}

+

{subTitle}

); } diff --git a/components/search-bar.tsx b/components/search-bar.tsx index d9b4e2c..b5f5555 100644 --- a/components/search-bar.tsx +++ b/components/search-bar.tsx @@ -15,6 +15,8 @@ export function SearchBar() { const inputRef = React.useRef(null); const [query, setQuery] = React.useState(searchParams.get('q') ?? ''); + const [isPending, startTransition] = React.useTransition(); + const isEmptyQuery = query === ''; React.useEffect(() => { @@ -50,7 +52,10 @@ export function SearchBar() { if (!query) return; inputRef.current?.blur(); - router.push(`/search?q=${query}`); + + startTransition(() => { + router.push(`/search?q=${query}`); + }); }; return ( @@ -62,6 +67,7 @@ export function SearchBar() { /> - {isEmptyQuery ? ( - - K - - ) : ( - - )} +
+ {isEmptyQuery ? ( + + K + + ) : isPending ? ( + + ) : ( + + )} +
); diff --git a/components/section.tsx b/components/section.tsx index 06aa1b2..1a2e6a6 100644 --- a/components/section.tsx +++ b/components/section.tsx @@ -14,11 +14,9 @@ export function Section({ children, icon, title, subtitle }: SectionProps) {
{icon}
-
-

{title}

-

- {subtitle} -

+
+

{title}

+

{subtitle}

{children}