diff --git a/app/lib/definitions.ts b/app/lib/definitions.ts index 824bc5f..5c008c9 100644 --- a/app/lib/definitions.ts +++ b/app/lib/definitions.ts @@ -1,23 +1,5 @@ /* Copyright (C) 2024 Manuel Bustillo*/ -// This file contains type definitions for your data. -// It describes the shape of the data, and what data type each property should accept. -// For simplicity of teaching, we're manually defining these types. -// However, these types are generated automatically if you're using an ORM such as Prisma. -export type User = { - id: string; - name: string; - email: string; - password: string; -}; - -export type Customer = { - id: string; - name: string; - email: string; - image_url: string; -}; - export type GuestStatus = 'considered' | 'invited' | 'confirmed' | 'declined' | 'tentative'; export type Guest = { id?: string; @@ -62,34 +44,6 @@ export type AttendanceSummary = { total: number; } -export type Invoice = { - id: string; - customer_id: string; - amount: number; - date: string; - // In TypeScript, this is called a string union type. - // It means that the "status" property can only be one of the two strings: 'pending' or 'paid'. - status: 'pending' | 'paid'; -}; - -export type Revenue = { - month: string; - revenue: number; -}; - -export type LatestInvoice = { - id: string; - name: string; - image_url: string; - email: string; - amount: string; -}; - -// The database returns a number for amount, but we later format it to a string with the formatCurrency function -export type LatestInvoiceRaw = Omit & { - amount: number; -}; - export type guestsTable = { id: string; customer_id: string; @@ -100,35 +54,3 @@ export type guestsTable = { amount: number; status: 'pending' | 'paid'; }; - -export type CustomersTableType = { - id: string; - name: string; - email: string; - image_url: string; - total_guests: number; - total_pending: number; - total_paid: number; -}; - -export type FormattedCustomersTable = { - id: string; - name: string; - email: string; - image_url: string; - total_guests: number; - total_pending: string; - total_paid: string; -}; - -export type CustomerField = { - id: string; - name: string; -}; - -export type InvoiceForm = { - id: string; - customer_id: string; - amount: number; - status: 'pending' | 'paid'; -}; diff --git a/app/lib/placeholder-data.ts b/app/lib/placeholder-data.ts deleted file mode 100644 index 2d78faa..0000000 --- a/app/lib/placeholder-data.ts +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -// This file contains placeholder data that you'll be replacing with real data in the Data Fetching chapter: -// https://nextjs.org/learn/dashboard-app/fetching-data -const users = [ - { - id: '410544b2-4001-4271-9855-fec4b6a6442a', - name: 'User', - email: 'user@nextmail.com', - password: '123456', - }, -]; - -const customers = [ - { - id: 'd6e15727-9fe1-4961-8c5b-ea44a9bd81aa', - name: 'Evil Rabbit', - email: 'evil@rabbit.com', - image_url: '/customers/evil-rabbit.png', - }, - { - id: '3958dc9e-712f-4377-85e9-fec4b6a6442a', - name: 'Delba de Oliveira', - email: 'delba@oliveira.com', - image_url: '/customers/delba-de-oliveira.png', - }, - { - id: '3958dc9e-742f-4377-85e9-fec4b6a6442a', - name: 'Lee Robinson', - email: 'lee@robinson.com', - image_url: '/customers/lee-robinson.png', - }, - { - id: '76d65c26-f784-44a2-ac19-586678f7c2f2', - name: 'Michael Novotny', - email: 'michael@novotny.com', - image_url: '/customers/michael-novotny.png', - }, - { - id: 'CC27C14A-0ACF-4F4A-A6C9-D45682C144B9', - name: 'Amy Burns', - email: 'amy@burns.com', - image_url: '/customers/amy-burns.png', - }, - { - id: '13D07535-C59E-4157-A011-F8D2EF4E0CBB', - name: 'Balazs Orban', - email: 'balazs@orban.com', - image_url: '/customers/balazs-orban.png', - }, -]; - -const guests = [ - { - customer_id: customers[0].id, - amount: 15795, - status: 'pending', - date: '2022-12-06', - }, - { - customer_id: customers[1].id, - amount: 20348, - status: 'pending', - date: '2022-11-14', - }, - { - customer_id: customers[4].id, - amount: 3040, - status: 'paid', - date: '2022-10-29', - }, - { - customer_id: customers[3].id, - amount: 44800, - status: 'paid', - date: '2023-09-10', - }, - { - customer_id: customers[5].id, - amount: 34577, - status: 'pending', - date: '2023-08-05', - }, - { - customer_id: customers[2].id, - amount: 54246, - status: 'pending', - date: '2023-07-16', - }, - { - customer_id: customers[0].id, - amount: 666, - status: 'pending', - date: '2023-06-27', - }, - { - customer_id: customers[3].id, - amount: 32545, - status: 'paid', - date: '2023-06-09', - }, - { - customer_id: customers[4].id, - amount: 1250, - status: 'paid', - date: '2023-06-17', - }, - { - customer_id: customers[5].id, - amount: 8546, - status: 'paid', - date: '2023-06-07', - }, - { - customer_id: customers[1].id, - amount: 500, - status: 'paid', - date: '2023-08-19', - }, - { - customer_id: customers[5].id, - amount: 8945, - status: 'paid', - date: '2023-06-03', - }, - { - customer_id: customers[2].id, - amount: 1000, - status: 'paid', - date: '2022-06-05', - }, -]; - -const revenue = [ - { month: 'Jan', revenue: 2000 }, - { month: 'Feb', revenue: 1800 }, - { month: 'Mar', revenue: 2200 }, - { month: 'Apr', revenue: 2500 }, - { month: 'May', revenue: 2300 }, - { month: 'Jun', revenue: 3200 }, - { month: 'Jul', revenue: 3500 }, - { month: 'Aug', revenue: 3700 }, - { month: 'Sep', revenue: 2500 }, - { month: 'Oct', revenue: 2800 }, - { month: 'Nov', revenue: 3000 }, - { month: 'Dec', revenue: 4800 }, -]; - -export { users, customers, guests, revenue }; diff --git a/app/seed/route.ts b/app/seed/route.ts deleted file mode 100644 index db632cd..0000000 --- a/app/seed/route.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -// import bcrypt from 'bcrypt'; -// import { db } from '@vercel/postgres'; -// import { guests, customers, revenue, users } from '../lib/placeholder-data'; - -// const client = await db.connect(); - -// async function seedUsers() { -// await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`; -// await client.sql` -// CREATE TABLE IF NOT EXISTS users ( -// id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, -// name VARCHAR(255) NOT NULL, -// email TEXT NOT NULL UNIQUE, -// password TEXT NOT NULL -// ); -// `; - -// const insertedUsers = await Promise.all( -// users.map(async (user) => { -// const hashedPassword = await bcrypt.hash(user.password, 10); -// return client.sql` -// INSERT INTO users (id, name, email, password) -// VALUES (${user.id}, ${user.name}, ${user.email}, ${hashedPassword}) -// ON CONFLICT (id) DO NOTHING; -// `; -// }), -// ); - -// return insertedUsers; -// } - -// async function seedguests() { -// await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`; - -// await client.sql` -// CREATE TABLE IF NOT EXISTS guests ( -// id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, -// customer_id UUID NOT NULL, -// amount INT NOT NULL, -// status VARCHAR(255) NOT NULL, -// date DATE NOT NULL -// ); -// `; - -// const insertedguests = await Promise.all( -// guests.map( -// (invoice) => client.sql` -// INSERT INTO guests (customer_id, amount, status, date) -// VALUES (${invoice.customer_id}, ${invoice.amount}, ${invoice.status}, ${invoice.date}) -// ON CONFLICT (id) DO NOTHING; -// `, -// ), -// ); - -// return insertedguests; -// } - -// async function seedCustomers() { -// await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`; - -// await client.sql` -// CREATE TABLE IF NOT EXISTS customers ( -// id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, -// name VARCHAR(255) NOT NULL, -// email VARCHAR(255) NOT NULL, -// image_url VARCHAR(255) NOT NULL -// ); -// `; - -// const insertedCustomers = await Promise.all( -// customers.map( -// (customer) => client.sql` -// INSERT INTO customers (id, name, email, image_url) -// VALUES (${customer.id}, ${customer.name}, ${customer.email}, ${customer.image_url}) -// ON CONFLICT (id) DO NOTHING; -// `, -// ), -// ); - -// return insertedCustomers; -// } - -// async function seedRevenue() { -// await client.sql` -// CREATE TABLE IF NOT EXISTS revenue ( -// month VARCHAR(4) NOT NULL UNIQUE, -// revenue INT NOT NULL -// ); -// `; - -// const insertedRevenue = await Promise.all( -// revenue.map( -// (rev) => client.sql` -// INSERT INTO revenue (month, revenue) -// VALUES (${rev.month}, ${rev.revenue}) -// ON CONFLICT (month) DO NOTHING; -// `, -// ), -// ); - -// return insertedRevenue; -// } - -export async function GET() { - return Response.json({ - message: - 'Uncomment this file and remove this line. You can delete this file when you are finished.', - }); - // try { - // await client.sql`BEGIN`; - // await seedUsers(); - // await seedCustomers(); - // await seedguests(); - // await seedRevenue(); - // await client.sql`COMMIT`; - - // return Response.json({ message: 'Database seeded successfully' }); - // } catch (error) { - // await client.sql`ROLLBACK`; - // return Response.json({ error }, { status: 500 }); - // } -} diff --git a/app/ui/customers/table.tsx b/app/ui/customers/table.tsx deleted file mode 100644 index 6a41e3f..0000000 --- a/app/ui/customers/table.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import Image from 'next/image'; -import { lusitana } from '@/app/ui/fonts'; -import Search from '@/app/ui/search'; -import { - CustomersTableType, - FormattedCustomersTable, -} from '@/app/lib/definitions'; - -export default async function CustomersTable({ - customers, -}: { - customers: FormattedCustomersTable[]; -}) { - return ( -
-

- Customers -

- -
-
-
-
-
- {customers?.map((customer) => ( -
-
-
-
-
- {`${customer.name}'s -

{customer.name}

-
-
-

- {customer.email} -

-
-
-
-
-

Pending

-

{customer.total_pending}

-
-
-

Paid

-

{customer.total_paid}

-
-
-
-

{customer.total_guests} guests

-
-
- ))} -
- - - - - - - - - - - - - {customers.map((customer) => ( - - - - - - - - ))} - -
- Name - - Email - - Total guests - - Total Pending - - Total Paid -
-
- {`${customer.name}'s -

{customer.name}

-
-
- {customer.email} - - {customer.total_guests} - - {customer.total_pending} - - {customer.total_paid} -
-
-
-
-
-
- ); -} diff --git a/app/ui/dashboard/cards.tsx b/app/ui/dashboard/cards.tsx deleted file mode 100644 index 687043c..0000000 --- a/app/ui/dashboard/cards.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { - BanknotesIcon, - ClockIcon, - UserGroupIcon, - InboxIcon, -} from '@heroicons/react/24/outline'; -import { lusitana } from '@/app/ui/fonts'; - -const iconMap = { - collected: BanknotesIcon, - customers: UserGroupIcon, - pending: ClockIcon, - guests: InboxIcon, -}; - -export default async function CardWrapper() { - return ( - <> - {/* NOTE: Uncomment this code in Chapter 9 */} - - {/* - - - */} - - ); -} - -export function Card({ - title, - value, - type, -}: { - title: string; - value: number | string; - type: 'guests' | 'customers' | 'pending' | 'collected'; -}) { - const Icon = iconMap[type]; - - return ( -
-
- {Icon ? : null} -

{title}

-
-

- {value} -

-
- ); -} diff --git a/app/ui/dashboard/latest-invoices.tsx b/app/ui/dashboard/latest-invoices.tsx deleted file mode 100644 index 7c668e9..0000000 --- a/app/ui/dashboard/latest-invoices.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { ArrowPathIcon } from '@heroicons/react/24/outline'; -import clsx from 'clsx'; -import Image from 'next/image'; -import { lusitana } from '@/app/ui/fonts'; -import { LatestInvoice } from '@/app/lib/definitions'; -export default async function Latestguests({ - latestguests, -}: { - latestguests: LatestInvoice[]; -}) { - return ( -
-

- Latest guests -

-
- {/* NOTE: Uncomment this code in Chapter 7 */} - - {/*
- {latestguests.map((invoice, i) => { - return ( -
-
- {`${invoice.name}'s -
-

- {invoice.name} -

-

- {invoice.email} -

-
-
-

- {invoice.amount} -

-
- ); - })} -
*/} -
- -

Updated just now

-
-
-
- ); -} diff --git a/app/ui/dashboard/revenue-chart.tsx b/app/ui/dashboard/revenue-chart.tsx deleted file mode 100644 index 023e61d..0000000 --- a/app/ui/dashboard/revenue-chart.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { generateYAxis } from '@/app/lib/utils'; -import { CalendarIcon } from '@heroicons/react/24/outline'; -import { lusitana } from '@/app/ui/fonts'; -import { Revenue } from '@/app/lib/definitions'; - -// This component is representational only. -// For data visualization UI, check out: -// https://www.tremor.so/ -// https://www.chartjs.org/ -// https://airbnb.io/visx/ - -export default async function RevenueChart({ - revenue, -}: { - revenue: Revenue[]; -}) { - const chartHeight = 350; - // NOTE: Uncomment this code in Chapter 7 - - // const { yAxisLabels, topLabel } = generateYAxis(revenue); - - // if (!revenue || revenue.length === 0) { - // return

No data available.

; - // } - - return ( -
-

- Recent Revenue -

- {/* NOTE: Uncomment this code in Chapter 7 */} - - {/*
-
-
- {yAxisLabels.map((label) => ( -

{label}

- ))} -
- - {revenue.map((month) => ( -
-
-

- {month.month} -

-
- ))} -
-
- -

Last 12 months

-
-
*/} -
- ); -} diff --git a/app/ui/guests/breadcrumbs.tsx b/app/ui/guests/breadcrumbs.tsx deleted file mode 100644 index 828a614..0000000 --- a/app/ui/guests/breadcrumbs.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { clsx } from 'clsx'; -import Link from 'next/link'; -import { lusitana } from '@/app/ui/fonts'; - -interface Breadcrumb { - label: string; - href: string; - active?: boolean; -} - -export default function Breadcrumbs({ - breadcrumbs, -}: { - breadcrumbs: Breadcrumb[]; -}) { - return ( - - ); -} diff --git a/app/ui/guests/buttons.tsx b/app/ui/guests/buttons.tsx deleted file mode 100644 index d4e2183..0000000 --- a/app/ui/guests/buttons.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/outline'; -import Link from 'next/link'; - -export function CreateInvoice() { - return ( - - Create Invoice{' '} - - - ); -} - -export function UpdateInvoice({ id }: { id: string }) { - return ( - - - - ); -} - -export function DeleteInvoice({ id }: { id: string }) { - return ( - <> - - - ); -} diff --git a/app/ui/guests/create-form.tsx b/app/ui/guests/create-form.tsx deleted file mode 100644 index d66a259..0000000 --- a/app/ui/guests/create-form.tsx +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { CustomerField } from '@/app/lib/definitions'; -import Link from 'next/link'; -import { - CheckIcon, - ClockIcon, - CurrencyDollarIcon, - UserCircleIcon, -} from '@heroicons/react/24/outline'; -import { Button } from '@/app/ui/button'; - -export default function Form({ customers }: { customers: CustomerField[] }) { - return ( -
-
- {/* Customer Name */} -
- -
- - -
-
- - {/* Invoice Amount */} -
- -
-
- - -
-
-
- - {/* Invoice Status */} -
- - Set the invoice status - -
-
-
- - -
-
- - -
-
-
-
-
-
- - Cancel - - -
-
- ); -} diff --git a/app/ui/guests/edit-form.tsx b/app/ui/guests/edit-form.tsx deleted file mode 100644 index d71a275..0000000 --- a/app/ui/guests/edit-form.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -'use client'; - -import { CustomerField, InvoiceForm } from '@/app/lib/definitions'; -import { - CheckIcon, - ClockIcon, - CurrencyDollarIcon, - UserCircleIcon, -} from '@heroicons/react/24/outline'; -import Link from 'next/link'; -import { Button } from '@/app/ui/button'; - -export default function EditInvoiceForm({ - invoice, - customers, -}: { - invoice: InvoiceForm; - customers: CustomerField[]; -}) { - return ( -
-
- {/* Customer Name */} -
- -
- - -
-
- - {/* Invoice Amount */} -
- -
-
- - -
-
-
- - {/* Invoice Status */} -
- - Set the invoice status - -
-
-
- - -
-
- - -
-
-
-
-
-
- - Cancel - - -
-
- ); -} diff --git a/app/ui/guests/pagination.tsx b/app/ui/guests/pagination.tsx deleted file mode 100644 index 42488ae..0000000 --- a/app/ui/guests/pagination.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -'use client'; - -import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/outline'; -import clsx from 'clsx'; -import Link from 'next/link'; -import { generatePagination } from '@/app/lib/utils'; - -export default function Pagination({ totalPages }: { totalPages: number }) { - // NOTE: Uncomment this code in Chapter 11 - - // const allPages = generatePagination(currentPage, totalPages); - - return ( - <> - {/* NOTE: Uncomment this code in Chapter 11 */} - - {/*
- - -
- {allPages.map((page, index) => { - let position: 'first' | 'last' | 'single' | 'middle' | undefined; - - if (index === 0) position = 'first'; - if (index === allPages.length - 1) position = 'last'; - if (allPages.length === 1) position = 'single'; - if (page === '...') position = 'middle'; - - return ( - - ); - })} -
- - = totalPages} - /> -
*/} - - ); -} - -function PaginationNumber({ - page, - href, - isActive, - position, -}: { - page: number | string; - href: string; - position?: 'first' | 'last' | 'middle' | 'single'; - isActive: boolean; -}) { - const className = clsx( - 'flex h-10 w-10 items-center justify-center text-sm border', - { - 'rounded-l-md': position === 'first' || position === 'single', - 'rounded-r-md': position === 'last' || position === 'single', - 'z-10 bg-blue-600 border-blue-600 text-white': isActive, - 'hover:bg-gray-100': !isActive && position !== 'middle', - 'text-gray-300': position === 'middle', - }, - ); - - return isActive || position === 'middle' ? ( -
{page}
- ) : ( - - {page} - - ); -} - -function PaginationArrow({ - href, - direction, - isDisabled, -}: { - href: string; - direction: 'left' | 'right'; - isDisabled?: boolean; -}) { - const className = clsx( - 'flex h-10 w-10 items-center justify-center rounded-md border', - { - 'pointer-events-none text-gray-300': isDisabled, - 'hover:bg-gray-100': !isDisabled, - 'mr-2 md:mr-4': direction === 'left', - 'ml-2 md:ml-4': direction === 'right', - }, - ); - - const icon = - direction === 'left' ? ( - - ) : ( - - ); - - return isDisabled ? ( -
{icon}
- ) : ( - - {icon} - - ); -} diff --git a/app/ui/guests/status.tsx b/app/ui/guests/status.tsx deleted file mode 100644 index f8a3a78..0000000 --- a/app/ui/guests/status.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { CheckIcon, ClockIcon } from '@heroicons/react/24/outline'; -import clsx from 'clsx'; - -export default function gueststatus({ status }: { status: string }) { - return ( - - {status === 'pending' ? ( - <> - Pending - - - ) : null} - {status === 'paid' ? ( - <> - Paid - - - ) : null} - - ); -} diff --git a/app/ui/login-form.tsx b/app/ui/login-form.tsx deleted file mode 100644 index 6e6241e..0000000 --- a/app/ui/login-form.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2024 Manuel Bustillo*/ - -import { lusitana } from '@/app/ui/fonts'; -import { - AtSymbolIcon, - KeyIcon, - ExclamationCircleIcon, -} from '@heroicons/react/24/outline'; -import { ArrowRightIcon } from '@heroicons/react/20/solid'; -import { Button } from './button'; - -export default function LoginForm() { - return ( -
-
-

- Please log in to continue. -

-
-
- -
- - -
-
-
- -
- - -
-
-
- -
- {/* Add form errors here */} -
-
-
- ); -} diff --git a/public/customers/amy-burns.png b/public/customers/amy-burns.png deleted file mode 100644 index 7b29d72..0000000 Binary files a/public/customers/amy-burns.png and /dev/null differ diff --git a/public/customers/balazs-orban.png b/public/customers/balazs-orban.png deleted file mode 100644 index 7fbc009..0000000 Binary files a/public/customers/balazs-orban.png and /dev/null differ diff --git a/public/customers/delba-de-oliveira.png b/public/customers/delba-de-oliveira.png deleted file mode 100644 index 08db1b8..0000000 Binary files a/public/customers/delba-de-oliveira.png and /dev/null differ diff --git a/public/customers/evil-rabbit.png b/public/customers/evil-rabbit.png deleted file mode 100644 index fe7990f..0000000 Binary files a/public/customers/evil-rabbit.png and /dev/null differ diff --git a/public/customers/lee-robinson.png b/public/customers/lee-robinson.png deleted file mode 100644 index 633ae98..0000000 Binary files a/public/customers/lee-robinson.png and /dev/null differ diff --git a/public/customers/michael-novotny.png b/public/customers/michael-novotny.png deleted file mode 100644 index 96a13a6..0000000 Binary files a/public/customers/michael-novotny.png and /dev/null differ