diff --git a/public/instagram-card.png b/public/instagram-card.png new file mode 100644 index 0000000..fe0c395 Binary files /dev/null and b/public/instagram-card.png differ diff --git a/public/tiktok-card.png b/public/tiktok-card.png new file mode 100644 index 0000000..bbe7a1d Binary files /dev/null and b/public/tiktok-card.png differ diff --git a/src/api/main.ts b/src/api/main.ts index 7b3e96d..6552de5 100644 --- a/src/api/main.ts +++ b/src/api/main.ts @@ -37,54 +37,53 @@ class OldApi { endpoint: string, options: RequestInit, schema: SchemaType, - includeHeaders: true, + includeHeaders: true ): Promise<{ data: ZodInfer; headers: Headers }>; async request( endpoint: string, options: RequestInit, schema: SchemaType, - includeHeaders?: false, + includeHeaders?: false ): Promise>; async request( endpoint: string, options: RequestInit, - schema: SchemaType, + schema: SchemaType ): Promise>; async request( endpoint: string, options: RequestInit, - includeHeaders: true, + includeHeaders: true ): Promise<{ data: unknown; headers: Headers }>; async request( endpoint: string, options?: RequestInit, - includeHeaders?: false, + includeHeaders?: false ): Promise; async request( endpoint: string, options?: RequestInit, - includeHeaders?: boolean, + includeHeaders?: boolean ): Promise; async request( endpoint: string, options?: RequestInit, - includeHeaders?: true, + includeHeaders?: true ): Promise; async request( endpoint: string, options: RequestInit = {}, schemaOrIncludeHeaders?: SchemaType | boolean, - includeHeadersFlag?: boolean, + includeHeadersFlag?: boolean ): Promise { const url = new URL(endpoint, this.baseUrl); - console.log(url); const controller = new AbortController(); let schema: SchemaType | undefined; @@ -114,7 +113,6 @@ class OldApi { try { const response = await this.fetch(url.href, mergedOptions); - console.log(response); if (!response.ok) { throw await ApiError.fromResponse(response.clone()); @@ -125,7 +123,7 @@ class OldApi { throw new ApiError( `Non-JSON response from ${url.href}`, 500, - "Invalid Content-Type", + "Invalid Content-Type" ); } @@ -139,7 +137,7 @@ class OldApi { if (!parseResult.success) { throw new ValidationError( `Response validation failed for ${url.href}`, - parseResult.error.issues, + parseResult.error.issues ); } parsedData = parseResult.data; @@ -154,7 +152,7 @@ class OldApi { throw new ApiError( `Invalid response structure from ${url.href}`, 500, - "Missing 'data' property in response", + "Missing 'data' property in response" ); } catch (error) { if (error instanceof ApiError || error instanceof ValidationError) { @@ -172,7 +170,7 @@ class OldApi { "Unknown error occurred", 0, "UNKNOWN_ERROR", - String(error), + String(error) ); } finally { controller.abort(); @@ -182,33 +180,32 @@ class OldApi { async get( endpoint: string, schema?: ZodSchema, - options?: RequestInit, + options?: RequestInit ): Promise; async get( endpoint: string, options?: RequestInit, - includeHeaders?: boolean, + includeHeaders?: boolean ): Promise; async get( endpoint: string, schemaOrOptions?: ZodSchema | RequestInit, - optionsOrIncludeHeaders?: RequestInit | boolean, + optionsOrIncludeHeaders?: RequestInit | boolean ): Promise { - console.log(endpoint, schemaOrOptions, optionsOrIncludeHeaders); if (schemaOrOptions instanceof ZodSchema) { return this.request( endpoint, (optionsOrIncludeHeaders as RequestInit) ?? {}, schemaOrOptions, - false, + false ); } return this.request( endpoint, (schemaOrOptions as RequestInit) ?? {}, - (optionsOrIncludeHeaders as boolean) ?? false, + (optionsOrIncludeHeaders as boolean) ?? false ); } @@ -216,21 +213,21 @@ class OldApi { endpoint: string, body: unknown, schema?: ZodSchema, - options?: RequestInit, + options?: RequestInit ): Promise; async post( endpoint: string, body: unknown, options?: RequestInit, - includeHeaders?: true, + includeHeaders?: true ): Promise; async post( endpoint: string, body: unknown, schemaOrOptions?: ZodSchema | RequestInit, - optionsOrIncludeHeaders?: RequestInit | boolean, + optionsOrIncludeHeaders?: RequestInit | boolean ): Promise { const mergedOptions: RequestInit = { method: "POST", @@ -242,13 +239,13 @@ class OldApi { endpoint, { ...mergedOptions, ...(optionsOrIncludeHeaders as RequestInit) }, schemaOrOptions, - false, + false ); } return this.request( endpoint, { ...mergedOptions, ...(schemaOrOptions as RequestInit) }, - (optionsOrIncludeHeaders as boolean) ?? false, + (optionsOrIncludeHeaders as boolean) ?? false ); } @@ -256,21 +253,21 @@ class OldApi { endpoint: string, body: unknown, schema?: ZodSchema, - options?: RequestInit, + options?: RequestInit ): Promise; async put( endpoint: string, body: unknown, options?: RequestInit, - includeHeaders?: boolean, + includeHeaders?: boolean ): Promise; async put( endpoint: string, body: unknown, schemaOrOptions?: ZodSchema | RequestInit, - optionsOrIncludeHeaders?: RequestInit | boolean, + optionsOrIncludeHeaders?: RequestInit | boolean ): Promise { const mergedOptions: RequestInit = { method: "PUT", @@ -282,50 +279,50 @@ class OldApi { endpoint, { ...mergedOptions, ...(optionsOrIncludeHeaders as RequestInit) }, schemaOrOptions, - false, + false ); } return this.request( endpoint, { ...mergedOptions, ...(schemaOrOptions as RequestInit) }, - (optionsOrIncludeHeaders as boolean) ?? false, + (optionsOrIncludeHeaders as boolean) ?? false ); } async delete( endpoint: string, schema?: ZodSchema, - options?: RequestInit, + options?: RequestInit ): Promise; async delete( endpoint: string, options?: RequestInit, - includeHeaders?: boolean, + includeHeaders?: boolean ): Promise; async delete( endpoint: string, schemaOrOptions?: ZodSchema | RequestInit, - optionsOrIncludeHeaders?: RequestInit | boolean, + optionsOrIncludeHeaders?: RequestInit | boolean ): Promise { if (schemaOrOptions instanceof ZodSchema) { return this.request( endpoint, (optionsOrIncludeHeaders as RequestInit) ?? {}, schemaOrOptions, - false, + false ); } return this.request( endpoint, (schemaOrOptions as RequestInit) ?? {}, - (optionsOrIncludeHeaders as boolean) ?? false, + (optionsOrIncludeHeaders as boolean) ?? false ); } private cleanHeaders( - headers: Record, + headers: Record ): Record { return Object.fromEntries( Object.entries(headers) @@ -333,7 +330,7 @@ class OldApi { .map(([key, value]) => [ key, String(value as NonNullable), - ]), + ]) ); } } @@ -342,5 +339,5 @@ if (typeof window === "undefined" && !process.env.BACKEND_URL) { throw new Error("Backend URL not set (server-side)"); } export const API = new OldApi( - process.env.BACKEND_URL || "https://api.flave.ee", + process.env.BACKEND_URL || "https://api.flave.ee" ); diff --git a/src/app/(pages)/(protected)/(user)/profile/page.tsx b/src/app/(pages)/(protected)/(user)/profile/page.tsx index 138445c..cd3ff10 100644 --- a/src/app/(pages)/(protected)/(user)/profile/page.tsx +++ b/src/app/(pages)/(protected)/(user)/profile/page.tsx @@ -6,7 +6,6 @@ import { LogoutButton } from "./_components/logout"; export default async function ProfilePage() { const user = await getCurrentUser(); - console.log("profile:", user); if (!user) { return

User not found

; } diff --git a/src/app/(pages)/(public)/(home)/components/categories.tsx b/src/app/(pages)/(public)/(home)/components/categories.tsx index 4bafd79..4c1c21e 100644 --- a/src/app/(pages)/(public)/(home)/components/categories.tsx +++ b/src/app/(pages)/(public)/(home)/components/categories.tsx @@ -16,7 +16,7 @@ const MarqueeItem: React.FC<{ text: string; src: string }> = ({
{text
-
{text}
+
#{text}
); diff --git a/src/app/(pages)/(public)/(home)/page.tsx b/src/app/(pages)/(public)/(home)/page.tsx index d6e7bec..7c111eb 100644 --- a/src/app/(pages)/(public)/(home)/page.tsx +++ b/src/app/(pages)/(public)/(home)/page.tsx @@ -1,8 +1,9 @@ -import { Button, RecipeDisplayBlock } from "@/components"; +import { Button, Image, RecipeDisplayBlock } from "@/components"; // import { fetchRecipes } from "@/util"; import { CategoryMarquee, Hero } from "./components"; import { ReviewsList } from "./components/reviews"; +import Link from "next/link"; export default async function Home() { return ( @@ -63,6 +64,21 @@ export default async function Home() {
+
+ {[ + ["/tiktok-card.png", "#"], + ["/instagram-card.png", "https://www.instagram.com/flavedotee/"], + ].map((social, index) => ( + + {social[0] + + ))} +
+ {/* */} ); diff --git a/src/app/(pages)/(public)/browse/_components/marquee.tsx b/src/app/(pages)/(public)/browse/_components/marquee.tsx index 09eee82..7f5a41b 100644 --- a/src/app/(pages)/(public)/browse/_components/marquee.tsx +++ b/src/app/(pages)/(public)/browse/_components/marquee.tsx @@ -16,7 +16,7 @@ const MarqueeItem: React.FC<{ text: string; src: string }> = ({
{text
-
{text}
+
#{text}
); diff --git a/src/app/(pages)/(public)/browse/page.tsx b/src/app/(pages)/(public)/browse/page.tsx index 2bb3a6d..3f630cc 100644 --- a/src/app/(pages)/(public)/browse/page.tsx +++ b/src/app/(pages)/(public)/browse/page.tsx @@ -6,7 +6,6 @@ import { validateSession } from "@/context/auth/actions"; export default async function Browse() { const isLoggedIn = await validateSession(); - console.log("isLoggedIn", isLoggedIn); return ( <> diff --git a/src/app/(pages)/(public)/recipes/[_id]/_components/creator.tsx b/src/app/(pages)/(public)/recipes/[_id]/_components/creator.tsx index dbc5617..adb89cf 100644 --- a/src/app/(pages)/(public)/recipes/[_id]/_components/creator.tsx +++ b/src/app/(pages)/(public)/recipes/[_id]/_components/creator.tsx @@ -31,7 +31,7 @@ export const Creator: React.FC> = ({ as="link" href={`/users/${_id}`} icon={} - className="bg-foreground outline-0 text-black" + className="bg-white outline-0 text-black" > View profile diff --git a/src/app/(pages)/(public)/recipes/[_id]/page.tsx b/src/app/(pages)/(public)/recipes/[_id]/page.tsx index 52d4c78..7129727 100644 --- a/src/app/(pages)/(public)/recipes/[_id]/page.tsx +++ b/src/app/(pages)/(public)/recipes/[_id]/page.tsx @@ -70,11 +70,9 @@ function LoadingFallback() { const RecipeContent = async ({ _id }: { _id: string }) => { const recipe = await API.get("recipes/" + _id); - console.log(recipe); const [start, end] = getDurationBucket(recipe.cookingDuration); const cookingDuration = `${start}-${end} mins`; - console.log(recipe.src); return ( <>
@@ -97,7 +95,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => { {recipe.tags.map(({ _id, value }) => ( {value} @@ -207,7 +205,7 @@ const RecipeContent = async ({ _id }: { _id: string }) => {
    {recipe.instructions.map((instruction, idx) => (
  1. -
    +
    {idx + 1}
    diff --git a/src/app/(pages)/(public)/recipes/_components/server.ts b/src/app/(pages)/(public)/recipes/_components/server.ts index b7d44d9..9cac60b 100644 --- a/src/app/(pages)/(public)/recipes/_components/server.ts +++ b/src/app/(pages)/(public)/recipes/_components/server.ts @@ -6,7 +6,6 @@ import { Recipe } from "@/types/recipe"; export async function fetchRecipes(query: string) { const { sessionToken } = await validateSession({ detailed: true }); - console.log("query ", query); // Fixed: Need to convert URLSearchParams to string and proper URL construction const endpoint = `/recipes?${query}`; console.log("enpoint: ", endpoint); diff --git a/src/app/(pages)/(public)/recipes/page.tsx b/src/app/(pages)/(public)/recipes/page.tsx index d27eb95..126169e 100644 --- a/src/app/(pages)/(public)/recipes/page.tsx +++ b/src/app/(pages)/(public)/recipes/page.tsx @@ -22,8 +22,6 @@ export default async function RecipesPage({ return [JSON.stringify(reason)]; }); - console.log(suggestions); - // Handle search params const { tags } = await searchParams; const params = new URLSearchParams(); @@ -41,9 +39,8 @@ export default async function RecipesPage({ (reason) => { console.log(reason); return []; - }, + } ); - console.log("Suggestions: ", suggestions); return ( <> diff --git a/src/context/auth/actions/getCurrentUser.ts b/src/context/auth/actions/getCurrentUser.ts index 4b54976..72740db 100644 --- a/src/context/auth/actions/getCurrentUser.ts +++ b/src/context/auth/actions/getCurrentUser.ts @@ -6,10 +6,10 @@ import { validateSession } from "./validateSession"; export async function getCurrentUser(): Promise; export async function getCurrentUser( - endpoint: string, + endpoint: string ): Promise; export async function getCurrentUser( - endpoint?: string, + endpoint?: string ): Promise { // Validate session and get token const { sessionToken, isValid, currentUser } = await validateSession({ @@ -17,26 +17,21 @@ export async function getCurrentUser( user: true, }); - console.log("Session validation", { isValid, sessionToken }); - if (!isValid || !sessionToken) { return null; } // If no endpoint provided, return basic user info if (!endpoint) { - console.log("Returning current user", currentUser); return currentUser; } // Fetch extended user data for specific endpoint try { - console.log(`Fetching user data from endpoint: ${endpoint}`); const data = await API.get(`/users/me/${endpoint}`, { headers: { Authorization: `Bearer ${sessionToken}` }, }); - console.log("Fetched data:", data); return data; } catch (error) { console.error("Failed to fetch user data:", error); diff --git a/src/context/auth/actions/validateSession.ts b/src/context/auth/actions/validateSession.ts index 79cd1f1..e4a32e5 100644 --- a/src/context/auth/actions/validateSession.ts +++ b/src/context/auth/actions/validateSession.ts @@ -40,10 +40,8 @@ export async function validateSession(options?: { > { try { const sessionToken = (await cookies()).get("session_token")?.value ?? null; - console.log("I have Session Token", sessionToken); if (!sessionToken) { - console.log("I don't have Session Token"); return options?.detailed ? options?.user ? { isValid: false, sessionToken: null, currentUser: null } @@ -51,14 +49,11 @@ export async function validateSession(options?: { : false; } - API.enableDebug(); const currentUser = await API.get("users/me", { headers: { Authorization: `Bearer ${sessionToken}` }, }); - console.log("Current User", currentUser); const isValid = !!currentUser && isUser(currentUser); - API.disableDebug(); if (options?.detailed) { return options?.user diff --git a/src/context/form/components/dropdown.tsx b/src/context/form/components/dropdown.tsx index 021eceb..ceaa2d0 100644 --- a/src/context/form/components/dropdown.tsx +++ b/src/context/form/components/dropdown.tsx @@ -1,4 +1,9 @@ -import { Listbox } from "@headlessui/react"; +import { + Listbox, + ListboxButton, + ListboxOption, + ListboxOptions, +} from "@headlessui/react"; import { Check, X } from "lucide-react"; import { ComponentProps } from "react"; import { FieldValues, Path } from "react-hook-form"; @@ -13,83 +18,100 @@ export function Dropdown({ }: { name: Path; label?: string; - options: { - value: string; - label: string; - Icon?: React.ComponentType<{ className?: string }>; - }[]; + options: ( + | string + | { + value: string; + label: string; + Icon?: React.ComponentType<{ className?: string }>; + } + )[]; } & ComponentProps<"select">) { const { setValue, watch, formState: { errors }, } = useFormContext(); - const selectedValue = watch(name); + const selectedValue = watch(name) || ""; + + // Normalize options into a consistent object structure + const normalizedOptions = options.map((option) => { + if (typeof option === "string") { + return { value: option, label: option, Icon: undefined }; + } + return option; + }); + + const selectedOption = normalizedOptions.find( + (opt) => opt.value === selectedValue + ); return ( - setValue(name, value)}> -
    + setValue(name, value as T[Path])} + > +
    {label && ( - + )}
    - -
    - {options.find((opt) => opt.value === selectedValue)?.Icon && ( -
    - + {selectedOption?.Icon && ( +
    +
    )} - {options.find((opt) => opt.value === selectedValue)?.label || - "Select..."} + {selectedOption?.label || "Select..."}
    - - - {options.map((option) => ( - + + {normalizedOptions.map((option) => ( + - `cursor-default select-none relative py-2 pl-3 pr-9 ${ - active ? "bg-blue-50 text-blue-900" : "text-gray-900" + className={({ selected }) => + `cursor-default select-none relative py-2.5 pl-3 pr-9 ${ + selected ? "bg-gray-light text-gray-dark" : "text-black" }` } > {({ selected }) => (
    {option.Icon && ( -
    +
    )} {option.label} {selected && ( - + )}
    )} - + ))} - +
    {errors[name] && ( -

    - +

    + {errors[name]?.message?.toString()}

    )} diff --git a/src/context/form/components/file-upload.tsx b/src/context/form/components/file-upload.tsx index a5c96b1..2f7bca7 100644 --- a/src/context/form/components/file-upload.tsx +++ b/src/context/form/components/file-upload.tsx @@ -125,7 +125,10 @@ export function FileUpload({ return (
    {label && ( -