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
79 changes: 79 additions & 0 deletions app/components/TransactionTable.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Demo data for TransactionTable component
// Use in Storybook or when showDemoData prop is true

import type { Transaction } from './TransactionTable';

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,
},
Comment on lines +6 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add prismId/accountId to demo rows used by filters.

Filters match on prismId/accountId; without them, selecting a prism/contact filters out all demo rows. Add matching IDs for the demo entries so filters remain meaningful.

🛠️ Suggested change (sample)
   {
     id: '1',
     date: '06/2025',
     prism: 'bitcoin Pizza',
+    prismId: 'prism-1',
     amount: '$1,250.00',
     status: 'Successful',
     account: 'Jamie Smith',
+    accountId: 'contact-1',
     isFavorite: false,
   },
   {
     id: '2',
     date: '07/2025',
     prism: 'Crypto Feast',
+    prismId: 'prism-2',
     amount: '$500.00',
     status: 'Pending',
     account: 'Alex Johnson',
+    accountId: 'contact-2',
     isFavorite: false,
   },
   {
     id: '3',
     date: '09/2025',
     prism: 'Tech Summit',
+    prismId: 'prism-3',
     amount: '225078764578.00 sats',
🤖 Prompt for AI Agents
In `@app/components/TransactionTable.data.ts` around lines 6 - 33, The
demoTransactions array is missing prismId and accountId fields used by the
filtering logic; update each object in the exported demoTransactions (and ensure
it matches the Transaction type) to include prismId and accountId values that
correspond to actual prism/contact IDs used by the filters so demo rows are
returned when a prism or account is selected (e.g., add prismId: 'bitcoin-pizza'
/ accountId: 'jamie-smith' or whatever canonical IDs your filters expect for the
three entries).

{
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,
Comment on lines +45 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace real-looking email with placeholder data.

Demo data should avoid real-looking email addresses to prevent accidental PII in the repo.

🛡️ Suggested change
-    account: 'deekshasatapathy@twelve.cash',
+    account: 'deeksha.s@example.com',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
date: '06/2024',
prism: 'The true man show movie...',
amount: '999999999999999 Sats',
status: 'Active',
account: 'deekshasatapathy@twelve.cash',
isFavorite: false,
date: '06/2024',
prism: 'The true man show movie...',
amount: '999999999999999 Sats',
status: 'Active',
account: 'deeksha.s@example.com',
isFavorite: false,
🤖 Prompt for AI Agents
In `@app/components/TransactionTable.data.ts` around lines 45 - 50, The demo data
contains a real-looking email in the transaction object (the account field in
the record with date '06/2024'); replace that value with a non-identifying
placeholder (e.g., "user@example.com" or "placeholder@example.com") so no PII is
checked into the repo and update any other similar account fields in
TransactionTable.data.ts to use the same placeholder convention.

},
{
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,
},
];
108 changes: 108 additions & 0 deletions app/components/TransactionTable.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import type { Meta, StoryObj } from '@storybook/react';
import TransactionTable from './TransactionTable';
import { demoTransactions } from './TransactionTable.data';

const meta: Meta<typeof TransactionTable> = {
title: 'Components/TransactionTable',
component: TransactionTable,
parameters: {
layout: 'padded',
},
tags: ['autodocs'],
argTypes: {
showDemoData: {
control: 'boolean',
description: 'Show demo data when no transactions provided',
},
transactions: {
control: 'object',
description: 'Array of transactions to display',
},
},
};

export default meta;
type Story = StoryObj<typeof TransactionTable>;

/**
* Default state with demo data enabled for visualization
*/
export const WithDemoData: Story = {
args: {
showDemoData: true,
},
};

/**
* Empty state when no transactions and showDemoData is false
*/
export const Empty: Story = {
args: {
showDemoData: false,
transactions: [],
},
};

/**
* With custom transactions passed as props
*/
export const WithCustomData: Story = {
args: {
showDemoData: false,
transactions: [
{
id: 'custom-1',
date: '01/2026',
prism: 'Monthly Subscription',
amount: '$9.99',
status: 'Successful',
account: 'john@example.com',
isFavorite: false,
},
{
id: 'custom-2',
date: '01/2026',
prism: 'One-time Purchase',
amount: '50000 Sats',
status: 'Pending',
account: 'jane@example.com',
isFavorite: true,
},
],
},
};

/**
* With filters populated (prisms and contacts)
*/
export const WithFilters: Story = {
args: {
showDemoData: true,
prisms: [
{ id: 'prism-1', name: 'Bitcoin Pizza' },
{ id: 'prism-2', name: 'Crypto Feast' },
{ id: 'prism-3', name: 'Tech Summit' },
],
contacts: [
{ id: 'contact-1', firstName: 'Jamie', lastName: 'Smith', email: 'jamie@example.com' },
{ id: 'contact-2', firstName: 'Alex', lastName: 'Johnson', email: 'alex@example.com' },
],
},
};

/**
* Interactive playground with all controls
*/
export const Playground: Story = {
args: {
showDemoData: true,
transactions: demoTransactions,
prisms: [
{ id: 'prism-1', name: 'Bitcoin Pizza' },
{ id: 'prism-2', name: 'Crypto Feast' },
],
contacts: [
{ id: 'contact-1', firstName: 'Jamie', lastName: 'Smith' },
],
},
};
92 changes: 13 additions & 79 deletions app/components/TransactionTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import { useState, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { ChevronUpIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
import { demoTransactions } from './TransactionTable.data';

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 {
export interface Transaction {
id: string;
date: string;
prism: string;
Expand All @@ -24,15 +25,21 @@ interface Transaction {
}

interface TransactionTableProps {
/** Array of transactions to display */
transactions?: Transaction[];
/** Available prisms for filtering */
prisms?: Array<{ id: string; name: string }>;
/** Available contacts for filtering */
contacts?: Array<{ id: string; firstName?: string | null; lastName?: string | null; screenName?: string | null; email?: string | null }>;
/** When true, shows demo data if no transactions provided. Use for Storybook/demos. */
showDemoData?: boolean;
}

export default function TransactionTable({
transactions = [],
prisms = [],
contacts = []
contacts = [],
showDemoData = false
}: TransactionTableProps) {
const router = useRouter();
const [favorites, setFavorites] = useState<Set<string>>(new Set());
Expand All @@ -59,82 +66,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,7 +137,10 @@ export default function TransactionTable({
});
};

const displayTransactions = transactions.length > 0 ? transactions : defaultTransactions;
// Use provided transactions, or demo data if showDemoData is true, otherwise empty
const displayTransactions = transactions.length > 0
? transactions
: (showDemoData ? demoTransactions : []);
const filteredTransactions = filterTransactions(displayTransactions);
const totalTransactions = filteredTransactions.length;
const totalPages = Math.ceil(totalTransactions / rowsPerPage);
Expand Down
31 changes: 21 additions & 10 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@ const compat = new FlatCompat({
baseDirectory: __dirname,
});

const eslintConfig = [...compat.extends("next/core-web-vitals", "next/typescript"), {
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
},
},
}, ...storybook.configs["flat/recommended"]];
...storybook.configs["flat/recommended"],
{
// Disable no-renderer-packages rule - we correctly use @storybook/nextjs-vite
// but the rule incorrectly flags transitive @storybook/react dependency
rules: {
"storybook/no-renderer-packages": "off",
},
},
];

export default eslintConfig;