From 342ceca5888ed6e0f7eeccbc2bc170182935dd42 Mon Sep 17 00:00:00 2001 From: Jeremiah Chienda Date: Fri, 18 Oct 2024 02:14:27 +0200 Subject: [PATCH] clean up crud interface --- app/@types/contributors.d.ts | 31 + app/@types/index.d.ts | 34 +- app/auth/README.md | 1 + app/components/atoms/contributors/detail.tsx | 2 +- app/components/blocks/crud-list.tsx | 44 + app/components/blocks/data-table.tsx | 190 +++ app/components/blocks/date-range-picker.tsx | 316 ++--- app/components/blocks/layout-header.tsx | 188 +-- app/components/blocks/sidebar.tsx | 256 ++-- app/components/blocks/transactions-table.tsx | 144 --- app/components/contributions/columns.tsx | 141 --- app/components/contributions/data-table.tsx | 189 --- app/components/contributions/data.ts | 1107 ----------------- app/components/layouts/MainLayout.tsx | 34 +- app/data/contributors.ts | 8 - app/data/contributors/contributors-summary.ts | 8 + app/data/contributors/data.ts | 227 ++++ app/{ => data}/db/dummy-data.ts | 0 app/{ => data}/db/index.ts | 0 app/{ => data}/db/migrate.ts | 0 app/{ => data}/db/schema.ts | 0 app/{ => data}/db/seed.ts | 0 app/{ => data}/db/utils.ts | 0 app/routes/_index/Dashboard.tsx | 92 -- app/routes/_index/components/dashboard.tsx | 92 ++ .../_index/components}/recent-salse.tsx | 0 .../_index/components/transactions-table.tsx | 156 +++ app/routes/_index/route.tsx | 24 +- app/routes/contributors.$id.edit/route.tsx | 4 + app/routes/contributors.$id.view/route.tsx | 4 + app/routes/contributors.create/route.tsx | 4 + .../contributors/components/columns.tsx | 140 +++ app/routes/contributors/route.tsx | 73 +- .../contributors/contributor-service.ts | 32 + 34 files changed, 1428 insertions(+), 2113 deletions(-) create mode 100644 app/@types/contributors.d.ts create mode 100644 app/auth/README.md create mode 100644 app/components/blocks/crud-list.tsx create mode 100644 app/components/blocks/data-table.tsx delete mode 100644 app/components/blocks/transactions-table.tsx delete mode 100644 app/components/contributions/columns.tsx delete mode 100644 app/components/contributions/data.ts delete mode 100644 app/data/contributors.ts create mode 100644 app/data/contributors/contributors-summary.ts create mode 100644 app/data/contributors/data.ts rename app/{ => data}/db/dummy-data.ts (100%) rename app/{ => data}/db/index.ts (100%) rename app/{ => data}/db/migrate.ts (100%) rename app/{ => data}/db/schema.ts (100%) rename app/{ => data}/db/seed.ts (100%) rename app/{ => data}/db/utils.ts (100%) delete mode 100644 app/routes/_index/Dashboard.tsx create mode 100644 app/routes/_index/components/dashboard.tsx rename app/{components/blocks => routes/_index/components}/recent-salse.tsx (100%) create mode 100644 app/routes/_index/components/transactions-table.tsx create mode 100644 app/routes/contributors.$id.edit/route.tsx create mode 100644 app/routes/contributors.$id.view/route.tsx create mode 100644 app/routes/contributors.create/route.tsx create mode 100644 app/routes/contributors/components/columns.tsx create mode 100644 app/services/contributors/contributor-service.ts diff --git a/app/@types/contributors.d.ts b/app/@types/contributors.d.ts new file mode 100644 index 0000000..f52793c --- /dev/null +++ b/app/@types/contributors.d.ts @@ -0,0 +1,31 @@ +import { Identifiable } from '.'; + +export interface TPartialContributor extends Identifiable { + id: string; + firstName: string; + lastName: string; + email: string; + gender: string; + dependent: boolean; + contributionAmount: number; + contributiionMethod: 'monthly' | 'annual'; + dateJoined: Date; +} + +export interface TContributor extends Identifiable { + id: string; + firstName: string; + lastName: string; + email: string; + gender: string; + dependent: boolean; + contributionAmount: number; + contributiionMethod: 'monthly' | 'annual'; + dateJoined: Date; +} + +interface ContributorsDetailsProps { + title: string; + value: string; + color: string; +} diff --git a/app/@types/index.d.ts b/app/@types/index.d.ts index efe6255..29eda14 100644 --- a/app/@types/index.d.ts +++ b/app/@types/index.d.ts @@ -1,26 +1,20 @@ -import { LucideIcon } from "lucide-react"; +import { LucideIcon } from 'lucide-react'; -interface NavItemProps { - label: string; - icon: LucideIcon; - href: string; - children?: NavItemProps[]; +export interface Identifiable { + id: string; } -export interface TContributors { - id: string; - firstName: string; - lastName: string; - email: string; - gender: string; - dependent: boolean; - contributionAmount: number; - contributiionMethod: "monthly" | "annual"; - dateJoined: Date; +interface NavItemProps { + label: string; + icon: LucideIcon; + href: string; + children?: NavItemProps[]; } -interface ContributorsDetailsProps { - title: string; - value: string; - color: string; +export interface ICrudService { + getAll(): Promise; + getById(id: string): Promise; + create(item: Omit): Promise; + update(id: string, item: Partial): Promise; + delete(id: string): Promise; } diff --git a/app/auth/README.md b/app/auth/README.md new file mode 100644 index 0000000..286482e --- /dev/null +++ b/app/auth/README.md @@ -0,0 +1 @@ +# Welcome to Auth diff --git a/app/components/atoms/contributors/detail.tsx b/app/components/atoms/contributors/detail.tsx index 2b54115..83057a1 100644 --- a/app/components/atoms/contributors/detail.tsx +++ b/app/components/atoms/contributors/detail.tsx @@ -1,4 +1,4 @@ -import { ContributorsSummaryData } from '@/data/contributors'; +import { ContributorsSummaryData } from '@/data/contributors/contributors-summary'; export const ContributorsDetails = () => { return ( diff --git a/app/components/blocks/crud-list.tsx b/app/components/blocks/crud-list.tsx new file mode 100644 index 0000000..51dd731 --- /dev/null +++ b/app/components/blocks/crud-list.tsx @@ -0,0 +1,44 @@ +// /components/CrudList.tsx + +import React from 'react'; +import { Sheet, SheetContent } from '@/components/ui/sheet'; +import { useNavigate, useParams, useLocation, Outlet } from '@remix-run/react'; +import { ICrudService, Identifiable } from '@/@types'; +import { DataTable } from './data-table'; +import { ColumnDef } from '@tanstack/react-table'; + +interface CrudListProps { + columns: ColumnDef[]; + data: T[]; + baseRoute: string; +} + +export function CrudList< + T extends Identifiable, + TM extends Identifiable, + TS extends ICrudService +>({ columns, data, baseRoute }: CrudListProps) { + const navigate = useNavigate(); + const location = useLocation(); + const { id } = useParams(); + + const isSheetOpen = + location.pathname.includes('/create') || + location.pathname.includes('/edit') || + location.pathname.includes('/view'); + + const handleClose = () => { + navigate(baseRoute); + }; + + return ( +
+ + + + + + +
+ ); +} diff --git a/app/components/blocks/data-table.tsx b/app/components/blocks/data-table.tsx new file mode 100644 index 0000000..e8c5972 --- /dev/null +++ b/app/components/blocks/data-table.tsx @@ -0,0 +1,190 @@ +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +import { + ColumnDef, + ColumnFiltersState, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import { Button } from "../ui/button"; +import { useState } from "react"; +import { Input } from "../ui/input"; +import { exportTableToCSV } from "@/lib/xlsx"; + +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export function DataTable({ + columns, + data, +}: DataTableProps) { + const [sorting, setSorting] = useState([]); + const [columnFilters, setColumnFilters] = useState([]); + const [rowSelection, setRowSelection] = useState({}); + const [columnVisibility, setColumnVisibility] = useState({}); + console.log(rowSelection); + + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + onRowSelectionChange: setRowSelection, + + state: { + sorting, + columnFilters, + columnVisibility, + rowSelection, + }, + }); + + return ( +
+
+ + table.getColumn("first_name")?.setFilterValue(event.target.value) + } + className="max-w-sm" + /> + + + + + + + {table + .getAllColumns() + .filter((column) => column.getCanHide()) + .map((column) => { + return ( + + column.toggleVisibility(!!value) + } + > + {column.id} + + ); + })} + + +
+ {/* table */} +
+ + + {table.getHeaderGroups().map((headerGroup) => { + return ( + + {headerGroup.headers.map((header) => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ); + })} + + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + No results + + )} + +
+
+ {/* pagination */} +
+ + +
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected +
+
+ ); +} diff --git a/app/components/blocks/date-range-picker.tsx b/app/components/blocks/date-range-picker.tsx index 6a3a2e5..b93f859 100644 --- a/app/components/blocks/date-range-picker.tsx +++ b/app/components/blocks/date-range-picker.tsx @@ -1,174 +1,174 @@ -"use client"; +'use client'; -import * as React from "react"; -import { useLocation } from "react-router-dom"; -import { Link, useNavigation } from "react-router-dom"; -import { redirect } from "@remix-run/react"; -import { useSearchParams } from "react-router-dom"; +import * as React from 'react'; +import { Link, redirect, useLocation, useNavigation } from '@remix-run/react'; -import { CalendarIcon } from "@radix-ui/react-icons"; -import { addDays, format } from "date-fns"; -import type { DateRange } from "react-day-picker"; +import { CalendarIcon } from '@radix-ui/react-icons'; +import { addDays, format } from 'date-fns'; +import type { DateRange } from 'react-day-picker'; -import { cn } from "@/lib/styles"; -import { Button, type ButtonProps } from "@/components/ui/button"; -import { Calendar } from "@/components/ui/calendar"; +import { cn } from '@/lib/styles'; +import { Button, type ButtonProps } from '@/components/ui/button'; +import { Calendar } from '@/components/ui/calendar'; import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; + Popover, + PopoverContent, + PopoverTrigger, +} from '@/components/ui/popover'; interface DateRangePickerProps - extends React.ComponentPropsWithoutRef { - /** - * The selected date range. - * @default undefined - * @type DateRange - * @example { from: new Date(), to: new Date() } - */ - dateRange?: DateRange; - - /** - * The number of days to display in the date range picker. - * @default undefined - * @type number - * @example 7 - */ - dayCount?: number; - - /** - * The placeholder text of the calendar trigger button. - * @default "Pick a date" - * @type string | undefined - */ - placeholder?: string; - - /** - * The variant of the calendar trigger button. - * @default "outline" - * @type "default" | "outline" | "secondary" | "ghost" - */ - triggerVariant?: Exclude; - - /** - * The size of the calendar trigger button. - * @default "default" - * @type "default" | "sm" | "lg" - */ - triggerSize?: Exclude; - - /** - * The class name of the calendar trigger button. - * @default undefined - * @type string - */ - triggerClassName?: string; + extends React.ComponentPropsWithoutRef { + /** + * The selected date range. + * @default undefined + * @type DateRange + * @example { from: new Date(), to: new Date() } + */ + dateRange?: DateRange; + + /** + * The number of days to display in the date range picker. + * @default undefined + * @type number + * @example 7 + */ + dayCount?: number; + + /** + * The placeholder text of the calendar trigger button. + * @default "Pick a date" + * @type string | undefined + */ + placeholder?: string; + + /** + * The variant of the calendar trigger button. + * @default "outline" + * @type "default" | "outline" | "secondary" | "ghost" + */ + triggerVariant?: Exclude; + + /** + * The size of the calendar trigger button. + * @default "default" + * @type "default" | "sm" | "lg" + */ + triggerSize?: Exclude; + + /** + * The class name of the calendar trigger button. + * @default undefined + * @type string + */ + triggerClassName?: string; } export function DateRangePicker({ - dateRange, - dayCount, - placeholder = "Pick a date", - triggerVariant = "outline", - triggerSize = "default", - triggerClassName, - className, - ...props + dateRange, + dayCount, + placeholder = 'Pick a date', + triggerVariant = 'outline', + triggerSize = 'default', + triggerClassName, + className, + ...props }: DateRangePickerProps) { - const location = useLocation(); - const pathname = location.pathname; - const [searchParams, setSearchParams] = useSearchParams(); - const navigation = useNavigation(); - - if (navigation.state === "idle") { - return Go to About Page; - } - - if (navigation.state === "submitting") { - return

Redirecting...

; - } - - const [date, setDate] = React.useState(() => { - const fromParam = searchParams.get("from"); - const toParam = searchParams.get("to"); - - let fromDay: Date | undefined; - let toDay: Date | undefined; - - if (dateRange) { - fromDay = dateRange.from; - toDay = dateRange.to; - } else if (dayCount) { - toDay = new Date(); - fromDay = addDays(toDay, -dayCount); - } + const location = useLocation(); + const pathname = location.pathname; + const [searchParams, setSearchParams] = useSearchParams(); + const navigation = useNavigation(); - return { - from: fromParam ? new Date(fromParam) : fromDay, - to: toParam ? new Date(toParam) : toDay, - }; - }); - - // Update query string - React.useEffect(() => { - const newSearchParams = new URLSearchParams(searchParams); - if (date?.from) { - newSearchParams.set("from", format(date.from, "yyyy-MM-dd")); - } else { - newSearchParams.delete("from"); + if (navigation.state === 'idle') { + return Go to About Page; } - if (date?.to) { - newSearchParams.set("to", format(date.to, "yyyy-MM-dd")); - } else { - newSearchParams.delete("to"); + if (navigation.state === 'submitting') { + return

Redirecting...

; } - redirect(`${pathname}?${newSearchParams.toString()}`); - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [date?.from, date?.to]); - - return ( -
- - - - - - - - -
- ); + const [date, setDate] = React.useState(() => { + const fromParam = searchParams.get('from'); + const toParam = searchParams.get('to'); + + let fromDay: Date | undefined; + let toDay: Date | undefined; + + if (dateRange) { + fromDay = dateRange.from; + toDay = dateRange.to; + } else if (dayCount) { + toDay = new Date(); + fromDay = addDays(toDay, -dayCount); + } + + return { + from: fromParam ? new Date(fromParam) : fromDay, + to: toParam ? new Date(toParam) : toDay, + }; + }); + + // Update query string + React.useEffect(() => { + const newSearchParams = new URLSearchParams(searchParams); + if (date?.from) { + newSearchParams.set('from', format(date.from, 'yyyy-MM-dd')); + } else { + newSearchParams.delete('from'); + } + + if (date?.to) { + newSearchParams.set('to', format(date.to, 'yyyy-MM-dd')); + } else { + newSearchParams.delete('to'); + } + + redirect(`${pathname}?${newSearchParams.toString()}`); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [date?.from, date?.to]); + + return ( +
+ + + + + + + + +
+ ); } diff --git a/app/components/blocks/layout-header.tsx b/app/components/blocks/layout-header.tsx index 603443d..fb4d476 100644 --- a/app/components/blocks/layout-header.tsx +++ b/app/components/blocks/layout-header.tsx @@ -2,6 +2,8 @@ import { ChevronDown, Languages, LanguagesIcon, + EllipsisIcon, + MenuIcon, LaptopIcon, MoonIcon, SunIcon, @@ -29,12 +31,18 @@ interface LayoutHeaderProps { title?: string; action?: React.ReactNode; minimalSidebar?: boolean; + isTablet?: boolean; + isMobile?: boolean; + onToggleTabletMenu?: () => void; } const LayoutHeader = ({ title = 'Dashboard', action, minimalSidebar = false, + isTablet = false, + isMobile = false, + onToggleTabletMenu = () => {}, }: LayoutHeaderProps) => { const hydrated = useHydrated(); const [, rerender] = useState({}); @@ -44,6 +52,10 @@ const LayoutHeader = ({ }, []); const theme = getTheme(); const [language, setLanguage] = useState('🇺🇸 English'); + const showSubmenu = useCallback(() => { + //TODO: Render a submenu modal + console.log('show submenu'); + }, []); const langaugeArray = [ '🇺🇸 English', @@ -57,93 +69,103 @@ const LayoutHeader = ({ minimalSidebar ? `w-full lg:w-[calc(100%-150px)]` : `w-full lg:w-[calc(100%-350px)] `, - `lg:fixed bg-card border rounded-lg flex items-center justify-between p-4 lg:p-6 mx-auto`, + `lg:fixed bg-card border rounded-lg flex items-center justify-between p-4 lg:p-6 mx-auto` )} > -

{title}

-
- {action} - - - - - - Language - - {langaugeArray.map((lang) => ( - - setLanguage(`${lang}`)} - /> - - ))} - - - - - - - - Theme - - - - - - - - - + + + Language + + {langaugeArray.map((lang) => ( + + setLanguage(`${lang}`)} + /> + + ))} + + + + + - - - -
+ Theme selector + {!hydrated ? null : theme === 'dark' ? ( + + ) : theme === 'light' ? ( + + ) : ( + + )} + + + + Theme + + + + + + + + + + + + + + )} ); }; diff --git a/app/components/blocks/sidebar.tsx b/app/components/blocks/sidebar.tsx index b80f772..e5812a8 100644 --- a/app/components/blocks/sidebar.tsx +++ b/app/components/blocks/sidebar.tsx @@ -1,138 +1,154 @@ -import { Link } from "@remix-run/react"; +import { Link } from '@remix-run/react'; import { - ArrowLeft, - Bell, - ChevronLeft, - ChevronRight, - Search, -} from "lucide-react"; -import { Button } from "../ui/button"; -import { Input } from "../ui/input"; + ArrowLeft, + Bell, + ChevronLeft, + ChevronRight, + Search, +} from 'lucide-react'; +import { Button } from '../ui/button'; +import { Input } from '../ui/input'; -import { ProfileDropdown } from "./profile-dropdown"; -import { NavItem } from "../atoms/nav-item"; -import { CollapsibleChild, CollapsibleItem } from "../atoms/collapsible-item"; -import { navItems, secondaryNavItems } from "@/data/nav"; -import { FC, useState } from "react"; -import { cn } from "@/lib/styles"; +import { ProfileDropdown } from './profile-dropdown'; +import { NavItem } from '../atoms/nav-item'; +import { CollapsibleChild, CollapsibleItem } from '../atoms/collapsible-item'; +import { navItems, secondaryNavItems } from '@/data/nav'; +import { FC, Key, useState } from 'react'; +import { cn } from '@/lib/styles'; interface SidebarProps { - minimalSidebar?: boolean; - toggleSidebar: () => void; + minimalSidebar?: boolean; + toggleSidebar: () => void; } const Sidebar: FC = ({ - minimalSidebar = false, - toggleSidebar, + minimalSidebar = false, + toggleSidebar, }) => { - // TODO(glen): Move this to a separate file + // TODO(glen): Move this to a separate file - return ( -
-
-
- {!minimalSidebar ? ( - - logo - FamCon - - ) : null} - -
-
- {minimalSidebar ? ( -
- - {/* TODO: automatically set focus to the search inpu field */} -
- ) : ( -
-
- - -
-
- )} - -
-
-
-
-
- ); + ); }; export default Sidebar; diff --git a/app/components/blocks/transactions-table.tsx b/app/components/blocks/transactions-table.tsx deleted file mode 100644 index d9af258..0000000 --- a/app/components/blocks/transactions-table.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; -import { Badge } from "../ui/badge"; - -const transactions = [ - { - customer: { - name: "Liam Johnson", - email: "liam@example.com", - }, - type: "Sale", - status: { - text: "Fulfilled", - variant: "secondary", - }, - date: "2023-06-23", - amount: "$250.00", - }, - { - customer: { - name: "Olivia Smith", - email: "olivia@example.com", - }, - type: "Refund", - status: { - text: "Declined", - variant: "outline", - }, - date: "2023-06-24", - amount: "$150.00", - }, - { - customer: { - name: "Noah Williams", - email: "noah@example.com", - }, - type: "Subscription", - status: { - text: "Fulfilled", - variant: "secondary", - }, - date: "2023-06-25", - amount: "$350.00", - }, - { - customer: { - name: "Emma Brown", - email: "emma@example.com", - }, - type: "Sale", - status: { - text: "Fulfilled", - variant: "secondary", - }, - date: "2023-06-26", - amount: "$450.00", - }, - { - customer: { - name: "James Taylor", - email: "james@example.com", - }, - type: "Refund", - status: { - text: "Declined", - variant: "outline", - }, - date: "2023-06-27", - amount: "$200.00", - }, - { - customer: { - name: "Sophia Lee", - email: "sophia@example.com", - }, - type: "Sale", - status: { - text: "Fulfilled", - variant: "secondary", - }, - date: "2023-06-28", - amount: "$300.00", - }, - { - customer: { - name: "Mason Martinez", - email: "mason@example.com", - }, - type: "Subscription", - status: { - text: "Fulfilled", - variant: "secondary", - }, - date: "2023-06-29", - amount: "$400.00", - }, -]; -const TransactionsTable = () => { - return ( - - - - Customer - Type - Status - Date - Amount - - - - {transactions.map((transaction, index) => ( - - -
{transaction.customer.name}
-
- {transaction.customer.email} -
-
- - {transaction.type} - - - - {transaction.status.text} - - - - {transaction.date} - - {transaction.amount} -
- ))} -
-
- ); -}; - -export default TransactionsTable; diff --git a/app/components/contributions/columns.tsx b/app/components/contributions/columns.tsx deleted file mode 100644 index 14d1c0f..0000000 --- a/app/components/contributions/columns.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { ColumnDef } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { ArrowDown, MoreHorizontal } from "lucide-react"; -import { Checkbox } from "../ui/checkbox"; - -export interface Contributors { - id: number; - first_name: string; - last_name: string; - email: string; - gender: string; - dependent: boolean; - contributionAmount: number; - contributionMethod: - | "Bank Transfer" - | "Cash" - | "Check" - | "Credit Card" - | "Online Payment"; - dateJoined: string; -} -export const columns: ColumnDef[] = [ - { - id: "select", - header: ({ table }) => { - return ( - { - table.toggleAllPageRowsSelected(!!value); - }} - /> - ); - }, - cell: ({ row }) => { - return ( - { - row.toggleSelected(!!value); - }} - /> - ); - }, - enableSorting: false, - enableHiding: false, - }, - { - accessorKey: "first_name", - header: ({ column }) => { - return ( - - ); - }, - cell: ({ row }) => { - return
{row.getValue("first_name")}
; - }, - }, - { - accessorKey: "last_name", - header: "Last Name", - }, - { - accessorKey: "email", - header: "Email", - }, - { - accessorKey: "dependent", - header: "Is Dependent?", - }, - { - accessorKey: "gender", - header: "Gender", - }, - { - accessorKey: "contributionAmount", - header: () =>
Amount
, - cell: ({ row }) => { - const amount = parseFloat(row.getValue("contributionAmount")); - const formated = new Intl.NumberFormat("en-US", { - style: "currency", - currency: "USD", - }).format(amount); - - return ( -
- {amount > 50 ? ( - {formated} - ) : ( - formated - )} -
- ); - }, - }, - { - id: "actions", - cell: ({ row }) => { - const contributor = row.original; - - return ( - - - - - - Actions - - navigator.clipboard.writeText(contributor.id.toString()) - } - > - Copy payment ID - - - View customer - View payment details - - - ); - }, - }, -]; diff --git a/app/components/contributions/data-table.tsx b/app/components/contributions/data-table.tsx index e8c5972..8b13789 100644 --- a/app/components/contributions/data-table.tsx +++ b/app/components/contributions/data-table.tsx @@ -1,190 +1 @@ -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; -import { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; - -import { - ColumnDef, - ColumnFiltersState, - SortingState, - VisibilityState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table"; -import { Button } from "../ui/button"; -import { useState } from "react"; -import { Input } from "../ui/input"; -import { exportTableToCSV } from "@/lib/xlsx"; - -interface DataTableProps { - columns: ColumnDef[]; - data: TData[]; -} - -export function DataTable({ - columns, - data, -}: DataTableProps) { - const [sorting, setSorting] = useState([]); - const [columnFilters, setColumnFilters] = useState([]); - const [rowSelection, setRowSelection] = useState({}); - const [columnVisibility, setColumnVisibility] = useState({}); - console.log(rowSelection); - - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - onColumnVisibilityChange: setColumnVisibility, - onRowSelectionChange: setRowSelection, - - state: { - sorting, - columnFilters, - columnVisibility, - rowSelection, - }, - }); - - return ( -
-
- - table.getColumn("first_name")?.setFilterValue(event.target.value) - } - className="max-w-sm" - /> - - - - - - - {table - .getAllColumns() - .filter((column) => column.getCanHide()) - .map((column) => { - return ( - - column.toggleVisibility(!!value) - } - > - {column.id} - - ); - })} - - -
- {/* table */} -
- - - {table.getHeaderGroups().map((headerGroup) => { - return ( - - {headerGroup.headers.map((header) => { - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ); - })} - - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ))} - - )) - ) : ( - - No results - - )} - -
-
- {/* pagination */} -
- - -
-
- {table.getFilteredSelectedRowModel().rows.length} of{" "} - {table.getFilteredRowModel().rows.length} row(s) selected -
-
- ); -} diff --git a/app/components/contributions/data.ts b/app/components/contributions/data.ts deleted file mode 100644 index 4786a7e..0000000 --- a/app/components/contributions/data.ts +++ /dev/null @@ -1,1107 +0,0 @@ -// how to infer types automatically from typescript -// type TContributor = (typeof contributors)[number] - -import { Contributors } from "./columns"; - -export const contributors: Contributors[] = [ - { - id: 1, - first_name: "Frasquito", - last_name: "Jean", - email: "fjean0@blinklist.com", - gender: "Male", - dependent: true, - contributionAmount: 39, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-03T02:15:47Z", - }, - { - id: 2, - first_name: "Friedrich", - last_name: "Ruthen", - email: "fruthen1@google.com.au", - gender: "Male", - dependent: true, - contributionAmount: 77, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-05T09:04:10Z", - }, - { - id: 3, - first_name: "Birdie", - last_name: "Grimme", - email: "bgrimme2@auda.org.au", - gender: "Female", - dependent: false, - contributionAmount: 71, - contributionMethod: "Cash", - dateJoined: "2023-09-28T21:05:56Z", - }, - { - id: 4, - first_name: "Edi", - last_name: "Tailour", - email: "etailour3@naver.com", - gender: "Female", - dependent: true, - contributionAmount: 9, - contributionMethod: "Online Payment", - dateJoined: "2023-09-17T00:48:14Z", - }, - { - id: 5, - first_name: "Harbert", - last_name: "aManger", - email: "hamanger4@cam.ac.uk", - gender: "Male", - dependent: true, - contributionAmount: 34, - contributionMethod: "Check", - dateJoined: "2024-02-24T06:35:14Z", - }, - { - id: 6, - first_name: "Cinnamon", - last_name: "Lievesley", - email: "clievesley5@51.la", - gender: "Female", - dependent: true, - contributionAmount: 60, - contributionMethod: "Credit Card", - dateJoined: "2024-04-15T09:21:54Z", - }, - { - id: 7, - first_name: "Theodor", - last_name: "Skullet", - email: "tskullet6@topsy.com", - gender: "Male", - dependent: false, - contributionAmount: 52, - contributionMethod: "Cash", - dateJoined: "2024-05-19T10:56:10Z", - }, - { - id: 8, - first_name: "Jarrad", - last_name: "Clashe", - email: "jclashe7@cmu.edu", - gender: "Male", - dependent: true, - contributionAmount: 90, - contributionMethod: "Bank Transfer", - dateJoined: "2024-05-30T02:39:55Z", - }, - { - id: 9, - first_name: "Vivia", - last_name: "Pomery", - email: "vpomery8@blogger.com", - gender: "Female", - dependent: true, - contributionAmount: 35, - contributionMethod: "Check", - dateJoined: "2024-02-12T12:26:40Z", - }, - { - id: 10, - first_name: "Kaela", - last_name: "Johnsson", - email: "kjohnsson9@ow.ly", - gender: "Female", - dependent: true, - contributionAmount: 68, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-18T19:20:31Z", - }, - { - id: 11, - first_name: "Erskine", - last_name: "Gillinghams", - email: "egillinghamsa@uiuc.edu", - gender: "Genderfluid", - dependent: true, - contributionAmount: 3, - contributionMethod: "Cash", - dateJoined: "2023-10-16T12:23:09Z", - }, - { - id: 12, - first_name: "Amelina", - last_name: "Overbury", - email: "aoverburyb@skyrock.com", - gender: "Female", - dependent: true, - contributionAmount: 78, - contributionMethod: "Bank Transfer", - dateJoined: "2024-06-05T20:36:05Z", - }, - { - id: 13, - first_name: "Darin", - last_name: "Janaszkiewicz", - email: "djanaszkiewiczc@blogger.com", - gender: "Male", - dependent: true, - contributionAmount: 91, - contributionMethod: "Cash", - dateJoined: "2024-05-26T18:10:00Z", - }, - { - id: 14, - first_name: "Ashlan", - last_name: "Thickins", - email: "athickinsd@mayoclinic.com", - gender: "Female", - dependent: false, - contributionAmount: 60, - contributionMethod: "Bank Transfer", - dateJoined: "2023-09-30T12:32:01Z", - }, - { - id: 15, - first_name: "Stewart", - last_name: "Arkcoll", - email: "sarkcolle@t-online.de", - gender: "Genderqueer", - dependent: true, - contributionAmount: 26, - contributionMethod: "Cash", - dateJoined: "2024-02-17T19:05:45Z", - }, - { - id: 16, - first_name: "Missie", - last_name: "Varndell", - email: "mvarndellf@addthis.com", - gender: "Female", - dependent: false, - contributionAmount: 28, - contributionMethod: "Bank Transfer", - dateJoined: "2023-12-02T13:25:03Z", - }, - { - id: 17, - first_name: "Inesita", - last_name: "Strick", - email: "istrickg@princeton.edu", - gender: "Female", - dependent: false, - contributionAmount: 70, - contributionMethod: "Credit Card", - dateJoined: "2023-10-10T05:34:23Z", - }, - { - id: 18, - first_name: "Tory", - last_name: "Peris", - email: "tperish@pinterest.com", - gender: "Female", - dependent: false, - contributionAmount: 91, - contributionMethod: "Cash", - dateJoined: "2023-12-18T17:50:53Z", - }, - { - id: 19, - first_name: "Pennie", - last_name: "Rosson", - email: "prossoni@usatoday.com", - gender: "Male", - dependent: true, - contributionAmount: 27, - contributionMethod: "Bank Transfer", - dateJoined: "2024-05-28T23:46:19Z", - }, - { - id: 20, - first_name: "Barbara-anne", - last_name: "Ruzicka", - email: "bruzickaj@house.gov", - gender: "Female", - dependent: false, - contributionAmount: 8, - contributionMethod: "Check", - dateJoined: "2023-12-08T06:03:19Z", - }, - { - id: 21, - first_name: "Laraine", - last_name: "Bellelli", - email: "lbellellik@gmpg.org", - gender: "Female", - dependent: false, - contributionAmount: 67, - contributionMethod: "Check", - dateJoined: "2023-12-21T04:58:13Z", - }, - { - id: 22, - first_name: "Claudianus", - last_name: "Elloit", - email: "celloitl@sciencedirect.com", - gender: "Male", - dependent: false, - contributionAmount: 24, - contributionMethod: "Cash", - dateJoined: "2023-08-11T22:47:26Z", - }, - { - id: 23, - first_name: "Jonas", - last_name: "Carabet", - email: "jcarabetm@telegraph.co.uk", - gender: "Male", - dependent: false, - contributionAmount: 81, - contributionMethod: "Check", - dateJoined: "2024-06-08T04:29:37Z", - }, - { - id: 24, - first_name: "Perle", - last_name: "Emeny", - email: "pemenyn@intel.com", - gender: "Female", - dependent: false, - contributionAmount: 97, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-02T16:34:07Z", - }, - { - id: 25, - first_name: "Beitris", - last_name: "Forrester", - email: "bforrestero@cdc.gov", - gender: "Genderfluid", - dependent: true, - contributionAmount: 73, - contributionMethod: "Online Payment", - dateJoined: "2023-09-20T19:45:54Z", - }, - { - id: 26, - first_name: "Norman", - last_name: "Thiese", - email: "nthiesep@toplist.cz", - gender: "Male", - dependent: true, - contributionAmount: 93, - contributionMethod: "Cash", - dateJoined: "2023-12-21T07:03:21Z", - }, - { - id: 27, - first_name: "Bailey", - last_name: "Creenan", - email: "bcreenanq@prweb.com", - gender: "Male", - dependent: false, - contributionAmount: 55, - contributionMethod: "Bank Transfer", - dateJoined: "2023-07-24T01:20:51Z", - }, - { - id: 28, - first_name: "Theda", - last_name: "Tinson", - email: "ttinsonr@cyberchimps.com", - gender: "Female", - dependent: false, - contributionAmount: 72, - contributionMethod: "Check", - dateJoined: "2024-05-14T06:29:44Z", - }, - { - id: 29, - first_name: "Dennie", - last_name: "MacAllaster", - email: "dmacallasters@google.it", - gender: "Genderfluid", - dependent: true, - contributionAmount: 89, - contributionMethod: "Credit Card", - dateJoined: "2023-07-18T04:20:29Z", - }, - { - id: 30, - first_name: "Anatol", - last_name: "Bonehill", - email: "abonehillt@thetimes.co.uk", - gender: "Male", - dependent: true, - contributionAmount: 94, - contributionMethod: "Bank Transfer", - dateJoined: "2023-08-10T19:21:43Z", - }, - { - id: 31, - first_name: "Griswold", - last_name: "Veivers", - email: "gveiversu@storify.com", - gender: "Male", - dependent: false, - contributionAmount: 99, - contributionMethod: "Check", - dateJoined: "2024-03-20T14:20:39Z", - }, - { - id: 32, - first_name: "Tedd", - last_name: "Tranfield", - email: "ttranfieldv@squidoo.com", - gender: "Male", - dependent: true, - contributionAmount: 36, - contributionMethod: "Cash", - dateJoined: "2023-09-16T13:40:06Z", - }, - { - id: 33, - first_name: "Pate", - last_name: "Robertelli", - email: "probertelliw@blogspot.com", - gender: "Polygender", - dependent: false, - contributionAmount: 60, - contributionMethod: "Check", - dateJoined: "2023-11-07T04:49:35Z", - }, - { - id: 34, - first_name: "Maegan", - last_name: "Hallam", - email: "mhallamx@csmonitor.com", - gender: "Female", - dependent: true, - contributionAmount: 34, - contributionMethod: "Check", - dateJoined: "2023-10-14T11:37:13Z", - }, - { - id: 35, - first_name: "Rebeka", - last_name: "Pembry", - email: "rpembryy@elegantthemes.com", - gender: "Female", - dependent: true, - contributionAmount: 52, - contributionMethod: "Check", - dateJoined: "2024-01-09T13:12:32Z", - }, - { - id: 36, - first_name: "Ricca", - last_name: "Musk", - email: "rmuskz@forbes.com", - gender: "Female", - dependent: false, - contributionAmount: 72, - contributionMethod: "Check", - dateJoined: "2023-09-12T23:15:15Z", - }, - { - id: 37, - first_name: "Israel", - last_name: "Kaplan", - email: "ikaplan10@ft.com", - gender: "Male", - dependent: false, - contributionAmount: 27, - contributionMethod: "Online Payment", - dateJoined: "2024-02-07T23:03:04Z", - }, - { - id: 38, - first_name: "Gabriele", - last_name: "Fero", - email: "gfero11@disqus.com", - gender: "Male", - dependent: false, - contributionAmount: 89, - contributionMethod: "Online Payment", - dateJoined: "2024-02-04T20:51:52Z", - }, - { - id: 39, - first_name: "Estella", - last_name: "Sicha", - email: "esicha12@apple.com", - gender: "Female", - dependent: false, - contributionAmount: 85, - contributionMethod: "Cash", - dateJoined: "2023-10-23T09:41:38Z", - }, - { - id: 40, - first_name: "Chantal", - last_name: "Neiland", - email: "cneiland13@blinklist.com", - gender: "Female", - dependent: true, - contributionAmount: 40, - contributionMethod: "Check", - dateJoined: "2023-12-07T23:03:15Z", - }, - { - id: 41, - first_name: "Reinold", - last_name: "McOmish", - email: "rmcomish14@multiply.com", - gender: "Male", - dependent: true, - contributionAmount: 46, - contributionMethod: "Bank Transfer", - dateJoined: "2024-02-07T15:19:24Z", - }, - { - id: 42, - first_name: "Frazier", - last_name: "Evens", - email: "fevens15@utexas.edu", - gender: "Male", - dependent: true, - contributionAmount: 34, - contributionMethod: "Check", - dateJoined: "2024-03-31T04:34:31Z", - }, - { - id: 43, - first_name: "Job", - last_name: "Fabbro", - email: "jfabbro16@unicef.org", - gender: "Agender", - dependent: false, - contributionAmount: 37, - contributionMethod: "Online Payment", - dateJoined: "2024-04-28T10:39:23Z", - }, - { - id: 44, - first_name: "Jessica", - last_name: "Rakes", - email: "jrakes17@storify.com", - gender: "Female", - dependent: true, - contributionAmount: 65, - contributionMethod: "Cash", - dateJoined: "2024-04-15T18:45:09Z", - }, - { - id: 45, - first_name: "Pierette", - last_name: "Chinge", - email: "pchinge18@infoseek.co.jp", - gender: "Female", - dependent: false, - contributionAmount: 29, - contributionMethod: "Cash", - dateJoined: "2024-01-21T21:29:07Z", - }, - { - id: 46, - first_name: "Niall", - last_name: "Neljes", - email: "nneljes19@g.co", - gender: "Male", - dependent: false, - contributionAmount: 89, - contributionMethod: "Check", - dateJoined: "2023-08-01T03:04:12Z", - }, - { - id: 47, - first_name: "Tarrah", - last_name: "Shank", - email: "tshank1a@psu.edu", - gender: "Female", - dependent: false, - contributionAmount: 89, - contributionMethod: "Bank Transfer", - dateJoined: "2023-12-03T07:09:59Z", - }, - { - id: 48, - first_name: "Chilton", - last_name: "Lambarton", - email: "clambarton1b@tiny.cc", - gender: "Agender", - dependent: true, - contributionAmount: 13, - contributionMethod: "Check", - dateJoined: "2024-03-11T04:25:06Z", - }, - { - id: 49, - first_name: "Todd", - last_name: "Hehnke", - email: "thehnke1c@nydailynews.com", - gender: "Male", - dependent: false, - contributionAmount: 25, - contributionMethod: "Bank Transfer", - dateJoined: "2024-03-26T03:09:15Z", - }, - { - id: 50, - first_name: "Darla", - last_name: "Linkin", - email: "dlinkin1d@imageshack.us", - gender: "Female", - dependent: false, - contributionAmount: 60, - contributionMethod: "Credit Card", - dateJoined: "2023-08-02T02:16:43Z", - }, - { - id: 51, - first_name: "Thornton", - last_name: "Van Der Straaten", - email: "tvanderstraaten1e@multiply.com", - gender: "Male", - dependent: true, - contributionAmount: 4, - contributionMethod: "Cash", - dateJoined: "2024-06-15T05:33:12Z", - }, - { - id: 52, - first_name: "Aileen", - last_name: "Goolden", - email: "agoolden1f@sitemeter.com", - gender: "Female", - dependent: false, - contributionAmount: 52, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-21T03:02:51Z", - }, - { - id: 53, - first_name: "Carita", - last_name: "Peasegod", - email: "cpeasegod1g@printfriendly.com", - gender: "Female", - dependent: false, - contributionAmount: 23, - contributionMethod: "Credit Card", - dateJoined: "2023-10-11T21:14:45Z", - }, - { - id: 54, - first_name: "Salli", - last_name: "Gorch", - email: "sgorch1h@army.mil", - gender: "Female", - dependent: true, - contributionAmount: 67, - contributionMethod: "Online Payment", - dateJoined: "2024-03-08T03:00:34Z", - }, - { - id: 55, - first_name: "Nigel", - last_name: "Byng", - email: "nbyng1i@mysql.com", - gender: "Male", - dependent: true, - contributionAmount: 91, - contributionMethod: "Credit Card", - dateJoined: "2024-06-20T17:16:44Z", - }, - { - id: 56, - first_name: "Ardisj", - last_name: "Mollen", - email: "amollen1j@seattletimes.com", - gender: "Non-binary", - dependent: false, - contributionAmount: 84, - contributionMethod: "Bank Transfer", - dateJoined: "2023-08-19T05:00:03Z", - }, - { - id: 57, - first_name: "Hillyer", - last_name: "Zelland", - email: "hzelland1k@gravatar.com", - gender: "Male", - dependent: true, - contributionAmount: 6, - contributionMethod: "Cash", - dateJoined: "2024-03-03T16:41:46Z", - }, - { - id: 58, - first_name: "Pablo", - last_name: "Benediktovich", - email: "pbenediktovich1l@wikia.com", - gender: "Male", - dependent: true, - contributionAmount: 47, - contributionMethod: "Credit Card", - dateJoined: "2023-10-15T03:18:53Z", - }, - { - id: 59, - first_name: "Marion", - last_name: "McReath", - email: "mmcreath1m@hugedomains.com", - gender: "Male", - dependent: false, - contributionAmount: 13, - contributionMethod: "Online Payment", - dateJoined: "2023-08-14T21:20:47Z", - }, - { - id: 60, - first_name: "Shelbi", - last_name: "Pfertner", - email: "spfertner1n@topsy.com", - gender: "Female", - dependent: false, - contributionAmount: 1, - contributionMethod: "Bank Transfer", - dateJoined: "2024-02-22T02:31:16Z", - }, - { - id: 61, - first_name: "Redd", - last_name: "Elleton", - email: "relleton1o@kickstarter.com", - gender: "Male", - dependent: false, - contributionAmount: 14, - contributionMethod: "Bank Transfer", - dateJoined: "2023-07-16T18:40:19Z", - }, - { - id: 62, - first_name: "Morissa", - last_name: "Abbis", - email: "mabbis1p@oakley.com", - gender: "Female", - dependent: false, - contributionAmount: 34, - contributionMethod: "Bank Transfer", - dateJoined: "2024-02-04T00:32:14Z", - }, - { - id: 63, - first_name: "Bree", - last_name: "Kilgallon", - email: "bkilgallon1q@tinyurl.com", - gender: "Female", - dependent: true, - contributionAmount: 14, - contributionMethod: "Credit Card", - dateJoined: "2023-07-11T03:48:11Z", - }, - { - id: 64, - first_name: "Jolie", - last_name: "Annis", - email: "jannis1r@edublogs.org", - gender: "Female", - dependent: true, - contributionAmount: 6, - contributionMethod: "Bank Transfer", - dateJoined: "2023-07-30T03:33:30Z", - }, - { - id: 65, - first_name: "Jorge", - last_name: "Louth", - email: "jlouth1s@people.com.cn", - gender: "Male", - dependent: true, - contributionAmount: 1, - contributionMethod: "Bank Transfer", - dateJoined: "2024-04-19T20:13:37Z", - }, - { - id: 66, - first_name: "Linn", - last_name: "Palmer", - email: "lpalmer1t@webnode.com", - gender: "Male", - dependent: true, - contributionAmount: 56, - contributionMethod: "Check", - dateJoined: "2023-08-06T08:30:04Z", - }, - { - id: 67, - first_name: "Codie", - last_name: "Lempenny", - email: "clempenny1u@youtu.be", - gender: "Female", - dependent: false, - contributionAmount: 80, - contributionMethod: "Credit Card", - dateJoined: "2024-02-05T00:34:53Z", - }, - { - id: 68, - first_name: "Elizabeth", - last_name: "Cleaton", - email: "ecleaton1v@ihg.com", - gender: "Female", - dependent: true, - contributionAmount: 25, - contributionMethod: "Check", - dateJoined: "2023-10-13T02:33:02Z", - }, - { - id: 69, - first_name: "Melissa", - last_name: "Broadwood", - email: "mbroadwood1w@blogtalkradio.com", - gender: "Female", - dependent: true, - contributionAmount: 82, - contributionMethod: "Credit Card", - dateJoined: "2023-07-03T11:21:18Z", - }, - { - id: 70, - first_name: "Laurent", - last_name: "Petroff", - email: "lpetroff1x@dmoz.org", - gender: "Male", - dependent: false, - contributionAmount: 92, - contributionMethod: "Cash", - dateJoined: "2024-04-08T06:47:53Z", - }, - { - id: 71, - first_name: "Wylie", - last_name: "Lies", - email: "wlies1y@icq.com", - gender: "Male", - dependent: false, - contributionAmount: 1, - contributionMethod: "Online Payment", - dateJoined: "2024-01-24T08:21:37Z", - }, - { - id: 72, - first_name: "Caitrin", - last_name: "Uzelli", - email: "cuzelli1z@cafepress.com", - gender: "Female", - dependent: true, - contributionAmount: 83, - contributionMethod: "Check", - dateJoined: "2024-03-31T01:38:29Z", - }, - { - id: 73, - first_name: "Zora", - last_name: "Mogey", - email: "zmogey20@reuters.com", - gender: "Female", - dependent: false, - contributionAmount: 89, - contributionMethod: "Bank Transfer", - dateJoined: "2023-10-18T17:12:11Z", - }, - { - id: 74, - first_name: "Byran", - last_name: "McCutcheon", - email: "bmccutcheon21@wiley.com", - gender: "Male", - dependent: true, - contributionAmount: 46, - contributionMethod: "Credit Card", - dateJoined: "2024-04-20T08:14:40Z", - }, - { - id: 75, - first_name: "Dix", - last_name: "Ferrieroi", - email: "dferrieroi22@hexun.com", - gender: "Bigender", - dependent: false, - contributionAmount: 51, - contributionMethod: "Cash", - dateJoined: "2023-12-02T11:13:05Z", - }, - { - id: 76, - first_name: "Frederick", - last_name: "McGlade", - email: "fmcglade23@intel.com", - gender: "Male", - dependent: true, - contributionAmount: 20, - contributionMethod: "Credit Card", - dateJoined: "2023-09-05T18:34:25Z", - }, - { - id: 77, - first_name: "Babita", - last_name: "Starkey", - email: "bstarkey24@ebay.co.uk", - gender: "Female", - dependent: false, - contributionAmount: 61, - contributionMethod: "Bank Transfer", - dateJoined: "2024-06-14T17:48:54Z", - }, - { - id: 78, - first_name: "Laurens", - last_name: "Chiles", - email: "lchiles25@shop-pro.jp", - gender: "Male", - dependent: false, - contributionAmount: 18, - contributionMethod: "Check", - dateJoined: "2024-03-04T10:28:45Z", - }, - { - id: 79, - first_name: "Conni", - last_name: "De Ferrari", - email: "cdeferrari26@house.gov", - gender: "Female", - dependent: true, - contributionAmount: 29, - contributionMethod: "Credit Card", - dateJoined: "2023-12-08T06:27:26Z", - }, - { - id: 80, - first_name: "Glen", - last_name: "Rhymes", - email: "grhymes27@goo.ne.jp", - gender: "Polygender", - dependent: false, - contributionAmount: 26, - contributionMethod: "Cash", - dateJoined: "2024-04-29T11:17:39Z", - }, - { - id: 81, - first_name: "Marcile", - last_name: "Georger", - email: "mgeorger28@cpanel.net", - gender: "Female", - dependent: false, - contributionAmount: 49, - contributionMethod: "Credit Card", - dateJoined: "2023-06-28T23:08:59Z", - }, - { - id: 82, - first_name: "Derrek", - last_name: "Mander", - email: "dmander29@desdev.cn", - gender: "Male", - dependent: false, - contributionAmount: 23, - contributionMethod: "Cash", - dateJoined: "2024-06-19T16:34:14Z", - }, - { - id: 83, - first_name: "Nappy", - last_name: "Eddie", - email: "neddie2a@upenn.edu", - gender: "Male", - dependent: false, - contributionAmount: 58, - contributionMethod: "Online Payment", - dateJoined: "2023-09-18T00:11:53Z", - }, - { - id: 84, - first_name: "Taite", - last_name: "Daines", - email: "tdaines2b@jiathis.com", - gender: "Male", - dependent: true, - contributionAmount: 46, - contributionMethod: "Check", - dateJoined: "2024-04-17T19:30:21Z", - }, - { - id: 85, - first_name: "Daven", - last_name: "Farraway", - email: "dfarraway2c@fotki.com", - gender: "Male", - dependent: true, - contributionAmount: 87, - contributionMethod: "Check", - dateJoined: "2023-12-10T09:56:48Z", - }, - { - id: 86, - first_name: "Beverie", - last_name: "Lamacraft", - email: "blamacraft2d@gravatar.com", - gender: "Female", - dependent: true, - contributionAmount: 27, - contributionMethod: "Bank Transfer", - dateJoined: "2023-09-20T07:00:26Z", - }, - { - id: 87, - first_name: "Lauraine", - last_name: "Gheerhaert", - email: "lgheerhaert2e@zimbio.com", - gender: "Female", - dependent: false, - contributionAmount: 60, - contributionMethod: "Check", - dateJoined: "2023-12-20T17:53:39Z", - }, - { - id: 88, - first_name: "Floris", - last_name: "Elloway", - email: "felloway2f@amazon.co.jp", - gender: "Female", - dependent: false, - contributionAmount: 30, - contributionMethod: "Online Payment", - dateJoined: "2024-05-01T07:06:27Z", - }, - { - id: 89, - first_name: "Keslie", - last_name: "Rylands", - email: "krylands2g@ca.gov", - gender: "Female", - dependent: false, - contributionAmount: 92, - contributionMethod: "Credit Card", - dateJoined: "2023-11-05T16:35:16Z", - }, - { - id: 90, - first_name: "Joellyn", - last_name: "Redgrave", - email: "jredgrave2h@blogger.com", - gender: "Female", - dependent: false, - contributionAmount: 87, - contributionMethod: "Credit Card", - dateJoined: "2024-05-16T01:16:19Z", - }, - { - id: 91, - first_name: "Deerdre", - last_name: "Mill", - email: "dmill2i@tmall.com", - gender: "Female", - dependent: true, - contributionAmount: 65, - contributionMethod: "Check", - dateJoined: "2023-10-06T01:17:26Z", - }, - { - id: 92, - first_name: "Merrill", - last_name: "Lillistone", - email: "mlillistone2j@webnode.com", - gender: "Female", - dependent: true, - contributionAmount: 72, - contributionMethod: "Bank Transfer", - dateJoined: "2023-08-06T03:03:54Z", - }, - { - id: 93, - first_name: "Winfield", - last_name: "Mockler", - email: "wmockler2k@youtu.be", - gender: "Non-binary", - dependent: false, - contributionAmount: 62, - contributionMethod: "Online Payment", - dateJoined: "2023-08-17T20:28:49Z", - }, - { - id: 94, - first_name: "Ingemar", - last_name: "Purkins", - email: "ipurkins2l@utexas.edu", - gender: "Male", - dependent: true, - contributionAmount: 63, - contributionMethod: "Online Payment", - dateJoined: "2024-01-14T04:09:32Z", - }, - { - id: 95, - first_name: "Maximilian", - last_name: "Staniforth", - email: "mstaniforth2m@blogs.com", - gender: "Male", - dependent: true, - contributionAmount: 50, - contributionMethod: "Credit Card", - dateJoined: "2024-05-04T06:42:26Z", - }, - { - id: 96, - first_name: "Nicolis", - last_name: "Poultney", - email: "npoultney2n@geocities.jp", - gender: "Male", - dependent: false, - contributionAmount: 58, - contributionMethod: "Check", - dateJoined: "2024-05-19T11:34:55Z", - }, - { - id: 97, - first_name: "Stewart", - last_name: "Rassell", - email: "srassell2o@cnet.com", - gender: "Male", - dependent: false, - contributionAmount: 97, - contributionMethod: "Bank Transfer", - dateJoined: "2023-07-17T14:45:40Z", - }, - { - id: 98, - first_name: "Haily", - last_name: "Dykins", - email: "hdykins2p@github.com", - gender: "Male", - dependent: true, - contributionAmount: 51, - contributionMethod: "Credit Card", - dateJoined: "2024-03-01T00:45:12Z", - }, - { - id: 99, - first_name: "Kalil", - last_name: "McAuslene", - email: "kmcauslene2q@princeton.edu", - gender: "Male", - dependent: true, - contributionAmount: 35, - contributionMethod: "Cash", - dateJoined: "2023-12-12T14:07:25Z", - }, - { - id: 100, - first_name: "Elbertine", - last_name: "Huckin", - email: "ehuckin2r@gov.uk", - gender: "Female", - dependent: true, - contributionAmount: 99, - contributionMethod: "Bank Transfer", - dateJoined: "2023-12-16T07:26:07Z", - }, -]; diff --git a/app/components/layouts/MainLayout.tsx b/app/components/layouts/MainLayout.tsx index b62aa97..6c886ce 100644 --- a/app/components/layouts/MainLayout.tsx +++ b/app/components/layouts/MainLayout.tsx @@ -1,6 +1,6 @@ import Sidebar from '../blocks/sidebar'; import LayoutHeader from '../blocks/layout-header'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; interface MainLayoutProps { @@ -14,27 +14,45 @@ export default function MainLayout({ action, title = 'Dashboard', }: MainLayoutProps) { - const [minimalSidebar, setMinimalSidebar] = useState(false); + const [minimalSidebar, setMinimalSidebar] = useState(false); const toggleSidebar = () => setMinimalSidebar(!minimalSidebar); + const [windowWidth, setWindowWidth] = useState(0); + const tabletBreakpoint = 1024; + const moblieBreakpoint = 640; + + //TODO: Add a toggle tablet menu callback + + useEffect(() => { + setWindowWidth(window.innerWidth); + window.addEventListener('resize', () => { + setWindowWidth(window.innerWidth); + }); + }, []); return (
- + {windowWidth < tabletBreakpoint ? null : ( + + )}
{children} diff --git a/app/data/contributors.ts b/app/data/contributors.ts deleted file mode 100644 index f7873c3..0000000 --- a/app/data/contributors.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ContributorsDetailsProps } from "@/@types"; - -export const ContributorsSummaryData: ContributorsDetailsProps[] = [ - { title: "Male Contributors", value: "1.382", color: "blue" }, - { title: "Female Contributors", value: "194", color: "green" }, - { title: "Average Contributors", value: "283", color: "red" }, - { title: "Average Dependents", value: "35", color: "orange" }, -]; diff --git a/app/data/contributors/contributors-summary.ts b/app/data/contributors/contributors-summary.ts new file mode 100644 index 0000000..029ff8b --- /dev/null +++ b/app/data/contributors/contributors-summary.ts @@ -0,0 +1,8 @@ +import { ContributorsDetailsProps } from '@/@types/contributors'; + +export const ContributorsSummaryData: ContributorsDetailsProps[] = [ + { title: 'Male Contributors', value: '1.382', color: 'blue' }, + { title: 'Female Contributors', value: '194', color: 'green' }, + { title: 'Average Contributors', value: '283', color: 'red' }, + { title: 'Average Dependents', value: '35', color: 'orange' }, +]; diff --git a/app/data/contributors/data.ts b/app/data/contributors/data.ts new file mode 100644 index 0000000..9367377 --- /dev/null +++ b/app/data/contributors/data.ts @@ -0,0 +1,227 @@ +// how to infer types automatically from typescript +// type TContributor = (typeof contributors)[number] + +import { TPartialContributor } from '@/@types/contributors'; + +export const contributors: TPartialContributor[] = [ + { + id: '1', + firstName: 'Emma', + lastName: 'Johnson', + email: 'emma.johnson@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 75, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-08-15T10:30:00Z'), + }, + { + id: '2', + firstName: 'Liam', + lastName: 'Smith', + email: 'liam.smith@email.com', + gender: 'Male', + dependent: true, + contributionAmount: 50, + contributiionMethod: 'annual', + dateJoined: new Date('2023-09-22T14:45:00Z'), + }, + { + id: '3', + firstName: 'Olivia', + lastName: 'Brown', + email: 'olivia.brown@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 100, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-07-03T09:15:00Z'), + }, + { + id: '4', + firstName: 'Noah', + lastName: 'Taylor', + email: 'noah.taylor@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 150, + contributiionMethod: 'annual', + dateJoined: new Date('2023-10-11T11:20:00Z'), + }, + { + id: '5', + firstName: 'Ava', + lastName: 'Wilson', + email: 'ava.wilson@email.com', + gender: 'Female', + dependent: true, + contributionAmount: 60, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-11-28T16:55:00Z'), + }, + { + id: '6', + firstName: 'Ethan', + lastName: 'Anderson', + email: 'ethan.anderson@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 200, + contributiionMethod: 'annual', + dateJoined: new Date('2023-06-17T13:40:00Z'), + }, + { + id: '7', + firstName: 'Sophia', + lastName: 'Thomas', + email: 'sophia.thomas@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 80, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-12-05T10:10:00Z'), + }, + { + id: '8', + firstName: 'Mason', + lastName: 'Jackson', + email: 'mason.jackson@email.com', + gender: 'Male', + dependent: true, + contributionAmount: 45, + contributiionMethod: 'monthly', + dateJoined: new Date('2024-01-20T15:30:00Z'), + }, + { + id: '9', + firstName: 'Isabella', + lastName: 'White', + email: 'isabella.white@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 120, + contributiionMethod: 'annual', + dateJoined: new Date('2023-08-30T09:50:00Z'), + }, + { + id: '10', + firstName: 'William', + lastName: 'Harris', + email: 'william.harris@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 90, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-10-03T14:15:00Z'), + }, + { + id: '11', + firstName: 'Mia', + lastName: 'Martin', + email: 'mia.martin@email.com', + gender: 'Female', + dependent: true, + contributionAmount: 55, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-11-12T11:25:00Z'), + }, + { + id: '12', + firstName: 'James', + lastName: 'Thompson', + email: 'james.thompson@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 180, + contributiionMethod: 'annual', + dateJoined: new Date('2023-07-25T16:40:00Z'), + }, + { + id: '13', + firstName: 'Charlotte', + lastName: 'Garcia', + email: 'charlotte.garcia@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 70, + contributiionMethod: 'monthly', + dateJoined: new Date('2024-02-08T10:05:00Z'), + }, + { + id: '14', + firstName: 'Benjamin', + lastName: 'Martinez', + email: 'benjamin.martinez@email.com', + gender: 'Male', + dependent: true, + contributionAmount: 40, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-09-14T13:55:00Z'), + }, + { + id: '15', + firstName: 'Amelia', + lastName: 'Robinson', + email: 'amelia.robinson@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 110, + contributiionMethod: 'annual', + dateJoined: new Date('2023-12-19T15:20:00Z'), + }, + { + id: '16', + firstName: 'Elijah', + lastName: 'Clark', + email: 'elijah.clark@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 85, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-08-07T11:35:00Z'), + }, + { + id: '17', + firstName: 'Harper', + lastName: 'Rodriguez', + email: 'harper.rodriguez@email.com', + gender: 'Female', + dependent: true, + contributionAmount: 65, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-10-26T14:50:00Z'), + }, + { + id: '18', + firstName: 'Daniel', + lastName: 'Lewis', + email: 'daniel.lewis@email.com', + gender: 'Male', + dependent: false, + contributionAmount: 160, + contributiionMethod: 'annual', + dateJoined: new Date('2023-11-30T09:25:00Z'), + }, + { + id: '19', + firstName: 'Evelyn', + lastName: 'Lee', + email: 'evelyn.lee@email.com', + gender: 'Female', + dependent: false, + contributionAmount: 95, + contributiionMethod: 'monthly', + dateJoined: new Date('2024-01-05T16:15:00Z'), + }, + { + id: '20', + firstName: 'Michael', + lastName: 'Walker', + email: 'michael.walker@email.com', + gender: 'Male', + dependent: true, + contributionAmount: 35, + contributiionMethod: 'monthly', + dateJoined: new Date('2023-12-28T10:40:00Z'), + }, +]; diff --git a/app/db/dummy-data.ts b/app/data/db/dummy-data.ts similarity index 100% rename from app/db/dummy-data.ts rename to app/data/db/dummy-data.ts diff --git a/app/db/index.ts b/app/data/db/index.ts similarity index 100% rename from app/db/index.ts rename to app/data/db/index.ts diff --git a/app/db/migrate.ts b/app/data/db/migrate.ts similarity index 100% rename from app/db/migrate.ts rename to app/data/db/migrate.ts diff --git a/app/db/schema.ts b/app/data/db/schema.ts similarity index 100% rename from app/db/schema.ts rename to app/data/db/schema.ts diff --git a/app/db/seed.ts b/app/data/db/seed.ts similarity index 100% rename from app/db/seed.ts rename to app/data/db/seed.ts diff --git a/app/db/utils.ts b/app/data/db/utils.ts similarity index 100% rename from app/db/utils.ts rename to app/data/db/utils.ts diff --git a/app/routes/_index/Dashboard.tsx b/app/routes/_index/Dashboard.tsx deleted file mode 100644 index 9bc67d4..0000000 --- a/app/routes/_index/Dashboard.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Link } from "@remix-run/react"; - -import { - Activity, - ArrowUpRight, - CreditCard, - DollarSign, - Users, -} from "lucide-react"; - -import { SummaryCard } from "@/components/atoms/summary-card"; -import { RecentSales } from "@/components/blocks/recent-salse"; -import TransactionsTable from "@/components/blocks/transactions-table"; - -const summaryCardArray = [ - { - title: "Total Revenue", - icon: DollarSign, - mainValue: "$45,231.89", - details: "+20.1% from last month", - }, - - { - title: "Subscriptions", - icon: Users, - mainValue: "+2350", - details: "+180.1% from last month", - }, - - { - title: "Sales", - icon: CreditCard, - mainValue: "+12,234", - details: "+19% from last month", - }, - - { - title: "Active Now", - icon: Activity, - mainValue: "+573", - details: "+201 since last hour", - }, -]; -export default function Dashboard() { - return ( -
-
- {summaryCardArray.map((item) => ( - - ))} -
-
- - -
- Transactions - - Recent transactions from your store. - -
- -
- - {/* some table here */} - - - -
- - -
-
- ); -} diff --git a/app/routes/_index/components/dashboard.tsx b/app/routes/_index/components/dashboard.tsx new file mode 100644 index 0000000..d63776c --- /dev/null +++ b/app/routes/_index/components/dashboard.tsx @@ -0,0 +1,92 @@ +import { Button } from '@/components/ui/button'; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card'; +import { Link } from '@remix-run/react'; + +import { + Activity, + ArrowUpRight, + CreditCard, + DollarSign, + Users, +} from 'lucide-react'; + +import { SummaryCard } from '@/components/atoms/summary-card'; +import TransactionsTable from './transactions-table'; +import { RecentSales } from './recent-salse'; + +const summaryCardArray = [ + { + title: 'Total Revenue', + icon: DollarSign, + mainValue: '$45,231.89', + details: '+20.1% from last month', + }, + + { + title: 'Subscriptions', + icon: Users, + mainValue: '+2350', + details: '+180.1% from last month', + }, + + { + title: 'Sales', + icon: CreditCard, + mainValue: '+12,234', + details: '+19% from last month', + }, + + { + title: 'Active Now', + icon: Activity, + mainValue: '+573', + details: '+201 since last hour', + }, +]; +export default function Dashboard() { + return ( +
+
+ {summaryCardArray.map((item) => ( + + ))} +
+
+ + +
+ Transactions + + Recent transactions from your store. + +
+ +
+ + {/* some table here */} + + + +
+ + +
+
+ ); +} diff --git a/app/components/blocks/recent-salse.tsx b/app/routes/_index/components/recent-salse.tsx similarity index 100% rename from app/components/blocks/recent-salse.tsx rename to app/routes/_index/components/recent-salse.tsx diff --git a/app/routes/_index/components/transactions-table.tsx b/app/routes/_index/components/transactions-table.tsx new file mode 100644 index 0000000..61b6b0d --- /dev/null +++ b/app/routes/_index/components/transactions-table.tsx @@ -0,0 +1,156 @@ +import { Badge } from '@/components/ui/badge'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table'; + +const transactions = [ + { + customer: { + name: 'Liam Johnson', + email: 'liam@example.com', + }, + type: 'Sale', + status: { + text: 'Fulfilled', + variant: 'secondary', + }, + date: '2023-06-23', + amount: '$250.00', + }, + { + customer: { + name: 'Olivia Smith', + email: 'olivia@example.com', + }, + type: 'Refund', + status: { + text: 'Declined', + variant: 'outline', + }, + date: '2023-06-24', + amount: '$150.00', + }, + { + customer: { + name: 'Noah Williams', + email: 'noah@example.com', + }, + type: 'Subscription', + status: { + text: 'Fulfilled', + variant: 'secondary', + }, + date: '2023-06-25', + amount: '$350.00', + }, + { + customer: { + name: 'Emma Brown', + email: 'emma@example.com', + }, + type: 'Sale', + status: { + text: 'Fulfilled', + variant: 'secondary', + }, + date: '2023-06-26', + amount: '$450.00', + }, + { + customer: { + name: 'James Taylor', + email: 'james@example.com', + }, + type: 'Refund', + status: { + text: 'Declined', + variant: 'outline', + }, + date: '2023-06-27', + amount: '$200.00', + }, + { + customer: { + name: 'Sophia Lee', + email: 'sophia@example.com', + }, + type: 'Sale', + status: { + text: 'Fulfilled', + variant: 'secondary', + }, + date: '2023-06-28', + amount: '$300.00', + }, + { + customer: { + name: 'Mason Martinez', + email: 'mason@example.com', + }, + type: 'Subscription', + status: { + text: 'Fulfilled', + variant: 'secondary', + }, + date: '2023-06-29', + amount: '$400.00', + }, +]; +const TransactionsTable = () => { + return ( + + + + Customer + Type + + Status + + Date + Amount + + + + {transactions.map((transaction, index) => ( + + +
+ {transaction.customer.name} +
+
+ {transaction.customer.email} +
+
+ + {transaction.type} + + + + {transaction.status.text} + + + + {transaction.date} + + + {transaction.amount} + +
+ ))} +
+
+ ); +}; + +export default TransactionsTable; diff --git a/app/routes/_index/route.tsx b/app/routes/_index/route.tsx index 7330847..e7da706 100644 --- a/app/routes/_index/route.tsx +++ b/app/routes/_index/route.tsx @@ -1,18 +1,18 @@ -import MainLayout from "@/components/layouts/MainLayout"; -import { MetaFunction } from "@remix-run/react"; -import Dashboard from "./Dashboard"; +import MainLayout from '@/components/layouts/MainLayout'; +import { MetaFunction } from '@remix-run/react'; +import Dashboard from './components/dashboard'; export const meta: MetaFunction = () => { - return [ - { title: "Welcome to FamCon" }, - { name: "description", content: "Welcome to Family Contributor!" }, - ]; + return [ + { title: 'Welcome to FamCon' }, + { name: 'description', content: 'Welcome to Family Contributor!' }, + ]; }; export default function Index() { - return ( - - - - ); + return ( + + + + ); } diff --git a/app/routes/contributors.$id.edit/route.tsx b/app/routes/contributors.$id.edit/route.tsx new file mode 100644 index 0000000..bb693ad --- /dev/null +++ b/app/routes/contributors.$id.edit/route.tsx @@ -0,0 +1,4 @@ +export default function ContributorEdit({ id }: { id: string }) { + // Implement edit form + return
Edit Contributor {id}
; +} diff --git a/app/routes/contributors.$id.view/route.tsx b/app/routes/contributors.$id.view/route.tsx new file mode 100644 index 0000000..1da001c --- /dev/null +++ b/app/routes/contributors.$id.view/route.tsx @@ -0,0 +1,4 @@ +export default function ContributorView({ id }: { id: string }) { + // Implement view details + return
View Contributor {id}
; +} diff --git a/app/routes/contributors.create/route.tsx b/app/routes/contributors.create/route.tsx new file mode 100644 index 0000000..2c6d62d --- /dev/null +++ b/app/routes/contributors.create/route.tsx @@ -0,0 +1,4 @@ +export default function ContributorCreate() { + // Implement create form + return
Create Contributor
; +} diff --git a/app/routes/contributors/components/columns.tsx b/app/routes/contributors/components/columns.tsx new file mode 100644 index 0000000..ac1c6c0 --- /dev/null +++ b/app/routes/contributors/components/columns.tsx @@ -0,0 +1,140 @@ +import { ColumnDef } from '@tanstack/react-table'; +import { Button } from '@/components/ui/button'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { ArrowDown, MoreHorizontal } from 'lucide-react'; +import { Checkbox } from '@/components/ui/checkbox'; +import { TPartialContributor } from '@/@types/contributors'; +import { useNavigate } from '@remix-run/react'; + +export const columns: ColumnDef[] = [ + { + id: 'select', + header: ({ table }) => { + return ( + { + table.toggleAllPageRowsSelected(!!value); + }} + /> + ); + }, + cell: ({ row }) => { + return ( + { + row.toggleSelected(!!value); + }} + /> + ); + }, + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: 'firstName', + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + return
{row.getValue('firstName')}
; + }, + }, + { + accessorKey: 'lastName', + header: 'Last Name', + }, + { + accessorKey: 'email', + header: 'Email', + }, + { + accessorKey: 'dependent', + header: 'Is Dependent?', + }, + { + accessorKey: 'gender', + header: 'Gender', + }, + { + accessorKey: 'contributionAmount', + header: () =>
Amount
, + cell: ({ row }) => { + const amount = parseFloat(row.getValue('contributionAmount')); + const formated = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }).format(amount); + + return ( +
+ {amount > 50 ? ( + {formated} + ) : ( + formated + )} +
+ ); + }, + }, + { + id: 'actions', + cell: ({ row }) => { + const contributor = row.original; + const navigate = useNavigate(); + + return ( + + + + + + Actions + + navigator.clipboard.writeText( + contributor.id.toString() + ) + } + > + Copy payment ID + + + + navigate(`/contributors/${contributor.id}/view`) + } + > + View Contributor + + + View payment details + + + + ); + }, + }, +]; diff --git a/app/routes/contributors/route.tsx b/app/routes/contributors/route.tsx index 1fe97b2..d0e25b5 100644 --- a/app/routes/contributors/route.tsx +++ b/app/routes/contributors/route.tsx @@ -1,38 +1,51 @@ -import MainLayout from "@/components/layouts/MainLayout"; +import MainLayout from '@/components/layouts/MainLayout'; -import { Button } from "@/components/ui/button"; +import { Button } from '@/components/ui/button'; -import { DemographicMap } from "@/components/atoms/role-demographics/demographic-map"; -import { ContributorSummaryCard } from "@/components/atoms/contributors/contributor-summary-card"; +import { ContributorSummaryCard } from '@/components/atoms/contributors/contributor-summary-card'; -import { Card } from "@/components/ui/card"; -import { columns } from "@/components/contributions/columns"; -import { Plus } from "lucide-react"; +import { Card } from '@/components/ui/card'; +import { Plus } from 'lucide-react'; -import { DataTable } from "@/components/contributions/data-table"; -import { contributors } from "@/components/contributions/data"; +import { columns } from './components/columns'; +import { contributors } from '@/data/contributors/data'; +import { CrudList } from '@/components/blocks/crud-list'; +import { TContributor, TPartialContributor } from '@/@types/contributors'; +import { ContributorService } from '@/services/contributors/contributor-service'; +import { useNavigate } from '@remix-run/react'; +// @Authorized(['admin']) export default function Contributors() { - return ( - - Add Contributor - - } - > -
-
- -
- - {/* table goes here */} + const navigate = useNavigate(); - {/* */} - - -
-
- ); + return ( + navigate('/contributors/create')} + > + Add Contributor + + } + > +
+
+ +
+ + + columns={columns} + data={contributors} + baseRoute={'/contributors'} + > + +
+
+ ); } diff --git a/app/services/contributors/contributor-service.ts b/app/services/contributors/contributor-service.ts new file mode 100644 index 0000000..cb05bbf --- /dev/null +++ b/app/services/contributors/contributor-service.ts @@ -0,0 +1,32 @@ +import { ICrudService } from '@/@types'; +import { TContributor, TPartialContributor } from '@/@types/contributors'; + +export class ContributorService implements ICrudService { + async getAll(): Promise { + // Implementation + throw new Error('Method not implemented.'); + } + + async getById(id: string): Promise { + // Implementation + throw new Error('Method not implemented.'); + } + + async create(item: Omit): Promise { + // Implementation + throw new Error('Method not implemented.'); + } + + async update( + id: string, + item: Partial + ): Promise { + // Implementation + throw new Error('Method not implemented.'); + } + + async delete(id: string): Promise { + // Implementation + throw new Error('Method not implemented.'); + } +}