diff --git a/app/components/TransactionTable.stories.tsx b/app/components/TransactionTable.stories.tsx new file mode 100644 index 0000000..e74bd4a --- /dev/null +++ b/app/components/TransactionTable.stories.tsx @@ -0,0 +1,102 @@ +import type { Meta, StoryObj } from "@storybook/nextjs-vite"; +import TransactionTable from "./TransactionTable"; +import { demoTransactions, demoPrisms, demoContacts } from "./fixtures/transactionTableData"; + +const meta: Meta = { + title: "Components/TransactionTable", + component: TransactionTable, + parameters: { + layout: "padded", + }, + tags: ["autodocs"], + argTypes: { + transactions: { + control: "object", + description: "Array of transaction data to display in the table", + }, + prisms: { + control: "object", + description: "Array of available prisms for filtering", + }, + contacts: { + control: "object", + description: "Array of contacts for user filtering", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +/** + * Default story with demo data showing the full transaction table with filters and pagination + */ +export const WithDemoData: Story = { + args: { + transactions: demoTransactions, + prisms: demoPrisms, + contacts: demoContacts, + }, +}; + +/** + * Empty state - shows how the table looks with no data + */ +export const Empty: Story = { + args: { + transactions: [], + prisms: [], + contacts: [], + }, +}; + +/** + * Single transaction - useful for testing the table with minimal data + */ +export const SingleTransaction: Story = { + args: { + transactions: [demoTransactions[0]], + prisms: [demoPrisms[0]], + contacts: [demoContacts[0]], + }, +}; + +/** + * Few transactions - shows pagination behavior with limited data + */ +export const FewTransactions: Story = { + args: { + transactions: demoTransactions.slice(0, 3), + prisms: demoPrisms.slice(0, 3), + contacts: demoContacts.slice(0, 3), + }, +}; + +/** + * With favorites - demonstrates transactions marked as favorites + */ +export const WithFavorites: Story = { + args: { + transactions: demoTransactions.map((txn, idx) => ({ + ...txn, + isFavorite: idx % 2 === 0, // Mark every other transaction as favorite + })), + prisms: demoPrisms, + contacts: demoContacts, + }, +}; + +/** + * Mixed statuses - shows all different transaction statuses + */ +export const MixedStatuses: Story = { + args: { + transactions: [ + { ...demoTransactions[0], status: 'Successful' as const }, + { ...demoTransactions[1], status: 'Pending' as const }, + { ...demoTransactions[2], status: 'Active' as const }, + ], + prisms: demoPrisms.slice(0, 3), + contacts: demoContacts.slice(0, 3), + }, +}; diff --git a/app/components/TransactionTable.tsx b/app/components/TransactionTable.tsx index c22e735..5d06af9 100644 --- a/app/components/TransactionTable.tsx +++ b/app/components/TransactionTable.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useRef } from 'react'; import { useRouter } from 'next/navigation'; import { ChevronUpIcon, ArrowRightIcon } from '@heroicons/react/24/outline'; +import type { Transaction } from './fixtures/transactionTableData'; const calendarIcon = "https://www.figma.com/api/mcp/asset/c83e973c-82cb-4edc-a5b4-c87f5774c875"; const starIconFilled = "https://www.figma.com/api/mcp/asset/e4b8e6a1-81fb-4b30-8c31-dad418948756"; @@ -10,19 +11,6 @@ const starIconOutline = "https://www.figma.com/api/mcp/asset/af286206-fd17-4ad9- const chevronDownIcon = "https://www.figma.com/api/mcp/asset/e353d42f-828c-4a09-a6cf-c4d48027b1b6"; const arrowLeftIcon = "https://www.figma.com/api/mcp/asset/79630a33-05bd-489c-a889-a56fbcdbdc81"; -interface Transaction { - id: string; - date: string; - prism: string; - prismId?: string; - amount: string; - status: 'Successful' | 'Pending' | 'Active'; - account: string; - accountId?: string; - paymentMode?: string; - isFavorite?: boolean; -} - interface TransactionTableProps { transactions?: Transaction[]; prisms?: Array<{ id: string; name: string }>; @@ -59,82 +47,6 @@ export default function TransactionTable({ const paymentModeDropdownRef = useRef(null); const rowsPerPageRef = useRef(null); - // Default sample data if none provided - const defaultTransactions: Transaction[] = [ - { - id: '1', - date: '06/2025', - prism: 'bitcoin Pizza', - amount: '$1,250.00', - status: 'Successful', - account: 'Jamie Smith', - isFavorite: false, - }, - { - id: '2', - date: '07/2025', - prism: 'Crypto Feast', - amount: '$500.00', - status: 'Pending', - account: 'Alex Johnson', - isFavorite: false, - }, - { - id: '3', - date: '09/2025', - prism: 'Tech Summit', - amount: '225078764578.00 sats', - status: 'Successful', - account: 'QHFI8WE8DYHWEBJhbsbdcus...', - isFavorite: true, - }, - { - id: '4', - date: '11/2025', - prism: 'Health Expo', - amount: '3000.00 Sats', - status: 'Active', - account: 'Michael Brown', - isFavorite: false, - }, - { - id: '5', - date: '06/2024', - prism: 'The true man show movie...', - amount: '999999999999999 Sats', - status: 'Active', - account: 'deekshasatapathy@twelve.cash', - isFavorite: false, - }, - { - id: '6', - date: '04/2025', - prism: 'Fashion Week', - amount: '56.5643679 Sats', - status: 'Successful', - account: 'Jessica Lee', - isFavorite: false, - }, - { - id: '7', - date: '08/2025', - prism: 'Food Festival', - amount: '1 Btc', - status: 'Successful', - account: 'kcuabcjbau2e482r982hufwueff...', - isFavorite: false, - }, - { - id: '8', - date: '12/2025', - prism: 'Finance Forum', - amount: '$1,200.00', - status: 'Pending', - account: 'Rachel Adams', - isFavorite: false, - }, - ]; - // Close dropdowns when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { @@ -206,8 +118,7 @@ export default function TransactionTable({ }); }; - const displayTransactions = transactions.length > 0 ? transactions : defaultTransactions; - const filteredTransactions = filterTransactions(displayTransactions); + const filteredTransactions = filterTransactions(transactions); const totalTransactions = filteredTransactions.length; const totalPages = Math.ceil(totalTransactions / rowsPerPage); const startIndex = (currentPage - 1) * rowsPerPage; @@ -229,7 +140,7 @@ export default function TransactionTable({ }; // Get unique payment modes from transactions - const paymentModes: string[] = Array.from(new Set(displayTransactions.map(t => t.paymentMode).filter((m): m is string => Boolean(m)))); + const paymentModes: string[] = Array.from(new Set(transactions.map(t => t.paymentMode).filter((m): m is string => Boolean(m)))); // Get display name for user const getUserDisplayName = (contact: { firstName?: string | null; lastName?: string | null; screenName?: string | null; email?: string | null }) => { diff --git a/app/components/fixtures/transactionTableData.ts b/app/components/fixtures/transactionTableData.ts new file mode 100644 index 0000000..3fdaa39 --- /dev/null +++ b/app/components/fixtures/transactionTableData.ts @@ -0,0 +1,114 @@ +/** + * Demo/fixture data for TransactionTable component + * Used for Storybook stories and development/testing + */ + +export interface Transaction { + id: string; + date: string; + prism: string; + prismId?: string; + amount: string; + status: 'Successful' | 'Pending' | 'Active'; + account: string; + accountId?: string; + paymentMode?: string; + isFavorite?: boolean; +} + +export const demoTransactions: Transaction[] = [ + { + id: '1', + date: '06/2025', + prism: 'bitcoin Pizza', + amount: '$1,250.00', + status: 'Successful', + account: 'Jamie Smith', + isFavorite: false, + }, + { + id: '2', + date: '07/2025', + prism: 'Crypto Feast', + amount: '$500.00', + status: 'Pending', + account: 'Alex Johnson', + isFavorite: false, + }, + { + id: '3', + date: '09/2025', + prism: 'Tech Summit', + amount: '225078764578.00 sats', + status: 'Successful', + account: 'QHFI8WE8DYHWEBJhbsbdcus...', + isFavorite: true, + }, + { + id: '4', + date: '11/2025', + prism: 'Health Expo', + amount: '3000.00 Sats', + status: 'Active', + account: 'Michael Brown', + isFavorite: false, + }, + { + id: '5', + date: '06/2024', + prism: 'The true man show movie...', + amount: '999999999999999 Sats', + status: 'Active', + account: 'deekshasatapathy@twelve.cash', + isFavorite: false, + }, + { + id: '6', + date: '04/2025', + prism: 'Fashion Week', + amount: '56.5643679 Sats', + status: 'Successful', + account: 'Jessica Lee', + isFavorite: false, + }, + { + id: '7', + date: '08/2025', + prism: 'Food Festival', + amount: '1 Btc', + status: 'Successful', + account: 'kcuabcjbau2e482r982hufwueff...', + isFavorite: false, + }, + { + id: '8', + date: '12/2025', + prism: 'Finance Forum', + amount: '$1,200.00', + status: 'Pending', + account: 'Rachel Adams', + isFavorite: false, + }, +]; + +export const demoPrisms = [ + { id: '1', name: 'bitcoin Pizza' }, + { id: '2', name: 'Crypto Feast' }, + { id: '3', name: 'Tech Summit' }, + { id: '4', name: 'Health Expo' }, + { id: '5', name: 'The true man show movie...' }, + { id: '6', name: 'Fashion Week' }, + { id: '7', name: 'Food Festival' }, + { id: '8', name: 'Finance Forum' }, +]; + +export const demoContacts = [ + { id: '1', firstName: 'Jamie', lastName: 'Smith', screenName: null, email: 'jamie.smith@example.com' }, + { id: '2', firstName: 'Alex', lastName: 'Johnson', screenName: null, email: 'alex.johnson@example.com' }, + { id: '3', firstName: null, lastName: null, screenName: 'CryptoUser123', email: 'crypto@example.com' }, + { id: '4', firstName: 'Michael', lastName: 'Brown', screenName: null, email: 'michael.brown@example.com' }, + { id: '5', firstName: null, lastName: null, screenName: null, email: 'deekshasatapathy@twelve.cash' }, + { id: '6', firstName: 'Jessica', lastName: 'Lee', screenName: null, email: 'jessica.lee@example.com' }, + { id: '7', firstName: null, lastName: null, screenName: 'BitcoinLover', email: 'btc@example.com' }, + { id: '8', firstName: 'Rachel', lastName: 'Adams', screenName: null, email: 'rachel.adams@example.com' }, +];