From b85b3e217bb3c614a4f58a212c6e33a243f35112 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:30:42 +0100 Subject: [PATCH] Add delete invoice functionality (#140) * Organize components * Add delete invoice component and action * Update customer emails * Add delete button, pending/paid UI, and placeholder edit button * Fix build errors * More errors --- .../app/dashboard/invoices/create/page.tsx | 2 +- .../15-final/app/dashboard/invoices/page.tsx | 4 +- dashboard/15-final/app/dashboard/layout.tsx | 6 +- dashboard/15-final/app/dashboard/page.tsx | 2 +- dashboard/15-final/app/lib/actions.tsx | 6 + dashboard/15-final/app/lib/dummy-data.tsx | 8 +- .../15-final/app/ui/{ => dashboard}/card.tsx | 0 .../ui/{ => dashboard}/latest-invoices.tsx | 0 .../overview.tsx} | 6 +- .../app/ui/{ => dashboard}/revenue-chart.tsx | 0 .../app/ui/{ => dashboard}/search.tsx | 0 .../sidenav.tsx} | 2 +- .../topnav.tsx} | 2 +- .../add-invoice-form.tsx} | 0 .../app/ui/invoices/delete-invoice-button.tsx | 18 +++ dashboard/15-final/app/ui/invoices/table.tsx | 132 ++++++++++++++++++ dashboard/15-final/app/ui/table.tsx | 75 ---------- dashboard/15-final/postcss.config.js | 2 +- 18 files changed, 173 insertions(+), 92 deletions(-) create mode 100644 dashboard/15-final/app/lib/actions.tsx rename dashboard/15-final/app/ui/{ => dashboard}/card.tsx (100%) rename dashboard/15-final/app/ui/{ => dashboard}/latest-invoices.tsx (100%) rename dashboard/15-final/app/ui/{dashboard-overview.tsx => dashboard/overview.tsx} (86%) rename dashboard/15-final/app/ui/{ => dashboard}/revenue-chart.tsx (100%) rename dashboard/15-final/app/ui/{ => dashboard}/search.tsx (100%) rename dashboard/15-final/app/ui/{dashboard-sidenav.tsx => dashboard/sidenav.tsx} (100%) rename dashboard/15-final/app/ui/{dashboard-topnav.tsx => dashboard/topnav.tsx} (73%) rename dashboard/15-final/app/ui/{invoice-form.tsx => invoices/add-invoice-form.tsx} (100%) create mode 100644 dashboard/15-final/app/ui/invoices/delete-invoice-button.tsx create mode 100644 dashboard/15-final/app/ui/invoices/table.tsx delete mode 100644 dashboard/15-final/app/ui/table.tsx diff --git a/dashboard/15-final/app/dashboard/invoices/create/page.tsx b/dashboard/15-final/app/dashboard/invoices/create/page.tsx index 754e94a..563cb0c 100644 --- a/dashboard/15-final/app/dashboard/invoices/create/page.tsx +++ b/dashboard/15-final/app/dashboard/invoices/create/page.tsx @@ -1,4 +1,4 @@ -import AddInvoiceForm from "@/app/ui/invoice-form"; +import AddInvoiceForm from "@/app/ui/invoices/add-invoice-form"; export default function Page() { return ; diff --git a/dashboard/15-final/app/dashboard/invoices/page.tsx b/dashboard/15-final/app/dashboard/invoices/page.tsx index dc34ed8..695f8b6 100644 --- a/dashboard/15-final/app/dashboard/invoices/page.tsx +++ b/dashboard/15-final/app/dashboard/invoices/page.tsx @@ -1,9 +1,9 @@ -import Table from "@/app/ui/table"; +import Table from "@/app/ui/invoices/table"; export default function Page() { return (
- ) + ); } diff --git a/dashboard/15-final/app/dashboard/layout.tsx b/dashboard/15-final/app/dashboard/layout.tsx index d4fd013..b657563 100644 --- a/dashboard/15-final/app/dashboard/layout.tsx +++ b/dashboard/15-final/app/dashboard/layout.tsx @@ -1,5 +1,5 @@ -import TopNav from "@/app/ui/dashboard-topnav"; -import SideNav from "../ui/dashboard-sidenav"; +import TopNav from "@/app/ui/dashboard/topnav"; +import SideNav from "@/app/ui/dashboard/sidenav"; export default function Layout({ children }: { children: React.ReactNode }) { return ( @@ -13,4 +13,4 @@ export default function Layout({ children }: { children: React.ReactNode }) { ); -} \ No newline at end of file +} diff --git a/dashboard/15-final/app/dashboard/page.tsx b/dashboard/15-final/app/dashboard/page.tsx index f6953bf..848bf1b 100644 --- a/dashboard/15-final/app/dashboard/page.tsx +++ b/dashboard/15-final/app/dashboard/page.tsx @@ -1,4 +1,4 @@ -import DashboardOverview from "@/app/ui/dashboard-overview"; +import DashboardOverview from "@/app/ui/dashboard/overview"; export default function Page() { return ( diff --git a/dashboard/15-final/app/lib/actions.tsx b/dashboard/15-final/app/lib/actions.tsx new file mode 100644 index 0000000..efebdd6 --- /dev/null +++ b/dashboard/15-final/app/lib/actions.tsx @@ -0,0 +1,6 @@ +"use server"; + +export async function deleteInvoice(id: number) { + // TO DO: Add delete invoice logic + console.log("Delete invoice", id); +} diff --git a/dashboard/15-final/app/lib/dummy-data.tsx b/dashboard/15-final/app/lib/dummy-data.tsx index 3351802..40b6887 100644 --- a/dashboard/15-final/app/lib/dummy-data.tsx +++ b/dashboard/15-final/app/lib/dummy-data.tsx @@ -14,25 +14,25 @@ export const customers: Customer[] = [ { id: 1, name: "Ada Lovelace", - email: "ada@earlycomputing.com", + email: "ada@lovelace.com", imageUrl: "/customers/ada-lovelace.png", }, { id: 2, name: "Grace Hopper", - email: "grace@personalcomputers.com", + email: "grace@hopper.com", imageUrl: "/customers/grace-hopper.png", }, { id: 3, name: "Hedy Lammar", - email: "hedy@wifi.com", + email: "hedy@lammar.com", imageUrl: "/customers/hedy-lammar.png", }, { id: 4, name: "Margaret Hamilton", - email: "margaret@nasa.com", + email: "margaret@hamilton.com", imageUrl: "/customers/margaret-hamilton.png", }, ]; diff --git a/dashboard/15-final/app/ui/card.tsx b/dashboard/15-final/app/ui/dashboard/card.tsx similarity index 100% rename from dashboard/15-final/app/ui/card.tsx rename to dashboard/15-final/app/ui/dashboard/card.tsx diff --git a/dashboard/15-final/app/ui/latest-invoices.tsx b/dashboard/15-final/app/ui/dashboard/latest-invoices.tsx similarity index 100% rename from dashboard/15-final/app/ui/latest-invoices.tsx rename to dashboard/15-final/app/ui/dashboard/latest-invoices.tsx diff --git a/dashboard/15-final/app/ui/dashboard-overview.tsx b/dashboard/15-final/app/ui/dashboard/overview.tsx similarity index 86% rename from dashboard/15-final/app/ui/dashboard-overview.tsx rename to dashboard/15-final/app/ui/dashboard/overview.tsx index 9065ba9..8ff64e0 100644 --- a/dashboard/15-final/app/ui/dashboard-overview.tsx +++ b/dashboard/15-final/app/ui/dashboard/overview.tsx @@ -1,8 +1,8 @@ -import Card from "@/app/ui/card"; +import Card from "@/app/ui/dashboard/card"; import { invoices, customers, revenue } from "@/app/lib/dummy-data"; import { calculateInvoices } from "@/app/lib/calculations"; -import RevenueChart from "@/app/ui/revenue-chart"; -import LatestInvoices from "@/app/ui/latest-invoices"; +import RevenueChart from "@/app/ui/dashboard/revenue-chart"; +import LatestInvoices from "@/app/ui/dashboard/latest-invoices"; export default function DashboardOverview() { const totalPaidInvoices = calculateInvoices(invoices, "paid"); diff --git a/dashboard/15-final/app/ui/revenue-chart.tsx b/dashboard/15-final/app/ui/dashboard/revenue-chart.tsx similarity index 100% rename from dashboard/15-final/app/ui/revenue-chart.tsx rename to dashboard/15-final/app/ui/dashboard/revenue-chart.tsx diff --git a/dashboard/15-final/app/ui/search.tsx b/dashboard/15-final/app/ui/dashboard/search.tsx similarity index 100% rename from dashboard/15-final/app/ui/search.tsx rename to dashboard/15-final/app/ui/dashboard/search.tsx diff --git a/dashboard/15-final/app/ui/dashboard-sidenav.tsx b/dashboard/15-final/app/ui/dashboard/sidenav.tsx similarity index 100% rename from dashboard/15-final/app/ui/dashboard-sidenav.tsx rename to dashboard/15-final/app/ui/dashboard/sidenav.tsx index 8da66e0..2c43d65 100644 --- a/dashboard/15-final/app/ui/dashboard-sidenav.tsx +++ b/dashboard/15-final/app/ui/dashboard/sidenav.tsx @@ -17,8 +17,8 @@ export default function SideNav() { const tabs = [ { name: "Home", href: "/dashboard", icon: HomeIcon }, - { name: "Customers", href: "/dashboard/customers", icon: UserGroupIcon }, { name: "Invoices", href: "/dashboard/invoices", icon: InboxIcon }, + { name: "Customers", href: "/dashboard/customers", icon: UserGroupIcon }, ]; return ( diff --git a/dashboard/15-final/app/ui/dashboard-topnav.tsx b/dashboard/15-final/app/ui/dashboard/topnav.tsx similarity index 73% rename from dashboard/15-final/app/ui/dashboard-topnav.tsx rename to dashboard/15-final/app/ui/dashboard/topnav.tsx index d5f95eb..485a697 100644 --- a/dashboard/15-final/app/ui/dashboard-topnav.tsx +++ b/dashboard/15-final/app/ui/dashboard/topnav.tsx @@ -1,4 +1,4 @@ -import Search from "./search"; +import Search from "@/app/ui/dashboard/search"; export default function TopNav() { return ( diff --git a/dashboard/15-final/app/ui/invoice-form.tsx b/dashboard/15-final/app/ui/invoices/add-invoice-form.tsx similarity index 100% rename from dashboard/15-final/app/ui/invoice-form.tsx rename to dashboard/15-final/app/ui/invoices/add-invoice-form.tsx diff --git a/dashboard/15-final/app/ui/invoices/delete-invoice-button.tsx b/dashboard/15-final/app/ui/invoices/delete-invoice-button.tsx new file mode 100644 index 0000000..2b271f4 --- /dev/null +++ b/dashboard/15-final/app/ui/invoices/delete-invoice-button.tsx @@ -0,0 +1,18 @@ +"use client"; + +import { TrashIcon } from "@heroicons/react/24/outline"; +import { useTransition } from "react"; +import { deleteInvoice } from "@/app/lib/actions"; + +export default function DeleteInvoice({ id }: { id: number }) { + const [isPending, startTransition] = useTransition(); + + return ( + + ); +} diff --git a/dashboard/15-final/app/ui/invoices/table.tsx b/dashboard/15-final/app/ui/invoices/table.tsx new file mode 100644 index 0000000..53964bb --- /dev/null +++ b/dashboard/15-final/app/ui/invoices/table.tsx @@ -0,0 +1,132 @@ +import { invoices, customers } from "@/app/lib/dummy-data"; +import { Customer } from "@/app/lib/definitions"; +import Link from "next/link"; +import { + PencilSquareIcon, + ClockIcon, + CheckCircleIcon, +} from "@heroicons/react/24/outline"; +import DeleteInvoice from "@/app/ui/invoices/delete-invoice-button"; + +function renderInvoiceStatus(status: string) { + if (status === "pending") { + return ( + + + Pending + + ); + } else { + return ( + + + Paid + + ); + } +} + +export default function Table() { + function getCustomerById(customerId: number): Customer | null { + const customer = customers.find((customer) => customer.id === customerId); + return customer ? customer : null; + } + + return ( +
+
+

Invoices

+ + Add Invoice + +
+
+
+
+
+ + + + + + + + + + + {/* */} + + + + {invoices.map((invoice) => ( + + + + + + + + + {/* */} + + ))} + +
+ # + + Customer + + Email + + Amount + + Date + + Status + + Edit + + View +
+ {invoice.id} + +
+ +

{getCustomerById(invoice.customerId)?.name}

+
+
+ {getCustomerById(invoice.customerId)?.email} + + {(invoice.amount / 100).toLocaleString("en-US", { + style: "currency", + currency: "USD", + })} + + {invoice.date} + + {renderInvoiceStatus(invoice.status)} + + + + + + View, {invoice.id} + +
+
+ + + + ); +} diff --git a/dashboard/15-final/app/ui/table.tsx b/dashboard/15-final/app/ui/table.tsx deleted file mode 100644 index 3b05a22..0000000 --- a/dashboard/15-final/app/ui/table.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import {invoices, customers} from "../lib/dummy-data"; -import Link from "next/link"; - -export default function Example() { - function getNameById(customerId: number) { - const customerName = customers.find(customer => customer.id === customerId); - return customerName ? customerName.name : null; - } - - return ( -
-
-

Invoices

- - Add Invoice - -
-
-
-
- - - - - - - - - - - - - {invoices.map((invoice) => ( - - - - - - - - - ))} - -
- ID - - Customer Name - - Amount - - Status - - Date - - View -
- {invoice.id} - {getNameById(invoice.customerId)}{invoice.amount.toLocaleString("en-US", {style: "currency", currency: "USD"})}{invoice.status}{invoice.date} - - View, {invoice.id} - -
-
-
-
-
- ) -} - - - - diff --git a/dashboard/15-final/postcss.config.js b/dashboard/15-final/postcss.config.js index 33ad091..12a703d 100644 --- a/dashboard/15-final/postcss.config.js +++ b/dashboard/15-final/postcss.config.js @@ -3,4 +3,4 @@ module.exports = { tailwindcss: {}, autoprefixer: {}, }, -} +};