Skip to content

Instantly share code, notes, and snippets.

@stefanoamorelli
Last active May 9, 2025 12:49
Show Gist options
  • Save stefanoamorelli/a448bc97d14bbae9e2d16e4ae298461b to your computer and use it in GitHub Desktop.
Save stefanoamorelli/a448bc97d14bbae9e2d16e4ae298461b to your computer and use it in GitHub Desktop.
Setup

Digit.dev workshop

Demo project

Installation

aider (free)

Gemini API Key

Get your Gemini API key (free tier)

fzf

fzf

gum

gum


Workshop files

Project business specs

πŸ“ One-Page Memecoin Portfolio Tracker – Product Requirements
🎯 Goal
A single-page web app that mocks a memecoin portfolio. All data is fake. Built with React and Tailwind CSS. Focus on fun UI/UX, minimal complexity.

πŸ“ Layout Overview
+---------------------------------------------+
|           πŸš€ My Memecoin Portfolio          |
+---------------------------------------------+
| Total Value: $69,420.00       β–² +4.20%      |
| β€œYou’re going to the moon! πŸŒ•β€              |
+---------------------------------------------+

| Coin   | Holdings | Price   | 24h % | Value   |
|--------|----------|---------|-------|---------|
| 🐢 DOGE | 10,000   | $0.08   | +2.1% | $800.00 |
| 🐸 PEPE | 42,069K  | $0.0001 | -1.2% | $4,206.90|
| 🍌 BAN  | 900      | $0.69   | +69%  | $621.00 |
+---------------------------------------------+

[ Refresh πŸ”„ ]         [ Dark Mode πŸŒ™ ]
βœ… Requirements
1. Single React Page
No routing.

One main component (App.jsx or similar).

State stored via useState.

2. Mock Data
Hardcoded in the component:

[
  { symbol: 'DOGE', name: 'DogeCoin', icon: '🐢', holdings: 10000, price: 0.08, change: 2.1 },
  { symbol: 'PEPE', name: 'PepeCoin', icon: '🐸', holdings: 42069000, price: 0.0001, change: -1.2 },
  { symbol: 'BAN',  name: 'Banana Token', icon: '🍌', holdings: 900, price: 0.69, change: 69 }
]
3. Core UI Sections
Header: Title, total value (sum of all holdings Γ— price), 24h gain/loss %.

Quote: Meme quote like β€œTo the moon!”

Table:

Icon + name

Holdings

Price

24h change (% with color: green/red)

Value per coin

Buttons:

πŸ”„ Fake refresh (randomizes 24h %)

πŸŒ™ Light/Dark mode toggle

4. Styling
Tailwind for layout, spacing, color, responsiveness

Responsive down to mobile

Fun meme fonts/colors (e.g., bold, Comic Sans–like optional vibe)

"based on these specs, create 1 react page"

CoinRow business specs

Component Name: CoinRow

Purpose:
The CoinRow component is responsible for displaying a single row of data about a specific cryptocurrency in a tabular format. It is typically used within a table that lists multiple cryptocurrencies owned by a user.

Input:
Prop: coin β€” An object of type Coin, which includes the following fields:
icon (string or JSX) β€” A visual representation or icon of the cryptocurrency.
symbol (string) β€” The ticker symbol of the cryptocurrency (e.g., BTC, ETH).
holdings (number) β€” The quantity of the coin the user holds.
price (number) β€” The current price per unit of the coin.
change (number) β€” The percentage change in the coin’s price over a certain period.

Display:
Each row (<tr>) includes five columns (<td>):
Coin Icon and Symbol: Displays the coin’s icon and its ticker symbol side by side.
Holdings: Shows the number of units the user owns, formatted with commas (e.g., 1,234.56).
Price: Shows the current price per unit, rounded to 4 decimal places and prefixed with $.
Price Change: Displays the percentage change. The text color is:

Green if the change is positive or zero.
Red if the change is negative.

Total Value: Calculates and displays the total value of the holdings (holdings Γ— price), formatted with commas and at least two decimal places, prefixed with $.

Design:
Uses padding (p-2) for consistent spacing in each cell.
Adds a border below each row for visual separation (border-b).

Adapts to light and dark themes using Tailwind's dark: utility classes.

CoinRow.test.tsx test file (manually written)

import React from 'react';
import { render, screen } from '@testing-library/react';
import CoinRow from './CoinRow';
import type { Coin } from '../types';

describe('CoinRow', () => {
  const mockCoin: Coin = {
    symbol: 'TEST',
    name: 'TestCoin',
    icon: 'πŸ§ͺ',
    holdings: 100,
    price: 1.2345,
    change: 5.5,
  };

  it('renders coin data correctly', () => {
    render(
      <table>
        <tbody>
          <CoinRow coin={mockCoin} />
        </tbody>
      </table>
    );

    expect(screen.getByText('πŸ§ͺ TEST')).toBeInTheDocument();
    expect(screen.getByText('100')).toBeInTheDocument(); // Holdings
    expect(screen.getByText('$1.2345')).toBeInTheDocument(); // Price
    expect(screen.getByText('5.5%')).toBeInTheDocument(); // Change
    expect(screen.getByText('$123.45')).toBeInTheDocument(); // Value
  });

  it('renders negative change with red color', () => {
    const negativeChangeCoin: Coin = { ...mockCoin, change: -2.0 };
    render(
      <table>
        <tbody>
          <CoinRow coin={negativeChangeCoin} />
        </tbody>
      </table>
    );
    const changeElement = screen.getByText('-2%'); // Use '-2%' instead of '-2.0%'
    expect(changeElement).toBeInTheDocument();
    expect(changeElement).toHaveClass('text-red-500');
  });

  it('renders positive change with green color', () => {
    render(
      <table>
        <tbody>
          <CoinRow coin={mockCoin} />
        </tbody>
      </table>
    );
    const changeElement = screen.getByText('5.5%');
    expect(changeElement).toBeInTheDocument();
    expect(changeElement).toHaveClass('text-green-500');
  });
});

Prompt

You are a senior software engineer tasked with implementing a scalable and maintainable React component.

Inputs:

- A business specification written in Markdown. It includes the functional description, user interface requirements, and any edge cases or constraints.
- A Vitest test file written manually, describing the expected behavior and usage of the component.

Your task:

- Read and understand the business specification and test file.
- Infer the structure, logic, props, and internal state of the component.

Write a complete React component (in TypeScript if type annotations are present in tests), following industry best practices for:

- Scalability (modular, composable structure)
- Maintainability (clear separation of concerns, minimal side effects)
- Accessibility (ARIA where relevant)
- Performance (memoization or lazy-loading if justified)
- Reusability (generic, configurable via props)

Requirements:

- Follow the Atomic Design or other consistent component hierarchy, if appropriate.
- Keep side effects isolated in useEffect or event handlers.
- Prefer hooks and functional components.
- Structure code for future extensibility.
- Ensure naming is clear and intuitive.
- Do not include the test file in the output.
- Include inline comments only where logic may be non-obvious.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment