fix: recipes page wasted too much vertical space above content on mobile
Search bar forced its own full-width row (w-full), pushing Sort/Filter to a second row below it — on mobile that's title + action buttons + search row + sort/filter row + toolbar row before any recipe appears. Sort/Filter now go icon-only below sm: (text labels hidden, matching the convention already used for compact-view badges), letting Search share one row with both instead of forcing its own. Also tightened the title size and inter-section spacing on mobile (unchanged at sm: and up). Verified at a real 390px mobile viewport: first recipe card now clears with room to spare, versus barely visible at the same viewport height before. Desktop screenshot confirms zero visual change there.
This commit is contained in:
@@ -104,7 +104,7 @@ export default async function RecipesPage({ searchParams }: { searchParams: Sear
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-4 sm:space-y-6">
|
||||||
<div className="flex items-center gap-2 text-sm">
|
<div className="flex items-center gap-2 text-sm">
|
||||||
<span className="rounded-full bg-accent px-3 py-1 font-medium">{m.recipes.tabMine}</span>
|
<span className="rounded-full bg-accent px-3 py-1 font-medium">{m.recipes.tabMine}</span>
|
||||||
<Link href="/recipes/favorites" className="rounded-full px-3 py-1 text-muted-foreground hover:bg-accent">
|
<Link href="/recipes/favorites" className="rounded-full px-3 py-1 text-muted-foreground hover:bg-accent">
|
||||||
|
|||||||
@@ -127,11 +127,11 @@ export function RecipesHeader({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-4">
|
<div className="space-y-3 sm:space-y-4">
|
||||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-3">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">{t("title")}</h1>
|
<h1 className="text-2xl sm:text-3xl font-bold tracking-tight">{t("title")}</h1>
|
||||||
<p className="text-muted-foreground mt-1">
|
<p className="text-muted-foreground text-sm sm:text-base mt-0.5 sm:mt-1">
|
||||||
{count === 0
|
{count === 0
|
||||||
? t("subtitle")
|
? t("subtitle")
|
||||||
: t(count !== 1 ? "resultPlural" : "resultSingular", { count })}
|
: t(count !== 1 ? "resultPlural" : "resultSingular", { count })}
|
||||||
@@ -154,8 +154,9 @@ export function RecipesHeader({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{/* Search */}
|
{/* Search — shares the row with Sort/Filter even on mobile now that
|
||||||
<div className="relative w-full sm:flex-1 sm:min-w-[200px] sm:max-w-sm">
|
those are icon-only there, instead of forcing a whole row to itself. */}
|
||||||
|
<div className="relative flex-1 min-w-[120px] sm:min-w-[200px] sm:max-w-sm">
|
||||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
|
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
|
||||||
<Input
|
<Input
|
||||||
value={query}
|
value={query}
|
||||||
@@ -178,11 +179,11 @@ export function RecipesHeader({
|
|||||||
<DropdownMenuTrigger
|
<DropdownMenuTrigger
|
||||||
className={cn(
|
className={cn(
|
||||||
buttonVariants({ variant: sortChanged ? "secondary" : "outline", size: "sm" }),
|
buttonVariants({ variant: sortChanged ? "secondary" : "outline", size: "sm" }),
|
||||||
"gap-1.5"
|
"gap-1.5 shrink-0"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ArrowUpDown className="h-4 w-4" />
|
<ArrowUpDown className="h-4 w-4" />
|
||||||
{SORT_KEYS[initialSort] ? t(SORT_KEYS[initialSort]) : t("sort")}
|
<span className="hidden sm:inline">{SORT_KEYS[initialSort] ? t(SORT_KEYS[initialSort]) : t("sort")}</span>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start">
|
<DropdownMenuContent align="start">
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
@@ -206,11 +207,11 @@ export function RecipesHeader({
|
|||||||
<DropdownMenuTrigger
|
<DropdownMenuTrigger
|
||||||
className={cn(
|
className={cn(
|
||||||
buttonVariants({ variant: activeFilterCount > 0 ? "secondary" : "outline", size: "sm" }),
|
buttonVariants({ variant: activeFilterCount > 0 ? "secondary" : "outline", size: "sm" }),
|
||||||
"gap-1.5"
|
"gap-1.5 shrink-0"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<SlidersHorizontal className="h-4 w-4" />
|
<SlidersHorizontal className="h-4 w-4" />
|
||||||
{t("filter")}
|
<span className="hidden sm:inline">{t("filter")}</span>
|
||||||
{activeFilterCount > 0 && (
|
{activeFilterCount > 0 && (
|
||||||
<Badge variant="secondary" className="ml-1 h-4 min-w-4 px-1 text-xs">
|
<Badge variant="secondary" className="ml-1 h-4 min-w-4 px-1 text-xs">
|
||||||
{activeFilterCount}
|
{activeFilterCount}
|
||||||
|
|||||||
Reference in New Issue
Block a user