From 4c94ca203befd5ab6496d2009ace7f31d7fce178 Mon Sep 17 00:00:00 2001 From: Eman Date: Sat, 6 Apr 2024 11:28:47 +0200 Subject: [PATCH 01/50] chore: draft PR --- packages/features/Inventory/AddProduct.tsx | 0 packages/features/Inventory/EditProduct.tsx | 0 packages/features/Inventory/ProductsTable.tsx | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/features/Inventory/AddProduct.tsx create mode 100644 packages/features/Inventory/EditProduct.tsx create mode 100644 packages/features/Inventory/ProductsTable.tsx diff --git a/packages/features/Inventory/AddProduct.tsx b/packages/features/Inventory/AddProduct.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/features/Inventory/EditProduct.tsx b/packages/features/Inventory/EditProduct.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/features/Inventory/ProductsTable.tsx b/packages/features/Inventory/ProductsTable.tsx new file mode 100644 index 00000000..e69de29b From 9a3b045d38fad4fcd4ef986c7b62f2ab00002b7b Mon Sep 17 00:00:00 2001 From: Eman Date: Sat, 6 Apr 2024 15:53:07 +0200 Subject: [PATCH 02/50] feat: refactor table and dropdown components --- apps/agent/src/Dashboard/AgentToolBar.tsx | 20 ++++- apps/client/src/Layout/layout.tsx | 10 ++- apps/client/src/pages/inventory/index.tsx | 10 +++ packages/ui/components/Dropdown.tsx | 39 +++++--- packages/ui/components/Navbar.tsx | 1 - packages/ui/components/{ => Table}/Table.tsx | 94 +++++++------------- packages/ui/components/Table/TableFooter.tsx | 13 +++ packages/ui/components/Table/TableHead.tsx | 11 +++ packages/ui/components/Table/TableRow.tsx | 72 +++++++++++++++ packages/ui/index.tsx | 3 +- 10 files changed, 194 insertions(+), 79 deletions(-) create mode 100644 apps/client/src/pages/inventory/index.tsx rename packages/ui/components/{ => Table}/Table.tsx (51%) create mode 100644 packages/ui/components/Table/TableFooter.tsx create mode 100644 packages/ui/components/Table/TableHead.tsx create mode 100644 packages/ui/components/Table/TableRow.tsx diff --git a/apps/agent/src/Dashboard/AgentToolBar.tsx b/apps/agent/src/Dashboard/AgentToolBar.tsx index f109c21a..52fb3004 100644 --- a/apps/agent/src/Dashboard/AgentToolBar.tsx +++ b/apps/agent/src/Dashboard/AgentToolBar.tsx @@ -7,7 +7,25 @@ import { HiOutlineBriefcase, } from "react-icons/hi2"; import Link from "next/link"; -import { Avatar, Card } from "ui"; +import { Avatar, Card, Dropdown } from "ui"; + +const dropdownOptions = [ + { + id: "business", + label: "Business", + icon: HiOutlineBriefcase, + }, + { + id: "courier", + label: "Courier", + icon: HiOutlineTruck, + }, + { + id: "supplier", + label: "Supplier", + icon: HiOutlineBuildingOffice, + }, +]; export const AgentToolBar = () => { return ( diff --git a/apps/client/src/Layout/layout.tsx b/apps/client/src/Layout/layout.tsx index 9ca16a35..2106c061 100644 --- a/apps/client/src/Layout/layout.tsx +++ b/apps/client/src/Layout/layout.tsx @@ -7,17 +7,18 @@ type LayoutProps = { children: ReactChild | ReactChild[]; }; import { - HiOutlineBriefcase, + HiOutlineShoppingCart, HiOutlineUserCircle, HiOutlineTruck, HiOutlineBuildingOffice, + HiOutlineCube } from "react-icons/hi2"; const links = [ { name: "Products", href: "/products", - icon: HiOutlineBriefcase, + icon: HiOutlineShoppingCart, }, { name: "Orders", @@ -29,6 +30,11 @@ const links = [ href: "/account", icon: HiOutlineUserCircle, }, + { + name: "Inventory", + href: "/inventory", + icon: HiOutlineCube, + } ]; export default function Layout({ children, ...props }: LayoutProps) { diff --git a/apps/client/src/pages/inventory/index.tsx b/apps/client/src/pages/inventory/index.tsx new file mode 100644 index 00000000..e52ec21d --- /dev/null +++ b/apps/client/src/pages/inventory/index.tsx @@ -0,0 +1,10 @@ +import { Card, Table } from "ui" + +export default function InventoryPage() { + return ( +
+

Inventory

+ + + ) +} \ No newline at end of file diff --git a/packages/ui/components/Dropdown.tsx b/packages/ui/components/Dropdown.tsx index d8f4a08e..f964e533 100644 --- a/packages/ui/components/Dropdown.tsx +++ b/packages/ui/components/Dropdown.tsx @@ -1,19 +1,38 @@ +import { FC } from "react"; import { HiArrowDown } from "react-icons/hi2"; -export const Dropdown = ({ helper }) => { +import { Icon } from "./Icon"; +import type { IconType } from "react-icons"; + +import { + HiOutlineArrowSmallDown, +} from "react-icons/hi2"; + +type DropdownOption = { + id?: string; + label?: string; + icon?: IconType; + handler?: () => void; +}; + +export type DropdownProps = { + CTA?: string; + options?: DropdownOption[]; +}; + +export const Dropdown: FC = ({ options, CTA }) => { return (
-
); }; diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index 06ffe703..2df5a209 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -30,7 +30,6 @@ export const Navbar: FC = ({ onSignOut, user = {}, }) => { - console.log(user?.image); return (
diff --git a/packages/ui/components/Table.tsx b/packages/ui/components/Table/Table.tsx similarity index 51% rename from packages/ui/components/Table.tsx rename to packages/ui/components/Table/Table.tsx index 39a81b6d..137cf606 100644 --- a/packages/ui/components/Table.tsx +++ b/packages/ui/components/Table/Table.tsx @@ -1,4 +1,7 @@ import { HiOutlineClock, HiOutlineArrowLongDown } from "react-icons/hi2"; +import { TableFooter } from "./TableFooter"; +import { TableRow } from "./TableRow"; +import { TableHead } from "./TableHead"; const orders = [ { @@ -46,52 +49,6 @@ export const TableControls = () => { ); }; -export type TableRowProps = { - row: Record; -} - -export const TableRow = ({ row }: TableRowProps) => { - return ( -
- - - - - - ); -}; - -export const TableHead = () => { - return ( - - - - - - - - - ); -}; export const TablePagination = () => { return ( @@ -104,32 +61,41 @@ export const TablePagination = () => { ); }; -export const TableFooter = () => { - return ( - - - - - - - - - - ); -}; + export const Table = () => { return (
-
-
-
{row.name}
-
{row.address}
-
-
-
{row.source}{row.createdAt} - -
- Name - - Source - - Date - - Status -
NameJobFavorite Color
- + {/* head */} + + + + + + + + + - {orders.map((order) => ( - - ))} + {/* row 1 */} + {orders.map(order => )} + {/* foot */} + + + + + + + + +
+ + NameJobFavorite Color
NameJobFavorite Color
-
); }; diff --git a/packages/ui/components/Table/TableFooter.tsx b/packages/ui/components/Table/TableFooter.tsx new file mode 100644 index 00000000..af58fb95 --- /dev/null +++ b/packages/ui/components/Table/TableFooter.tsx @@ -0,0 +1,13 @@ +export const TableFooter = () => { + return ( + + + + Name + Job + Favorite Color + Hello + + + ); + }; \ No newline at end of file diff --git a/packages/ui/components/Table/TableHead.tsx b/packages/ui/components/Table/TableHead.tsx new file mode 100644 index 00000000..b969e010 --- /dev/null +++ b/packages/ui/components/Table/TableHead.tsx @@ -0,0 +1,11 @@ +export const TableHead = () => { + return ( + + + Name + Source + Date + + + ); + }; \ No newline at end of file diff --git a/packages/ui/components/Table/TableRow.tsx b/packages/ui/components/Table/TableRow.tsx new file mode 100644 index 00000000..9e20697d --- /dev/null +++ b/packages/ui/components/Table/TableRow.tsx @@ -0,0 +1,72 @@ +import { FC } from "react"; +import { Dropdown } from "../Dropdown"; + +import { + HiOutlineShoppingCart, + HiOutlineUserCircle, + HiOutlineTruck, + HiOutlineBuildingOffice, + HiOutlineCube, + HiOutlineXMark +} from "react-icons/hi2"; + +export type TableRowProps = { + row: Record; +}; + +const options = [ + { + id: 1, + label: "Enroute", + icon: HiOutlineTruck, + }, + { + id: 2, + label: "Delivered", + icon: HiOutlineCube, + }, + { + id: 3, + label: "Cancelled", + icon: HiOutlineXMark, + } +]; + +export const TableRow = ({ row }: TableRowProps) => { + return ( + + + + + +
+
+
+ Avatar Tailwind CSS Component +
+
+
+
Hart Hagerty
+
United States
+
+
+ + + Zemlak, Daniel and Leannon +
+ + Desktop Support Technician + + + Purple + + + + + ); +}; diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 02cc0103..35ed3ba4 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -4,6 +4,7 @@ import * as React from "react"; export * from "./components/Avatar"; export * from "./components/Button"; export * from "./components/Card"; +export * from "./components/Dropdown"; export * from "./components/FormControl"; export * from "./components/Header"; export * from "./components/Icon"; @@ -24,7 +25,7 @@ export * from "./components/Stats"; export * from "./components/Steps"; export * from "./components/StepsPaginator"; export * from "./components/Tabs"; -export * from "./components/Table"; +export * from "./components/Table/Table"; export * from "./components/Toggle"; export * from "./components/Wrapper"; export * from "./components/CheckBox"; From 882f405e34c927da3cc6c35f515c95a7a0bf3cec Mon Sep 17 00:00:00 2001 From: Eman Date: Sat, 6 Apr 2024 17:15:14 +0200 Subject: [PATCH 03/50] feat: added split button component --- .../src/pages/inventory/[productId].tsx | 14 +++++++ apps/client/src/pages/inventory/index.tsx | 39 ++++++++++++++++--- .../features/Reports/ExportDataButton.tsx | 3 ++ packages/ui/components/Dropdown.tsx | 14 ++++--- packages/ui/components/SplitButton.tsx | 19 +++++++++ packages/ui/components/Table/Table.tsx | 2 +- packages/ui/components/Table/TableRow.tsx | 34 ++++++++-------- packages/ui/index.tsx | 1 + 8 files changed, 96 insertions(+), 30 deletions(-) create mode 100644 apps/client/src/pages/inventory/[productId].tsx create mode 100644 packages/features/Reports/ExportDataButton.tsx create mode 100644 packages/ui/components/SplitButton.tsx diff --git a/apps/client/src/pages/inventory/[productId].tsx b/apps/client/src/pages/inventory/[productId].tsx new file mode 100644 index 00000000..a03e7151 --- /dev/null +++ b/apps/client/src/pages/inventory/[productId].tsx @@ -0,0 +1,14 @@ +// import { OrderHistory } from "@sahil/features/Orders/ListOrders"; + +export default function ProductPage() { + return ( +
+
+

+ Product Page +

+
+
+ ); + } + \ No newline at end of file diff --git a/apps/client/src/pages/inventory/index.tsx b/apps/client/src/pages/inventory/index.tsx index e52ec21d..b93db236 100644 --- a/apps/client/src/pages/inventory/index.tsx +++ b/apps/client/src/pages/inventory/index.tsx @@ -1,10 +1,37 @@ -import { Card, Table } from "ui" +import { Card, Table, SplitButton } from "ui"; +import { HiOutlineArrowDown, HiOutlinePlus, HiOutlinePencil } from "react-icons/hi2"; + + export default function InventoryPage() { - return ( -
+ + const onOptionClick = () => {} + return ( +
+ +
+

Inventory

- + +
+ +
- ) -} \ No newline at end of file + +
+ + ); +} diff --git a/packages/features/Reports/ExportDataButton.tsx b/packages/features/Reports/ExportDataButton.tsx new file mode 100644 index 00000000..5c4738fb --- /dev/null +++ b/packages/features/Reports/ExportDataButton.tsx @@ -0,0 +1,3 @@ +// main action is print +// other options = print, email or store in the cloud +// use a split button \ No newline at end of file diff --git a/packages/ui/components/Dropdown.tsx b/packages/ui/components/Dropdown.tsx index f964e533..e751a103 100644 --- a/packages/ui/components/Dropdown.tsx +++ b/packages/ui/components/Dropdown.tsx @@ -3,9 +3,7 @@ import { HiArrowDown } from "react-icons/hi2"; import { Icon } from "./Icon"; import type { IconType } from "react-icons"; -import { - HiOutlineArrowSmallDown, -} from "react-icons/hi2"; +import { HiOutlineArrowSmallDown } from "react-icons/hi2"; type DropdownOption = { id?: string; @@ -29,9 +27,13 @@ export const Dropdown: FC = ({ options, CTA }) => { tabIndex={0} className="dropdown-content z-[1] menu p-2 border bg-base-100 rounded-box mt-4 space-y-2" > - {options?.map((option: DropdownOption) =>
  • - -
  • )} + {options?.map((option: DropdownOption) => ( +
  • + +
  • + ))} ); diff --git a/packages/ui/components/SplitButton.tsx b/packages/ui/components/SplitButton.tsx new file mode 100644 index 00000000..dcc6c426 --- /dev/null +++ b/packages/ui/components/SplitButton.tsx @@ -0,0 +1,19 @@ +import { IconButton } from "./IconButton"; +import { JoinGrid } from "./JoinGrid"; +import { Icon } from "./Icon"; +import { HiOutlineArrowDown } from "react-icons/hi2"; + +export const SplitButton = () => { + return ( + + + + + ); +}; diff --git a/packages/ui/components/Table/Table.tsx b/packages/ui/components/Table/Table.tsx index 137cf606..8e27d7e4 100644 --- a/packages/ui/components/Table/Table.tsx +++ b/packages/ui/components/Table/Table.tsx @@ -77,7 +77,7 @@ export const Table = () => {
    - + diff --git a/packages/ui/components/Table/TableRow.tsx b/packages/ui/components/Table/TableRow.tsx index 9e20697d..8dbd3b1f 100644 --- a/packages/ui/components/Table/TableRow.tsx +++ b/packages/ui/components/Table/TableRow.tsx @@ -1,5 +1,6 @@ import { FC } from "react"; import { Dropdown } from "../Dropdown"; +import Link from "next/link"; import { HiOutlineShoppingCart, @@ -7,7 +8,7 @@ import { HiOutlineTruck, HiOutlineBuildingOffice, HiOutlineCube, - HiOutlineXMark + HiOutlineXMark, } from "react-icons/hi2"; export type TableRowProps = { @@ -17,19 +18,19 @@ export type TableRowProps = { const options = [ { id: 1, - label: "Enroute", + label: "Available", icon: HiOutlineTruck, }, { id: 2, - label: "Delivered", + label: "Out of Stock", icon: HiOutlineCube, }, { id: 3, - label: "Cancelled", + label: "Sale", icon: HiOutlineXMark, - } + }, ]; export const TableRow = ({ row }: TableRowProps) => { @@ -50,22 +51,21 @@ export const TableRow = ({ row }: TableRowProps) => { /> -
    -
    Hart Hagerty
    -
    United States
    +
    +
    + {row.name} +
    +
    + Groceries + Groceries +
    - - + + ); diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 35ed3ba4..eed502db 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -20,6 +20,7 @@ export * from "./components/Modal"; export * from "./components/Radio"; export * from "./components/Select"; export * from "./components/SidebarWrapper"; +export * from "./components/SplitButton"; export * from "./components/Spinner"; export * from "./components/Stats"; export * from "./components/Steps"; From 4a6f272cf87e83d36c8cbc863f20b364cedaf880 Mon Sep 17 00:00:00 2001 From: Eman Date: Sun, 14 Apr 2024 09:40:09 +0200 Subject: [PATCH 04/50] feat: supplier inventory components --- apps/client/src/pages/inventory/index.tsx | 6 +++--- apps/client/src/pages/inventory/new/index.tsx | 14 ++++++++++++++ packages/ui/components/Dropdown.tsx | 2 +- packages/ui/components/JoinGrid.tsx | 2 +- packages/ui/components/ProductScanner.tsx | 7 +++++++ packages/ui/components/SplitButton.tsx | 2 +- packages/ui/components/Table/Table.tsx | 12 ++++++------ 7 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 apps/client/src/pages/inventory/new/index.tsx create mode 100644 packages/ui/components/ProductScanner.tsx diff --git a/apps/client/src/pages/inventory/index.tsx b/apps/client/src/pages/inventory/index.tsx index b93db236..50fed8dd 100644 --- a/apps/client/src/pages/inventory/index.tsx +++ b/apps/client/src/pages/inventory/index.tsx @@ -7,11 +7,11 @@ export default function InventoryPage() { const onOptionClick = () => {} return ( -
    +
    -
    +
    -

    Inventory

    +

    Inventory

    +
    +

    + Add Product Page +

    +
    + + ); + } + \ No newline at end of file diff --git a/packages/ui/components/Dropdown.tsx b/packages/ui/components/Dropdown.tsx index e751a103..4c822797 100644 --- a/packages/ui/components/Dropdown.tsx +++ b/packages/ui/components/Dropdown.tsx @@ -25,7 +25,7 @@ export const Dropdown: FC = ({ options, CTA }) => {
      {options?.map((option: DropdownOption) => (
    • diff --git a/packages/ui/components/JoinGrid.tsx b/packages/ui/components/JoinGrid.tsx index a76d1c37..a8038bdd 100644 --- a/packages/ui/components/JoinGrid.tsx +++ b/packages/ui/components/JoinGrid.tsx @@ -6,7 +6,7 @@ export type JoinGridProps = { }; export const JoinGrid: FC = ({ children, cols = 2 }) => { return ( -
      +
      {children}
      ); diff --git a/packages/ui/components/ProductScanner.tsx b/packages/ui/components/ProductScanner.tsx new file mode 100644 index 00000000..67b0eeb4 --- /dev/null +++ b/packages/ui/components/ProductScanner.tsx @@ -0,0 +1,7 @@ +export const ProductScanner = () => { + return ( +
      +

      Hello, Scanner

      +
      + ) +} \ No newline at end of file diff --git a/packages/ui/components/SplitButton.tsx b/packages/ui/components/SplitButton.tsx index dcc6c426..dd256e63 100644 --- a/packages/ui/components/SplitButton.tsx +++ b/packages/ui/components/SplitButton.tsx @@ -6,7 +6,7 @@ import { HiOutlineArrowDown } from "react-icons/hi2"; export const SplitButton = () => { return ( - +
    Name JobFavorite ColorQuantity
    - Zemlak, Daniel and Leannon -
    - - Desktop Support Technician - -
    Purple15,000 SSP15 available - +
    +
    +
    {/* head */} - + - - + + From e7169d6581e5be5987d88ab7453b8f2ea03bbc3f Mon Sep 17 00:00:00 2001 From: Eman Date: Sun, 11 Aug 2024 22:29:22 +0200 Subject: [PATCH 05/50] feat: view orders in admin --- apps/admin/src/pages/orders/index.tsx | 38 +++++++++++++++---- apps/admin/src/pages/zones/index.tsx | 22 +++++++++-- packages/features/Zones/ListZones.tsx | 40 ++++++++++++++++++++ packages/features/Zones/ZoneOverviewCard.tsx | 3 ++ 4 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 packages/features/Zones/ListZones.tsx create mode 100644 packages/features/Zones/ZoneOverviewCard.tsx diff --git a/apps/admin/src/pages/orders/index.tsx b/apps/admin/src/pages/orders/index.tsx index b01fdb8c..331a7714 100644 --- a/apps/admin/src/pages/orders/index.tsx +++ b/apps/admin/src/pages/orders/index.tsx @@ -1,10 +1,32 @@ +import { useRouter } from "next/router"; +import { HiPlus, HiOutlineDocumentMagnifyingGlass } from "react-icons/hi2"; +import { ListOrders } from "@sahil/features/Orders/ListOrders"; +import { Card, Stats, Stat } from "ui"; + export default function Orders() { - return ( -
    -
    -

    Orders Page

    + const router = useRouter(); + return ( +
    + +
    +
    +

    Orders

    +
    +
    + + +
    -
    - ); - } - \ No newline at end of file + + +
    + ); +} diff --git a/apps/admin/src/pages/zones/index.tsx b/apps/admin/src/pages/zones/index.tsx index 11537551..5b23ce77 100644 --- a/apps/admin/src/pages/zones/index.tsx +++ b/apps/admin/src/pages/zones/index.tsx @@ -1,9 +1,25 @@ +import { useRouter } from "next/router"; +import { HiPlus, HiOutlineDocumentMagnifyingGlass } from "react-icons/hi2"; +import { ListZones } from "@sahil/features/Zones/ListZones"; + export default function Zones() { + const router = useRouter(); return ( -
    -
    -

    Zones Page

    +
    +
    +
    +

    Zones

    +
    +
    + +
    +
    ); } diff --git a/packages/features/Zones/ListZones.tsx b/packages/features/Zones/ListZones.tsx new file mode 100644 index 00000000..04c72244 --- /dev/null +++ b/packages/features/Zones/ListZones.tsx @@ -0,0 +1,40 @@ +import { List, ListHeader, ListErrorState, ListPagination } from "ui"; +import { ZoneOverviewCard } from "./ZoneOverviewCard"; + + +const zones = [ + { + id: 1, + name: "Zone 1", + description: "Zone 1 description", + }, + { + id: 2, + name: "Zone 2", + description: "Zone 2 description", + }, + { + id: 3, + name: "Zone 3", + description: "Zone 3 description", + }, +]; + +export const ListZones = () => { + return ( +
    + + <> + + ( + // @ts-ignore + + )} + /> +
    + ); +}; \ No newline at end of file diff --git a/packages/features/Zones/ZoneOverviewCard.tsx b/packages/features/Zones/ZoneOverviewCard.tsx new file mode 100644 index 00000000..5f1eac19 --- /dev/null +++ b/packages/features/Zones/ZoneOverviewCard.tsx @@ -0,0 +1,3 @@ +export const ZoneOverviewCard = () => { + return
    ZoneOverviewCard
    ; +}; \ No newline at end of file From ce87366996f97a19871dd1e094b8384e433339b5 Mon Sep 17 00:00:00 2001 From: Eman Date: Sun, 11 Aug 2024 23:02:40 +0200 Subject: [PATCH 06/50] feat: add more admin pages --- apps/admin/src/pages/agents/[agentId].tsx | 3 ++ apps/admin/src/pages/agents/index.tsx | 29 +++++++++--- apps/admin/src/pages/clients/[clientId].tsx | 3 ++ apps/admin/src/pages/clients/index.tsx | 22 +++++---- apps/admin/src/pages/orders/[orderId].tsx | 3 ++ apps/admin/src/pages/zones/[zoneId].tsx | 3 ++ apps/admin/src/pages/zones/new.tsx | 3 ++ .../features/Agents/AgentOverviewCard.tsx | 3 ++ packages/features/Agents/ListAgents.tsx | 36 +++++++++++++++ .../features/Clients/ClientOverviewCard.tsx | 24 ++++++++++ packages/features/Clients/ListClients.tsx | 46 +++++++++++++++++++ 11 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 apps/admin/src/pages/agents/[agentId].tsx create mode 100644 apps/admin/src/pages/clients/[clientId].tsx create mode 100644 apps/admin/src/pages/orders/[orderId].tsx create mode 100644 apps/admin/src/pages/zones/[zoneId].tsx create mode 100644 apps/admin/src/pages/zones/new.tsx create mode 100644 packages/features/Agents/AgentOverviewCard.tsx create mode 100644 packages/features/Agents/ListAgents.tsx create mode 100644 packages/features/Clients/ClientOverviewCard.tsx create mode 100644 packages/features/Clients/ListClients.tsx diff --git a/apps/admin/src/pages/agents/[agentId].tsx b/apps/admin/src/pages/agents/[agentId].tsx new file mode 100644 index 00000000..765e9edc --- /dev/null +++ b/apps/admin/src/pages/agents/[agentId].tsx @@ -0,0 +1,3 @@ +export default function AgentPage() { + return
    Agent
    ; +} \ No newline at end of file diff --git a/apps/admin/src/pages/agents/index.tsx b/apps/admin/src/pages/agents/index.tsx index d052951a..e1210a3a 100644 --- a/apps/admin/src/pages/agents/index.tsx +++ b/apps/admin/src/pages/agents/index.tsx @@ -1,10 +1,25 @@ +import { useRouter } from "next/router"; +import { HiPlus, HiOutlineDocumentMagnifyingGlass } from "react-icons/hi2"; +import { ListAgents } from "@sahil/features/Agents/ListAgents"; + export default function Agents() { - return ( -
    + const router = useRouter(); + return ( +
    +
    -

    Agents Page

    +

    Agent

    -
    - ); - } - \ No newline at end of file +
    + +
    +
    + +
    + ); +} diff --git a/apps/admin/src/pages/clients/[clientId].tsx b/apps/admin/src/pages/clients/[clientId].tsx new file mode 100644 index 00000000..11a4c31b --- /dev/null +++ b/apps/admin/src/pages/clients/[clientId].tsx @@ -0,0 +1,3 @@ +export default function ClientPage() { + return
    Client
    ; +} \ No newline at end of file diff --git a/apps/admin/src/pages/clients/index.tsx b/apps/admin/src/pages/clients/index.tsx index 9c12d59b..99fe1e82 100644 --- a/apps/admin/src/pages/clients/index.tsx +++ b/apps/admin/src/pages/clients/index.tsx @@ -1,10 +1,12 @@ -export default function Clients() { - return ( -
    -
    -

    Clients Page

    -
    -
    - ); - } - \ No newline at end of file +import { useRouter } from "next/router"; +import { HiPlus, HiOutlineDocumentMagnifyingGlass } from "react-icons/hi2"; +import { ListClients } from "@sahil/features/Clients/ListClients"; + +export default function Zones() { + const router = useRouter(); + return ( +
    + +
    + ); +} diff --git a/apps/admin/src/pages/orders/[orderId].tsx b/apps/admin/src/pages/orders/[orderId].tsx new file mode 100644 index 00000000..d4745d3b --- /dev/null +++ b/apps/admin/src/pages/orders/[orderId].tsx @@ -0,0 +1,3 @@ +export default function OrderPage() { + return
    Order
    ; +} \ No newline at end of file diff --git a/apps/admin/src/pages/zones/[zoneId].tsx b/apps/admin/src/pages/zones/[zoneId].tsx new file mode 100644 index 00000000..7e114996 --- /dev/null +++ b/apps/admin/src/pages/zones/[zoneId].tsx @@ -0,0 +1,3 @@ +export default function ZonePage() { + return
    Zone
    ; +} \ No newline at end of file diff --git a/apps/admin/src/pages/zones/new.tsx b/apps/admin/src/pages/zones/new.tsx new file mode 100644 index 00000000..2fa07df6 --- /dev/null +++ b/apps/admin/src/pages/zones/new.tsx @@ -0,0 +1,3 @@ +export default function NewZonePage() { + return
    New Zone Page
    ; +} \ No newline at end of file diff --git a/packages/features/Agents/AgentOverviewCard.tsx b/packages/features/Agents/AgentOverviewCard.tsx new file mode 100644 index 00000000..77eb9046 --- /dev/null +++ b/packages/features/Agents/AgentOverviewCard.tsx @@ -0,0 +1,3 @@ +export const AgentOverviewCard = () => { + return
    AgentOverviewCard
    ; +}; \ No newline at end of file diff --git a/packages/features/Agents/ListAgents.tsx b/packages/features/Agents/ListAgents.tsx new file mode 100644 index 00000000..d3a18afe --- /dev/null +++ b/packages/features/Agents/ListAgents.tsx @@ -0,0 +1,36 @@ +import { AgentOverviewCard } from "./AgentOverviewCard"; +import { List, ListHeader, ListErrorState, ListPagination } from "ui"; + +const agents = [ + { + id: "1", + name: "Agent 1", + description: "Agent 1 Description", + status: "Active", + }, + { + id: "2", + name: "Agent 2", + description: "Agent 2 Description", + status: "Inactive", + }, +]; + +export const ListAgents = () => { + return ( +
    + + <> + + ( + // @ts-ignore + + )} + /> +
    + ); +}; \ No newline at end of file diff --git a/packages/features/Clients/ClientOverviewCard.tsx b/packages/features/Clients/ClientOverviewCard.tsx new file mode 100644 index 00000000..1a15b99d --- /dev/null +++ b/packages/features/Clients/ClientOverviewCard.tsx @@ -0,0 +1,24 @@ +export const ClientOverviewCard = ({ client }: { client: any }) => { + return ( +
    +
    +
    +
    +
    + {client.name} +
    +
    {client.email}
    +
    +
    +
    + {client.phone} +
    +
    + {client.address.city}, {client.address.state} +
    +
    +
    +
    +
    + ); +}; \ No newline at end of file diff --git a/packages/features/Clients/ListClients.tsx b/packages/features/Clients/ListClients.tsx new file mode 100644 index 00000000..d3e606f7 --- /dev/null +++ b/packages/features/Clients/ListClients.tsx @@ -0,0 +1,46 @@ +import { ClientOverviewCard } from "./ClientOverviewCard"; +import { List, ListHeader, ListErrorState, ListPagination } from "ui"; +import { useRouter } from "next/router"; + +const clients = [ + { + id: "1", + name: "Client 1", + email: "client1@example.com", + phone: "(123) 456-7890", + address: { + city: "New York", + state: "NY", + }, + }, + { + id: "2", + name: "Client 2", + email: "client2@example.com", + phone: "(123) 456-7890", + address: { + city: "Los Angeles", + state: "CA", + }, + }, +]; + +export const ListClients = () => { + const router = useRouter(); + return ( +
    + +

    Clients

    +
    + ( + // @ts-ignore + + )} + /> +
    + ); +}; \ No newline at end of file From e8b9b292708134b4de713e1fe60075782260df96 Mon Sep 17 00:00:00 2001 From: eman-bfloat Date: Thu, 26 Sep 2024 03:58:18 +0300 Subject: [PATCH 07/50] feat: add billing and account pages --- apps/client/src/Layout/layout.tsx | 7 +- apps/client/src/pages/account/index.tsx | 131 ------------------ apps/client/src/pages/billing/index.tsx | 102 ++++++++++++++ packages/features/auth/lib/accessRules.ts | 2 +- .../features/auth/lib/handleDecryptToken.ts | 1 + 5 files changed, 110 insertions(+), 133 deletions(-) create mode 100644 apps/client/src/pages/billing/index.tsx diff --git a/apps/client/src/Layout/layout.tsx b/apps/client/src/Layout/layout.tsx index 83e6016b..7a1499c2 100644 --- a/apps/client/src/Layout/layout.tsx +++ b/apps/client/src/Layout/layout.tsx @@ -10,7 +10,7 @@ import { HiOutlineBriefcase, HiOutlineUserCircle, HiOutlineTruck, - HiOutlineBuildingOffice, + HiOutlineCreditCard, } from "react-icons/hi2"; const links = [ @@ -29,6 +29,11 @@ const links = [ href: "/account", icon: HiOutlineUserCircle, }, + { + name: "Billing", + href: "/billing", + icon: HiOutlineCreditCard, + } ]; export default function Layout({ children, ...props }: LayoutProps) { diff --git a/apps/client/src/pages/account/index.tsx b/apps/client/src/pages/account/index.tsx index f4384f68..b070f606 100644 --- a/apps/client/src/pages/account/index.tsx +++ b/apps/client/src/pages/account/index.tsx @@ -35,7 +35,6 @@ export default function Account() { // @ts-ignore business && } -
    @@ -46,136 +45,6 @@ export default function Account() { ); } -const MomoAccountDetails = () => { - return ( - -

    Momo Account Details

    - - -
    - ); -}; - -const MomoUserInfo = () => { - // const { data, loading, refetch } = useGetMomoAccountInfo(); - // const [isRefetching, setIsRefetching] = useState(false); - - // const handleRefetch = async () => { - // if (!isRefetching) { - // setIsRefetching(true); - // await refetch().then(() => setIsRefetching(false)); - // } - // }; - return ( - -
    -
    -

    Given Name

    - {/* {loading ? ( -
    - ) : ( -

    {data?.given_name}

    - )} */} -
    -
    -

    Family Name

    - {/* {loading ? ( -
    - ) : ( -

    {data?.family_name}

    - )} */} -
    -
    -

    Gender

    - {/* {loading ? ( -
    - ) : ( -

    {data?.gender}

    - )} */} -
    -
    -

    Status

    - {/* {loading ? ( -
    - ) : ( -

    {data?.status || "Active"}

    - )} */} -
    -
    - {/* {data === null && ( -
    -

    - {isRefetching - ? "Refetching account info..." - : "Couldn't fetch account info."} -

    - -
    - )} */} - - ); -}; - -const MomoAccountBalance = () => { - // const { data, loading, refetch } = useGetAccountBalance(); - const [isRefetching, setIsRefetching] = useState(false); - - // const handleRefetch = async () => { - // if (!isRefetching) { - // setIsRefetching(true); - // await refetch().then(() => setIsRefetching(false)); - // } - // }; - - return ( - -

    Hello

    - {/*
    -
    -

    Currency

    - {loading ? ( -
    - ) : ( -

    {data?.currency}

    - )} -
    -
    -

    Balance

    - {loading ? ( -
    - ) : ( -

    {data?.availableBalance}

    - )} -
    -
    - {data === null && ( -
    -

    - {isRefetching - ? "Refetching balance..." - : "Couldn't fetch account balance."} -

    - -
    - )} */} - - ); -}; - const TransactionsHistory = () => { const transactions = [ { diff --git a/apps/client/src/pages/billing/index.tsx b/apps/client/src/pages/billing/index.tsx new file mode 100644 index 00000000..4ecf82af --- /dev/null +++ b/apps/client/src/pages/billing/index.tsx @@ -0,0 +1,102 @@ +import { HiOutlineCurrencyDollar, HiOutlineCreditCard, HiOutlineDocumentText, HiPlus } from "react-icons/hi2"; +import { Card } from "ui"; +import { useState } from "react"; + +const PaymentMethodCard = ({ method, isPreferred, onEdit, onSetPreferred }) => ( + +
    +
    + {method.type} ending in {method.last4} + {isPreferred && Preferred} +
    +
    + + {!isPreferred && ( + + )} +
    +
    +
    +); + +export default function Billing() { + const [paymentMethods, setPaymentMethods] = useState([ + { id: 1, type: 'Visa', last4: '1234' }, + { id: 2, type: 'Mastercard', last4: '5678' }, + ]); + const [preferredMethodId, setPreferredMethodId] = useState(1); + + const handleAddPaymentMethod = () => { + // Implement add payment method logic + }; + + const handleEditPaymentMethod = (id) => { + // Implement edit payment method logic + }; + + const handleSetPreferred = (id) => { + setPreferredMethodId(id); + }; + + return ( +
    +

    Billing

    +
    +
    +

    + Payment Methods +

    + {paymentMethods.map((method) => ( + handleEditPaymentMethod(method.id)} + onSetPreferred={() => handleSetPreferred(method.id)} + /> + ))} + +
    +
    +
    +
    +

    + Summary +

    +
    +
    + Total Earned + $1,234.56 +
    +
    + Total Spent + $567.89 +
    +
    +
    +
    +

    + Recent Transactions +

    +
      +
    • + Product Sale + +$50.00 +
    • +
    • + Platform Fee + -$5.00 +
    • +
    +
    +
    +
    +
    +
    + ); +} diff --git a/packages/features/auth/lib/accessRules.ts b/packages/features/auth/lib/accessRules.ts index 9cf22039..3aa54068 100644 --- a/packages/features/auth/lib/accessRules.ts +++ b/packages/features/auth/lib/accessRules.ts @@ -11,7 +11,7 @@ export const AGENT_ACCESS_RULES = [ ]; export const CLIENT_ACCESS_RULES = [ - { path: "/", roles: ["supplier", "business"] }, + { path: "/", roles: ["supplier", "business", "admin"] }, // Add more rules as needed for client ]; diff --git a/packages/features/auth/lib/handleDecryptToken.ts b/packages/features/auth/lib/handleDecryptToken.ts index 8a19c94c..f07ec02e 100644 --- a/packages/features/auth/lib/handleDecryptToken.ts +++ b/packages/features/auth/lib/handleDecryptToken.ts @@ -6,6 +6,7 @@ export function handleDecryptToken( return async function handler(req: NextApiRequest, res: NextApiResponse) { try { const payload = await getIdTokenClaims(req); + console.log("payload", payload); if (!payload) { res.status(401).json({ message: "Unauthorized" }); return; From 15185ef36b5bda0d9d9815f7f0679c66fb22ef7a Mon Sep 17 00:00:00 2001 From: eman-bfloat Date: Thu, 3 Oct 2024 19:50:49 +0300 Subject: [PATCH 08/50] feat: add notifications page --- apps/client/src/pages/notifications/index.tsx | 9 ++ .../Notifications/ListNotifications.tsx | 99 +++++++++++++++++++ .../Notifications/NotificationOverview.tsx | 83 ++++++++++++++++ packages/ui/components/Button.tsx | 46 ++++++++- packages/ui/components/IconButton.tsx | 7 +- packages/ui/components/Navbar.tsx | 6 ++ 6 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 apps/client/src/pages/notifications/index.tsx create mode 100644 packages/features/Notifications/ListNotifications.tsx create mode 100644 packages/features/Notifications/NotificationOverview.tsx diff --git a/apps/client/src/pages/notifications/index.tsx b/apps/client/src/pages/notifications/index.tsx new file mode 100644 index 00000000..03359b0b --- /dev/null +++ b/apps/client/src/pages/notifications/index.tsx @@ -0,0 +1,9 @@ +import { ListNotifications } from "@sahil/features/Notifications/ListNotifications"; + +export default function Notifications() { + return ( +
    + +
    + ); +} diff --git a/packages/features/Notifications/ListNotifications.tsx b/packages/features/Notifications/ListNotifications.tsx new file mode 100644 index 00000000..a17594a3 --- /dev/null +++ b/packages/features/Notifications/ListNotifications.tsx @@ -0,0 +1,99 @@ +import React, { useState, useEffect } from 'react'; +import { useSession } from 'next-auth/react'; +import { NotificationOverview } from './NotificationOverview'; +import { Button } from 'ui'; + +interface Notification { + id: string; + type: string; + title: string; + description: string; + time: string; + read: boolean; + entityId: string; +} + +export const ListNotifications: React.FC = () => { + const [notifications, setNotifications] = useState([]); + const { data: session } = useSession(); + + useEffect(() => { + const fetchNotifications = async () => { + // Stubbed data for demonstration + const dummyNotifications: Notification[] = [ + { + id: '1', + type: 'order', + title: 'New Order Received', + description: 'Order #12345 has been placed for Office Supplies Bundle.', + time: '2 hours ago', + read: false, + entityId: '12345' + }, + { + id: '2', + type: 'stock', + title: 'Low Stock Alert', + description: 'Printer Paper is running low. Consider restocking soon.', + time: '1 day ago', + read: false, + entityId: 'printer-paper' + }, + { + id: '3', + type: 'payment', + title: 'Payment Received', + description: 'Payment of $1,250.00 received for Order #12340.', + time: '3 days ago', + read: true, + entityId: '12340' + }, + ]; + + await new Promise(resolve => setTimeout(resolve, 500)); + setNotifications(dummyNotifications); + }; + + if (session?.user) { + fetchNotifications(); + } + }, [session]); + + const markAsRead = async (id: string) => { + setNotifications(prevNotifications => + prevNotifications.map(notification => + notification.id === id ? { ...notification, read: true } : notification + ) + ); + // Here you would typically also update the server + console.log(`Marking notification ${id} as read`); + }; + + return ( +
    +
    +

    Notifications

    +
    + Filter: All Notifications +
    +
    + {notifications.length === 0 ? ( +

    No notifications

    + ) : ( + notifications.map((notification) => ( + + )) + )} + {notifications.length > 0 && ( +
    + Page 1 of 5 + +
    + )} +
    + ); +}; \ No newline at end of file diff --git a/packages/features/Notifications/NotificationOverview.tsx b/packages/features/Notifications/NotificationOverview.tsx new file mode 100644 index 00000000..3f5b3f57 --- /dev/null +++ b/packages/features/Notifications/NotificationOverview.tsx @@ -0,0 +1,83 @@ +import React from "react"; +import { Button, Card } from "ui"; +import { HiOutlineBell, HiOutlineCheckCircle, HiOutlineExclamationCircle } from "react-icons/hi"; +import { useRouter } from 'next/router'; + +interface NotificationProps { + notification: { + id: string; + type: string; + title: string; + description: string; + time: string; + read: boolean; + entityId: string; + }; + onMarkAsRead: (id: string) => void; +} + +const NotificationIcon: React.FC<{ type: string }> = ({ type }) => { + const iconColors: { [key: string]: string } = { + order: "bg-green-500", + stock: "bg-yellow-500", + payment: "bg-blue-500", + }; + + return ( +
    + {type === 'order' && } + {type === 'stock' && } + {type === 'payment' && } + {!['order', 'stock', 'payment'].includes(type) && } +
    + ); +}; + +export const NotificationOverview: React.FC = ({ + notification, + onMarkAsRead, +}) => { + const { id, type, title, description, time, read, entityId } = notification; + const router = useRouter(); + + const handleClick = () => { + if (type === 'order') { + router.push(`/orders/${entityId}`); + } else if (type === 'stock') { + router.push(`/inventory/${entityId}`); + } else if (type === 'payment') { + router.push(`/payments/${entityId}`); + } else { + router.push(`/notifications/${id}`); + } + }; + + return ( + +
    +
    + +
    +

    {title}

    +

    {description}

    +

    {time}

    +
    + {!read && ( + + )} +
    +
    +
    + ); +}; diff --git a/packages/ui/components/Button.tsx b/packages/ui/components/Button.tsx index 22c32458..6c35b10d 100644 --- a/packages/ui/components/Button.tsx +++ b/packages/ui/components/Button.tsx @@ -1,14 +1,50 @@ "use client"; -import { FC } from "react"; +import { FC, ReactNode, MouseEvent } from "react"; +import { twMerge } from "tailwind-merge"; export type ButtonProps = { - cta: string; + children: ReactNode; + className?: string; + variant?: "primary" | "secondary" | "outline"; + size?: "sm" | "md" | "lg"; + onClick?: (event: MouseEvent) => void; + leftIcon?: ReactNode; + rightIcon?: ReactNode; }; -export const Button: FC = ({ cta = "button" }) => { +export const Button: FC = ({ + children, + className, + variant = "primary", + size = "md", + onClick, + leftIcon, + rightIcon, +}) => { + const baseClasses = "btn"; + const variantClasses = { + primary: "btn-primary", + secondary: "btn-secondary", + outline: "btn-outline", + }; + const sizeClasses = { + sm: "btn-sm", + md: "btn-md", + lg: "btn-lg", + }; + + const mergedClasses = twMerge( + baseClasses, + variantClasses[variant], + sizeClasses[size], + className + ); + return ( - ); }; diff --git a/packages/ui/components/IconButton.tsx b/packages/ui/components/IconButton.tsx index 5136182c..c483c7ce 100644 --- a/packages/ui/components/IconButton.tsx +++ b/packages/ui/components/IconButton.tsx @@ -1,16 +1,17 @@ -import { FC } from "react"; +import { FC, MouseEvent } from "react"; import { Icon, IconProps } from "./Icon"; import { twMerge } from "tailwind-merge"; export type IconButtonProps = IconProps & { className?: any; title?: string; + onClick?: (event: MouseEvent) => void; }; -export const IconButton: FC = ({ className, icon, title }) => { +export const IconButton: FC = ({ className, icon, title, onClick }) => { const merged = twMerge("btn btn-xs btn-square", className); return ( - ); diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index bb76679b..48f99dee 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -101,6 +101,12 @@ const Right = ({
    */} + + + Date: Mon, 7 Oct 2024 12:24:34 +0300 Subject: [PATCH 09/50] feat: added new settings UI on agent --- apps/agent/src/pages/settings/billing.tsx | 27 +++ apps/agent/src/pages/settings/general.tsx | 27 +++ apps/agent/src/pages/settings/index.tsx | 9 - .../src/pages/settings/notifications.tsx | 27 +++ apps/agent/src/pages/settings/profile.tsx | 33 +++ apps/agent/src/pages/settings/security.tsx | 27 +++ packages/features/Settings/BillingCard.tsx | 191 ++++++++++++++++++ .../features/Settings/DeleteAccountCard.tsx | 36 ++++ packages/features/Settings/GeneralCard.tsx | 69 +++++++ .../features/Settings/NotificationsCard.tsx | 109 ++++++++++ packages/features/Settings/ProfileCard.tsx | 116 +++++++++++ packages/features/Settings/SecurityCard.tsx | 28 +++ packages/features/Settings/index.ts | 6 + packages/ui/components/Navbar.tsx | 151 +++++++++----- .../components/Settings/SettingsContainer.tsx | 13 ++ .../ui/components/Settings/SettingsHeader.tsx | 18 ++ .../ui/components/Settings/SettingsLink.tsx | 28 +++ .../components/Settings/SettingsSection.tsx | 13 ++ packages/ui/components/Settings/index.ts | 4 + packages/ui/components/Sidebar.tsx | 78 +++++++ packages/ui/index.tsx | 2 + 21 files changed, 951 insertions(+), 61 deletions(-) create mode 100644 apps/agent/src/pages/settings/billing.tsx create mode 100644 apps/agent/src/pages/settings/general.tsx delete mode 100644 apps/agent/src/pages/settings/index.tsx create mode 100644 apps/agent/src/pages/settings/notifications.tsx create mode 100644 apps/agent/src/pages/settings/profile.tsx create mode 100644 apps/agent/src/pages/settings/security.tsx create mode 100644 packages/features/Settings/BillingCard.tsx create mode 100644 packages/features/Settings/DeleteAccountCard.tsx create mode 100644 packages/features/Settings/GeneralCard.tsx create mode 100644 packages/features/Settings/NotificationsCard.tsx create mode 100644 packages/features/Settings/ProfileCard.tsx create mode 100644 packages/features/Settings/SecurityCard.tsx create mode 100644 packages/features/Settings/index.ts create mode 100644 packages/ui/components/Settings/SettingsContainer.tsx create mode 100644 packages/ui/components/Settings/SettingsHeader.tsx create mode 100644 packages/ui/components/Settings/SettingsLink.tsx create mode 100644 packages/ui/components/Settings/SettingsSection.tsx create mode 100644 packages/ui/components/Settings/index.ts create mode 100644 packages/ui/components/Sidebar.tsx diff --git a/apps/agent/src/pages/settings/billing.tsx b/apps/agent/src/pages/settings/billing.tsx new file mode 100644 index 00000000..0e721625 --- /dev/null +++ b/apps/agent/src/pages/settings/billing.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { BillingCard } from "@sahil/features/Settings/BillingCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function BillingSettings({ children, ...props }: SidebarProps) { + return ( + + +
    + + + +
    +
    + ); +} diff --git a/apps/agent/src/pages/settings/general.tsx b/apps/agent/src/pages/settings/general.tsx new file mode 100644 index 00000000..a485c198 --- /dev/null +++ b/apps/agent/src/pages/settings/general.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { GeneralCard } from "@sahil/features/Settings/GeneralCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function GeneralSettings({ children, ...props }: SidebarProps) { + return ( + + +
    + + + +
    +
    + ); +} diff --git a/apps/agent/src/pages/settings/index.tsx b/apps/agent/src/pages/settings/index.tsx deleted file mode 100644 index 6218dd3d..00000000 --- a/apps/agent/src/pages/settings/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { useGetUsers } from "@/hooks/users"; - -export default function Settings() { - return ( -
    -

    Settings Page!

    -
    - ); -} diff --git a/apps/agent/src/pages/settings/notifications.tsx b/apps/agent/src/pages/settings/notifications.tsx new file mode 100644 index 00000000..df7de6c4 --- /dev/null +++ b/apps/agent/src/pages/settings/notifications.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { NotificationsCard } from "@sahil/features/Settings/NotificationsCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function NotificationsSettings({ children, ...props }: SidebarProps) { + return ( + + +
    + + + +
    +
    + ); +} diff --git a/apps/agent/src/pages/settings/profile.tsx b/apps/agent/src/pages/settings/profile.tsx new file mode 100644 index 00000000..cf5724eb --- /dev/null +++ b/apps/agent/src/pages/settings/profile.tsx @@ -0,0 +1,33 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { ProfileCard } from "@sahil/features/Settings/ProfileCard"; +import { DeleteAccountCard } from "@sahil/features/Settings/DeleteAccountCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function ProfileSettings({ children, ...props }: SidebarProps) { + + return ( + + +
    + + + + + + + +
    +
    + ); +} diff --git a/apps/agent/src/pages/settings/security.tsx b/apps/agent/src/pages/settings/security.tsx new file mode 100644 index 00000000..51e41c79 --- /dev/null +++ b/apps/agent/src/pages/settings/security.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { SecurityCard } from "@sahil/features/Settings/SecurityCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function SecuritySettings({ children, ...props }: SidebarProps) { + return ( + + +
    + + + +
    +
    + ); +} diff --git a/packages/features/Settings/BillingCard.tsx b/packages/features/Settings/BillingCard.tsx new file mode 100644 index 00000000..3eb8a4ae --- /dev/null +++ b/packages/features/Settings/BillingCard.tsx @@ -0,0 +1,191 @@ +import { useState } from 'react'; +import { SettingsHeader } from "ui"; +import { HiOutlineCreditCard, HiOutlineBanknotes } from "react-icons/hi2"; +import { IconType } from 'react-icons'; + +type PaymentMethodType = 'credit' | 'paypal' | 'cash'; + +interface PaymentMethodModalProps { + type: 'credit' | 'paypal'; + isOpen: boolean; + onClose: () => void; +} + +interface PaymentMethod { + id: PaymentMethodType; + name: string; + icon: IconType; + requiresModal: boolean; +} + +const PaymentMethodModal: React.FC = ({ type, isOpen, onClose }) => { + return ( + +
    +

    + {type === 'credit' ? 'Add Credit Card' : 'Connect PayPal'} +

    + + {type === 'credit' ? ( +
    +
    + + +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    + ) : ( +
    +

    + You will be redirected to PayPal to complete the connection. +

    + +
    + )} + +
    + + +
    +
    +
    + + +
    + ); +}; + +export const BillingCard: React.FC = () => { + const [preferredMethod, setPreferredMethod] = useState('cash'); + const [activeModal, setActiveModal] = useState(null); + + const paymentMethods: PaymentMethod[] = [ + { + id: 'cash', + name: 'Cash on Delivery', + icon: HiOutlineBanknotes, + requiresModal: false + }, + { + id: 'credit', + name: 'Credit Card', + icon: HiOutlineCreditCard, + requiresModal: true + }, + { + id: 'paypal', + name: 'PayPal', + icon: HiOutlineCreditCard, + requiresModal: true + } + ]; + + const handleMethodClick = (methodId: PaymentMethodType, requiresModal: boolean): void => { + setPreferredMethod(methodId); + if (requiresModal) { + setActiveModal(methodId); + } + }; + + return ( + <> + +
    + +
    + + Info +
    + Info alert! Currently, we only accept Cash on Delivery as the default mode of payment. You'll be notified when other modes of payment are implemented. +
    +
    + +
    + {paymentMethods.map((method) => ( +
    +
    +
    handleMethodClick(method.id, method.requiresModal)} + > +
    + +
    + {method.name} +
    + {preferredMethod === method.id && ( + Preferred method + )} + {method.requiresModal && ( + Set up + )} +
    +
    +
    + handleMethodClick(method.id, method.requiresModal)} + /> +
    +
    +
    + ))} +
    + + {/* Modals */} + {(activeModal === 'credit' || activeModal === 'paypal') && ( + setActiveModal(null)} + /> + )} + + ); +}; \ No newline at end of file diff --git a/packages/features/Settings/DeleteAccountCard.tsx b/packages/features/Settings/DeleteAccountCard.tsx new file mode 100644 index 00000000..dc45563e --- /dev/null +++ b/packages/features/Settings/DeleteAccountCard.tsx @@ -0,0 +1,36 @@ + +export const DeleteAccountCard = () => { + return ( + <> +

    Delete Account

    +
    +
    +
    +
    + + + +
    +
    +

    + Be Careful! Account deletion cannot be undone. All your account history will be deleted without the possibility to restore +

    +
    +
    +
    + +
    +
    +
    + + ); +}; diff --git a/packages/features/Settings/GeneralCard.tsx b/packages/features/Settings/GeneralCard.tsx new file mode 100644 index 00000000..27bb8c23 --- /dev/null +++ b/packages/features/Settings/GeneralCard.tsx @@ -0,0 +1,69 @@ +import { SettingsHeader } from "ui"; + +export const GeneralCard = () => { + return ( + <> + +
    +
    +
    +
    +
    + Language +

    + Default language for Sahil +

    + +
    +
    + Timezone +

    + Select preferred timezone +

    + +
    +
    + +
    + +
    + +
    +
    +
    + +

    + Select preferred theme color +

    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    + + + ); +}; diff --git a/packages/features/Settings/NotificationsCard.tsx b/packages/features/Settings/NotificationsCard.tsx new file mode 100644 index 00000000..501c5559 --- /dev/null +++ b/packages/features/Settings/NotificationsCard.tsx @@ -0,0 +1,109 @@ +import { SettingsHeader } from "ui"; + +export const NotificationsCard = () => { + return ( + <> + +
    +
    +
    +
    +
    +
    + + Push Notifications + +

    + Alerts sent to the user's mobile device or desktop +

    +
    +
    + +
    +
    +
    +
    + + Email Notifications + +

    + Receive messages sent to the your email address +

    +
    +
    + +
    +
    +
    +
    + + In-App Notifications + +

    + Alerts that appear within the application interface +

    +
    +
    + +
    +
    +
    +
    + + SMS Notifications + +

    + Receive Text messages sent to the your phone number +

    +
    +
    + +
    +
    +
    +
    + + Updates & Features + +

    + Notifications about new updates and their features +

    +
    +
    + +
    +
    +
    +
    + + + ); +}; diff --git a/packages/features/Settings/ProfileCard.tsx b/packages/features/Settings/ProfileCard.tsx new file mode 100644 index 00000000..c01a8137 --- /dev/null +++ b/packages/features/Settings/ProfileCard.tsx @@ -0,0 +1,116 @@ +import { useSession } from "next-auth/react"; +import { Avatar, SettingsHeader } from "ui"; + +export const ProfileCard = () => { + const { data: session } = useSession(); + return ( + <> + +
    +
    +
    +
    + +

    + PNG, JPG, or SVG under 5MB +

    +
    + + +
    +
    + +
    +
    + + +
    + +
    + +
    + + Primary +
    +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    + +
    +
    + + + ); +}; diff --git a/packages/features/Settings/SecurityCard.tsx b/packages/features/Settings/SecurityCard.tsx new file mode 100644 index 00000000..405eadfc --- /dev/null +++ b/packages/features/Settings/SecurityCard.tsx @@ -0,0 +1,28 @@ +import { SettingsHeader } from "ui"; + +export const SecurityCard = () => { + return ( + <> + +
    +
    +
    +

    Your account is managed by Google

    +

    + To change your password, enable two-factor authentication and more, please visit your Google account settings. +

    + + Manage account + +
    +
    + + ); +}; diff --git a/packages/features/Settings/index.ts b/packages/features/Settings/index.ts new file mode 100644 index 00000000..1f7943e5 --- /dev/null +++ b/packages/features/Settings/index.ts @@ -0,0 +1,6 @@ +export * from "./ProfileCard"; +export * from "./DeleteAccountCard"; +export * from "./GeneralCard"; +export * from "./NotificationsCard"; +export * from "./SecurityCard"; +export * from "./BillingCard"; \ No newline at end of file diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index bb76679b..6343dbcc 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -4,9 +4,9 @@ import Link from "next/link"; import { Icon } from "./Icon"; import type { IconType } from "react-icons"; import { - HiOutlineAdjustmentsHorizontal, + HiOutlineInformationCircle, HiOutlineArrowRightOnRectangle, - HiOutlinePlus, + HiOutlineUser, HiOutlineCog6Tooth, HiOutlineBell } from "react-icons/hi2"; @@ -35,35 +35,65 @@ export const Navbar: FC = ({ }) => { return (
    -
    - - {logo && ( - - )} - {header} - - +
    +
    + + {logo && ( + + )} + {header} + + +
    @@ -96,13 +126,14 @@ const Right = ({ return (
    - {/* for now commented out the notification icon */} - {/*
    + -
    -
    */} + @@ -120,28 +151,44 @@ const Right = ({
      -
    • -

      Quick Menu:

      -
    • - {links.map(({ name, href, icon }) => { - return ( -
    • - - {name} - -
    • - ); - })} -
      +
      +
      +
      + {user.name} +
      +
      +
      +

      {user.name}

      +

      {user.email}

      +
      +
      +
      +
    • + + View profile + +
    • - - Settings + + Account settings
    • +
      + +
    • -
    • diff --git a/packages/ui/components/Settings/SettingsContainer.tsx b/packages/ui/components/Settings/SettingsContainer.tsx new file mode 100644 index 00000000..ed7d9ecc --- /dev/null +++ b/packages/ui/components/Settings/SettingsContainer.tsx @@ -0,0 +1,13 @@ +import { ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +interface SettingsContainerProps { + children: ReactNode; + className?: string; +} + +export const SettingsContainer = ({ children, className }: SettingsContainerProps) => { + const defaultClass = "w-full rounded-xl bg-white p-4 sm:p-6 border"; + const mergedClass = twMerge(defaultClass, className); + return
      {children}
      ; +}; diff --git a/packages/ui/components/Settings/SettingsHeader.tsx b/packages/ui/components/Settings/SettingsHeader.tsx new file mode 100644 index 00000000..651814b8 --- /dev/null +++ b/packages/ui/components/Settings/SettingsHeader.tsx @@ -0,0 +1,18 @@ + +interface SettingsHeaderProps { + title: string; + description?: string; +} + +export const SettingsHeader = ({ title, description }: SettingsHeaderProps) => { + return ( +
      +

      + {title} +

      +

      + {description} +

      +
      + ) +}; diff --git a/packages/ui/components/Settings/SettingsLink.tsx b/packages/ui/components/Settings/SettingsLink.tsx new file mode 100644 index 00000000..54dfc207 --- /dev/null +++ b/packages/ui/components/Settings/SettingsLink.tsx @@ -0,0 +1,28 @@ + +interface SettingsLinks { + name: string; + href: string; +} + +export const settingslinks: SettingsLinks[] = [ + { + name: "Profile", + href: "/settings/profile", + }, + { + name: "General", + href: "/settings/general", + }, + { + name: "Notifications", + href: "/settings/notifications", + }, + { + name: "Billing", + href: "/settings/billing", + }, + { + name: "Security", + href: "/settings/security", + }, +]; diff --git a/packages/ui/components/Settings/SettingsSection.tsx b/packages/ui/components/Settings/SettingsSection.tsx new file mode 100644 index 00000000..5be97f61 --- /dev/null +++ b/packages/ui/components/Settings/SettingsSection.tsx @@ -0,0 +1,13 @@ +import { ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +interface SettingsSectionProps { + children: ReactNode; + className?: string; +} + +export const SettingsSection = ({ children, className }: SettingsSectionProps) => { + const defaultClass = "pt-4 flex flex-col lg:flex-row"; + const mergedClass = twMerge(defaultClass, className); + return
      {children}
      ; +}; diff --git a/packages/ui/components/Settings/index.ts b/packages/ui/components/Settings/index.ts new file mode 100644 index 00000000..1d3b41f7 --- /dev/null +++ b/packages/ui/components/Settings/index.ts @@ -0,0 +1,4 @@ +export * from "./SettingsHeader"; +export * from "./SettingsLink"; +export * from "./SettingsSection"; +export * from "./SettingsContainer"; diff --git a/packages/ui/components/Sidebar.tsx b/packages/ui/components/Sidebar.tsx new file mode 100644 index 00000000..1fd0e075 --- /dev/null +++ b/packages/ui/components/Sidebar.tsx @@ -0,0 +1,78 @@ +import { FC } from "react"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { settingslinks } from "./Settings"; + +type SidebarLink = { + name: string; + href: string; +}; + +export type SidebarProps = { + links: SidebarLink[]; +}; + +export const Sidebar: FC = ({ + links, +}) => { + const router = useRouter(); + return ( +
      +
      +
      +

      Settings

      +
      +
      +
      +
      + +
      +
      +
      +
      + +
      + + ); +}; + +export default Sidebar; diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index e3a9a400..f623c46f 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -35,4 +35,6 @@ export * from "./components/StatusPage"; export * from "./components/CustomContainer"; export * from "./components/Schedule"; export * from "./components/SectionHeader"; +export * from "./components/Sidebar"; +export * from "./components/Settings"; From ce622d72af6e67abebcbf59746440793f35d0694 Mon Sep 17 00:00:00 2001 From: eman-bfloat Date: Wed, 20 Nov 2024 02:00:30 +0300 Subject: [PATCH 10/50] feat: update navbar --- packages/ui/components/Navbar.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index cde3137c..552bace0 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -131,12 +131,6 @@ const Right = ({ return (
      - - - From 94684833635311346390105c477c4af9a2cf0baf Mon Sep 17 00:00:00 2001 From: eman-bfloat Date: Wed, 20 Nov 2024 02:25:48 +0300 Subject: [PATCH 11/50] feat: add client details page --- apps/admin/src/pages/clients/[clientId].tsx | 98 ++++++++++++++- apps/admin/src/pages/clients/index.tsx | 7 +- apps/client/src/pages/settings/billing.tsx | 27 ++++ apps/client/src/pages/settings/general.tsx | 27 ++++ .../src/pages/settings/notifications.tsx | 27 ++++ apps/client/src/pages/settings/profile.tsx | 33 +++++ apps/client/src/pages/settings/security.tsx | 27 ++++ .../features/Clients/ClientOverviewCard.tsx | 118 +++++++++++++++--- packages/features/Clients/ListClients.tsx | 92 ++++++++------ 9 files changed, 399 insertions(+), 57 deletions(-) create mode 100644 apps/client/src/pages/settings/billing.tsx create mode 100644 apps/client/src/pages/settings/general.tsx create mode 100644 apps/client/src/pages/settings/notifications.tsx create mode 100644 apps/client/src/pages/settings/profile.tsx create mode 100644 apps/client/src/pages/settings/security.tsx diff --git a/apps/admin/src/pages/clients/[clientId].tsx b/apps/admin/src/pages/clients/[clientId].tsx index 11a4c31b..180879ba 100644 --- a/apps/admin/src/pages/clients/[clientId].tsx +++ b/apps/admin/src/pages/clients/[clientId].tsx @@ -1,3 +1,99 @@ +import { useRouter } from "next/router"; +import { useFetchSupplierByPK } from "@sahil/lib/hooks/suppliers"; +import { useFetchBusinessByPK } from "@sahil/lib/hooks/businesses"; +import { + SupplierOrderHistory, + SupplierProducts, + ServiceZones, + SupplierProfileOverview, +} from "@sahil/features/Suppliers"; +import { + BusinessProfileOverview, + BusinessOrderHistory, +} from "@sahil/features/businesses"; + export default function ClientPage() { - return
      Client
      ; + const router = useRouter(); + const { clientId, type } = router.query; + const isSupplier = type === 'supplier'; + + if (!clientId || !type) { + return
      Invalid client details
      ; + } + + if (isSupplier) { + return ; + } + + return ; +} + +function SupplierView({ clientId }: { clientId: string }) { + const { + data: supplier, + error: supplierError, + loading: supplierLoading + } = useFetchSupplierByPK(clientId); + + if (supplierLoading) { + return

      Loading...

      ; + } + + if (supplierError) { + return
      Error loading supplier details
      ; + } + + if (!supplier) { + return
      Supplier not found
      ; + } + + return ( +
      +
      +
      + + +
      +
      + + +
      +
      +
      + ); +} + +function BusinessView({ clientId }: { clientId: string }) { + const { + data: business, + error: businessError, + loading: businessLoading + } = useFetchBusinessByPK(clientId); + + if (businessLoading) { + return

      Loading...

      ; + } + + if (businessError) { + return
      Error loading business details
      ; + } + + if (!business) { + return
      Business not found
      ; + } + + return ( +
      +
      +
      + +
      +
      + +
      +
      +
      + ); } \ No newline at end of file diff --git a/apps/admin/src/pages/clients/index.tsx b/apps/admin/src/pages/clients/index.tsx index 99fe1e82..ceabfe8f 100644 --- a/apps/admin/src/pages/clients/index.tsx +++ b/apps/admin/src/pages/clients/index.tsx @@ -2,11 +2,12 @@ import { useRouter } from "next/router"; import { HiPlus, HiOutlineDocumentMagnifyingGlass } from "react-icons/hi2"; import { ListClients } from "@sahil/features/Clients/ListClients"; -export default function Zones() { +export default function Clients() { const router = useRouter(); + return ( -
      +
      -
      + ); } diff --git a/apps/client/src/pages/settings/billing.tsx b/apps/client/src/pages/settings/billing.tsx new file mode 100644 index 00000000..0e721625 --- /dev/null +++ b/apps/client/src/pages/settings/billing.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { BillingCard } from "@sahil/features/Settings/BillingCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function BillingSettings({ children, ...props }: SidebarProps) { + return ( + + +
      + + + +
      +
      + ); +} diff --git a/apps/client/src/pages/settings/general.tsx b/apps/client/src/pages/settings/general.tsx new file mode 100644 index 00000000..a485c198 --- /dev/null +++ b/apps/client/src/pages/settings/general.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { GeneralCard } from "@sahil/features/Settings/GeneralCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function GeneralSettings({ children, ...props }: SidebarProps) { + return ( + + +
      + + + +
      +
      + ); +} diff --git a/apps/client/src/pages/settings/notifications.tsx b/apps/client/src/pages/settings/notifications.tsx new file mode 100644 index 00000000..df7de6c4 --- /dev/null +++ b/apps/client/src/pages/settings/notifications.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { NotificationsCard } from "@sahil/features/Settings/NotificationsCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function NotificationsSettings({ children, ...props }: SidebarProps) { + return ( + + +
      + + + +
      +
      + ); +} diff --git a/apps/client/src/pages/settings/profile.tsx b/apps/client/src/pages/settings/profile.tsx new file mode 100644 index 00000000..cf5724eb --- /dev/null +++ b/apps/client/src/pages/settings/profile.tsx @@ -0,0 +1,33 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { ProfileCard } from "@sahil/features/Settings/ProfileCard"; +import { DeleteAccountCard } from "@sahil/features/Settings/DeleteAccountCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function ProfileSettings({ children, ...props }: SidebarProps) { + + return ( + + +
      + + + + + + + +
      +
      + ); +} diff --git a/apps/client/src/pages/settings/security.tsx b/apps/client/src/pages/settings/security.tsx new file mode 100644 index 00000000..51e41c79 --- /dev/null +++ b/apps/client/src/pages/settings/security.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react"; +import { + SettingsSection, + Sidebar, + settingslinks, + SettingsContainer +} from "ui"; +import { SecurityCard } from "@sahil/features/Settings/SecurityCard"; + +type SidebarProps = { + children: ReactNode; +}; + +export default function SecuritySettings({ children, ...props }: SidebarProps) { + return ( + + +
      + + + +
      +
      + ); +} diff --git a/packages/features/Clients/ClientOverviewCard.tsx b/packages/features/Clients/ClientOverviewCard.tsx index 1a15b99d..e338f073 100644 --- a/packages/features/Clients/ClientOverviewCard.tsx +++ b/packages/features/Clients/ClientOverviewCard.tsx @@ -1,24 +1,110 @@ -export const ClientOverviewCard = ({ client }: { client: any }) => { +import { FC } from "react"; +import Link from "next/link"; +import { + HiOutlineMapPin, + HiOutlinePhone, + HiEllipsisHorizontal, +} from "react-icons/hi2"; +import { generateInitials } from "@sahil/lib/strings"; +import { Card } from "ui"; + +type ClientProps = { + client: { + id: string; + name: string; + contactName?: string; + phoneNumber?: string; + streetAddress?: string; + categories?: Array<{ category_name: string }>; + zone?: string; + type?: string; + addresses?: Array<{ street_address: string }>; + }; +}; + +export const ClientOverviewCard: FC = ({ client }) => { + const isSupplier = Boolean(client.categories); + const baseUrl = "clients"; + const address = isSupplier + ? client.streetAddress + : client.addresses?.[0]?.street_address; + return ( -
      -
      -
      -
      -
      - {client.name} -
      -
      {client.email}
      + +
      + +
      + {generateInitials(client.name)} +
      + + +
      + +
      + + {client.name} + + {isSupplier && client.categories && ( +
      + {client.categories.map(({ category_name }) => ( + + {category_name} + + ))} +
      + )} +
      + +
      +
      +
      + + {isSupplier ? "Service Zone" : "Business Type"} + +

      {isSupplier ? client.zone : client.type}

      +
      +
      + Contact Name +

      {client.contactName}

      -
      -
      - {client.phone} +
      + +
      + {address && ( +
      + + + +

      {address}

      -
      - {client.address.city}, {client.address.state} + )} + {client.phoneNumber && ( +
      + + + +

      {client.phoneNumber}

      -
      + )}
      -
      + ); }; \ No newline at end of file diff --git a/packages/features/Clients/ListClients.tsx b/packages/features/Clients/ListClients.tsx index d3e606f7..e67e1e8d 100644 --- a/packages/features/Clients/ListClients.tsx +++ b/packages/features/Clients/ListClients.tsx @@ -1,46 +1,64 @@ import { ClientOverviewCard } from "./ClientOverviewCard"; import { List, ListHeader, ListErrorState, ListPagination } from "ui"; import { useRouter } from "next/router"; - -const clients = [ - { - id: "1", - name: "Client 1", - email: "client1@example.com", - phone: "(123) 456-7890", - address: { - city: "New York", - state: "NY", - }, - }, - { - id: "2", - name: "Client 2", - email: "client2@example.com", - phone: "(123) 456-7890", - address: { - city: "Los Angeles", - state: "CA", - }, - }, -]; +import { useFetchSuppliers } from "@sahil/lib/hooks/suppliers"; +import { useFetchBusinesses } from "@sahil/lib/hooks/businesses"; export const ListClients = () => { const router = useRouter(); + + const { + data: suppliers = [], + isLoading: isSuppliersLoading, + error: suppliersError + } = useFetchSuppliers(); + + const { + data: businesses = [], + isLoading: isBusinessesLoading, + error: businessesError + } = useFetchBusinesses(); + + const isLoading = isSuppliersLoading || isBusinessesLoading; + const hasError = suppliersError || businessesError; + + if (hasError) { + return ; + } + return ( -
      - -

      Clients

      -
      - ( - // @ts-ignore - - )} - /> -
      +
      +
      + + ( + + )} + /> +
      + +
      + + ( + + )} + /> +
      +
      ); }; \ No newline at end of file From 9e8f85db1989db37a5c773d1c9011602c09b7fc1 Mon Sep 17 00:00:00 2001 From: eman-bfloat Date: Wed, 20 Nov 2024 02:27:23 +0300 Subject: [PATCH 12/50] feat: update navbar --- packages/ui/components/Navbar.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index 552bace0..0d6092e6 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -137,12 +137,6 @@ const Right = ({ > - - -
      Date: Wed, 20 Nov 2024 03:34:11 +0300 Subject: [PATCH 13/50] feat: update inventory page --- apps/agent/src/Dashboard/AgentToolBar.tsx | 4 +- apps/client/src/Layout/layout.tsx | 2 +- apps/client/src/pages/index.tsx | 2 +- .../src/pages/inventory/[productId].tsx | 207 ++++++++++++++- apps/client/src/pages/inventory/index.tsx | 239 ++++++++++++++++-- packages/lib/graphql/queries/products.ts | 24 ++ packages/lib/graphql/queries/users.ts | 92 +++++++ packages/lib/hooks/products.ts | 38 ++- packages/lib/hooks/useUserOrganizations.tsx | 77 ++++++ packages/lib/hooks/users.tsx | 79 +++++- packages/ui/components/Button.tsx | 21 +- .../ui/components/OrganizationSwitcher.tsx | 70 +++++ packages/ui/components/table/Table.tsx | 230 ++++++----------- 13 files changed, 881 insertions(+), 204 deletions(-) create mode 100644 packages/lib/hooks/useUserOrganizations.tsx create mode 100644 packages/ui/components/OrganizationSwitcher.tsx diff --git a/apps/agent/src/Dashboard/AgentToolBar.tsx b/apps/agent/src/Dashboard/AgentToolBar.tsx index a412a152..1e0afe2a 100644 --- a/apps/agent/src/Dashboard/AgentToolBar.tsx +++ b/apps/agent/src/Dashboard/AgentToolBar.tsx @@ -3,6 +3,7 @@ import { HiChevronDown, HiOutlineTruck, HiOutlineBriefcase, + HiOutlineBuildingOffice, } from "react-icons/hi2"; import Link from "next/link"; @@ -26,9 +27,6 @@ const dropdownOptions = [ }, ]; - -import { Avatar } from "ui"; - import { useSession } from "next-auth/react"; import { formatCurrentDate } from "@sahil/lib/dates"; diff --git a/apps/client/src/Layout/layout.tsx b/apps/client/src/Layout/layout.tsx index 89c1ef2f..defd3c38 100644 --- a/apps/client/src/Layout/layout.tsx +++ b/apps/client/src/Layout/layout.tsx @@ -11,7 +11,7 @@ import { HiOutlineUserCircle, HiOutlineTruck, HiOutlineBuildingOffice, - HiOutlineCube + HiOutlineCube, HiOutlineCreditCard, } from "react-icons/hi2"; diff --git a/apps/client/src/pages/index.tsx b/apps/client/src/pages/index.tsx index 75ae6b8d..14a7ea67 100644 --- a/apps/client/src/pages/index.tsx +++ b/apps/client/src/pages/index.tsx @@ -58,7 +58,7 @@ export default function Home() { Radisson Blu - + ); } diff --git a/apps/client/src/pages/inventory/[productId].tsx b/apps/client/src/pages/inventory/[productId].tsx index a03e7151..e51f0adc 100644 --- a/apps/client/src/pages/inventory/[productId].tsx +++ b/apps/client/src/pages/inventory/[productId].tsx @@ -1,14 +1,197 @@ -// import { OrderHistory } from "@sahil/features/Orders/ListOrders"; +import React, { useState } from 'react'; +import { HiHeart, HiChatBubbleOvalLeft, HiFlag, HiPencilSquare, HiTrash, HiPlus, HiChevronLeft, HiChevronRight } from 'react-icons/hi2'; +import { useRouter } from 'next/router'; +import { Card, Button } from 'ui'; -export default function ProductPage() { - return ( -
      -
      -

      - Product Page -

      +const ProductDetailsPage = ({ isSellerView = false }) => { + const [currentImageIndex, setCurrentImageIndex] = useState(0); + const [isEditing, setIsEditing] = useState(false); + + const images = [ + "https://res.cloudinary.com/dwacr3zpp/image/upload/v1711123098/Sahil/How-to-Choose-a-Laptop-August-2023-Gear.webp", + "https://res.cloudinary.com/dwacr3zpp/image/upload/v1711123098/Sahil/How-to-Choose-a-Laptop-August-2023-Gear.webp", + "https://res.cloudinary.com/dwacr3zpp/image/upload/v1711123098/Sahil/How-to-Choose-a-Laptop-August-2023-Gear.webp" + ]; + + const [viewMode, setViewMode] = useState('supplier'); + const [isAdmin, setIsAdmin] = useState(false); // This should be set based on user role + + const toggleView = () => { + setViewMode(prevMode => prevMode === 'supplier' ? 'business' : 'supplier'); + }; + + const isSupplierView = viewMode === 'supplier'; + const isBusinessView = viewMode === 'business'; + + const nextImage = () => { + setCurrentImageIndex((prevIndex) => (prevIndex + 1) % images.length); + }; + + const prevImage = () => { + setCurrentImageIndex((prevIndex) => (prevIndex - 1 + images.length) % images.length); + }; + + return ( + +
      +

      Product Details

      + {isSellerView && ( +
      + + +
      + )} +
      + +
      +
      + Product + + +
      + {images.map((_, index) => ( +
      + ))} +
      + {isSellerView && ( + + )}
      -
      - ); - } - \ No newline at end of file + + +

      + {isEditing ? ( + + ) : ( + "Embelazo by Clack Ssaku" + )} +

      +

      + {isEditing ? ( + + ) : ( + "USh 2,000,000" + )} +

      +
      + Condition: + {isEditing ? ( + + ) : ( + "New" + )} +
      +
      + Quantity: + {isEditing ? ( + + ) : ( + "1" + )} +
      +

      + {isEditing ? ( +

    NameJobProduct Price Quantity