Skip to content

Commit

Permalink
feat: added wishlist
Browse files Browse the repository at this point in the history
  • Loading branch information
jacob-ebey committed Jan 8, 2022
1 parent 6baf32e commit 9ab52e0
Show file tree
Hide file tree
Showing 20 changed files with 833 additions and 60 deletions.
1 change: 0 additions & 1 deletion app/components/cart-popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export function CartPopover({
<span className="ml-2">{translations.Close}</span>
</button>
<span className="relative flex items-center">
<span className="sr-only">{translations.Close}</span>
<CartIcon className="w-8 h-8" />
{!!cartCount && (
<span
Expand Down
2 changes: 1 addition & 1 deletion app/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ChevronUp, GithubIcon } from "./icons";
import { OptimizedImage } from "./optimized-image";

export type FooterPage = {
id: string | number;
id: string;
title: string;
to: To;
};
Expand Down
24 changes: 19 additions & 5 deletions app/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ export function Navbar({
categories,
translations,
cartCount,
wishlistCount,
}: {
cartCount?: number;
wishlistCount?: number;
onOpenCart: () => void;
onOpenWishlist: () => void;
lang: Language;
Expand Down Expand Up @@ -80,7 +82,8 @@ export function Navbar({
<li key={category.name + "|" + i} className="mx-2">
<Link
className="whitespace-nowrap hover:text-gray-300"
prefetch="intent" to={category.to}
prefetch="intent"
to={category.to}
>
{category.name}
</Link>
Expand All @@ -100,7 +103,8 @@ export function Navbar({
</div>
<div className="flex items-center">
<Link
prefetch="intent" to={`/${lang}/cart`}
prefetch="intent"
to={`/${lang}/cart`}
className="group relative inline-block hover:text-gray-300 ml-4"
onClick={(event) => {
event.preventDefault();
Expand All @@ -121,8 +125,9 @@ export function Navbar({
)}
</Link>
<Link
prefetch="intent" to={`/${lang}/wishlist`}
className="hover:text-gray-300 ml-4"
prefetch="intent"
to={`/${lang}/wishlist`}
className="group relative hover:text-gray-300 ml-4"
onClick={(event) => {
event.preventDefault();
onOpenWishlist();
Expand All @@ -132,6 +137,14 @@ export function Navbar({
{translations ? translations["Wishlist"] : null}
</span>
<WishlistIcon className="w-8 h-8" />
{!!wishlistCount && (
<span
style={{ lineHeight: "0.75rem" }}
className="absolute bottom-0 left-0 translate translate-y-[25%] translate-x-[-25%] inline-flex items-center justify-center px-[0.25rem] py-[0.125rem] text-xs text-zinc-900 bg-gray-50 group-hover:bg-gray-300 rounded-full"
>
{wishlistCount}
</span>
)}
</Link>
<Popover className="lg:hidden relative flex items-center ml-4">
{({ close }) => (
Expand Down Expand Up @@ -182,7 +195,8 @@ export function Navbar({
<Link
onClick={() => close()}
className="text-xl text-blue-400 hover:text-blue-500"
prefetch="intent" to={category.to}
prefetch="intent"
to={category.to}
>
{category.name}
</Link>
Expand Down
9 changes: 5 additions & 4 deletions app/components/scrolling-product-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import cn from "classnames";
import { OptimizedImage } from "./optimized-image";

export type ScrollingProductListProduct = {
id: string | number;
id: string;
title: ReactNode;
image: string;
to: To;
Expand All @@ -27,7 +27,8 @@ function ScrollingProductItem({
return (
<li className="lg:pr-12 relative">
<Link
prefetch="intent" to={to}
prefetch="intent"
to={to}
className="group block aspect-square overflow-hidden w-screen max-w-sm"
tabIndex={disabled ? -1 : undefined}
>
Expand Down Expand Up @@ -65,7 +66,7 @@ export function ScrollingProductList({
key={product.id}
image={product.image}
title={product.title}
prefetch="intent" to={product.to}
to={product.to}
/>
)),
[products]
Expand All @@ -80,7 +81,7 @@ export function ScrollingProductList({
key={product.id}
image={product.image}
title={product.title}
prefetch="intent" to={product.to}
to={product.to}
disabled
/>
)),
Expand Down
58 changes: 49 additions & 9 deletions app/components/three-product-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import type { ReactNode } from "react";
import { useMemo } from "react";
import { Link } from "remix";
import { Link, useFetcher, useLocation } from "remix";
import type { To } from "react-router-dom";
import cn from "classnames";
import { useId } from "@reach/auto-id";

import { WishlistIcon } from "./icons";
import { OptimizedImage } from "./optimized-image";
import { PickTranslations } from "~/translations.server";

export type ThreeProductGridProduct = {
id: string | number;
id: string;
defaultVariantId: string;
title: ReactNode;
formattedPrice: ReactNode;
favorited: boolean;
Expand All @@ -22,13 +24,17 @@ function ThreeProductGridItem({
wishlistColors,
product,
index,
translations,
}: {
backgroundColor: string;
wishlistColors: string[];
product: ThreeProductGridProduct;
index: number;
translations: PickTranslations<"Add to wishlist" | "Remove from wishlist">;
}) {
let id = `three-product-grid-item-${useId()}`;
let { Form } = useFetcher();
let location = useLocation();

return (
<li key={product.id} className={`three-product-grid__item-${index % 3}`}>
Expand All @@ -38,7 +44,12 @@ function ThreeProductGridItem({
backgroundColor
)}
>
<Link className="block group" prefetch="intent" to={product.to} aria-labelledby={id}>
<Link
className="block group"
prefetch="intent"
to={product.to}
aria-labelledby={id}
>
<OptimizedImage
className="object-cover w-full h-full transform transition duration-500 motion-safe:group-focus:scale-110 motion-safe:group-hover:scale-110"
src={product.image}
Expand Down Expand Up @@ -87,7 +98,8 @@ function ThreeProductGridItem({
<div className="absolute top-0 left-0 right-0">
<div className="flex">
<Link
prefetch="intent" to={product.to}
prefetch="intent"
to={product.to}
className="group-tpgi block flex-1"
tabIndex={-1}
id={id}
Expand All @@ -100,20 +112,45 @@ function ThreeProductGridItem({
{product.formattedPrice}
</p>
</Link>
<div>
<Form replace action="/wishlist" method="post">
<input
key={product.favorited.toString()}
type="hidden"
name="_action"
defaultValue={product.favorited ? "delete" : "add"}
/>
<input
type="hidden"
name="redirect"
defaultValue={location.pathname + location.search}
/>
<input
key={product.id}
type="hidden"
name="productId"
defaultValue={product.id}
/>
<input
key={product.defaultVariantId}
type="hidden"
name="variantId"
defaultValue={product.defaultVariantId}
/>

<button
className={cn(
"p-2 bg-zinc-900 focus:bg-zinc-900 hover:bg-zinc-900 transition-colors ease-in-out duration-300",
...wishlistColors
product.favorited ? "text-red-brand" : wishlistColors
)}
onClick={() => alert("wishlist")}
>
<span className="sr-only">
Add "{product.title}" to wishlist
{product.favorited
? translations["Remove from wishlist"]
: translations["Add to wishlist"]}
</span>
<WishlistIcon className="w-8 h-8" />
</button>
</div>
</Form>
</div>
</div>
</div>
Expand All @@ -124,9 +161,11 @@ function ThreeProductGridItem({
export function ThreeProductGrid({
products,
variant = "primary",
translations,
}: {
products: ThreeProductGridProduct[];
variant?: "primary" | "secondary";
translations: PickTranslations<"Add to wishlist" | "Remove from wishlist">;
}) {
let [backgroundColors, wishlistColors] = useMemo(
() =>
Expand Down Expand Up @@ -176,6 +215,7 @@ export function ThreeProductGrid({
index={index}
backgroundColor={backgroundColors[index % 3]}
wishlistColors={wishlistColors[index % 3]}
translations={translations}
/>
))}
</ul>
Expand Down
Loading

0 comments on commit 9ab52e0

Please sign in to comment.