Hone logo
Hone
Problems

Interactive Kanban Board in React with TypeScript

Build a functional and interactive Kanban board application using React and TypeScript. This challenge will test your ability to manage component state, handle user interactions, and implement drag-and-drop functionality, all while ensuring type safety. A Kanban board is a visual project management tool that helps teams organize and track work, making it a fundamental component for many productivity applications.

Problem Description

Your task is to create a Kanban board where users can:

  1. Display Columns: Render multiple columns (e.g., "To Do", "In Progress", "Done"). Each column should have a title.
  2. Display Cards: Within each column, display cards representing individual tasks. Each card should have a title and potentially a description.
  3. Add New Cards: Allow users to add new cards to a specific column. This could be via a button or an input field.
  4. Edit Card Details: Enable users to edit the title and/or description of an existing card.
  5. Delete Cards: Provide a mechanism to delete cards from the board.
  6. Drag and Drop Cards: Implement drag-and-drop functionality allowing users to move cards between columns and reorder cards within the same column.
  7. Persistence (Optional but Recommended): If time permits, explore ways to persist the board state (e.g., using local storage or a simple API).

Key Requirements:

  • All components should be implemented using React function components and TypeScript.
  • State management should be handled efficiently, considering the dynamic nature of the Kanban board.
  • The drag-and-drop mechanism should be intuitive and responsive.
  • The application should be well-structured and maintainable.

Expected Behavior:

  • Users can see predefined columns with cards.
  • Clicking an "Add Card" button or similar UI element within a column should allow a new card to be created in that column.
  • Clicking on a card should reveal an editing interface (e.g., a modal or inline editing).
  • A "Delete" button or icon should be present on each card, allowing its removal.
  • Users can click and hold a card, drag it to a different column or reorder it within its current column, and drop it to update its position.

Edge Cases to Consider:

  • Empty columns: How does the UI behave when a column has no cards?
  • Long card titles/descriptions: How should text be handled to prevent UI overflow?
  • Concurrent drag operations (though less critical for a single-user client-side app).
  • User canceling a drag operation.

Examples

Example 1: Initial State

Input Data (Conceptual):
{
  columns: [
    { id: 'col-1', title: 'To Do', cards: [{ id: 'card-1', title: 'Design UI', description: 'Create mockups for the homepage.' }] },
    { id: 'col-2', title: 'In Progress', cards: [] },
    { id: 'col-3', title: 'Done', cards: [{ id: 'card-2', title: 'Setup project', description: 'Initialize React project with TypeScript.' }] }
  ]
}
Output (Conceptual UI Representation):
--------------------------------------------------------------------
| To Do               | In Progress        | Done               |
--------------------------------------------------------------------
| [Card: Design UI    |                    | [Card: Setup       |
|  Description:       |                    |  project           |
|  Create mockups...] |                    |  Description:      |
|                     |                    |  Initialize React..|
--------------------------------------------------------------------
| [+ Add Card]        | [+ Add Card]       | [+ Add Card]       |
--------------------------------------------------------------------

Example 2: Dragging a Card

  • User Action: Drags "Design UI" card from "To Do" to "In Progress".
  • Expected State Change: The columns data structure updates to reflect the card's new position.
Updated Data (Conceptual):
{
  columns: [
    { id: 'col-1', title: 'To Do', cards: [] },
    { id: 'col-2', title: 'In Progress', cards: [{ id: 'card-1', title: 'Design UI', description: 'Create mockups for the homepage.' }] },
    { id: 'col-3', title: 'Done', cards: [{ id: 'card-2', title: 'Setup project', description: 'Initialize React project with TypeScript.' }] }
  ]
}

Example 3: Adding a Card

  • User Action: Clicks "+ Add Card" in the "To Do" column and enters "Write tests" for the title.
  • Expected State Change: A new card is added to the "To Do" column.
Updated Data (Conceptual):
{
  columns: [
    { id: 'col-1', title: 'To Do', cards: [{ id: 'card-1', title: 'Design UI', description: 'Create mockups for the homepage.' }, { id: 'card-3', title: 'Write tests', description: '' }] },
    { id: 'col-2', title: 'In Progress', cards: [] },
    { id: 'col-3', title: 'Done', cards: [{ id: 'card-2', title: 'Setup project', description: 'Initialize React project with TypeScript.' }] }
  ]
}

Constraints

  • The application must be built using React and TypeScript.
  • Avoid using external libraries for the core Kanban board logic (e.g., pre-built Kanban component libraries) unless specifically allowed for drag-and-drop. You are encouraged to use a popular drag-and-drop library like react-beautiful-dnd or explore native HTML5 drag-and-drop API.
  • Initial data structure for columns and cards should be managed within the React component's state (e.g., using useState or useReducer).
  • The solution should be client-side only.

Notes

  • Consider how you will manage unique IDs for columns and cards.
  • Think about the data flow and how state updates will propagate through your components.
  • For drag-and-drop, focus on a smooth user experience.
  • Break down the problem into smaller, manageable components (e.g., KanbanBoard, Column, Card, AddCardForm).
  • Hint: You might want to define interfaces for Card and Column to leverage TypeScript's type checking. For drag-and-drop, consider libraries that provide good accessibility and performance.
Loading editor...
typescript