From b646fc4887c050b60d2ea75c8424f44f9bfa931e Mon Sep 17 00:00:00 2001 From: Tania Gutierrez Date: Thu, 21 Mar 2024 01:17:00 -0400 Subject: [PATCH] feat: Created Pinning banner to show inprogress and completed PinningProcess --- app/components/general-layout.tsx | 218 +++++++++++---------- app/components/pinnning-network-banner.tsx | 107 ++++++++++ app/components/ui/accordion.tsx | 58 ++++++ app/components/ui/tabs.tsx | 53 +++++ app/routes/file-manager/columns.tsx | 183 +++++++++-------- package.json | 2 + 6 files changed, 431 insertions(+), 190 deletions(-) create mode 100644 app/components/pinnning-network-banner.tsx create mode 100644 app/components/ui/accordion.tsx create mode 100644 app/components/ui/tabs.tsx diff --git a/app/components/general-layout.tsx b/app/components/general-layout.tsx index 01025de..4aceb5f 100644 --- a/app/components/general-layout.tsx +++ b/app/components/general-layout.tsx @@ -30,123 +30,129 @@ import { Avatar } from "@radix-ui/react-avatar"; import { cn } from "~/utils"; import { useGetIdentity, useLogout } from "@refinedev/core"; import { Identity } from "~/data/auth-provider"; +import { PinningNetworkBanner } from "./pinnning-network-banner"; +import { PinningProvider } from "~/providers/PinningProvider"; export const GeneralLayout = ({ children }: React.PropsWithChildren<{}>) => { const location = useLocation(); const { data: identity } = useGetIdentity(); const{ mutate: logout } = useLogout() + return ( -
-
- Lume logo + +
+
+ Lume logo - - -

Freedom

-

Privacy

-

Ownership

-
- - - - - - - - -
- -
-
- - - - - - - - - logout()}> - - Logout - - - - + + + + + +
+ +
+
+ + + + + + + + + logout()}> + + Logout + + + + +
+ + {children} + +
+
    +
  • + + + +
  • +
  • + + + +
  • +
+
- - {children} - -
-
    -
  • - - - -
  • -
  • - - - -
  • -
-
- + + ); }; diff --git a/app/components/pinnning-network-banner.tsx b/app/components/pinnning-network-banner.tsx new file mode 100644 index 0000000..d521914 --- /dev/null +++ b/app/components/pinnning-network-banner.tsx @@ -0,0 +1,107 @@ +import { useEffect, useMemo } from "react"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "./ui/accordion"; +import { Progress } from "./ui/progress"; +import { usePinning } from "~/hooks/usePinnning"; +import { IPinningData } from "~/providers/PinningProvider"; +import { Tabs, TabsTrigger, TabsList, TabsContent } from "./ui/tabs"; +import { Button } from "./ui/button"; +import { Cross2Icon } from "@radix-ui/react-icons"; + +export const PinningNetworkBanner = () => { + const { cidList } = usePinning(); + + const itemsLeft = useMemo( + () => cidList.filter((item) => item.progress < 100), + [cidList], + ); + + const completedItems = useMemo( + () => cidList.filter((item) => item.progress === 100), + [cidList], + ); + + return ( +
+ + + + {itemsLeft.length > 0 ? `${itemsLeft.length} left` : "Completed"} + + + + + In Progress + Completed + + + {itemsLeft.length ? ( + itemsLeft.map((cid) => ( + + )) + ) : ( +
+ Nothing yet. +
+ )} +
+ + {completedItems.length ? ( + completedItems.map((cid) => ( + + )) + ) : ( +
+ Nothing yet. +
+ )} +
+
+
+
+
+
+ ); +}; + +const PinCidItem = ({ item }: { item: IPinningData }) => { + const { getProgress, onRemoveCidFromList } = usePinning(); + + useEffect(() => { + if (item.progress < 100) { + const intervalId = setInterval(() => { + getProgress(item.cid); + }, 1000); // Adjust the interval time (1000ms = 1 second) as needed + + return () => clearInterval(intervalId); // Clear interval on component unmount + } + }, [getProgress, item]); // Add dependencies to ensure the effect runs correctly + + return ( +
+
+ {item.cid} + {item.progress}% +
+ +
+
+ +
+ ); +}; diff --git a/app/components/ui/accordion.tsx b/app/components/ui/accordion.tsx new file mode 100644 index 0000000..a6fc9f4 --- /dev/null +++ b/app/components/ui/accordion.tsx @@ -0,0 +1,58 @@ +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDownIcon } from "@radix-ui/react-icons"; + +import { cn } from "~/utils"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className, + )} + {...props}> + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { + Accordion, + AccordionItem, + AccordionTrigger, + AccordionContent, +}; diff --git a/app/components/ui/tabs.tsx b/app/components/ui/tabs.tsx new file mode 100644 index 0000000..9167d14 --- /dev/null +++ b/app/components/ui/tabs.tsx @@ -0,0 +1,53 @@ +import * as React from "react"; +import * as TabsPrimitive from "@radix-ui/react-tabs"; + +import { cn } from "~/utils"; + +const Tabs = TabsPrimitive.Root; + +const TabsList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsList.displayName = TabsPrimitive.List.displayName; + +const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; + +const TabsContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsContent.displayName = TabsPrimitive.Content.displayName; + +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/app/routes/file-manager/columns.tsx b/app/routes/file-manager/columns.tsx index b4a1f2b..67ec095 100644 --- a/app/routes/file-manager/columns.tsx +++ b/app/routes/file-manager/columns.tsx @@ -1,96 +1,111 @@ import { DrawingPinIcon, TrashIcon } from "@radix-ui/react-icons"; -import type { ColumnDef, RowData } from "@tanstack/react-table"; +import type { ColumnDef, Row } from "@tanstack/react-table"; import { FileIcon, MoreIcon } from "~/components/icons"; import { Checkbox } from "~/components/ui/checkbox"; -import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "~/components/ui/dropdown-menu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "~/components/ui/dropdown-menu"; + +import { usePinning } from "~/hooks/usePinnning"; import { cn } from "~/utils"; // This type is used to define the shape of our data. // You can use a Zod schema here if you want. export type File = { - name: string; - cid: string; - size: string; - createdOn: string; + name: string; + cid: string; + size: string; + createdOn: string; }; -declare module '@tanstack/table-core' { - interface TableMeta { - hoveredRowId: string, - } -} +const CreatedOnCell = ({ row }: { row: Row }) => { + // const { open } = useNotification(); + const { onPin } = usePinning(); + + return ( +
+ {row.getValue("createdOn")} + + + + + + + { + console.log(`Adding ${row.getValue("cid")} for pinning...`); + onPin(row.getValue("cid")); + }}> + + Ping CID + + + + + Delete + + + + +
+ ); +}; export const columns: ColumnDef[] = [ - { - id: "select", - size: 20, - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, - { - accessorKey: "name", - header: "Name", - cell: ({ row }) => ( -
- - {row.getValue("name")} -
- ) - }, - { - accessorKey: "cid", - header: "CID", - }, - { - accessorKey: "size", - header: "Size", - }, - { - accessorKey: "createdOn", - size: 200, - header: "Created On", - cell: ({ row }) => ( -
- {row.getValue("createdOn")} - - - - - - - - - Ping CID - - - - - Delete - - - - -
- ) - } -]; \ No newline at end of file + { + id: "select", + size: 20, + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "name", + header: "Name", + cell: ({ row }) => ( +
+ + {row.getValue("name")} +
+ ), + }, + { + accessorKey: "cid", + header: "CID", + }, + { + accessorKey: "size", + header: "Size", + }, + { + accessorKey: "createdOn", + size: 200, + header: "Created On", + cell: ({ row }) => , + }, +]; diff --git a/package.json b/package.json index 0a92fb1..c5bc542 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@conform-to/zod": "^1.0.2", "@fontsource-variable/manrope": "^5.0.19", "@lumeweb/portal-sdk": "0.0.0-20240319140708", + "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", @@ -26,6 +27,7 @@ "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.5", "@refinedev/cli": "^2.16.1", "@refinedev/core": "https://gitpkg.now.sh/LumeWeb/refine/packages/core?remix",