From 6851d9ef053a929a1aaac14ada1ad3f857a9b061 Mon Sep 17 00:00:00 2001 From: DGoiana Date: Sun, 18 Aug 2024 17:05:11 +0100 Subject: [PATCH 01/15] initial shop design with card implementation --- app/(site)/shop/page.tsx | 65 ++++++++++++++++++++++++++++++++++ collections/Product.ts | 22 ++++++++++++ components/ShopCard/index.tsx | 36 +++++++++++++++++++ public/images/cactus.jpg | Bin 0 -> 21165 bytes tailwind.config.js | 2 ++ 5 files changed, 125 insertions(+) create mode 100644 app/(site)/shop/page.tsx create mode 100644 collections/Product.ts create mode 100644 components/ShopCard/index.tsx create mode 100644 public/images/cactus.jpg diff --git a/app/(site)/shop/page.tsx b/app/(site)/shop/page.tsx new file mode 100644 index 0000000..5e89325 --- /dev/null +++ b/app/(site)/shop/page.tsx @@ -0,0 +1,65 @@ +"use server"; + +import ShopCard from "components/ShopCard"; +import { getPayload } from "payload"; +import config from "payload.config"; +import Image from "next/image"; + +export default async function ShopPage() { + const payload = await getPayload({ config }); + + const result = await payload.find({ + collection: "product", + }); + + return ( + <> +
+
+ hero +
+

+ Sweatshirt +

+ + bestseller + +
+

+ A nossa nova sweathshirt clássica feita com algodão de melhor + qualidade. Apropriada para verão e inverno para estares sempre + confortável a representar a melhor faculdade do país. +

+ +
+
+

+ Student Essentials +

+

+ Os merch-essentials{" "} + deste ano para viveres a tua vida académica ao máximo, com estilo. +

+
+
+ + + + +
+
+
+
+ + ); +} diff --git a/collections/Product.ts b/collections/Product.ts new file mode 100644 index 0000000..a848a95 --- /dev/null +++ b/collections/Product.ts @@ -0,0 +1,22 @@ +import type { CollectionConfig } from "payload"; + +export const Product: CollectionConfig = { + slug: "product", + fields: [ + { + name: "name", + type: "text", + required: true, + }, + { + name: "price", + type: "number", + required: true, + }, + { + name: "description", + type: "text", + required: true, + }, + ], +}; diff --git a/components/ShopCard/index.tsx b/components/ShopCard/index.tsx new file mode 100644 index 0000000..3d2cd16 --- /dev/null +++ b/components/ShopCard/index.tsx @@ -0,0 +1,36 @@ +import { Product } from "@/payload-types"; +import Image from "next/image"; + +type ShopCardProps = { + product: Product; +}; + +const ShopCard = ({ product }: ShopCardProps) => { + return ( +
+ Product image +
+

+ T-shirt oficial +

+ + +
+
+ ); +}; + +export default ShopCard; diff --git a/public/images/cactus.jpg b/public/images/cactus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f93ce4a077186a8aded677362508f391637ef66d GIT binary patch literal 21165 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%0DCYw{7;IBG3Gokjd>|7=K#LEzlHui8H${zEfQ-K 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 literal 0 HcmV?d00001 diff --git a/tailwind.config.js b/tailwind.config.js index 2a5a71e..2862cd1 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -13,6 +13,7 @@ module.exports = { theme: { fontFamily: { inter: ["Inter", "sans-serif"], + serif: ["ui-serif", "Georgia"], }, extend: { colors: { @@ -37,6 +38,7 @@ module.exports = { alabaster: "#FBFBFB", zumthor: "#EDF5FF", socialicon: "#D1D8E0", + engenharia: "#8C2D19", // secondary: "#C4C6B9", // accent: #562920 From 70d96bd1928b22f877fb651d818ed6f10156e66c Mon Sep 17 00:00:00 2001 From: DGoiana Date: Tue, 20 Aug 2024 00:34:51 +0100 Subject: [PATCH 02/15] adding reactivity --- components/Shop/ProductPreview/index.tsx | 38 ++++++++++++++++++++++++ components/{ => Shop}/ShopCard/index.tsx | 10 +++++-- payload-types.ts | 13 ++++++++ payload.config.ts | 3 +- 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 components/Shop/ProductPreview/index.tsx rename components/{ => Shop}/ShopCard/index.tsx (74%) diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx new file mode 100644 index 0000000..686f974 --- /dev/null +++ b/components/Shop/ProductPreview/index.tsx @@ -0,0 +1,38 @@ +import { Product } from "@/payload-types"; +import Image from "next/image"; + +type ProductPreviewProps = { + product: Product; +}; + +const ProductPreview = ({ product }: ProductPreviewProps) => { + return ( + <> + hero +
+

+ {product.name} +

+ + bestseller + +
+

+ {product.description} +

+ + + ); +}; + +export default ProductPreview; diff --git a/components/ShopCard/index.tsx b/components/Shop/ShopCard/index.tsx similarity index 74% rename from components/ShopCard/index.tsx rename to components/Shop/ShopCard/index.tsx index 3d2cd16..fd2ae9a 100644 --- a/components/ShopCard/index.tsx +++ b/components/Shop/ShopCard/index.tsx @@ -3,11 +3,15 @@ import Image from "next/image"; type ShopCardProps = { product: Product; + customClick?: () => void; }; -const ShopCard = ({ product }: ShopCardProps) => { +const ShopCard = ({ product, customClick }: ShopCardProps) => { return ( -
+
{ />

- T-shirt oficial + {product.name}

- -
-

- Student Essentials -

-

- Os merch-essentials{" "} - deste ano para viveres a tua vida académica ao máximo, com estilo. -

-
-
- - - - -
-
-
-
- - ); + return ; } diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx new file mode 100644 index 0000000..1f3a0e1 --- /dev/null +++ b/app/(site)/shop/pageContent.tsx @@ -0,0 +1,50 @@ +"use client"; + +import SectionHeader from "@/components/Common/SectionHeader"; +import ProductPreview from "@/components/Shop/ProductPreview"; +import ShopCard from "@/components/Shop/ShopCard"; +import { Product } from "@/payload-types"; +import React from "react"; + +export default function ShopPageContent({ products }) { + const [previewProduct, setPreviewProduct] = React.useState(products[0]); + + return ( + <> +
+ +
+
+
+ +
+
+

+ Student Essentials +

+

+ Os merch-essentials{" "} + deste ano para viveres a tua vida académica ao máximo, com estilo. +

+
+
+ {products.map((product: Product) => ( + setPreviewProduct(product)} + > + ))} +
+
+
+
+ + ); +} From 1d659fc0c61208d6a8ca4f1b6f57ab6806987a28 Mon Sep 17 00:00:00 2001 From: DGoiana Date: Mon, 30 Sep 2024 22:49:15 +0100 Subject: [PATCH 04/15] starting shop cart --- app/(site)/shop/pageContent.tsx | 17 +- app/globals.css | 3 + components.json | 20 + components/Shop/Cart/index.tsx | 40 ++ components/Shop/CartItem/index.tsx | 25 ++ components/Shop/ProductPreview/index.tsx | 17 +- components/Shop/SizePicker/index.tsx | 12 + components/ui/sheet.tsx | 140 +++++++ lib/utils.ts | 6 + package.json | 8 +- pnpm-lock.yaml | 470 +++++++++++++++++++++++ tailwind.config.js | 308 +++++++-------- 12 files changed, 896 insertions(+), 170 deletions(-) create mode 100644 components.json create mode 100644 components/Shop/Cart/index.tsx create mode 100644 components/Shop/CartItem/index.tsx create mode 100644 components/Shop/SizePicker/index.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 lib/utils.ts diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx index 1f3a0e1..6ea67b1 100644 --- a/app/(site)/shop/pageContent.tsx +++ b/app/(site)/shop/pageContent.tsx @@ -1,6 +1,8 @@ "use client"; import SectionHeader from "@/components/Common/SectionHeader"; +import ShopCart from "@/components/Shop/Cart"; +import CartItem from "@/components/Shop/CartItem"; import ProductPreview from "@/components/Shop/ProductPreview"; import ShopCard from "@/components/Shop/ShopCard"; import { Product } from "@/payload-types"; @@ -8,22 +10,15 @@ import React from "react"; export default function ShopPageContent({ products }) { const [previewProduct, setPreviewProduct] = React.useState(products[0]); + const [openCart, setOpenCart] = React.useState(false); return ( <> -
- -
-
+
- +
+

Student Essentials diff --git a/app/globals.css b/app/globals.css index 8648ec5..975fd36 100644 --- a/app/globals.css +++ b/app/globals.css @@ -23,6 +23,9 @@ body { @apply relative z-1 font-inter text-regular font-normal text-waterloo dark:text-manatee; } + :root { + --radius: 0.5rem; + } } @layer components { diff --git a/components.json b/components.json new file mode 100644 index 0000000..676bbad --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": false, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx new file mode 100644 index 0000000..d690b94 --- /dev/null +++ b/components/Shop/Cart/index.tsx @@ -0,0 +1,40 @@ +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import React from "react"; +import CartItem from "../CartItem"; +import { Product } from "@/payload-types"; + +type ShopCartProps = { + isOpen: boolean, + onOpenChange: (bool: boolean) => void, + products: Product[], +} + +const ShopCart = ({ isOpen, onOpenChange, products }: ShopCartProps) => { + return + + + Cart + + {products.map((p) => { + return <> + +
+ + })} +
+
+ + + +
+
+} + +export default ShopCart; \ No newline at end of file diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx new file mode 100644 index 0000000..bb4af1e --- /dev/null +++ b/components/Shop/CartItem/index.tsx @@ -0,0 +1,25 @@ +import { Product } from "@/payload-types"; +import Image from 'next/image'; + +type CartItemProps = { + product: Product, + +} + +const CartItem = ({ product }: CartItemProps) => { + return
+ hero +
+

{product.name}

+

{product.price}$

+
+
+} + +export default CartItem; \ No newline at end of file diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index 686f974..fe2b5fa 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -1,11 +1,13 @@ import { Product } from "@/payload-types"; import Image from "next/image"; +import SizePicker from "../SizePicker"; type ProductPreviewProps = { product: Product; + setCartState: Function; }; -const ProductPreview = ({ product }: ProductPreviewProps) => { +const ProductPreview = ({ product, setCartState }: ProductPreviewProps) => { return ( <> {

{product.description}

- +
+ + +
); }; diff --git a/components/Shop/SizePicker/index.tsx b/components/Shop/SizePicker/index.tsx new file mode 100644 index 0000000..e649ebb --- /dev/null +++ b/components/Shop/SizePicker/index.tsx @@ -0,0 +1,12 @@ +const SizePicker = () => { + return <> + + +} + +export default SizePicker; \ No newline at end of file diff --git a/components/ui/sheet.tsx b/components/ui/sheet.tsx new file mode 100644 index 0000000..8989d81 --- /dev/null +++ b/components/ui/sheet.tsx @@ -0,0 +1,140 @@ +"use client" + +import * as React from "react" +import * as SheetPrimitive from "@radix-ui/react-dialog" +import { cva, type VariantProps } from "class-variance-authority" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Sheet = SheetPrimitive.Root + +const SheetTrigger = SheetPrimitive.Trigger + +const SheetClose = SheetPrimitive.Close + +const SheetPortal = SheetPrimitive.Portal + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName + +const sheetVariants = cva( + "fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 dark:bg-slate-950", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + } +) + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = "right", className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +SheetContent.displayName = SheetPrimitive.Content.displayName + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetHeader.displayName = "SheetHeader" + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetFooter.displayName = "SheetFooter" + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetTitle.displayName = SheetPrimitive.Title.displayName + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetDescription.displayName = SheetPrimitive.Description.displayName + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +} diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/package.json b/package.json index f359149..fc90e4d 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,15 @@ "@payloadcms/richtext-lexical": "3.0.0-beta.71", "@payloadcms/richtext-slate": "3.0.0-beta.71", "@payloadcms/ui": "3.0.0-beta.71", + "@radix-ui/react-dialog": "^1.1.1", "autoprefixer": "^10.4.19", "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "cross-env": "^7.0.3", "framer-motion": "^11.3.19", "graphql": "^16.8.2", + "lucide-react": "^0.446.0", "next": "15.0.0-canary.77", "next-themes": "^0.3.0", "payload": "3.0.0-beta.71", @@ -29,7 +33,9 @@ "react-hot-toast": "^2.4.1", "sharp": "0.32.6", "swiper": "^9.3.2", - "tailwindcss": "^3.4.7" + "tailwind-merge": "^2.5.2", + "tailwindcss": "^3.4.7", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@payloadcms/graphql": "3.0.0-beta.71", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b5e73c..c10e765 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,12 +30,21 @@ importers: '@payloadcms/ui': specifier: 3.0.0-beta.71 version: 3.0.0-beta.71(monaco-editor@0.50.0)(next@15.0.0-canary.77(babel-plugin-react-compiler@0.0.0)(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(sass@1.77.4))(payload@3.0.0-beta.71(@swc/core@1.7.3(@swc/helpers@0.5.12))(@swc/types@0.1.12)(graphql@16.9.0)(typescript@5.5.3))(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-dialog': + specifier: ^1.1.1 + version: 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.40) babel-plugin-react-compiler: specifier: ^0.0.0-experimental-592953e-20240517 version: 0.0.0 + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 + clsx: + specifier: ^2.1.1 + version: 2.1.1 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -45,6 +54,9 @@ importers: graphql: specifier: ^16.8.2 version: 16.9.0 + lucide-react: + specifier: ^0.446.0 + version: 0.446.0(react@19.0.0-rc-6230622a1a-20240610) next: specifier: 15.0.0-canary.77 version: 15.0.0-canary.77(babel-plugin-react-compiler@0.0.0)(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(sass@1.77.4) @@ -69,9 +81,15 @@ importers: swiper: specifier: ^9.3.2 version: 9.4.1 + tailwind-merge: + specifier: ^2.5.2 + version: 2.5.2 tailwindcss: specifier: ^3.4.7 version: 3.4.7 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.7) devDependencies: '@payloadcms/graphql': specifier: 3.0.0-beta.71 @@ -1076,6 +1094,168 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.1': + resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} @@ -1460,6 +1640,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -1658,6 +1842,9 @@ packages: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} + class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -1668,6 +1855,10 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1829,6 +2020,9 @@ packages: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -2282,6 +2476,10 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-stdin@8.0.0: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} @@ -2463,6 +2661,9 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -2758,6 +2959,11 @@ packages: lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + lucide-react@0.446.0: + resolution: {integrity: sha512-BU7gy8MfBMqvEdDPH79VhOXSEgyG8TSPOKWaExWGCQVqnGH7wGgDngPbofu+KdtVjPQBWbEmnfMTq90CTiiDRg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + md5@2.3.0: resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} @@ -3291,12 +3497,42 @@ packages: react: ^15.5.x || ^16.x || ^17.x || ^18.x react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-select@5.8.0: resolution: {integrity: sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-transition-group@4.4.5: resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: @@ -3655,6 +3891,14 @@ packages: tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.5.2: + resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.7: resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==} engines: {node: '>=14.0.0'} @@ -3811,6 +4055,16 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-context-selector@2.0.0: resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==} peerDependencies: @@ -3826,6 +4080,16 @@ packages: '@types/react': optional: true + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -5300,6 +5564,141 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-compose-refs@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-context@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-dialog@1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + aria-hidden: 1.2.4 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-remove-scroll: 2.5.7(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-dismissable-layer@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-escape-keydown': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-focus-guards@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-focus-scope@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-id@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-portal@1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-presence@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-primitive@2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-slot@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-controllable-state@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-escape-keydown@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@rushstack/eslint-patch@1.10.4': {} '@smithy/abort-controller@3.1.1': @@ -5805,6 +6204,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.3 + aria-query@5.1.3: dependencies: deep-equal: 2.2.3 @@ -6045,6 +6448,10 @@ snapshots: ci-info@4.0.0: {} + class-variance-authority@0.7.0: + dependencies: + clsx: 2.0.0 + classnames@2.5.1: {} cli-color@2.0.4: @@ -6057,6 +6464,8 @@ snapshots: client-only@0.0.1: {} + clsx@2.0.0: {} + clsx@2.1.1: {} color-convert@1.9.3: @@ -6215,6 +6624,8 @@ snapshots: detect-libc@2.0.3: {} + detect-node-es@1.1.0: {} + didyoumean@1.2.2: {} diff@5.2.0: {} @@ -6824,6 +7235,8 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-nonce@1.0.1: {} + get-stdin@8.0.0: {} get-symbol-description@1.0.2: @@ -7003,6 +7416,10 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + ip-address@9.0.5: dependencies: jsbn: 1.1.0 @@ -7284,6 +7701,10 @@ snapshots: dependencies: es5-ext: 0.10.64 + lucide-react@0.446.0(react@19.0.0-rc-6230622a1a-20240610): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + md5@2.3.0: dependencies: charenc: 0.0.2 @@ -7866,6 +8287,25 @@ snapshots: react: 19.0.0-rc-6230622a1a-20240610 react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-remove-scroll-bar@2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + react-remove-scroll@2.5.7(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-remove-scroll-bar: 2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.3 + use-callback-ref: 1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + use-sidecar: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + react-select@5.8.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): dependencies: '@babel/runtime': 7.25.0 @@ -7883,6 +8323,15 @@ snapshots: - '@types/react' - supports-color + react-style-singleton@2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + react-transition-group@4.4.5(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): dependencies: '@babel/runtime': 7.25.0 @@ -8305,6 +8754,12 @@ snapshots: tabbable@6.2.0: {} + tailwind-merge@2.5.2: {} + + tailwindcss-animate@1.0.7(tailwindcss@3.4.7): + dependencies: + tailwindcss: 3.4.7 + tailwindcss@3.4.7: dependencies: '@alloc/quick-lru': 5.2.0 @@ -8513,6 +8968,13 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + use-context-selector@2.0.0(react@19.0.0-rc-6230622a1a-20240610)(scheduler@0.25.0-rc-f994737d14-20240522): dependencies: react: 19.0.0-rc-6230622a1a-20240610 @@ -8524,6 +8986,14 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 + use-sidecar@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} diff --git a/tailwind.config.js b/tailwind.config.js index 2862cd1..f4ec278 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,157 +1,161 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./app/**/*.{js,ts,jsx,tsx,mdx}", - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", + content: [ + "./app/**/*.{js,ts,jsx,tsx,mdx}", + "./pages/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", - // Or if using `src` directory: - "./src/**/*.{js,ts,jsx,tsx,mdx}", - ], - darkMode: "class", - theme: { - fontFamily: { - inter: ["Inter", "sans-serif"], - serif: ["ui-serif", "Georgia"], - }, - extend: { - colors: { - current: "currentColor", - transparent: "transparent", - stroke: "#EEEEEE", - strokedark: "#2D2F40", - hoverdark: "#252A42", - titlebg: "#ADFFF8", - titlebg2: "#FFEAC2", - titlebgdark: "#46495A", - btndark: "#292E45", - white: "#FFFFFF", - black: "#181C31", - blackho: "#2C3149", - blacksection: "#1C2136", - primary: "#97321D", - primaryho: "#0063EC", - meta: "#20C5A8", - waterloo: "#757693", - manatee: "#999AA1", - alabaster: "#FBFBFB", - zumthor: "#EDF5FF", - socialicon: "#D1D8E0", - engenharia: "#8C2D19", - - // secondary: "#C4C6B9", - // accent: #562920 - // background: #FAFAFA - // dark-primary: #96311D - // dark-secondary: #444639 - // dark-accent: #CDA59D - // dark-background: #161416 - }, - fontSize: { - metatitle: ["12px", "20px"], - sectiontitle: ["14px", "22px"], - regular: ["16px", "26px"], - metatitle3: ["18px", "26px"], - metatitle2: ["20px", "32px"], - para2: ["22px", "35px"], - itemtitle: ["26px", "32px"], - itemtitle2: ["24px", "32px"], - hero: ["44px", "58px"], - sectiontitle3: ["44px", "55px"], - sectiontitle2: ["40px", "52px"], - sectiontitle4: ["34px", "48px"], - }, - spacing: { - 4.5: "1.125rem", - 5.5: "1.375rem", - 6.5: "1.625rem", - 7.5: "1.875rem", - 8.5: "2.125rem", - 10.5: "2.625rem", - 11.5: "2.875rem", - 12.5: "3.125rem", - 13: "3.25rem", - 13.5: "3.375rem", - 14.5: "3.625rem", - 15: "3.75rem", - 15.5: "3.875rem", - 16: "4rem", - 17: "4.25rem", - 17.5: "4.375rem", - 18: "4.5rem", - 18.5: "4.625rem", - 19: "4.75rem", - 21: "5.25rem", - 21.5: "5.375rem", - 22: "5.5rem", - 22.5: "5.625rem", - 25: "6.25rem", - 27: "6.75rem", - 27.5: "6.875rem", - 29: "7.25rem", - 29.5: "7.375rem", - 30: "7.5rem", - 32.5: "8.125rem", - 35: "8.75rem", - 37.5: "9.375rem", - 40: "10rem", - 42.5: "10.625rem", - 45: "11.25rem", - 46: "11.5rem", - 47.5: "11.875rem", - 50: "12.5rem", - 55: "13.75rem", - 60: "15rem", - 65: "16.25rem", - 67: "16.75rem", - 67.5: "16.875rem", - 90: "22.5rem", - }, - maxWidth: { - "c-1390": "86.875rem", - "c-1315": "82.188rem", - "c-1280": "80rem", - "c-1235": "77.188rem", - "c-1154": "72.125rem", - "c-1016": "63.5rem", - }, - zIndex: { - 99999: "99999", - 999: "999", - 1: "1", - }, - opacity: { - 65: ".65", - }, - transitionProperty: { width: "width" }, - boxShadow: { - "solid-l": "0px 10px 120px 0px rgba(45, 74, 170, 0.1)", - "solid-2": "0px 2px 10px rgba(122, 135, 167, 0.05)", - "solid-3": "0px 6px 90px rgba(8, 14, 40, 0.04)", - "solid-4": "0px 6px 90px rgba(8, 14, 40, 0.1)", - "solid-5": "0px 8px 24px rgba(45, 74, 170, 0.08)", - "solid-6": "0px 8px 24px rgba(10, 16, 35, 0.08)", - "solid-7": "0px 30px 50px rgba(45, 74, 170, 0.1)", - "solid-8": "0px 12px 120px rgba(45, 74, 170, 0.06)", - "solid-9": "0px 12px 30px rgba(45, 74, 170, 0.06)", - "solid-10": "0px 8px 30px rgba(45, 74, 170, 0.06)", - "solid-11": "0px 6px 20px rgba(45, 74, 170, 0.05)", - "solid-12": "0px 2px 10px rgba(0, 0, 0, 0.05)", - "solid-13": "0px 2px 19px rgba(0, 0, 0, 0.05)", - }, - keyframes: { - line: { - "0%, 100%": { transform: "translateY(100%)" }, - "50%": { transform: "translateY(0)" }, - }, - }, - animation: { - line1: "line 3s linear infinite", - line2: "line 6s linear infinite", - line3: "line 9s linear infinite", - }, - }, - }, - plugins: [], + // Or if using `src` directory: + "./src/**/*.{js,ts,jsx,tsx,mdx}", + ], + darkMode: ["class", "class"], + theme: { + fontFamily: { + inter: ["Inter", "sans-serif"], + serif: ["ui-serif", "Georgia"] + }, + extend: { + colors: { + current: 'currentColor', + transparent: 'transparent', + stroke: '#EEEEEE', + strokedark: '#2D2F40', + hoverdark: '#252A42', + titlebg: '#ADFFF8', + titlebg2: '#FFEAC2', + titlebgdark: '#46495A', + btndark: '#292E45', + white: '#FFFFFF', + black: '#181C31', + blackho: '#2C3149', + blacksection: '#1C2136', + primary: '#97321D', + primaryho: '#0063EC', + meta: '#20C5A8', + waterloo: '#757693', + manatee: '#999AA1', + alabaster: '#FBFBFB', + zumthor: '#EDF5FF', + socialicon: '#D1D8E0', + engenharia: '#8C2D19' + }, + fontSize: { + metatitle: ["12px", "20px"], + sectiontitle: ["14px", "22px"], + regular: ["16px", "26px"], + metatitle3: ["18px", "26px"], + metatitle2: ["20px", "32px"], + para2: ["22px", "35px"], + itemtitle: ["26px", "32px"], + itemtitle2: ["24px", "32px"], + hero: ["44px", "58px"], + sectiontitle3: ["44px", "55px"], + sectiontitle2: ["40px", "52px"], + sectiontitle4: ["34px", "48px"] + }, + spacing: { + '13': '3.25rem', + '15': '3.75rem', + '16': '4rem', + '17': '4.25rem', + '18': '4.5rem', + '19': '4.75rem', + '21': '5.25rem', + '22': '5.5rem', + '25': '6.25rem', + '27': '6.75rem', + '29': '7.25rem', + '30': '7.5rem', + '35': '8.75rem', + '40': '10rem', + '45': '11.25rem', + '46': '11.5rem', + '50': '12.5rem', + '55': '13.75rem', + '60': '15rem', + '65': '16.25rem', + '67': '16.75rem', + '90': '22.5rem', + '4.5': '1.125rem', + '5.5': '1.375rem', + '6.5': '1.625rem', + '7.5': '1.875rem', + '8.5': '2.125rem', + '10.5': '2.625rem', + '11.5': '2.875rem', + '12.5': '3.125rem', + '13.5': '3.375rem', + '14.5': '3.625rem', + '15.5': '3.875rem', + '17.5': '4.375rem', + '18.5': '4.625rem', + '21.5': '5.375rem', + '22.5': '5.625rem', + '27.5': '6.875rem', + '29.5': '7.375rem', + '32.5': '8.125rem', + '37.5': '9.375rem', + '42.5': '10.625rem', + '47.5': '11.875rem', + '67.5': '16.875rem' + }, + maxWidth: { + 'c-1390': '86.875rem', + 'c-1315': '82.188rem', + 'c-1280': '80rem', + 'c-1235': '77.188rem', + 'c-1154': '72.125rem', + 'c-1016': '63.5rem' + }, + zIndex: { + '1': '1', + '999': '999', + '99999': '99999', + '100000': '100000', + }, + opacity: { + '65': '.65' + }, + transitionProperty: { + width: 'width' + }, + boxShadow: { + 'solid-l': '0px 10px 120px 0px rgba(45, 74, 170, 0.1)', + 'solid-2': '0px 2px 10px rgba(122, 135, 167, 0.05)', + 'solid-3': '0px 6px 90px rgba(8, 14, 40, 0.04)', + 'solid-4': '0px 6px 90px rgba(8, 14, 40, 0.1)', + 'solid-5': '0px 8px 24px rgba(45, 74, 170, 0.08)', + 'solid-6': '0px 8px 24px rgba(10, 16, 35, 0.08)', + 'solid-7': '0px 30px 50px rgba(45, 74, 170, 0.1)', + 'solid-8': '0px 12px 120px rgba(45, 74, 170, 0.06)', + 'solid-9': '0px 12px 30px rgba(45, 74, 170, 0.06)', + 'solid-10': '0px 8px 30px rgba(45, 74, 170, 0.06)', + 'solid-11': '0px 6px 20px rgba(45, 74, 170, 0.05)', + 'solid-12': '0px 2px 10px rgba(0, 0, 0, 0.05)', + 'solid-13': '0px 2px 19px rgba(0, 0, 0, 0.05)' + }, + keyframes: { + line: { + '0%, 100%': { + transform: 'translateY(100%)' + }, + '50%': { + transform: 'translateY(0)' + } + } + }, + animation: { + line1: 'line 3s linear infinite', + line2: 'line 6s linear infinite', + line3: 'line 9s linear infinite' + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)' + } + } + }, + plugins: [require("tailwindcss-animate")], }; From 5f6ab5d6260d4ed7fde50eeabe9188c0fca39636 Mon Sep 17 00:00:00 2001 From: DGoiana Date: Tue, 1 Oct 2024 00:14:34 +0100 Subject: [PATCH 05/15] state in the cart --- app/(site)/shop/pageContent.tsx | 13 ++++++++++-- components/Shop/Cart/index.tsx | 7 ++++--- components/Shop/CartItem/index.tsx | 26 ++++++++++++++++-------- components/Shop/ProductPreview/index.tsx | 9 ++++---- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx index 6ea67b1..6c894ce 100644 --- a/app/(site)/shop/pageContent.tsx +++ b/app/(site)/shop/pageContent.tsx @@ -11,14 +11,23 @@ import React from "react"; export default function ShopPageContent({ products }) { const [previewProduct, setPreviewProduct] = React.useState(products[0]); const [openCart, setOpenCart] = React.useState(false); + const [cartProducts, setCardProducts] = React.useState([]); + + const addToCart = (product: Product) => { + setCardProducts((prevCardProducts) => [...prevCardProducts, product]); + } + + const removeFromCart = (productID: number) => { + setCardProducts((prevCardProducts) => prevCardProducts.filter((product) => product.id !== productID)); + } return ( <>
- +
- +

Student Essentials diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx index d690b94..83fb155 100644 --- a/components/Shop/Cart/index.tsx +++ b/components/Shop/Cart/index.tsx @@ -14,17 +14,18 @@ type ShopCartProps = { isOpen: boolean, onOpenChange: (bool: boolean) => void, products: Product[], + removeFromCart: (productID: number) => void, } -const ShopCart = ({ isOpen, onOpenChange, products }: ShopCartProps) => { +const ShopCart = ({ isOpen, onOpenChange, products, removeFromCart }: ShopCartProps) => { return - Cart + Cart {products.map((p) => { return <> - +
})} diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx index bb4af1e..342781e 100644 --- a/components/Shop/CartItem/index.tsx +++ b/components/Shop/CartItem/index.tsx @@ -3,23 +3,33 @@ import Image from 'next/image'; type CartItemProps = { product: Product, - + removeFromCart: (productID: number) => void, } -const CartItem = ({ product }: CartItemProps) => { - return
+const CartItem = ({ product, removeFromCart }: CartItemProps) => { + return
hero -
-

{product.name}

-

{product.price}$

+
+
+

{product.name}

+

{product.price} €

+
+ 1 un + XS + Green +
+
+
+ + +
-
+
} export default CartItem; \ No newline at end of file diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index fe2b5fa..10b0b9b 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -3,11 +3,12 @@ import Image from "next/image"; import SizePicker from "../SizePicker"; type ProductPreviewProps = { - product: Product; - setCartState: Function; + product: Product, + setCartState: (bool: boolean) => void, + addToCart: (product: Product) => void, }; -const ProductPreview = ({ product, setCartState }: ProductPreviewProps) => { +const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProps) => { return ( <> { {product.description}

- +
+
+

+ Student Essentials +

+

+ Os merch-essentials{" "} + deste ano para viveres a tua vida académica ao máximo, com estilo. +

+
+
+ + + + +
+
+
+
+ + ); +} diff --git a/collections/Product.ts b/collections/Product.ts new file mode 100644 index 0000000..a848a95 --- /dev/null +++ b/collections/Product.ts @@ -0,0 +1,22 @@ +import type { CollectionConfig } from "payload"; + +export const Product: CollectionConfig = { + slug: "product", + fields: [ + { + name: "name", + type: "text", + required: true, + }, + { + name: "price", + type: "number", + required: true, + }, + { + name: "description", + type: "text", + required: true, + }, + ], +}; diff --git a/components/ShopCard/index.tsx b/components/ShopCard/index.tsx new file mode 100644 index 0000000..3d2cd16 --- /dev/null +++ b/components/ShopCard/index.tsx @@ -0,0 +1,36 @@ +import { Product } from "@/payload-types"; +import Image from "next/image"; + +type ShopCardProps = { + product: Product; +}; + +const ShopCard = ({ product }: ShopCardProps) => { + return ( +
+ Product image +
+

+ T-shirt oficial +

+ + +
+
+ ); +}; + +export default ShopCard; diff --git a/public/images/cactus.jpg b/public/images/cactus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f93ce4a077186a8aded677362508f391637ef66d GIT binary patch literal 21165 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%0DCYw{7;IBG3Gokjd>|7=K#LEzlHui8H${zEfQ-K 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 literal 0 HcmV?d00001 diff --git a/tailwind.config.js b/tailwind.config.js index 2a5a71e..2862cd1 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -13,6 +13,7 @@ module.exports = { theme: { fontFamily: { inter: ["Inter", "sans-serif"], + serif: ["ui-serif", "Georgia"], }, extend: { colors: { @@ -37,6 +38,7 @@ module.exports = { alabaster: "#FBFBFB", zumthor: "#EDF5FF", socialicon: "#D1D8E0", + engenharia: "#8C2D19", // secondary: "#C4C6B9", // accent: #562920 From f077facc3f7fc9dd4404a4dab0692866de7b6875 Mon Sep 17 00:00:00 2001 From: DGoiana Date: Tue, 20 Aug 2024 00:34:51 +0100 Subject: [PATCH 07/15] adding reactivity --- components/Shop/ProductPreview/index.tsx | 38 ++++++++++++++++++++++++ components/{ => Shop}/ShopCard/index.tsx | 10 +++++-- payload-types.ts | 13 ++++++++ payload.config.ts | 2 ++ 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 components/Shop/ProductPreview/index.tsx rename components/{ => Shop}/ShopCard/index.tsx (74%) diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx new file mode 100644 index 0000000..686f974 --- /dev/null +++ b/components/Shop/ProductPreview/index.tsx @@ -0,0 +1,38 @@ +import { Product } from "@/payload-types"; +import Image from "next/image"; + +type ProductPreviewProps = { + product: Product; +}; + +const ProductPreview = ({ product }: ProductPreviewProps) => { + return ( + <> + hero +
+

+ {product.name} +

+ + bestseller + +
+

+ {product.description} +

+ + + ); +}; + +export default ProductPreview; diff --git a/components/ShopCard/index.tsx b/components/Shop/ShopCard/index.tsx similarity index 74% rename from components/ShopCard/index.tsx rename to components/Shop/ShopCard/index.tsx index 3d2cd16..fd2ae9a 100644 --- a/components/ShopCard/index.tsx +++ b/components/Shop/ShopCard/index.tsx @@ -3,11 +3,15 @@ import Image from "next/image"; type ShopCardProps = { product: Product; + customClick?: () => void; }; -const ShopCard = ({ product }: ShopCardProps) => { +const ShopCard = ({ product, customClick }: ShopCardProps) => { return ( -
+
{ />

- T-shirt oficial + {product.name}

-
-
-

- Student Essentials -

-

- Os merch-essentials{" "} - deste ano para viveres a tua vida académica ao máximo, com estilo. -

-
-
- - - - -
-
-
-
- - ); + return ; } diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx new file mode 100644 index 0000000..1f3a0e1 --- /dev/null +++ b/app/(site)/shop/pageContent.tsx @@ -0,0 +1,50 @@ +"use client"; + +import SectionHeader from "@/components/Common/SectionHeader"; +import ProductPreview from "@/components/Shop/ProductPreview"; +import ShopCard from "@/components/Shop/ShopCard"; +import { Product } from "@/payload-types"; +import React from "react"; + +export default function ShopPageContent({ products }) { + const [previewProduct, setPreviewProduct] = React.useState(products[0]); + + return ( + <> +
+ +
+
+
+ +
+
+

+ Student Essentials +

+

+ Os merch-essentials{" "} + deste ano para viveres a tua vida académica ao máximo, com estilo. +

+
+
+ {products.map((product: Product) => ( + setPreviewProduct(product)} + > + ))} +
+
+
+
+ + ); +} From f5d3599dedd07d11c80c4a0de5f27fd2299f65e1 Mon Sep 17 00:00:00 2001 From: DGoiana Date: Mon, 30 Sep 2024 22:49:15 +0100 Subject: [PATCH 09/15] starting shop cart --- app/(site)/shop/pageContent.tsx | 17 +- app/globals.css | 3 + components.json | 20 + components/Shop/Cart/index.tsx | 40 ++ components/Shop/CartItem/index.tsx | 25 ++ components/Shop/ProductPreview/index.tsx | 17 +- components/Shop/SizePicker/index.tsx | 12 + components/ui/sheet.tsx | 140 ++++++ lib/utils.ts | 6 + package.json | 10 +- pnpm-lock.yaml | 522 +++++++++++++++++++++-- tailwind.config.js | 308 ++++++------- 12 files changed, 916 insertions(+), 204 deletions(-) create mode 100644 components.json create mode 100644 components/Shop/Cart/index.tsx create mode 100644 components/Shop/CartItem/index.tsx create mode 100644 components/Shop/SizePicker/index.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 lib/utils.ts diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx index 1f3a0e1..6ea67b1 100644 --- a/app/(site)/shop/pageContent.tsx +++ b/app/(site)/shop/pageContent.tsx @@ -1,6 +1,8 @@ "use client"; import SectionHeader from "@/components/Common/SectionHeader"; +import ShopCart from "@/components/Shop/Cart"; +import CartItem from "@/components/Shop/CartItem"; import ProductPreview from "@/components/Shop/ProductPreview"; import ShopCard from "@/components/Shop/ShopCard"; import { Product } from "@/payload-types"; @@ -8,22 +10,15 @@ import React from "react"; export default function ShopPageContent({ products }) { const [previewProduct, setPreviewProduct] = React.useState(products[0]); + const [openCart, setOpenCart] = React.useState(false); return ( <> -
- -
-
+
- +
+

Student Essentials diff --git a/app/globals.css b/app/globals.css index af0aa4e..fbb58ac 100644 --- a/app/globals.css +++ b/app/globals.css @@ -23,6 +23,9 @@ body { @apply relative z-1 font-inter text-regular font-normal text-waterloo dark:text-manatee; } + :root { + --radius: 0.5rem; + } } @layer components { diff --git a/components.json b/components.json new file mode 100644 index 0000000..676bbad --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": false, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx new file mode 100644 index 0000000..d690b94 --- /dev/null +++ b/components/Shop/Cart/index.tsx @@ -0,0 +1,40 @@ +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import React from "react"; +import CartItem from "../CartItem"; +import { Product } from "@/payload-types"; + +type ShopCartProps = { + isOpen: boolean, + onOpenChange: (bool: boolean) => void, + products: Product[], +} + +const ShopCart = ({ isOpen, onOpenChange, products }: ShopCartProps) => { + return + + + Cart + + {products.map((p) => { + return <> + +
+ + })} +
+
+ + + +
+
+} + +export default ShopCart; \ No newline at end of file diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx new file mode 100644 index 0000000..bb4af1e --- /dev/null +++ b/components/Shop/CartItem/index.tsx @@ -0,0 +1,25 @@ +import { Product } from "@/payload-types"; +import Image from 'next/image'; + +type CartItemProps = { + product: Product, + +} + +const CartItem = ({ product }: CartItemProps) => { + return
+ hero +
+

{product.name}

+

{product.price}$

+
+
+} + +export default CartItem; \ No newline at end of file diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index 686f974..fe2b5fa 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -1,11 +1,13 @@ import { Product } from "@/payload-types"; import Image from "next/image"; +import SizePicker from "../SizePicker"; type ProductPreviewProps = { product: Product; + setCartState: Function; }; -const ProductPreview = ({ product }: ProductPreviewProps) => { +const ProductPreview = ({ product, setCartState }: ProductPreviewProps) => { return ( <> {

{product.description}

- +
+ + +
); }; diff --git a/components/Shop/SizePicker/index.tsx b/components/Shop/SizePicker/index.tsx new file mode 100644 index 0000000..e649ebb --- /dev/null +++ b/components/Shop/SizePicker/index.tsx @@ -0,0 +1,12 @@ +const SizePicker = () => { + return <> + + +} + +export default SizePicker; \ No newline at end of file diff --git a/components/ui/sheet.tsx b/components/ui/sheet.tsx new file mode 100644 index 0000000..8989d81 --- /dev/null +++ b/components/ui/sheet.tsx @@ -0,0 +1,140 @@ +"use client" + +import * as React from "react" +import * as SheetPrimitive from "@radix-ui/react-dialog" +import { cva, type VariantProps } from "class-variance-authority" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Sheet = SheetPrimitive.Root + +const SheetTrigger = SheetPrimitive.Trigger + +const SheetClose = SheetPrimitive.Close + +const SheetPortal = SheetPrimitive.Portal + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName + +const sheetVariants = cva( + "fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 dark:bg-slate-950", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + } +) + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = "right", className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +SheetContent.displayName = SheetPrimitive.Content.displayName + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetHeader.displayName = "SheetHeader" + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetFooter.displayName = "SheetFooter" + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetTitle.displayName = SheetPrimitive.Title.displayName + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetDescription.displayName = SheetPrimitive.Description.displayName + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +} diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/package.json b/package.json index c1d4f72..3cac20f 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,15 @@ "@payloadcms/richtext-lexical": "3.0.0-beta.71", "@payloadcms/richtext-slate": "3.0.0-beta.71", "@payloadcms/ui": "3.0.0-beta.71", + "@radix-ui/react-dialog": "^1.1.1", "autoprefixer": "^10.4.19", "babel-plugin-react-compiler": "^0.0.0", "cross-env": "^7.0.3", "lucide-react": "^0.427.0", "framer-motion": "^11.3.24", "graphql": "^16.9.0", - "lucide-react": "^0.436.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "next": "15.0.0-canary.77", "next-themes": "^0.3.0", "payload": "3.0.0-beta.71", @@ -31,7 +33,9 @@ "react-hot-toast": "^2.4.1", "sharp": "0.32.6", "swiper": "^9.4.1", - "tailwindcss": "^3.4.7" + "tailwindcss": "^3.4.7", + "tailwind-merge": "^2.5.2", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@payloadcms/graphql": "3.0.0-beta.71", @@ -52,4 +56,4 @@ "@types/react": "npm:types-react@19.0.0-rc.0", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.0" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96a1ef9..0113da7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,24 +30,33 @@ importers: '@payloadcms/ui': specifier: 3.0.0-beta.71 version: 3.0.0-beta.71(monaco-editor@0.50.0)(next@15.0.0-canary.77(babel-plugin-react-compiler@0.0.0)(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(sass@1.77.4))(payload@3.0.0-beta.71(@swc/core@1.7.3(@swc/helpers@0.5.12))(@swc/types@0.1.12)(graphql@16.9.0)(typescript@5.5.3))(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-dialog': + specifier: ^1.1.1 + version: 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) autoprefixer: specifier: ^10.4.19 - version: 10.4.19(postcss@8.4.41) + version: 10.4.19(postcss@8.4.40) babel-plugin-react-compiler: specifier: ^0.0.0 version: 0.0.0 + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 + clsx: + specifier: ^2.1.1 + version: 2.1.1 cross-env: specifier: ^7.0.3 version: 7.0.3 framer-motion: specifier: ^11.3.24 - version: 11.3.24(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610) + version: 11.9.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610) graphql: specifier: ^16.9.0 version: 16.9.0 lucide-react: - specifier: ^0.436.0 - version: 0.436.0(react@19.0.0-rc-6230622a1a-20240610) + specifier: ^0.427.0 + version: 0.427.0(react@19.0.0-rc-6230622a1a-20240610) next: specifier: 15.0.0-canary.77 version: 15.0.0-canary.77(babel-plugin-react-compiler@0.0.0)(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(sass@1.77.4) @@ -72,9 +81,15 @@ importers: swiper: specifier: ^9.4.1 version: 9.4.1 + tailwind-merge: + specifier: ^2.5.2 + version: 2.5.2 tailwindcss: specifier: ^3.4.7 version: 3.4.7 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.7) devDependencies: '@payloadcms/graphql': specifier: 3.0.0-beta.71 @@ -1079,6 +1094,168 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.1': + resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} @@ -1463,6 +1640,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -1661,6 +1842,9 @@ packages: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} + class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -1671,6 +1855,10 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1832,6 +2020,9 @@ packages: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -2246,8 +2437,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@11.3.24: - resolution: {integrity: sha512-kl0YI7HwAtyV0VOAWuU/rXoOS8+z5qSkMN6rZS+a9oe6fIha6SC3vjJN6u/hBpvjrg5MQNdSnqnjYxm0WYTX9g==} + framer-motion@11.9.0: + resolution: {integrity: sha512-nCfGxvsQecVLjjYDu35G2F5ls+ArE3FBfhxV0RSiisMaUKqteq5DMBFNRKwMyVj+VqKTNhawt+BV480YCHKFlQ==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 @@ -2285,6 +2476,10 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-stdin@8.0.0: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} @@ -2466,6 +2661,9 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -2718,8 +2916,8 @@ packages: lexical@0.16.1: resolution: {integrity: sha512-+R05d3+N945OY8pTUjTqQrWoApjC+ctzvjnmNETtx9WmVAaiW0tQVG+AYLt5pDGY8dQXtd4RPorvnxBTECt9SA==} - lib0@0.2.97: - resolution: {integrity: sha512-Q4d1ekgvufi9FiHkkL46AhecfNjznSL9MRNoJRQ76gBHS9OqU2ArfQK0FvBpuxgWeJeNI0LVgAYMIpsGeX4gYg==} + lib0@0.2.95: + resolution: {integrity: sha512-St5XGDh5omvNawGkAOa7CFRjxl4xEKLj9DxgT8Nl7rmrD6l2WRTngvmZGhJKRaniROterT0RDVdnwLlU9PiEOg==} engines: {node: '>=16'} hasBin: true @@ -2761,8 +2959,8 @@ packages: lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - lucide-react@0.436.0: - resolution: {integrity: sha512-N292bIxoqm1aObAg0MzFtvhYwgQE6qnIOWx/GLj5ONgcTPH6N0fD9bVq/GfdeC9ZORBXozt/XeEKDpiB3x3vlQ==} + lucide-react@0.427.0: + resolution: {integrity: sha512-lv9s6c5BDF/ccuA0EgTdskTxIe11qpwBDmzRZHJAKtp8LTewAvDvOM+pTES9IpbBuTqkjiMhOmGpJ/CB+mKjFw==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc @@ -3163,8 +3361,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + postcss@8.4.40: + resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -3299,12 +3497,42 @@ packages: react: ^15.5.x || ^16.x || ^17.x || ^18.x react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-select@5.8.0: resolution: {integrity: sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-transition-group@4.4.5: resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: @@ -3663,6 +3891,14 @@ packages: tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.5.2: + resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.7: resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==} engines: {node: '>=14.0.0'} @@ -3819,6 +4055,16 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-context-selector@2.0.0: resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==} peerDependencies: @@ -3834,6 +4080,16 @@ packages: '@types/react': optional: true + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -5308,6 +5564,141 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-compose-refs@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-context@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-dialog@1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + aria-hidden: 1.2.4 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-remove-scroll: 2.5.7(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-dismissable-layer@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-escape-keydown': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-focus-guards@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-focus-scope@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-id@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-portal@1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-presence@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-primitive@2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + + '@radix-ui/react-slot@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-controllable-state@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-escape-keydown@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + '@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@rushstack/eslint-patch@1.10.4': {} '@smithy/abort-controller@3.1.1': @@ -5813,6 +6204,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.3 + aria-query@5.1.3: dependencies: deep-equal: 2.2.3 @@ -5888,14 +6283,14 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.19(postcss@8.4.41): + autoprefixer@10.4.19(postcss@8.4.40): dependencies: browserslist: 4.23.2 caniuse-lite: 1.0.30001645 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 - postcss: 8.4.41 + postcss: 8.4.40 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -6053,6 +6448,10 @@ snapshots: ci-info@4.0.0: {} + class-variance-authority@0.7.0: + dependencies: + clsx: 2.0.0 + classnames@2.5.1: {} cli-color@2.0.4: @@ -6065,6 +6464,8 @@ snapshots: client-only@0.0.1: {} + clsx@2.0.0: {} + clsx@2.1.1: {} color-convert@1.9.3: @@ -6223,6 +6624,8 @@ snapshots: detect-libc@2.0.3: {} + detect-node-es@1.1.0: {} + didyoumean@1.2.2: {} diff@5.2.0: {} @@ -6799,7 +7202,7 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@11.3.24(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): + framer-motion@11.9.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): dependencies: tslib: 2.6.3 optionalDependencies: @@ -6832,6 +7235,8 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-nonce@1.0.1: {} + get-stdin@8.0.0: {} get-symbol-description@1.0.2: @@ -7011,6 +7416,10 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + ip-address@9.0.5: dependencies: jsbn: 1.1.0 @@ -7258,7 +7667,7 @@ snapshots: lexical@0.16.1: {} - lib0@0.2.97: + lib0@0.2.95: dependencies: isomorphic.js: 0.2.5 @@ -7292,7 +7701,7 @@ snapshots: dependencies: es5-ext: 0.10.64 - lucide-react@0.436.0(react@19.0.0-rc-6230622a1a-20240610): + lucide-react@0.427.0(react@19.0.0-rc-6230622a1a-20240610): dependencies: react: 19.0.0-rc-6230622a1a-20240610 @@ -7700,28 +8109,28 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-import@15.1.0(postcss@8.4.41): + postcss-import@15.1.0(postcss@8.4.40): dependencies: - postcss: 8.4.41 + postcss: 8.4.40 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - postcss-js@4.0.1(postcss@8.4.41): + postcss-js@4.0.1(postcss@8.4.40): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.41 + postcss: 8.4.40 - postcss-load-config@4.0.2(postcss@8.4.41): + postcss-load-config@4.0.2(postcss@8.4.40): dependencies: lilconfig: 3.1.2 yaml: 2.5.0 optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.40 - postcss-nested@6.2.0(postcss@8.4.41): + postcss-nested@6.2.0(postcss@8.4.40): dependencies: - postcss: 8.4.41 + postcss: 8.4.40 postcss-selector-parser: 6.1.1 postcss-selector-parser@6.1.1: @@ -7737,7 +8146,7 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - postcss@8.4.41: + postcss@8.4.40: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 @@ -7878,6 +8287,25 @@ snapshots: react: 19.0.0-rc-6230622a1a-20240610 react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-remove-scroll-bar@2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + + react-remove-scroll@2.5.7(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-remove-scroll-bar: 2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.3 + use-callback-ref: 1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + use-sidecar: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + react-select@5.8.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): dependencies: '@babel/runtime': 7.25.0 @@ -7895,6 +8323,15 @@ snapshots: - '@types/react' - supports-color + react-style-singleton@2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + react-transition-group@4.4.5(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): dependencies: '@babel/runtime': 7.25.0 @@ -8317,6 +8754,12 @@ snapshots: tabbable@6.2.0: {} + tailwind-merge@2.5.2: {} + + tailwindcss-animate@1.0.7(tailwindcss@3.4.7): + dependencies: + tailwindcss: 3.4.7 + tailwindcss@3.4.7: dependencies: '@alloc/quick-lru': 5.2.0 @@ -8333,11 +8776,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.1 - postcss: 8.4.41 - postcss-import: 15.1.0(postcss@8.4.41) - postcss-js: 4.0.1(postcss@8.4.41) - postcss-load-config: 4.0.2(postcss@8.4.41) - postcss-nested: 6.2.0(postcss@8.4.41) + postcss: 8.4.40 + postcss-import: 15.1.0(postcss@8.4.40) + postcss-js: 4.0.1(postcss@8.4.40) + postcss-load-config: 4.0.2(postcss@8.4.40) + postcss-nested: 6.2.0(postcss@8.4.40) postcss-selector-parser: 6.1.1 resolve: 1.22.8 sucrase: 3.35.0 @@ -8525,6 +8968,13 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + use-context-selector@2.0.0(react@19.0.0-rc-6230622a1a-20240610)(scheduler@0.25.0-rc-f994737d14-20240522): dependencies: react: 19.0.0-rc-6230622a1a-20240610 @@ -8536,6 +8986,14 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 + use-sidecar@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.3 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} @@ -8629,7 +9087,7 @@ snapshots: yjs@13.6.18: dependencies: - lib0: 0.2.97 + lib0: 0.2.95 yocto-queue@0.1.0: {} diff --git a/tailwind.config.js b/tailwind.config.js index 2862cd1..f4ec278 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,157 +1,161 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./app/**/*.{js,ts,jsx,tsx,mdx}", - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", + content: [ + "./app/**/*.{js,ts,jsx,tsx,mdx}", + "./pages/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", - // Or if using `src` directory: - "./src/**/*.{js,ts,jsx,tsx,mdx}", - ], - darkMode: "class", - theme: { - fontFamily: { - inter: ["Inter", "sans-serif"], - serif: ["ui-serif", "Georgia"], - }, - extend: { - colors: { - current: "currentColor", - transparent: "transparent", - stroke: "#EEEEEE", - strokedark: "#2D2F40", - hoverdark: "#252A42", - titlebg: "#ADFFF8", - titlebg2: "#FFEAC2", - titlebgdark: "#46495A", - btndark: "#292E45", - white: "#FFFFFF", - black: "#181C31", - blackho: "#2C3149", - blacksection: "#1C2136", - primary: "#97321D", - primaryho: "#0063EC", - meta: "#20C5A8", - waterloo: "#757693", - manatee: "#999AA1", - alabaster: "#FBFBFB", - zumthor: "#EDF5FF", - socialicon: "#D1D8E0", - engenharia: "#8C2D19", - - // secondary: "#C4C6B9", - // accent: #562920 - // background: #FAFAFA - // dark-primary: #96311D - // dark-secondary: #444639 - // dark-accent: #CDA59D - // dark-background: #161416 - }, - fontSize: { - metatitle: ["12px", "20px"], - sectiontitle: ["14px", "22px"], - regular: ["16px", "26px"], - metatitle3: ["18px", "26px"], - metatitle2: ["20px", "32px"], - para2: ["22px", "35px"], - itemtitle: ["26px", "32px"], - itemtitle2: ["24px", "32px"], - hero: ["44px", "58px"], - sectiontitle3: ["44px", "55px"], - sectiontitle2: ["40px", "52px"], - sectiontitle4: ["34px", "48px"], - }, - spacing: { - 4.5: "1.125rem", - 5.5: "1.375rem", - 6.5: "1.625rem", - 7.5: "1.875rem", - 8.5: "2.125rem", - 10.5: "2.625rem", - 11.5: "2.875rem", - 12.5: "3.125rem", - 13: "3.25rem", - 13.5: "3.375rem", - 14.5: "3.625rem", - 15: "3.75rem", - 15.5: "3.875rem", - 16: "4rem", - 17: "4.25rem", - 17.5: "4.375rem", - 18: "4.5rem", - 18.5: "4.625rem", - 19: "4.75rem", - 21: "5.25rem", - 21.5: "5.375rem", - 22: "5.5rem", - 22.5: "5.625rem", - 25: "6.25rem", - 27: "6.75rem", - 27.5: "6.875rem", - 29: "7.25rem", - 29.5: "7.375rem", - 30: "7.5rem", - 32.5: "8.125rem", - 35: "8.75rem", - 37.5: "9.375rem", - 40: "10rem", - 42.5: "10.625rem", - 45: "11.25rem", - 46: "11.5rem", - 47.5: "11.875rem", - 50: "12.5rem", - 55: "13.75rem", - 60: "15rem", - 65: "16.25rem", - 67: "16.75rem", - 67.5: "16.875rem", - 90: "22.5rem", - }, - maxWidth: { - "c-1390": "86.875rem", - "c-1315": "82.188rem", - "c-1280": "80rem", - "c-1235": "77.188rem", - "c-1154": "72.125rem", - "c-1016": "63.5rem", - }, - zIndex: { - 99999: "99999", - 999: "999", - 1: "1", - }, - opacity: { - 65: ".65", - }, - transitionProperty: { width: "width" }, - boxShadow: { - "solid-l": "0px 10px 120px 0px rgba(45, 74, 170, 0.1)", - "solid-2": "0px 2px 10px rgba(122, 135, 167, 0.05)", - "solid-3": "0px 6px 90px rgba(8, 14, 40, 0.04)", - "solid-4": "0px 6px 90px rgba(8, 14, 40, 0.1)", - "solid-5": "0px 8px 24px rgba(45, 74, 170, 0.08)", - "solid-6": "0px 8px 24px rgba(10, 16, 35, 0.08)", - "solid-7": "0px 30px 50px rgba(45, 74, 170, 0.1)", - "solid-8": "0px 12px 120px rgba(45, 74, 170, 0.06)", - "solid-9": "0px 12px 30px rgba(45, 74, 170, 0.06)", - "solid-10": "0px 8px 30px rgba(45, 74, 170, 0.06)", - "solid-11": "0px 6px 20px rgba(45, 74, 170, 0.05)", - "solid-12": "0px 2px 10px rgba(0, 0, 0, 0.05)", - "solid-13": "0px 2px 19px rgba(0, 0, 0, 0.05)", - }, - keyframes: { - line: { - "0%, 100%": { transform: "translateY(100%)" }, - "50%": { transform: "translateY(0)" }, - }, - }, - animation: { - line1: "line 3s linear infinite", - line2: "line 6s linear infinite", - line3: "line 9s linear infinite", - }, - }, - }, - plugins: [], + // Or if using `src` directory: + "./src/**/*.{js,ts,jsx,tsx,mdx}", + ], + darkMode: ["class", "class"], + theme: { + fontFamily: { + inter: ["Inter", "sans-serif"], + serif: ["ui-serif", "Georgia"] + }, + extend: { + colors: { + current: 'currentColor', + transparent: 'transparent', + stroke: '#EEEEEE', + strokedark: '#2D2F40', + hoverdark: '#252A42', + titlebg: '#ADFFF8', + titlebg2: '#FFEAC2', + titlebgdark: '#46495A', + btndark: '#292E45', + white: '#FFFFFF', + black: '#181C31', + blackho: '#2C3149', + blacksection: '#1C2136', + primary: '#97321D', + primaryho: '#0063EC', + meta: '#20C5A8', + waterloo: '#757693', + manatee: '#999AA1', + alabaster: '#FBFBFB', + zumthor: '#EDF5FF', + socialicon: '#D1D8E0', + engenharia: '#8C2D19' + }, + fontSize: { + metatitle: ["12px", "20px"], + sectiontitle: ["14px", "22px"], + regular: ["16px", "26px"], + metatitle3: ["18px", "26px"], + metatitle2: ["20px", "32px"], + para2: ["22px", "35px"], + itemtitle: ["26px", "32px"], + itemtitle2: ["24px", "32px"], + hero: ["44px", "58px"], + sectiontitle3: ["44px", "55px"], + sectiontitle2: ["40px", "52px"], + sectiontitle4: ["34px", "48px"] + }, + spacing: { + '13': '3.25rem', + '15': '3.75rem', + '16': '4rem', + '17': '4.25rem', + '18': '4.5rem', + '19': '4.75rem', + '21': '5.25rem', + '22': '5.5rem', + '25': '6.25rem', + '27': '6.75rem', + '29': '7.25rem', + '30': '7.5rem', + '35': '8.75rem', + '40': '10rem', + '45': '11.25rem', + '46': '11.5rem', + '50': '12.5rem', + '55': '13.75rem', + '60': '15rem', + '65': '16.25rem', + '67': '16.75rem', + '90': '22.5rem', + '4.5': '1.125rem', + '5.5': '1.375rem', + '6.5': '1.625rem', + '7.5': '1.875rem', + '8.5': '2.125rem', + '10.5': '2.625rem', + '11.5': '2.875rem', + '12.5': '3.125rem', + '13.5': '3.375rem', + '14.5': '3.625rem', + '15.5': '3.875rem', + '17.5': '4.375rem', + '18.5': '4.625rem', + '21.5': '5.375rem', + '22.5': '5.625rem', + '27.5': '6.875rem', + '29.5': '7.375rem', + '32.5': '8.125rem', + '37.5': '9.375rem', + '42.5': '10.625rem', + '47.5': '11.875rem', + '67.5': '16.875rem' + }, + maxWidth: { + 'c-1390': '86.875rem', + 'c-1315': '82.188rem', + 'c-1280': '80rem', + 'c-1235': '77.188rem', + 'c-1154': '72.125rem', + 'c-1016': '63.5rem' + }, + zIndex: { + '1': '1', + '999': '999', + '99999': '99999', + '100000': '100000', + }, + opacity: { + '65': '.65' + }, + transitionProperty: { + width: 'width' + }, + boxShadow: { + 'solid-l': '0px 10px 120px 0px rgba(45, 74, 170, 0.1)', + 'solid-2': '0px 2px 10px rgba(122, 135, 167, 0.05)', + 'solid-3': '0px 6px 90px rgba(8, 14, 40, 0.04)', + 'solid-4': '0px 6px 90px rgba(8, 14, 40, 0.1)', + 'solid-5': '0px 8px 24px rgba(45, 74, 170, 0.08)', + 'solid-6': '0px 8px 24px rgba(10, 16, 35, 0.08)', + 'solid-7': '0px 30px 50px rgba(45, 74, 170, 0.1)', + 'solid-8': '0px 12px 120px rgba(45, 74, 170, 0.06)', + 'solid-9': '0px 12px 30px rgba(45, 74, 170, 0.06)', + 'solid-10': '0px 8px 30px rgba(45, 74, 170, 0.06)', + 'solid-11': '0px 6px 20px rgba(45, 74, 170, 0.05)', + 'solid-12': '0px 2px 10px rgba(0, 0, 0, 0.05)', + 'solid-13': '0px 2px 19px rgba(0, 0, 0, 0.05)' + }, + keyframes: { + line: { + '0%, 100%': { + transform: 'translateY(100%)' + }, + '50%': { + transform: 'translateY(0)' + } + } + }, + animation: { + line1: 'line 3s linear infinite', + line2: 'line 6s linear infinite', + line3: 'line 9s linear infinite' + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)' + } + } + }, + plugins: [require("tailwindcss-animate")], }; From 7c87c62f8d4018c317229ac35f343540f4ad339c Mon Sep 17 00:00:00 2001 From: DGoiana Date: Tue, 1 Oct 2024 00:14:34 +0100 Subject: [PATCH 10/15] state in the cart --- app/(site)/shop/pageContent.tsx | 13 ++++++++++-- components/Shop/Cart/index.tsx | 7 ++++--- components/Shop/CartItem/index.tsx | 26 ++++++++++++++++-------- components/Shop/ProductPreview/index.tsx | 9 ++++---- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx index 6ea67b1..6c894ce 100644 --- a/app/(site)/shop/pageContent.tsx +++ b/app/(site)/shop/pageContent.tsx @@ -11,14 +11,23 @@ import React from "react"; export default function ShopPageContent({ products }) { const [previewProduct, setPreviewProduct] = React.useState(products[0]); const [openCart, setOpenCart] = React.useState(false); + const [cartProducts, setCardProducts] = React.useState([]); + + const addToCart = (product: Product) => { + setCardProducts((prevCardProducts) => [...prevCardProducts, product]); + } + + const removeFromCart = (productID: number) => { + setCardProducts((prevCardProducts) => prevCardProducts.filter((product) => product.id !== productID)); + } return ( <>
- +
- +

Student Essentials diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx index d690b94..83fb155 100644 --- a/components/Shop/Cart/index.tsx +++ b/components/Shop/Cart/index.tsx @@ -14,17 +14,18 @@ type ShopCartProps = { isOpen: boolean, onOpenChange: (bool: boolean) => void, products: Product[], + removeFromCart: (productID: number) => void, } -const ShopCart = ({ isOpen, onOpenChange, products }: ShopCartProps) => { +const ShopCart = ({ isOpen, onOpenChange, products, removeFromCart }: ShopCartProps) => { return - Cart + Cart {products.map((p) => { return <> - +
})} diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx index bb4af1e..342781e 100644 --- a/components/Shop/CartItem/index.tsx +++ b/components/Shop/CartItem/index.tsx @@ -3,23 +3,33 @@ import Image from 'next/image'; type CartItemProps = { product: Product, - + removeFromCart: (productID: number) => void, } -const CartItem = ({ product }: CartItemProps) => { - return
+const CartItem = ({ product, removeFromCart }: CartItemProps) => { + return
hero -
-

{product.name}

-

{product.price}$

+
+
+

{product.name}

+

{product.price} €

+
+ 1 un + XS + Green +
+
+
+ + +
-
+
} export default CartItem; \ No newline at end of file diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index fe2b5fa..10b0b9b 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -3,11 +3,12 @@ import Image from "next/image"; import SizePicker from "../SizePicker"; type ProductPreviewProps = { - product: Product; - setCartState: Function; + product: Product, + setCartState: (bool: boolean) => void, + addToCart: (product: Product) => void, }; -const ProductPreview = ({ product, setCartState }: ProductPreviewProps) => { +const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProps) => { return ( <> { {product.description}

- + {product.quantity} un + +
XS Green
-
diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index 10b0b9b..3944d75 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -1,13 +1,24 @@ import { Product } from "@/payload-types"; import Image from "next/image"; import SizePicker from "../SizePicker"; +import { cartProduct } from "@/types/cartProduct"; type ProductPreviewProps = { product: Product, setCartState: (bool: boolean) => void, - addToCart: (product: Product) => void, + addToCart: (product: cartProduct) => void, }; +const buildCartProduct = (product: Product): cartProduct => ({ + id: product.id, + name: product.name, + price: product.price, + quantity: 1, + size: 'XS', + color: 'Green', + description: product.description, +}); + const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProps) => { return ( <> @@ -30,7 +41,7 @@ const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProp {product.description}
- +
+ setNumber(e.target.value)} /> + +
diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx index 030066b..cd0ac50 100644 --- a/components/Shop/CartItem/index.tsx +++ b/components/Shop/CartItem/index.tsx @@ -23,7 +23,6 @@ const CartItem = ({ product, removeFromCart }: CartItemProps) => { } } - return
{ {product.quantity} un
- XS - Green + {product.size} + {product.color}
diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index 3944d75..a736f2e 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -1,7 +1,8 @@ -import { Product } from "@/payload-types"; +import { Product, ProductInstance } from "@/payload-types"; import Image from "next/image"; import SizePicker from "../SizePicker"; import { cartProduct } from "@/types/cartProduct"; +import React from "react"; type ProductPreviewProps = { product: Product, @@ -9,17 +10,19 @@ type ProductPreviewProps = { addToCart: (product: cartProduct) => void, }; -const buildCartProduct = (product: Product): cartProduct => ({ - id: product.id, - name: product.name, - price: product.price, - quantity: 1, - size: 'XS', - color: 'Green', - description: product.description, -}); - const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProps) => { + const [instance, setInstance] = React.useState(); + + const buildCartProduct = (instance: ProductInstance): cartProduct => ({ + id: instance.id, + name: product.name, + price: product.price, + quantity: 1, + size: instance.size, + color: product.color, + description: product.description, + }); + return ( <>
- - +
); diff --git a/components/Shop/SizePicker/index.tsx b/components/Shop/SizePicker/index.tsx index e649ebb..eb6344b 100644 --- a/components/Shop/SizePicker/index.tsx +++ b/components/Shop/SizePicker/index.tsx @@ -1,12 +1,47 @@ -const SizePicker = () => { - return <> - - -} - -export default SizePicker; \ No newline at end of file +import { useEffect, useState } from "react"; +import { Product, ProductInstance } from "@/payload-types"; +import { getInstances } from "components/Shop/SizePicker/payloadAction"; + +type SizePickerProps = { + product: Product, + setInstance: (instance: ProductInstance) => void, +}; + +const SizePicker = ({ product, setInstance }: SizePickerProps) => { + const [instances, setInstances] = useState([]); + + useEffect(() => { + const fetchInstances = async () => { + const allInstances = (await getInstances()).docs; + + const filteredInstances = allInstances.filter( + (instance: ProductInstance) => { + return (instance.product as Product).id == product.id; + } + ); + setInstances(filteredInstances); + }; + + fetchInstances(); + }, [product]); + + const handleSizeChange = (e: React.ChangeEvent) => { + const selectedInstance = instances.find((instance) => instance.size === e.target.value); + if (selectedInstance) { + setInstance(selectedInstance); + } + }; + + return ( + + ); +}; + +export default SizePicker; diff --git a/components/Shop/SizePicker/payloadAction.tsx b/components/Shop/SizePicker/payloadAction.tsx new file mode 100644 index 0000000..24dcecd --- /dev/null +++ b/components/Shop/SizePicker/payloadAction.tsx @@ -0,0 +1,26 @@ +"use server" + +import { getPayload } from "payload"; +import config from "payload.config"; + +export async function getInstances() { + + const payload = await getPayload({ config }); + + const instances = await payload.find({ + collection: "productInstance", + }); + + return instances; +} + +export async function getProducts() { + + const payload = await getPayload({ config }); + + const products = await payload.find({ + collection: "product", + }); + + return products; +} \ No newline at end of file diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..7a957e3 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300", + { + variants: { + variant: { + default: "bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90", + destructive: + "bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90", + outline: + "border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50", + secondary: + "bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80", + ghost: "hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50", + link: "text-slate-900 underline-offset-4 hover:underline dark:text-slate-50", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/components/ui/input.tsx b/components/ui/input.tsx new file mode 100644 index 0000000..ec857fc --- /dev/null +++ b/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/package.json b/package.json index 3cac20f..f410689 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,16 @@ "@payloadcms/richtext-slate": "3.0.0-beta.71", "@payloadcms/ui": "3.0.0-beta.71", "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-slot": "^1.1.0", "autoprefixer": "^10.4.19", + "axios": "^1.7.7", "babel-plugin-react-compiler": "^0.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "cross-env": "^7.0.3", - "lucide-react": "^0.427.0", "framer-motion": "^11.3.24", "graphql": "^16.9.0", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", + "lucide-react": "^0.427.0", "next": "15.0.0-canary.77", "next-themes": "^0.3.0", "payload": "3.0.0-beta.71", @@ -33,8 +35,8 @@ "react-hot-toast": "^2.4.1", "sharp": "0.32.6", "swiper": "^9.4.1", - "tailwindcss": "^3.4.7", "tailwind-merge": "^2.5.2", + "tailwindcss": "^3.4.7", "tailwindcss-animate": "^1.0.7" }, "devDependencies": { diff --git a/payload-types.ts b/payload-types.ts index 0823649..36e6737 100644 --- a/payload-types.ts +++ b/payload-types.ts @@ -20,6 +20,7 @@ export interface Config { position: Position; board_section: BoardSection; product: Product; + productInstance: ProductInstance; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; @@ -245,6 +246,19 @@ export interface Product { name: string; price: number; description: string; + color: string; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "productInstance". + */ +export interface ProductInstance { + id: number; + product: number | Product; + quantity: number; + size: 'XS' | 'S' | 'M' | 'L' | 'XL' | 'XXL'; updatedAt: string; createdAt: string; } diff --git a/payload.config.ts b/payload.config.ts index 1d70bc8..543db65 100644 --- a/payload.config.ts +++ b/payload.config.ts @@ -14,6 +14,7 @@ import { Link } from "./collections/Link"; import { Position } from "./collections/Position"; import { BoardSection } from "./collections/BoardSection"; import { Product } from "./collections/Product"; +import { ProductInstance } from "./collections/ProductInstance"; const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); @@ -32,7 +33,8 @@ export default buildConfig({ Link, Position, BoardSection, - Product + Product, + ProductInstance ], editor: lexicalEditor(), secret: process.env.PAYLOAD_SECRET || "", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0113da7..18902a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,9 +33,15 @@ importers: '@radix-ui/react-dialog': specifier: ^1.1.1 version: 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-slot': + specifier: ^1.1.0 + version: 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.40) + axios: + specifier: ^1.7.7 + version: 1.7.7 babel-plugin-react-compiler: specifier: ^0.0.0 version: 0.0.0 @@ -1686,6 +1692,9 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -1705,6 +1714,9 @@ packages: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axobject-query@3.1.1: resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} @@ -1886,6 +1898,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -2012,6 +2028,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -2427,6 +2447,15 @@ packages: focus-trap@7.5.4: resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -2434,6 +2463,10 @@ packages: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -2985,6 +3018,14 @@ packages: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -3413,6 +3454,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -6281,6 +6325,8 @@ snapshots: ast-types-flow@0.0.8: {} + asynckit@0.4.0: {} + atomic-sleep@1.0.0: {} autoprefixer@10.4.19(postcss@8.4.40): @@ -6299,6 +6345,14 @@ snapshots: axe-core@4.10.0: {} + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@3.1.1: dependencies: deep-equal: 2.2.3 @@ -6492,6 +6546,10 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@2.20.3: {} commander@4.1.1: {} @@ -6620,6 +6678,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delayed-stream@1.0.0: {} + dequal@2.0.3: {} detect-libc@2.0.3: {} @@ -7191,6 +7251,8 @@ snapshots: dependencies: tabbable: 6.2.0 + follow-redirects@1.15.9: {} + for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -7200,6 +7262,12 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + fraction.js@4.3.7: {} framer-motion@11.9.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): @@ -7734,6 +7802,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-response@3.1.0: {} minimatch@3.1.2: @@ -8198,6 +8272,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proxy-from-env@1.1.0: {} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 From e68e07c3f3f602fd9f4ff349d636f7d4e8d36bac Mon Sep 17 00:00:00 2001 From: DGoiana Date: Thu, 10 Oct 2024 00:45:45 +0100 Subject: [PATCH 13/15] removing merge conflict --- components/Shop/CartItem/index.tsx | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx index 5d45989..cd0ac50 100644 --- a/components/Shop/CartItem/index.tsx +++ b/components/Shop/CartItem/index.tsx @@ -1,22 +1,14 @@ import { Product } from "@/payload-types"; -<<<<<<< HEAD import { cartProduct } from "@/types/cartProduct"; import Image from 'next/image'; import React from "react"; type CartItemProps = { product: cartProduct, -======= -import Image from 'next/image'; - -type CartItemProps = { - product: Product, ->>>>>>> 5f6ab5d6260d4ed7fde50eeabe9188c0fca39636 removeFromCart: (productID: number) => void, } const CartItem = ({ product, removeFromCart }: CartItemProps) => { -<<<<<<< HEAD const [quantity, setQuantity] = React.useState(product.quantity); const increaseQuantity = () => { @@ -31,8 +23,6 @@ const CartItem = ({ product, removeFromCart }: CartItemProps) => { } } -======= ->>>>>>> 5f6ab5d6260d4ed7fde50eeabe9188c0fca39636 return
{

{product.name}

{product.price} €

-<<<<<<< HEAD
@@ -56,16 +45,6 @@ const CartItem = ({ product, removeFromCart }: CartItemProps) => {
-======= -
- 1 un - XS - Green -
-
-
- ->>>>>>> 5f6ab5d6260d4ed7fde50eeabe9188c0fca39636
From 802b5c883bf88c5ef0fdfe4b6020c276c35fda4c Mon Sep 17 00:00:00 2001 From: DGoiana Date: Thu, 10 Oct 2024 23:15:29 +0100 Subject: [PATCH 14/15] modulating files and start working on payment process --- app/(site)/shop/pageContent.tsx | 12 +++--- collections/Product.ts | 39 +++++++++++++++++++ collections/ProductInstance.ts | 25 ------------ .../Shop/Cart/{apiCall.tsx => apiCall.ts} | 28 ++++++++----- components/Shop/Cart/index.tsx | 21 +++++----- components/Shop/Cart/payment.ts | 11 ++++++ components/Shop/CartItem/index.tsx | 25 ++++++------ components/Shop/PaymentForm/index.tsx | 24 ++++++++++++ components/Shop/ProductPreview/index.tsx | 9 ++--- components/Shop/SizePicker/index.tsx | 29 +++----------- components/Shop/SizePicker/payloadAction.tsx | 11 ------ package.json | 3 +- payload-types.ts | 20 ++++------ payload.config.ts | 2 - pnpm-lock.yaml | 14 +++++++ types/cartProduct.ts | 8 ++-- types/productInstance.ts | 7 ++++ 17 files changed, 165 insertions(+), 123 deletions(-) delete mode 100644 collections/ProductInstance.ts rename components/Shop/Cart/{apiCall.tsx => apiCall.ts} (55%) create mode 100644 components/Shop/Cart/payment.ts create mode 100644 components/Shop/PaymentForm/index.tsx create mode 100644 types/productInstance.ts diff --git a/app/(site)/shop/pageContent.tsx b/app/(site)/shop/pageContent.tsx index ddf47d8..d505142 100644 --- a/app/(site)/shop/pageContent.tsx +++ b/app/(site)/shop/pageContent.tsx @@ -14,17 +14,17 @@ export default function ShopPageContent({ products }) { const [openCart, setOpenCart] = React.useState(false); const [cartProducts, setCardProducts] = React.useState([]); - const addToCart = (product: cartProduct) => { + const addToCart = (item: cartProduct) => { setCardProducts((prevCardProducts) => { - if (prevCardProducts.every((p) => p.id !== product.id)) { - return [...prevCardProducts, product]; + if (prevCardProducts.some((p) => p.product.id === item.product.id && p.size === item.size)) { + return prevCardProducts; } - return prevCardProducts; + return [...prevCardProducts, item]; }); } - const removeFromCart = (productID: number) => { - setCardProducts((prevCardProducts) => prevCardProducts.filter((product) => product.id !== productID)); + const removeFromCart = (itemCart: cartProduct) => { + setCardProducts((prevCardProducts) => prevCardProducts.filter((item) => item.product.id !== itemCart.product.id || (item.product.id === itemCart.product.id && item.size !== itemCart.size))); } return ( diff --git a/collections/Product.ts b/collections/Product.ts index 2707f97..d962458 100644 --- a/collections/Product.ts +++ b/collections/Product.ts @@ -23,5 +23,44 @@ export const Product: CollectionConfig = { type: "text", required: true, }, + { + name: "instances", + type: "array", + fields: [ + { + name: "Size", + type: "select", + hasMany: false, + options: [ + { + label: "XS", + value: "XS" + }, + { + label: "S", + value: "S" + }, + { + label: "M", + value: "M" + }, + { + label: "L", + value: "L" + }, + { + label: "XL", + value: "XL" + }, + ], + required: true, + }, + { + name: "quantity", + type: "number", + required: true, + } + ] + } ], }; diff --git a/collections/ProductInstance.ts b/collections/ProductInstance.ts deleted file mode 100644 index 11fb4e3..0000000 --- a/collections/ProductInstance.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { CollectionConfig } from "payload"; - -export const ProductInstance: CollectionConfig = { - slug: "productInstance", - fields: [ - { - name: "product", - type: "relationship", - required: true, - relationTo: "product", - }, - { - name: "quantity", - type: "number", - required: true, - }, - - { - name: "size", - type: "select", - required: true, - options: ["XS", "S", "M", "L", "XL", "XXL"] - }, - ] -} \ No newline at end of file diff --git a/components/Shop/Cart/apiCall.tsx b/components/Shop/Cart/apiCall.ts similarity index 55% rename from components/Shop/Cart/apiCall.tsx rename to components/Shop/Cart/apiCall.ts index 3bda0cb..e23fccb 100644 --- a/components/Shop/Cart/apiCall.tsx +++ b/components/Shop/Cart/apiCall.ts @@ -1,7 +1,8 @@ import axios from 'axios'; -import { Database } from 'lucide-react'; -export async function requestMBWAY(phoneNumber: string) { +export async function requestMBWAY(phoneNumber: string, amount: number) { + console.log("Function requestMBWAY called with:", phoneNumber, amount); // Initial log + const options = { method: 'POST', url: 'https://api.ifthenpay.com/spg/payment/mbway', @@ -9,17 +10,20 @@ export async function requestMBWAY(phoneNumber: string) { data: { mbWayKey: 'BYX-186558', orderId: 'teste', - amount: '499.99', + amount: amount.toString(), mobileNumber: '351#' + phoneNumber, } }; + console.log("Options prepared:", options); // Log options + try { const { data } = await axios.request(options); - console.log(data); - pollPaymentStatus(data.requestId); + console.log("Response data:", data); // Log response data + pollPaymentStatus(data.RequestId); + return; } catch (error) { - console.error(error); + console.error("Error occurred:", error); // Log error } } @@ -40,10 +44,16 @@ export async function checkPayment(requestID: string) { } const pollPaymentStatus = (requestID: string) => { - setInterval(async () => { + const paymentStatus = setInterval(async () => { const status = await checkPayment(requestID) - if (status.Message == "Success") alert("euerka") - else alert(status.Message) + if (status.Message == "Success") { + alert("euerka"); + clearInterval(paymentStatus) + } + if (status.Message == "Declined by user") { + alert("declined by user"); + clearInterval(paymentStatus) + } }, 5000) } \ No newline at end of file diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx index 0d1f01c..9e552e3 100644 --- a/components/Shop/Cart/index.tsx +++ b/components/Shop/Cart/index.tsx @@ -9,19 +9,20 @@ import { import React from "react"; import CartItem from "../CartItem"; import { cartProduct } from "@/types/cartProduct"; -import { Input } from "@/components/ui/input" -import { Button } from "@/components/ui/button"; -import { requestMBWAY } from "./apiCall"; +import startPaymentProcess from "./payment"; +import PaymentForm from "../PaymentForm"; +import PuffLoader from "react-spinners/PuffLoader"; type ShopCartProps = { isOpen: boolean, onOpenChange: (bool: boolean) => void, products: cartProduct[], - removeFromCart: (productID: number) => void, + removeFromCart: (item: cartProduct) => void, } const ShopCart = ({ isOpen, onOpenChange, products, removeFromCart }: ShopCartProps) => { const [number, setNumber] = React.useState("") + const [processingPayment, setProcessingPayment] = React.useState(false) return @@ -30,17 +31,19 @@ const ShopCart = ({ isOpen, onOpenChange, products, removeFromCart }: ShopCartPr {products.map((p) => { return <> - +
})}
-
- setNumber(e.target.value)} /> - -
+ {!processingPayment ? : +
+

Waiting for confirmation

+ +
+ }
diff --git a/components/Shop/Cart/payment.ts b/components/Shop/Cart/payment.ts new file mode 100644 index 0000000..15ae5d2 --- /dev/null +++ b/components/Shop/Cart/payment.ts @@ -0,0 +1,11 @@ +import { cartProduct } from "@/types/cartProduct"; +import { requestMBWAY } from "./apiCall"; + +export default async function startPaymentProcess(products: cartProduct[]) { + await requestMBWAY("915612870", calculcateCost(products)); +} + +function calculcateCost(products: cartProduct[]) { + const totalCost = 0 + return products.reduce((prev, curr) => prev + curr.product.price, totalCost) +} \ No newline at end of file diff --git a/components/Shop/CartItem/index.tsx b/components/Shop/CartItem/index.tsx index cd0ac50..7a4cad5 100644 --- a/components/Shop/CartItem/index.tsx +++ b/components/Shop/CartItem/index.tsx @@ -1,25 +1,24 @@ -import { Product } from "@/payload-types"; import { cartProduct } from "@/types/cartProduct"; import Image from 'next/image'; import React from "react"; type CartItemProps = { - product: cartProduct, - removeFromCart: (productID: number) => void, + item: cartProduct, + removeFromCart: (item: cartProduct) => void, } -const CartItem = ({ product, removeFromCart }: CartItemProps) => { - const [quantity, setQuantity] = React.useState(product.quantity); +const CartItem = ({ item, removeFromCart }: CartItemProps) => { + const [quantity, setQuantity] = React.useState(item.quantity); const increaseQuantity = () => { setQuantity(quantity + 1) - product.quantity = quantity + 1 + item.quantity = quantity + 1 } const decreaseQuantity = () => { if (quantity - 1 > 0) { setQuantity(quantity - 1) - product.quantity = quantity - 1 + item.quantity = quantity - 1 } } @@ -32,20 +31,20 @@ const CartItem = ({ product, removeFromCart }: CartItemProps) => { />
-

{product.name}

-

{product.price} €

+

{item.product.name}

+

{item.product.price} €

- {product.quantity} un + {item.quantity} un
- {product.size} - {product.color} + {item.size} + {item.product.color}
- +
diff --git a/components/Shop/PaymentForm/index.tsx b/components/Shop/PaymentForm/index.tsx new file mode 100644 index 0000000..a86c547 --- /dev/null +++ b/components/Shop/PaymentForm/index.tsx @@ -0,0 +1,24 @@ +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import startPaymentProcess from "../Cart/payment" +import { cartProduct } from "@/types/cartProduct" + +type PaymentFormProps = { + setNumber: (phone: string) => void + setProcessingPayment: (status: boolean) => void, + products: cartProduct[] +} + +const PaymentForm = ({ setNumber, products, setProcessingPayment }: PaymentFormProps) => { + return ( +
+
+ setNumber(e.target.value)} /> + < Input type="email" placeholder="Phone Number" onChange={(e) => setNumber(e.target.value)} /> +
+ < Button type="submit" className="self-end" onClick={() => setProcessingPayment(true)}> Pay +
+ ) +} + +export default PaymentForm \ No newline at end of file diff --git a/components/Shop/ProductPreview/index.tsx b/components/Shop/ProductPreview/index.tsx index 6446a02..6b41583 100644 --- a/components/Shop/ProductPreview/index.tsx +++ b/components/Shop/ProductPreview/index.tsx @@ -1,8 +1,9 @@ -import { Product, ProductInstance } from "@/payload-types"; +import { Product } from "@/payload-types"; import Image from "next/image"; import SizePicker from "../SizePicker"; import { cartProduct } from "@/types/cartProduct"; import React from "react"; +import { ProductInstance } from "@/types/productInstance"; type ProductPreviewProps = { product: Product, @@ -14,13 +15,9 @@ const ProductPreview = ({ product, setCartState, addToCart }: ProductPreviewProp const [instance, setInstance] = React.useState(); const buildCartProduct = (instance: ProductInstance): cartProduct => ({ - id: instance.id, - name: product.name, - price: product.price, + product: product, quantity: 1, size: instance.size, - color: product.color, - description: product.description, }); return ( diff --git a/components/Shop/SizePicker/index.tsx b/components/Shop/SizePicker/index.tsx index eb6344b..898f306 100644 --- a/components/Shop/SizePicker/index.tsx +++ b/components/Shop/SizePicker/index.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { Product, ProductInstance } from "@/payload-types"; -import { getInstances } from "components/Shop/SizePicker/payloadAction"; +import { Product } from "@/payload-types"; +import { ProductInstance } from "@/types/productInstance"; type SizePickerProps = { product: Product, @@ -8,25 +8,8 @@ type SizePickerProps = { }; const SizePicker = ({ product, setInstance }: SizePickerProps) => { - const [instances, setInstances] = useState([]); - - useEffect(() => { - const fetchInstances = async () => { - const allInstances = (await getInstances()).docs; - - const filteredInstances = allInstances.filter( - (instance: ProductInstance) => { - return (instance.product as Product).id == product.id; - } - ); - setInstances(filteredInstances); - }; - - fetchInstances(); - }, [product]); - const handleSizeChange = (e: React.ChangeEvent) => { - const selectedInstance = instances.find((instance) => instance.size === e.target.value); + const selectedInstance = { product: product, size: e.target.value, quantity: 0 }; if (selectedInstance) { setInstance(selectedInstance); } @@ -35,9 +18,9 @@ const SizePicker = ({ product, setInstance }: SizePickerProps) => { return ( diff --git a/components/Shop/SizePicker/payloadAction.tsx b/components/Shop/SizePicker/payloadAction.tsx index 24dcecd..c95b829 100644 --- a/components/Shop/SizePicker/payloadAction.tsx +++ b/components/Shop/SizePicker/payloadAction.tsx @@ -3,17 +3,6 @@ import { getPayload } from "payload"; import config from "payload.config"; -export async function getInstances() { - - const payload = await getPayload({ config }); - - const instances = await payload.find({ - collection: "productInstance", - }); - - return instances; -} - export async function getProducts() { const payload = await getPayload({ config }); diff --git a/package.json b/package.json index d2040df..3bd50f0 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "@radix-ui/react-slot": "^1.1.0", "autoprefixer": "^10.4.19", "axios": "^1.7.7", + "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cross-env": "^7.0.3", "framer-motion": "^11.3.24", "graphql": "^16.9.0", - "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517", "lucide-react": "^0.446.0", "next": "15.0.0-canary.77", "next-themes": "^0.3.0", @@ -33,6 +33,7 @@ "react": "19.0.0-rc-6230622a1a-20240610", "react-dom": "19.0.0-rc-6230622a1a-20240610", "react-hot-toast": "^2.4.1", + "react-spinners": "^0.14.1", "sharp": "0.32.6", "swiper": "^9.4.1", "tailwind-merge": "^2.5.2", diff --git a/payload-types.ts b/payload-types.ts index 220c3fc..4c814c8 100644 --- a/payload-types.ts +++ b/payload-types.ts @@ -22,7 +22,6 @@ export interface Config { position: Position; board_section: BoardSection; product: Product; - productInstance: ProductInstance; president: President; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; @@ -283,18 +282,13 @@ export interface Product { price: number; description: string; color: string; - updatedAt: string; - createdAt: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "productInstance". - */ -export interface ProductInstance { - id: number; - product: number | Product; - quantity: number; - size: 'XS' | 'S' | 'M' | 'L' | 'XL' | 'XXL'; + instances?: + | { + Size: 'XS' | 'S' | 'M' | 'L' | 'XL'; + quantity: number; + id?: string | null; + }[] + | null; updatedAt: string; createdAt: string; } diff --git a/payload.config.ts b/payload.config.ts index 464f5bf..94f50a5 100644 --- a/payload.config.ts +++ b/payload.config.ts @@ -16,7 +16,6 @@ import { Link } from "./collections/Link"; import { Position } from "./collections/Position"; import { BoardSection } from "./collections/BoardSection"; import { Product } from "./collections/Product"; -import { ProductInstance } from "./collections/ProductInstance"; import { President } from "./collections/President"; const filename = fileURLToPath(import.meta.url); @@ -39,7 +38,6 @@ export default buildConfig({ Position, BoardSection, Product, - ProductInstance, President, ], editor: lexicalEditor(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ff3e83..4c8cbc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -81,6 +81,9 @@ importers: react-hot-toast: specifier: ^2.4.1 version: 2.4.1(csstype@3.1.3)(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610) + react-spinners: + specifier: ^0.14.1 + version: 0.14.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610) sharp: specifier: 0.32.6 version: 0.32.6 @@ -3567,6 +3570,12 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-spinners@0.14.1: + resolution: {integrity: sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} @@ -8399,6 +8408,11 @@ snapshots: - '@types/react' - supports-color + react-spinners@0.14.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610): + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-style-singleton@2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): dependencies: get-nonce: 1.0.1 diff --git a/types/cartProduct.ts b/types/cartProduct.ts index 0cbf79f..439829e 100644 --- a/types/cartProduct.ts +++ b/types/cartProduct.ts @@ -1,9 +1,7 @@ +import { Product } from "@/payload-types"; + export type cartProduct = { - id: number, - name: string, + product: Product, quantity: number, size: string, - color: string, - price: number, - description: string, } \ No newline at end of file diff --git a/types/productInstance.ts b/types/productInstance.ts new file mode 100644 index 0000000..564f2ef --- /dev/null +++ b/types/productInstance.ts @@ -0,0 +1,7 @@ +import { Product } from "@/payload-types" + +export type ProductInstance = { + product: Product + size: string, + quantity: number, +} \ No newline at end of file From b1d9c3e1f27b62802d4338f24747ec7f28d494bc Mon Sep 17 00:00:00 2001 From: DGoiana Date: Thu, 14 Nov 2024 14:46:25 +0000 Subject: [PATCH 15/15] adding stuff --- components/Shop/Cart/apiCall.ts | 8 +- components/Shop/Cart/index.tsx | 6 +- components/Shop/PaymentForm/index.tsx | 56 ++++++++-- package.json | 1 + pnpm-lock.yaml | 25 +++++ public/images/shop/mbway.svg | 146 ++++++++++++++++++++++++++ 6 files changed, 228 insertions(+), 14 deletions(-) create mode 100644 public/images/shop/mbway.svg diff --git a/components/Shop/Cart/apiCall.ts b/components/Shop/Cart/apiCall.ts index e23fccb..54d7421 100644 --- a/components/Shop/Cart/apiCall.ts +++ b/components/Shop/Cart/apiCall.ts @@ -1,7 +1,7 @@ import axios from 'axios'; export async function requestMBWAY(phoneNumber: string, amount: number) { - console.log("Function requestMBWAY called with:", phoneNumber, amount); // Initial log + console.log("Function requestMBWAY called with:", phoneNumber, amount); const options = { method: 'POST', @@ -15,15 +15,15 @@ export async function requestMBWAY(phoneNumber: string, amount: number) { } }; - console.log("Options prepared:", options); // Log options + console.log("Options prepared:", options); try { const { data } = await axios.request(options); - console.log("Response data:", data); // Log response data + console.log("Response data:", data); pollPaymentStatus(data.RequestId); return; } catch (error) { - console.error("Error occurred:", error); // Log error + console.error("Error occurred:", error); } } diff --git a/components/Shop/Cart/index.tsx b/components/Shop/Cart/index.tsx index 9e552e3..5cb90de 100644 --- a/components/Shop/Cart/index.tsx +++ b/components/Shop/Cart/index.tsx @@ -12,6 +12,7 @@ import { cartProduct } from "@/types/cartProduct"; import startPaymentProcess from "./payment"; import PaymentForm from "../PaymentForm"; import PuffLoader from "react-spinners/PuffLoader"; +import { Separator } from "@/components/ui/separator" type ShopCartProps = { isOpen: boolean, @@ -32,12 +33,13 @@ const ShopCart = ({ isOpen, onOpenChange, products, removeFromCart }: ShopCartPr {products.map((p) => { return <> -
+ })} - + + {!processingPayment ? :

Waiting for confirmation

diff --git a/components/Shop/PaymentForm/index.tsx b/components/Shop/PaymentForm/index.tsx index a86c547..3cd4ec9 100644 --- a/components/Shop/PaymentForm/index.tsx +++ b/components/Shop/PaymentForm/index.tsx @@ -1,7 +1,10 @@ import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" -import startPaymentProcess from "../Cart/payment" import { cartProduct } from "@/types/cartProduct" +import React from "react" +import Image from "next/image" +import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card" +import { University } from 'lucide-react'; type PaymentFormProps = { setNumber: (phone: string) => void @@ -9,16 +12,53 @@ type PaymentFormProps = { products: cartProduct[] } +enum cardSelected { + mbway, + presential +} + const PaymentForm = ({ setNumber, products, setProcessingPayment }: PaymentFormProps) => { + + const [selectedCard, setSelectedCard] = React.useState(null) + return ( -
-
- setNumber(e.target.value)} /> - < Input type="email" placeholder="Phone Number" onChange={(e) => setNumber(e.target.value)} /> + <> +
+
+ setSelectedCard(cardSelected.mbway)}> + + {"mbway + + + setSelectedCard(cardSelected.presential)}> + +
+ +

On-site

+
+ +
+
+
+
+ { + selectedCard == cardSelected.mbway ? +
+
+ setNumber(e.target.value)} /> + setNumber(e.target.value)} /> +
+ +
: +
+ setNumber(e.target.value)} /> + +
+ } +
- < Button type="submit" className="self-end" onClick={() => setProcessingPayment(true)}> Pay -
- ) + ) + } export default PaymentForm \ No newline at end of file diff --git a/package.json b/package.json index 3bd50f0..69d1bb2 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@payloadcms/richtext-slate": "3.0.0-beta.71", "@payloadcms/ui": "3.0.0-beta.71", "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", "autoprefixer": "^10.4.19", "axios": "^1.7.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c8cbc9..daa4b4b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ importers: '@radix-ui/react-dialog': specifier: ^1.1.1 version: 1.1.1(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + '@radix-ui/react-separator': + specifier: ^1.1.0 + version: 1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) @@ -1220,6 +1223,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-separator@1.1.0': + resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + '@types/react-dom': npm:types-react-dom@19.0.0-rc.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.1.0': resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} peerDependencies: @@ -5719,6 +5735,15 @@ snapshots: '@types/react': types-react@19.0.0-rc.0 '@types/react-dom': types-react-dom@19.0.0-rc.0 + '@radix-ui/react-separator@1.1.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610))(react@19.0.0-rc-6230622a1a-20240610)(types-react-dom@19.0.0-rc.0)(types-react@19.0.0-rc.0) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + optionalDependencies: + '@types/react': types-react@19.0.0-rc.0 + '@types/react-dom': types-react-dom@19.0.0-rc.0 + '@radix-ui/react-slot@1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) diff --git a/public/images/shop/mbway.svg b/public/images/shop/mbway.svg new file mode 100644 index 0000000..2f1e11e --- /dev/null +++ b/public/images/shop/mbway.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +