Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend/feature/154 my profile #249

Merged
merged 5 commits into from
May 15, 2024
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
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@hookform/resolvers": "^3.3.4",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/assets/Icon/General/Plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion frontend/src/components/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { UserSummary } from "@/services/api/semanticBrowseSchemas";

Expand Down
35 changes: 30 additions & 5 deletions frontend/src/components/NavbarLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { CircleUser, Menu, Package2, UtensilsCrossed } from "lucide-react";
import {
CircleUser,
LogOut,
Menu,
Package2,
User,
UtensilsCrossed,
} from "lucide-react";
import {
Link,
NavLink,
Expand All @@ -10,6 +17,8 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "./ui/dropdown-menu";
import { Button } from "./ui/button";
Expand Down Expand Up @@ -107,11 +116,27 @@ export const NavbarLayout = () => {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>
<fetcher.Form method="POST" action="/logout">
<Button type="submit">Log out</Button>
</fetcher.Form>
<DropdownMenuLabel>Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link to="/users/me">
<User className="mr-2 h-4 w-4" />
<span>Profile</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
<fetcher.Form
className="contents"
method="POST"
action="/logout"
>
<DropdownMenuItem asChild>
<button type="submit">
<LogOut className="mr-2 h-4 w-4" />
<span>Log out</span>
</button>
</DropdownMenuItem>
</fetcher.Form>
</DropdownMenuContent>
</DropdownMenu>
) : (
Expand Down
48 changes: 21 additions & 27 deletions frontend/src/components/Recipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,20 @@ import BookmarkIcon from "@/assets/Icon/General/Bookmark.svg";
import TimeIcon from "@/assets/Icon/General/Clock.svg";
import StarIcon from "@/assets/Icon/General/Star.svg";
import FoodIcon from "@/assets/Icon/General/Food.svg";
import { DishSummary, UserSummary } from "@/services/api/semanticBrowseSchemas";

interface Recipe {
name: string;
images: string[];
avgRating?: number;
ratingsCount: number;
cookTime: number;
dish: DishSummary;
author: UserSummary;
}
import { RecipeSummary } from "@/services/api/semanticBrowseSchemas";
import { Link } from "react-router-dom";

export const Recipe = ({
recipe: { name, images, avgRating, ratingsCount, cookTime, dish, author },
recipe: { id, name, images, avgRating, ratingsCount, cookTime, dish, author },
}: {
recipe: Recipe;
recipe: RecipeSummary;
}) => {
return (
<div className="flex flex-col self-stretch justify-self-stretch">
<div className="-mb-16 w-[70%] self-center">
<AspectRatio ratio={16 / 9}>
<img
src={images[0]}
src={images?.[0] || "https://placehold.co/640x640"}
className="h-full w-full rounded-2xl object-cover"
alt={name}
/>
Expand Down Expand Up @@ -58,20 +49,20 @@ export const Recipe = ({
</div>
</CardHeader>
<CardContent className="flex flex-1 flex-col justify-between gap-2">
<div className="flex items-center">
<img src={StarIcon} alt="avgRating icon" className="mr-2 h-4 w-4" />
<p className="text-sm text-gray-500">
{avgRating} ({ratingsCount} Reviews)
</p>
<div className="flex items-center gap-2">
<img src={StarIcon} alt="avgRating icon" className="h-6 w-6" />
<span className="text-sm">
{avgRating} ({ratingsCount || 0} Reviews)
</span>
</div>
<div className="flex items-center">
<img src={TimeIcon} alt="Time icon" className="mr-2 h-4 w-4" />
<p className="text-sm text-gray-500">{cookTime}</p>
<div className="flex items-center gap-2">
<img src={TimeIcon} alt="Time icon" className="h-6 w-6" />
<span className="text-sm">{cookTime}</span>
</div>
{dish && (
<div className="flex items-center">
<img src={FoodIcon} alt="Food icon" className="mr-2 h-4 w-4" />
<p className="text-sm text-gray-500">{dish.name}</p>
<div className="flex items-center gap-2">
<img src={FoodIcon} alt="Food icon" className="h-6 w-6" />
<span className="text-sm">{dish.name}</span>
</div>
)}
{author && author.profilePicture && (
Expand All @@ -84,9 +75,12 @@ export const Recipe = ({
</div>
)}
<div className="self-end">
<a className="cursor-not-allowed text-sm font-medium text-blue-500 hover:underline">
<Link
to={`/recipes/${id}`}
className="cursor-pointer text-sm font-medium text-gray-600 hover:underline"
>
Go to recipe →
</a>
</Link>
</div>
</CardContent>
</Card>
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ export const SearchBar = () => {
<form
onSubmit={(e) => {
e.preventDefault();
const params = new URLSearchParams();
params.append("q", search);
if (cuisine) params.append("cuisine", cuisine);
if (foodType) params.append("foodType", foodType);

navigate("/search?q=" + encodeURIComponent(search));
navigate("/search?" + params.toString());
}}
className="flex gap-4"
>
Expand Down
93 changes: 55 additions & 38 deletions frontend/src/components/SearchFilterPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,24 @@ const predefinedCuisines = [
];
const predefinedTypeOfFood = ["Meat", "Baked", "Dairy", "Eggs"];

export default function SearchFilterPopover({
cuisine,
setCuisine,
foodType,
setFoodType,
}: {
type CuisineFilter = {
cuisine: string;
setCuisine: (cuisine: string) => void;
};
type FoodTypeFilter = {
foodType: string;
setFoodType: (foodType: string) => void;
}) {
};
export default function SearchFilterPopover(
props: (object | CuisineFilter) & (object | FoodTypeFilter),
) {
const {
cuisine = "",
foodType = "",
setCuisine = null,
setFoodType = null,
} = props as CuisineFilter & FoodTypeFilter;

const [tempCuisine, setTempCuisine] = useState(cuisine);
const [tempFoodType, setTempFoodType] = useState(foodType);

Expand Down Expand Up @@ -63,40 +70,50 @@ export default function SearchFilterPopover({
<PopoverClose aria-label="Close" className="absolute right-4 top-4">
<XIcon />
</PopoverClose>
<h4 className="text-2xl font-bold">Filter</h4>
<div className="flex flex-col gap-3">
<h5 className="text-xl font-semibold">Cuisine</h5>
<div className="flex flex-wrap gap-3 gap-y-2">
{predefinedCuisines.map((cuisine) => (
<FilterCheckbox
key={cuisine}
label={cuisine}
checked={tempCuisine === cuisine}
onChange={(e) =>
setTempCuisine(e.target.checked ? cuisine : "")
}
/>
))}
</div>
</div>
<div className="flex flex-col gap-3">
<h5 className="text-xl font-semibold">Type of Food</h5>
<div className="flex flex-wrap gap-3 gap-y-2">
{predefinedTypeOfFood.map((type) => (
<FilterCheckbox
key={type}
label={type}
checked={tempFoodType === type}
onChange={(e) => setTempFoodType(e.target.checked ? type : "")}
/>
))}
</div>
</div>
{setCuisine && (
<>
<h4 className="text-2xl font-bold">Filter</h4>
<div className="flex flex-col gap-3">
<h5 className="text-xl font-semibold">Cuisine</h5>
<div className="flex flex-wrap gap-3 gap-y-2">
{predefinedCuisines.map((cuisine) => (
<FilterCheckbox
key={cuisine}
label={cuisine}
checked={tempCuisine === cuisine}
onChange={(e) =>
setTempCuisine(e.target.checked ? cuisine : "")
}
/>
))}
</div>
</div>
</>
)}
{setFoodType && (
<>
<div className="flex flex-col gap-3">
<h5 className="text-xl font-semibold">Type of Food</h5>
<div className="flex flex-wrap gap-3 gap-y-2">
{predefinedTypeOfFood.map((type) => (
<FilterCheckbox
key={type}
label={type}
checked={tempFoodType === type}
onChange={(e) =>
setTempFoodType(e.target.checked ? type : "")
}
/>
))}
</div>
</div>
</>
)}
<PopoverClose asChild>
<Button
onClick={() => {
setCuisine(tempCuisine);
setFoodType(tempFoodType);
setCuisine?.(tempCuisine);
setFoodType?.(tempFoodType);
}}
className="self-end"
>
Expand Down
48 changes: 48 additions & 0 deletions frontend/src/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from "react";
import * as AvatarPrimitive from "@radix-ui/react-avatar";

import { cn } from "@/lib/utils";

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className,
)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className,
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;

export { Avatar, AvatarImage, AvatarFallback };
4 changes: 2 additions & 2 deletions frontend/src/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const TabsList = React.forwardRef<
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
"flex items-center justify-stretch gap-4 text-primary",
className,
)}
{...props}
Expand All @@ -27,7 +27,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
"text-normal flex flex-1 items-center justify-center whitespace-nowrap rounded-2xl px-8 py-4 font-bold opacity-50 ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-white data-[state=active]:opacity-100 data-[state=active]:shadow-sm",
className,
)}
{...props}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ h1 {
}

h2 {
@apply scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0;
@apply scroll-m-20 pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0;
}

h3 {
Expand Down
Loading
Loading