From 40926b71064d7c57ed578d4cbe70ee8b64c89f92 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 12 Jul 2023 15:41:58 +0100 Subject: [PATCH] Added layout of toolbar n portfolio page --- components.json | 16 ++ package-lock.json | 256 ++++++------------ package.json | 9 +- src/app/components/portfolio/AddNew.tsx | 99 +++++-- src/app/components/portfolio/Toolbar.tsx | 49 ++++ src/app/portfolio/[slug]/page.tsx | 1 - .../shadcn_components/ui/navigation-menu.tsx | 128 +++++++++ src/lib/utils.ts | 2 +- 8 files changed, 357 insertions(+), 203 deletions(-) create mode 100644 components.json create mode 100644 src/app/components/portfolio/Toolbar.tsx create mode 100644 src/app/shadcn_components/ui/navigation-menu.tsx diff --git a/components.json b/components.json new file mode 100644 index 00000000..56e0650c --- /dev/null +++ b/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true + }, + "aliases": { + "components": "src/app/shadcn_components", + "utils": "@/lib/utils" + } +} diff --git a/package-lock.json b/package-lock.json index 9d68206b..0aa1b119 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,15 +12,14 @@ "@heroicons/react": "^2.0.18", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-hover-card": "^1.0.6", - "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-navigation-menu": "^1.1.3", "@radix-ui/react-slot": "^1.0.2", - "@radix-ui/react-toolbar": "^1.0.4", "@tanstack/react-query": "^4.29.12", "@types/node": "20.2.3", "@types/react": "18.2.7", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", - "class-variance-authority": "^0.6.0", + "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", "drizzle-orm": "^0.27.1", "eslint": "8.41.0", @@ -33,9 +32,9 @@ "postcss": "8.4.23", "react": "18.2.0", "react-dom": "18.2.0", - "tailwind-merge": "^1.13.0", + "tailwind-merge": "^1.13.2", "tailwindcss": "3.3.2", - "tailwindcss-animate": "^1.0.5", + "tailwindcss-animate": "^1.0.6", "typescript": "5.0.4" }, "devDependencies": { @@ -1692,14 +1691,6 @@ } } }, - "node_modules/@radix-ui/react-icons": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", - "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", - "peerDependencies": { - "react": "^16.x || ^17.x || ^18.x" - } - }, "node_modules/@radix-ui/react-id": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", @@ -1718,6 +1709,42 @@ } } }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.3.tgz", + "integrity": "sha512-x4Uv0N47ABx3/frJazYXxvMpZeKJe0qmRIgQ2o3lhTqnTVg+CaZfVVO4nQLn3QJcDkTz8icElKffhFng47XIBA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", @@ -1820,60 +1847,6 @@ } } }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", - "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", - "integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", @@ -1892,89 +1865,6 @@ } } }, - "node_modules/@radix-ui/react-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz", - "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz", - "integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-toggle": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toolbar": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.0.4.tgz", - "integrity": "sha512-tBgmM/O7a07xbaEkYJWYTXkIdU/1pW4/KZORR43toC/4XWyBCURK0ei9kMUdp+gTPPKBgYLxXmRSH1EVcIDp8Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-separator": "1.0.3", - "@radix-ui/react-toggle-group": "1.0.4" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", @@ -2045,6 +1935,23 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", + "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", @@ -2081,6 +1988,29 @@ } } }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", + "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/rect": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", @@ -3226,22 +3156,14 @@ } }, "node_modules/class-variance-authority": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.6.0.tgz", - "integrity": "sha512-qdRDgfjx3GRb9fpwpSvn+YaidnT7IUJNe4wt5/SWwM+PmUwJUhQRk/8zAyNro0PmVfmen2635UboTjIBXXxy5A==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.6.1.tgz", + "integrity": "sha512-eurOEGc7YVx3majOrOb099PNKgO3KnKSApOprXI4BTq6bcfbqbQXPN2u+rPPmIJ2di23bMwhk0SxCCthBmszEQ==", "dependencies": { "clsx": "1.2.1" }, "funding": { "url": "https://joebell.co.uk" - }, - "peerDependencies": { - "typescript": ">= 4.5.5 < 6" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, "node_modules/clean-stack": { @@ -8502,9 +8424,9 @@ } }, "node_modules/tailwind-merge": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.13.0.tgz", - "integrity": "sha512-mUTmDbcU+IhOvJ0c42eLQ/nRkvolTqfpVaVQRSxfJAv9TabS6Y2zW/1wKpKLdKzyL3Gh8j6NTLl6MWNmvOM6kA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.13.2.tgz", + "integrity": "sha512-R2/nULkdg1VR/EL4RXg4dEohdoxNUJGLMnWIQnPKL+O9Twu7Cn3Rxi4dlXkDzZrEGtR+G+psSXFouWlpTyLhCQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" @@ -8548,9 +8470,9 @@ } }, "node_modules/tailwindcss-animate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.5.tgz", - "integrity": "sha512-UU3qrOJ4lFQABY+MVADmBm+0KW3xZyhMdRvejwtXqYOL7YjHYxmuREFAZdmVG5LPe5E9CAst846SLC4j5I3dcw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.6.tgz", + "integrity": "sha512-4WigSGMvbl3gCCact62ZvOngA+PRqhAn7si3TQ3/ZuPuQZcIEtVap+ENSXbzWhpojKB8CpvnIsrwBu8/RnHtuw==", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } diff --git a/package.json b/package.json index ca4cc47e..25f23493 100644 --- a/package.json +++ b/package.json @@ -18,15 +18,14 @@ "@heroicons/react": "^2.0.18", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-hover-card": "^1.0.6", - "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-navigation-menu": "^1.1.3", "@radix-ui/react-slot": "^1.0.2", - "@radix-ui/react-toolbar": "^1.0.4", "@tanstack/react-query": "^4.29.12", "@types/node": "20.2.3", "@types/react": "18.2.7", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", - "class-variance-authority": "^0.6.0", + "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", "drizzle-orm": "^0.27.1", "eslint": "8.41.0", @@ -39,9 +38,9 @@ "postcss": "8.4.23", "react": "18.2.0", "react-dom": "18.2.0", - "tailwind-merge": "^1.13.0", + "tailwind-merge": "^1.13.2", "tailwindcss": "3.3.2", - "tailwindcss-animate": "^1.0.5", + "tailwindcss-animate": "^1.0.6", "typescript": "5.0.4" }, "devDependencies": { diff --git a/src/app/components/portfolio/AddNew.tsx b/src/app/components/portfolio/AddNew.tsx index f2f88a42..eb72c8e8 100644 --- a/src/app/components/portfolio/AddNew.tsx +++ b/src/app/components/portfolio/AddNew.tsx @@ -1,35 +1,76 @@ "use client"; - -import { Menu } from "@headlessui/react"; -import Link from "next/link"; +import { + NavigationMenu, + NavigationMenuContent, + NavigationMenuItem, + NavigationMenuLink, + NavigationMenuList, + NavigationMenuTrigger, + navigationMenuTriggerStyle, +} from "@/app/shadcn_components/ui/navigation-menu"; import { PlusIcon, TableCellsIcon } from "@heroicons/react/24/outline"; +import * as React from "react"; -export default function AddNew({ portfolioId }: { portfolioId: number }) { +import { cn } from "@/lib/utils"; + +const ListItem = React.forwardRef< + React.ElementRef<"a">, + React.ComponentPropsWithoutRef<"a"> +>(({ className, title, children, ...props }, ref) => { return ( - - -
Add New
-
- - - - - Add Unit - - - - - - -
+
  • + + +
    {title}
    +

    + {children} +

    +
    +
    +
  • + ); +}); +ListItem.displayName = "ListItem"; + +export default function AddNewDropDown({ + portfolioId, +}: { + portfolioId: number; +}) { + function handleCickAddUnit() { + console.log("Add unit"); + } + + function handleClickUploadCSV() { + console.log("Uplaod csv"); + } + + return ( + + Add New + +
      + +
      + Add Unit +
      +
      + + +
      + Upload CSV +
      + Upload a csv of multiple units +
      +
    +
    +
    ); } diff --git a/src/app/components/portfolio/Toolbar.tsx b/src/app/components/portfolio/Toolbar.tsx new file mode 100644 index 00000000..ed0dbd22 --- /dev/null +++ b/src/app/components/portfolio/Toolbar.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { Cog6ToothIcon } from "@heroicons/react/24/outline"; +import { + NavigationMenu, + NavigationMenuItem, + NavigationMenuList, + navigationMenuTriggerStyle, +} from "@/app/shadcn_components/ui/navigation-menu"; +import AddNewDropDown from "./AddNew"; + +function PortfolioSettings({ portfolioId }: { portfolioId: number }) { + const onClick = () => { + console.log("Go to settings"); + }; + return ( + + ); +} + +interface ToolbarProps { + portfolioId: number; +} + +export function Toolbar({ portfolioId }: ToolbarProps) { + function handleClickSettings() { + console.log("Settings were clicked, implement me"); + } + return ( + + + + Settings + + + + + ); +} diff --git a/src/app/portfolio/[slug]/page.tsx b/src/app/portfolio/[slug]/page.tsx index a010a245..97faa0ac 100644 --- a/src/app/portfolio/[slug]/page.tsx +++ b/src/app/portfolio/[slug]/page.tsx @@ -1,5 +1,4 @@ import { PencilSquareIcon, HomeIcon } from "@heroicons/react/24/outline"; -import AddNew from "../../components/portfolio/AddNew"; import { formatNumber } from "@/app/utils"; import Link from "next/link"; import { ArrowRightCircleIcon } from "@heroicons/react/20/solid"; diff --git a/src/app/shadcn_components/ui/navigation-menu.tsx b/src/app/shadcn_components/ui/navigation-menu.tsx new file mode 100644 index 00000000..1419f566 --- /dev/null +++ b/src/app/shadcn_components/ui/navigation-menu.tsx @@ -0,0 +1,128 @@ +import * as React from "react" +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" +import { cva } from "class-variance-authority" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const NavigationMenu = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children} + + +)) +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName + +const NavigationMenuList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName + +const NavigationMenuItem = NavigationMenuPrimitive.Item + +const navigationMenuTriggerStyle = cva( + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50" +) + +const NavigationMenuTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children}{" "} + +)) +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName + +const NavigationMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName + +const NavigationMenuLink = NavigationMenuPrimitive.Link + +const NavigationMenuViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
    + +
    +)) +NavigationMenuViewport.displayName = + NavigationMenuPrimitive.Viewport.displayName + +const NavigationMenuIndicator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +
    + +)) +NavigationMenuIndicator.displayName = + NavigationMenuPrimitive.Indicator.displayName + +export { + navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 23af5b26..ec79801f 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,4 +1,4 @@ -import { ClassValue, clsx } from "clsx" +import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) {