Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions app/components/TransactionTable.stories.tsx
Original file line number Diff line number Diff line change
@@ -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<typeof TransactionTable> = {
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<typeof meta>;

/**
* 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),
},
};
95 changes: 3 additions & 92 deletions app/components/TransactionTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,14 @@
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";
const starIconOutline = "https://www.figma.com/api/mcp/asset/af286206-fd17-4ad9-9042-9ba3cc6cf3cc";
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 }>;
Expand Down Expand Up @@ -59,82 +47,6 @@ export default function TransactionTable({
const paymentModeDropdownRef = useRef<HTMLDivElement>(null);
const rowsPerPageRef = useRef<HTMLDivElement>(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) => {
Expand Down Expand Up @@ -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;
Expand All @@ -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 }) => {
Expand Down
114 changes: 114 additions & 0 deletions app/components/fixtures/transactionTableData.ts
Original file line number Diff line number Diff line change
@@ -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' },
];