Welcome to the Payment Search Challenge! This is a frontend coding challenge designed to assess your ability to implement a payment search feature using modern web technologies.
Your task is to build a payment search interface that allows users to:
- View payment details organised in a table
- Search for payments by payment ID & currency and clear filters
- Handle various edge cases and error states
- Implement pagination for the table
- π οΈ Tech Stack
- π‘ API Documentation
- π Localization (i18n)
- π Evaluation Criteria
- β±οΈ Time Limit
- π‘ Tips
- π Implementation Steps
Note: We don't expect candidates to complete all steps. Please work your way through the steps incrementally, focusing on quality over quantity. Each step builds upon the previous one, so take your time to implement each feature properly.
The project comes with the following pre-configured technologies:
- React 19 - For building the user interface
- TypeScript - For type safety and better developer experience
- Tailwind CSS - For styling and responsive design
- MSW (Mock Service Worker) - For API mocking
- Vitest - For testing
- Testing Library - For component testing
Note: You are free to use additional libraries, packages, or technologies to solve this challenge. Feel free to install and use any dependencies that will help you implement the features more effectively or improve the user experience.
Important: Please do not use AI tools (like ChatGPT, GitHub Copilot, etc.) to solve this challenge. We want to see your own coding style, problem-solving approach, and engineering decisions. This helps us understand your actual skills and thought process.
The project uses MSW to mock the payment search API. The API URL is defined in src/constants/index.ts
as API_URL = "/api/payments"
.
Endpoint: GET /api/payments
Description: Search and retrieve payments with filtering and pagination support.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
search |
string | No | "" |
Search term to filter payments (supports Payment ID, Status, Currency, Customer Name) |
currency |
string | No | "" |
Filter by currency code (USD , EUR , GBP , AUD , CAD , ZAR ) - available in src/constants/index.ts |
page |
number | No | 1 |
Page number for pagination |
pageSize |
number | No | 5 |
Number of payments per page |
GET /api/payments?search=pay_134¤cy=USD&page=1&pageSize=5
Success Response (200 OK):
{
"payments": [
{
"id": "pay_123456789",
"customerName": "John Doe",
"amount": 150.00,
"customerAddress": "123 Main St, City, Country",
"currency": "USD",
"status": "completed",
"date": "2024-01-15T10:30:00Z",
"description": "Payment for services",
"clientId": "cli_123"
}
],
"total": 25,
"page": 1,
"pageSize": 5
}
The mock API includes the following payment IDs for testing:
pay_134_1
,pay_134_2
,pay_134_3
,pay_134_4
,pay_134_5
- Various payment statusespay_205_1
,pay_205_2
,pay_205_3
,pay_205_4
,pay_205_5
- Multiple payments with different currenciespay_404
- Returns404
errorpay_500
- Returns500
error
Important: Use the i18n constants for all user-facing text. All strings can be found in the constants files:
- Main i18n strings:
src/constants/i18n.ts
- Contains all user-facing text including labels, buttons, messages, and table headers
Import the i18n constants like this:
import { I18N } from './constants/i18n';
Note: These strings are used by our tests and scoring system, so using the exact i18n constants is required for your solution to pass validation.
Your solution will be evaluated based on:
- π§Ή Clean, maintainable code
- π Proper TypeScript usage
- ποΈ Well-structured components
- π― Efficient state management
You have 60 minutes to complete this challenge. Focus on:
- Implementing core features first
- Ensuring basic functionality works
- Work on one step at a time, you don't need to complete all steps at once
- Start with Step 1 and work through each step incrementally
- Run tests after each step to verify your progress
- Keep accessibility in mind throughout development
- Use TypeScript effectively
- Test with the provided payment IDs to verify error handling
- Don't hesitate to install additional packages if they help you solve the problem more efficiently
- Consider using libraries for state management, form handling, or UI components if they improve your solution
This challenge is designed to be completed incrementally. Each step builds upon the previous one, and you can run tests to verify your progress.
Good luck! π
Goal: Fetch and display payments in a table with proper formatting
Requirements:
- Fetch payments from the API with
page=1
andpageSize=5
- Display payments in a table with headers using i18n strings (see
src/constants/i18n.ts
) - Format amounts and dates using the provided formatters (see
src/utils/formatters.ts
)
The main payments interface showing the search form, filters, and payment table
Test to pass: App - Step 1: Basic Payment List
Command to run: npm run test:step1
Goal: Add search functionality for payment IDs
Requirements:
- Add a search input with proper ARIA labels
- Add a search button
- Implement search functionality that queries the API
- Use the i18n strings for labels and placeholders (see
src/constants/i18n.ts
)
Search input for payments by payment ID
Searching for payments by payment ID with results displayed in the table
Test to pass: App - Step 2: Search by Payment ID
Command to run: npm run test:step2
Goal: Add ability to clear all active filters
Requirements:
- Show a "Clear Filters" button when any filter is active
- Reset the search input to empty
- Hide the clear button when no filters are active
Test to pass: App - Step 3: Clear Filters
Command to run: npm run test:step3
Goal: Display appropriate error message when payment is not found
Requirements:
- Handle 404 responses from the API (use
pay_404
as the payment ID) - Display the error message from i18n constants
- Show the error message in a user-friendly way
Error message displayed when a payment is not found (404 error)
Test to pass: App - Step 4: Handle Payment Not Found
Command to run: npm run test:step4
Goal: Display error message for server errors
Requirements:
- Handle 500 responses from the API (use
pay_500
as the payment ID) - Display the appropriate error message from i18n
- Ensure the error is clearly visible to users
Error message displayed when a server error occurs (500 error)
Test to pass: App - Step 5: Handle Server Error
Command to run: npm run test:step5
Goal: Add currency filtering functionality
Requirements:
- Add a currency dropdown with all available currencies
- Filter payments by selected currency
- Use proper ARIA labels for accessibility
- Include all currencies: USD, EUR, GBP, AUD, CAD, ZAR (see
src/constants/index.ts
) - Clear all filters clicked should clear the currency filter
Filtering payments by currency using the dropdown selector
Test to pass: App - Step 6: Currency Filter
Command to run: npm run test:step6
Goal: Ensure currency and payment ID filters work together
Requirements:
- Allow filtering by both currency and payment ID simultaneously
- Ensure the API receives both filter parameters
- Display results that match both criteria
Filtering payments by payment ID and currency
Test to pass: App - Step 7: Combined Currency and Payment ID Filter
Command to run: npm run test:step7
Goal: Implement pagination functionality
Requirements:
- Display pagination controls (Previous/Next buttons) (use the i18n strings for the buttons the icons are unicode characters in the i18n strings)
- Show current page number (e.g., "Page 1")
- Disable Previous button on first page
- Enable Previous button after navigating to next page
- Show different payments on different pages
- Allow navigation back to previous pages
Pagination controls allowing navigation between pages of results
Pagination controls allowing navigation between pages of results
Test to pass: App - Step 8: Pagination
Command to run: npm run test:step8