Skip to content

Commit

Permalink
Merge pull request #249 from bounswe/frontend/feature/154-my-profile
Browse files Browse the repository at this point in the history
Frontend/feature/154 my profile
  • Loading branch information
mmtftr authored May 15, 2024
2 parents bf91f52 + 2f71575 commit c77f9ba
Show file tree
Hide file tree
Showing 18 changed files with 338 additions and 125 deletions.
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

0 comments on commit c77f9ba

Please sign in to comment.