Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/1920x880-HERO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/NEW-GRAY-DECAL-WITH-CHEF.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/browse-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/recipes-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/(pages)/(public)/(home)/components/categories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const MarqueeItem: React.FC<{ text: string; src: string }> = ({
}) => (
<div className="flex flex-col items-center gap-2.5 w-60 px-5">
<div className="relative aspect-square w-full overflow-hidden golden-circle rounded-full">
<Image src={src} alt={text || "Category image"} fill quality={80} />
<Image src={src} alt={text || "Category image"} fill quality={95} />
</div>
<h5 className="uppercase truncate max-w-[90%]">{text}</h5>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(pages)/(public)/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default async function Home() {
params={["all"]}
seeMore
/>
<section className="flex aspect-section-lg bg-black text-white">
<section className="flex aspect-section bg-black text-white">
<div className="w-full flex items-center justify-center">
<div className="aspect-[123/100] bg-black h-full">
<div className="w-full h-full p-20 flex flex-col items-center justify-center text-center gap-20">
Expand Down
2 changes: 1 addition & 1 deletion src/app/(pages)/(public)/browse/_components/marquee.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const MarqueeItem: React.FC<{ text: string; src: string }> = ({
}) => (
<div className="flex flex-col items-center gap-2.5 w-60 px-5">
<div className="relative aspect-square w-full overflow-hidden golden-circle rounded-full">
<Image src={src} alt={text || "Category image"} fill quality={80} />
<Image src={src} alt={text || "Category image"} fill quality={95} />
</div>
<h5 className="uppercase truncate max-w-[90%] text-white">{text}</h5>
</div>
Expand Down
21 changes: 9 additions & 12 deletions src/app/(pages)/(public)/recipes/[_id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { API } from "@/api";
import { Recipe } from "@/types/recipe";
import { Suspense } from "react";
import { ClientSide, Review, FavButton } from "./_components";
import { ClientSide } from "./_components";
import { Metadata, ResolvingMetadata } from "next";
import {
Button,
RecipeDisplayBlock,
SectionHeader,
Image,
Tag,
DisplayResource,
} from "@/components";
import clsx from "clsx";
import Link from "next/link";
import { Clock, Ham, Loader2, MessageSquare } from "lucide-react";
import { Clock, Ham, Loader2 } from "lucide-react";
import { Creator } from "./_components/creator";

export async function generateMetadata(
Expand All @@ -22,7 +21,7 @@ export async function generateMetadata(
}: {
params: Promise<{ _id: string }>;
},
parent: ResolvingMetadata,
parent: ResolvingMetadata
): Promise<Metadata> {
const { _id } = await params;

Expand Down Expand Up @@ -78,7 +77,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
console.log(recipe.src);
return (
<>
<section className="flex gap-10 w-full aspect-section p-20 -mt-10 recipe-details-man-decal-bg">
<section className="flex gap-10 w-full aspect-section-lg p-20 -mt-10 recipe-details-man-decal-bg">
<div className="flex-1 bg-gray/10 relative rounded-lg hover:bg-gray-dark/10 delay-750 ease-in duration-500 transition-all">
<Image
src={typeof recipe.src === "object" ? recipe.src.url : recipe.src}
Expand Down Expand Up @@ -107,9 +106,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
</div>
<Link
href={`/users/${recipe.user._id}`}
className={clsx(
"bg-black p-5 rounded-lg flex w-full h-25 gap-5",
)}
className={clsx("py-5 rounded-lg flex w-full h-25 gap-5")}
>
<div className="w-15 aspect-square">
<Image
Expand All @@ -128,7 +125,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
<div className="w-full h-full flex justify-between">
<div className="w-full flex justify-between min-w-0">
<div className="flex flex-col justify-center items-start gap-1 min-w-0 overflow-hidden">
<h4 className="text-white truncate w-full">
<h4 className="text-black truncate w-full">
{recipe.user.firstName && recipe.user.lastName
? `${recipe.user.firstName} ${recipe.user.lastName}`.trim()
: `@${recipe.user.username}`}
Expand All @@ -137,7 +134,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
{recipe.user.firstName &&
recipe.user.lastName &&
recipe.user.username && (
<small className="text-gray-light truncate w-full">
<small className="text-gray-dark truncate w-full">
@{recipe.user.username}
</small>
)}
Expand Down Expand Up @@ -198,7 +195,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
<li
key={idx}
>{`${value} - ${quantity}${unitsOfMeasurement}`}</li>
),
)
)}
</ul>
</div>
Expand Down Expand Up @@ -266,7 +263,7 @@ export async function generateStaticParams() {
console.log(
recipes.map((recipe) => ({
_id: String(recipe._id),
})),
}))
);
return recipes.map((recipe) => ({
_id: String(recipe._id),
Expand Down
40 changes: 25 additions & 15 deletions src/app/(pages)/(public)/recipes/_components/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { z } from "zod";
import { useRouter } from "next/navigation";
import { fetchRecipes } from "./server";

export const MAX_TAGS = 5;

export const Form: React.FC<{ suggestions: Array<string> }> = ({
suggestions,
}) => {
const router = useRouter();
const searchSchema = z.object({
tags: z.array(z.string().max(32)).max(10).optional(),
tags: z.array(z.string().max(32)).optional(),
});

const searchAction = createAction(searchSchema, async (_, { tags }) => {
Expand All @@ -24,7 +22,7 @@ export const Form: React.FC<{ suggestions: Array<string> }> = ({
}
const endpoint = `/recipes?${params.toString()}&matchAll=true`;
const data = await fetchRecipes(endpoint);

console.log("fetched recipes (data): ", data);
router.push(endpoint);

return {
Expand All @@ -41,17 +39,29 @@ export const Form: React.FC<{ suggestions: Array<string> }> = ({
});

return (
<FormProvider schema={searchSchema} action={searchAction} className="p-20">
<TagInput
name="tags"
maxTags={MAX_TAGS}
suggestions={suggestions}
placeholder="Search recipes..."
validateTag={(tag) => {
if (!/^[a-z0-9 ]+$/i.test(tag)) return "Alphanumeric only";
return true;
}}
/>
<FormProvider
schema={searchSchema}
action={searchAction}
className="p-20 search-bar-bg aspect-section-md"
>
<div className="lg:max-w-3/5 md:max-w-3/5 flex flex-col gap-5 relative">
<div>
<h1>Plenty of recipes</h1>
<h3>At your fingertips</h3>
</div>
<TagInput
name="tags"
className=" bg-white"
maxTags={20}
suggestions={suggestions}
placeholder="Search recipes..."
validateTag={(tag) => {
if (!/^[a-z0-9 ]+$/i.test(tag)) return "Alphanumeric only";
return true;
}}
/>
</div>

<Submit className="w-max mt-4">Search</Submit>
</FormProvider>
);
Expand Down
4 changes: 2 additions & 2 deletions src/app/(pages)/(public)/recipes/_components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TextMask } from "@/components/textMask";

export const Hero = () => (
<section className="w-full recipes-hero-bg flex flex-col justify-end -mt-15 p-20 h-[calc(100vh-2rem)]">
<TextMask
{/* <TextMask
fontFamily="Plus Jakarta Sans"
fallbackColor="var(--color-foreground)"
svgWidth={800}
Expand All @@ -11,6 +11,6 @@ export const Hero = () => (
>
<h1 className="text-9xl font-extrabold">Recipes</h1>
<h3>Amazing combinations.</h3>
</TextMask>
</TextMask> */}
</section>
);
30 changes: 17 additions & 13 deletions src/context/form/components/tag-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ interface TagInputProps<T extends FieldValues> extends ComponentProps<"input"> {
allowCustomTags?: boolean;
validateTag?: (tag: string) => boolean | string;
onTagsChange?: (tags: string[]) => void;
suggestionClassName?: string;
}

export function TagInput<T extends FieldValues>({
name,
maxTags,
suggestions = [],
allowCustomTags = true,
allowCustomTags = false,
validateTag = () => true,
onTagsChange,
className,
suggestionClassName,
...props
}: TagInputProps<T>) {
const {
Expand Down Expand Up @@ -153,9 +155,8 @@ export function TagInput<T extends FieldValues>({
<div className="relative">
<div
className={clsx(
"flex flex-wrap gap-2 items-center px-3 py-2 rounded-lg border",
"flex flex-wrap gap-2 items-center p-2.5 rounded-lg border",
error ? errorStyles : normalStyles,
"focus-within:ring-2 focus-within:ring-primary/30",
className
)}
>
Expand All @@ -164,7 +165,7 @@ export function TagInput<T extends FieldValues>({
type="button"
key={`${tag}-${i}`}
onClick={() => removeTag(i)}
className="text-sm hover:bg-gray-200 px-2.5 py-1 rounded-md inline-flex items-center gap-1 bg-gray-100 transition-colors"
className="text-sm hover:bg-gray-light px-2.5 py-1 rounded-md inline-flex items-center gap-1 bg-gray/50 transition-colors"
disabled={disabled}
aria-label={`Remove tag ${tag}`}
>
Expand All @@ -182,7 +183,7 @@ export function TagInput<T extends FieldValues>({
onKeyDown={handleKeyDown}
onFocus={() => setIsSuggestionsOpen(true)}
onBlur={() => setTimeout(() => setIsSuggestionsOpen(false), 200)}
className="flex-1 min-w-[100px] bg-transparent outline-none placeholder:text-gray-400"
className="flex-1 min-w-25 bg-transparent outline-none placeholder:text-gray"
placeholder={
tagsLimitReached
? "Maximum tags reached"
Expand All @@ -192,13 +193,13 @@ export function TagInput<T extends FieldValues>({
aria-autocomplete="list"
/>

<div className="flex items-center gap-2 ml-2">
{!error && tags.length > 0 && (
<Check className="h-4 w-4 text-green-600" />
<div className="flex items-center gap-2.5 ml-2">
{!error && !allowCustomTags && tags.length > 0 && (
<Check className="h-5 w-5 text-success" />
)}
<ChevronDown
className={clsx(
"h-4 w-4 text-gray-400 transition-transform",
"h-5 w-5 text-gray transition-transform",
showSuggestions && "rotate-180"
)}
/>
Expand All @@ -209,7 +210,10 @@ export function TagInput<T extends FieldValues>({
<div
role="listbox"
aria-label="Suggestions"
className="absolute z-10 mt-1 w-full max-h-60 overflow-auto bg-white border border-gray-200 rounded-lg shadow-lg"
className={clsx(
"absolute z-10 mt-1 w-full max-h-60 overflow-auto bg-white border border-gray-light rounded-lg shadow-lg",
suggestionClassName
)}
>
{filteredSuggestions.map((suggestion, index) => (
<div
Expand All @@ -225,8 +229,8 @@ export function TagInput<T extends FieldValues>({
}
}}
className={clsx(
"w-full px-4 py-2 text-left hover:bg-gray-50",
highlightedIndex === index && "bg-gray-50",
"w-full px-5 py-2.5 text-left hover:bg-gray-light",
highlightedIndex === index && "bg-gray-light",
"transition-colors"
)}
aria-selected={highlightedIndex === index}
Expand All @@ -239,7 +243,7 @@ export function TagInput<T extends FieldValues>({
</div>

{error && (
<p className="text-sm text-red-600 mt-1">{String(error.message)}</p>
<p className="text-sm text-error mt-1">{String(error.message)}</p>
)}
</div>
);
Expand Down
30 changes: 20 additions & 10 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ body {
@theme {
--aspect-section-xs: 768/75;
--aspect-section-sm: 384/75;
--aspect-section: 192/75;
--aspect-section-md: 256/75;
--aspect-section-lg: 192/75;
--aspect-section: 192/75;
--aspect-section-lg: 128/75;
--aspect-section-xl: 64/75;
}

@layer base {
Expand Down Expand Up @@ -240,6 +241,7 @@ body {
}
.drafts-hero-bg {
background-image: url("../../public/images/drafts-bg.png");
background-repeat: no-repeat;
}

.diamond-pattern-bg {
Expand All @@ -248,10 +250,12 @@ body {

.home-food-collage-for-hero-bg {
background-image: url("../../public/images/collage-for-home-page.png");
background-repeat: no-repeat;
}

.home-hero-bg {
background-image: url("../../public/LANDING-PAGE-HERO.png");
background-image: url("../../public/1920x880-HERO.png");
background-repeat: no-repeat;
}

.user-hero-bg {
Expand All @@ -261,17 +265,23 @@ body {
}

.browse-hero-bg {
background-image: url("../../public/NEW-BROWSE-FULLHERO-W_TEXT.png");
background-size: 110%;
background-position: 50% 90%;
background-image: url("../../public/browse-page.png");
background-size: 100%;
background-position: 50% 100%;
background-repeat: no-repeat;
}

.recipes-hero-bg {
background-image: url("../../public/NEW-HERO-IMG-TOP-3.jpg");
background-color: var(--overlay);
background-image: url("../../public/recipes-page.png");
background-size: 100%;
background-position: 50% 110%;
background-repeat: no-repeat;
}

.search-bar-bg {
background-image: url("../../public/NEW-GRAY-DECAL-WITH-CHEF.png");
background-size: 100%;
background-position: 50% 75%;
background-blend-mode: multiply;
background-position: 50% 100%;
}

.hero-pattern {
Expand Down
Loading