Skip to content

Commit

Permalink
Merge pull request #11 from edwintantawi/dev
Browse files Browse the repository at this point in the history
v0.3.0
  • Loading branch information
edwintantawi authored Aug 7, 2023
2 parents 91e9853 + be4c7dd commit ee7bb78
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 61 deletions.
4 changes: 3 additions & 1 deletion app/analyze/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -184,7 +186,7 @@ export default function AnalyzePage() {
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Failed to Access Device Camera!
<Balancer>Failed to Access Device Camera!</Balancer>
</AlertDialogTitle>
<AlertDialogDescription>
Please make sure you have granted access to your device camera
Expand Down
8 changes: 7 additions & 1 deletion app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

import * as React from 'react';

import { Provider as ReactWrapBalancerProvider } from 'react-wrap-balancer';

import { TooltipProvider } from '~/components/ui/tooltip';

interface ProvidersProps {
children?: React.ReactNode;
}

export function Providers({ children }: ProvidersProps) {
return <TooltipProvider>{children}</TooltipProvider>;
return (
<TooltipProvider>
<ReactWrapBalancerProvider>{children}</ReactWrapBalancerProvider>
</TooltipProvider>
);
}
28 changes: 0 additions & 28 deletions app/search/not-found.tsx

This file was deleted.

38 changes: 36 additions & 2 deletions app/search/page.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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 {};
Expand All @@ -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 (
<main className="container flex flex-1 items-center py-4">
<div className="flex w-full flex-col items-center rounded-lg border p-6 text-center">
<Icons.NotFound size={50} className="mb-2" />

<h1 className="mb-1 text-xl font-bold">{constant.notFound.title}</h1>
<p className="mb-4 text-sm text-muted-foreground">
<Balancer>{constant.notFound.description}</Balancer>
</p>

<Button asChild className="w-full gap-2">
<Link href="/">
<Icons.Back size={20} /> Back To Home
</Link>
</Button>
</div>
</main>
);
}

return (
<main className="container flex-1">
Expand Down
10 changes: 2 additions & 8 deletions components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import * as React from 'react';

import { Balancer } from 'react-wrap-balancer';

interface HeaderProps {
title: string;
subTitle: React.ReactNode;
Expand All @@ -10,12 +8,8 @@ interface HeaderProps {
export function Header({ title, subTitle }: HeaderProps) {
return (
<header className="my-3 rounded-md border px-4 py-3">
<h1 className="font-bold">
<Balancer>{title}</Balancer>
</h1>
<p className="text-sm text-muted-foreground">
<Balancer>{subTitle}</Balancer>
</p>
<h1 className="font-bold">{title}</h1>
<p className="text-xs text-muted-foreground sm:text-sm">{subTitle}</p>
</header>
);
}
45 changes: 29 additions & 16 deletions components/search-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export function SearchBar() {
const inputRef = React.useRef<HTMLInputElement>(null);
const [query, setQuery] = React.useState(searchParams.get('q') ?? '');

const [isPending, startTransition] = React.useTransition();

const isEmptyQuery = query === '';

React.useEffect(() => {
Expand Down Expand Up @@ -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 (
Expand All @@ -62,6 +67,7 @@ export function SearchBar() {
/>
<Input
ref={inputRef}
disabled={isPending}
className={cn('truncate px-11', {
'pr-14': isEmptyQuery,
})}
Expand All @@ -70,21 +76,28 @@ export function SearchBar() {
onChange={handleChangeQuery}
/>

{isEmptyQuery ? (
<kbd className="pointer-events-none absolute bottom-1/2 right-2 flex h-7 translate-y-1/2 select-none items-center gap-1 rounded border bg-muted px-2 font-mono text-[10px] font-medium">
<span className="text-xs"></span>K
</kbd>
) : (
<Button
type="reset"
variant="secondary"
className="absolute bottom-1/2 right-1.5 h-7 w-7 translate-y-1/2 border p-1"
onClick={handleClearSearch}
>
<Icons.Cancel size={16} />
<span className="sr-only">Clear search</span>
</Button>
)}
<div className="absolute bottom-1/2 right-1.5 grid translate-y-1/2 place-items-center">
{isEmptyQuery ? (
<kbd className="pointer-events-none flex h-7 select-none items-center gap-1 rounded border bg-muted px-2 font-mono text-[10px] font-medium">
<span className="text-xs"></span>K
</kbd>
) : isPending ? (
<Icons.Loader
size={20}
className="mr-1 animate-spin text-muted-foreground"
/>
) : (
<Button
type="reset"
variant="secondary"
className="h-7 w-7 border p-1"
onClick={handleClearSearch}
>
<Icons.Cancel size={16} />
<span className="sr-only">Clear search</span>
</Button>
)}
</div>
</div>
</form>
);
Expand Down
8 changes: 3 additions & 5 deletions components/section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ export function Section({ children, icon, title, subtitle }: SectionProps) {
<div className="flex aspect-square w-10 shrink-0 items-center justify-center rounded-lg border bg-slate-100 text-primary">
{icon}
</div>
<div className="sm:-mt-1">
<h2 className="font-bold sm:text-lg">{title}</h2>
<p className="text-xs text-muted-foreground sm:-mt-1 sm:text-sm">
{subtitle}
</p>
<div>
<h2 className="font-bold">{title}</h2>
<p className="text-xs text-muted-foreground">{subtitle}</p>
</div>
</header>
{children}
Expand Down

0 comments on commit ee7bb78

Please sign in to comment.