Client Work — React + TypeScript
November 2025 – Present
An internal financial dashboard that transforms complex POS data into clear, actionable insights for restaurant managers and accountants. Compares point-of-sale transactions with actual payment tenders across multiple payment methods, highlighting discrepancies in real time. This ongoing project demonstrates expertise in data visualisation, business logic implementation, and building practical tools that solve real operational challenges.

Payment reconciliation interface with colour-coded status indicators and difference calculations (sample data).
Technical Implementation
Key Features
Handles iZettle, Vipps, Cash, Gift Cards, and multiple payment methods with separate tip tracking.
Colour-coded differences (green for matched, yellow for minor, red for significant) with clear icons.
Tracks three locations (DLC, Cafe, Odins) with location-specific colour schemes.
Easy navigation between days with period status tracking and validation checks.
Automatic warnings for open tables, unclosed periods, and open food items.
Built-in cash counting modal with API submission to payment system.
Development Process
Before this dashboard, managers had to manually scroll through raw POS data to reconcile daily transactions. The process was time-consuming, error-prone, and required mental math to spot discrepancies across multiple payment methods and tip categories.
Transform Raw Data into Clear Tables
Before: raw numbers requiring scrolling and manual calculations.
After: clean, organised table showing POS vs Tenders with automatic difference calculations and visual status indicators.
Impact: saves several minutes per closing and reduces accounting errors.
The most technically challenging aspect was implementing the payment method routing logic. Different payment methods appear in different columns (POS-only, Tenders-only, or both), and tips are tracked separately for specific methods. This required careful conditional rendering and business rule implementation.
Implementation Highlights
shouldShowInPOS(): determines which methods display in POS column (excludes delivery types).
shouldShowInTenders(): filters POS-only methods like faktura, offline, brekk.
Tip Tracking: separate logic for POS tips vs Tender tips per payment method.
This project is actively developed and improved based on real user feedback from managers and accountants. Working in test mode allows safe development while the backend team builds out remaining features.
Current Status
Completed: core reconciliation UI, payment routing, visual indicators, date navigation.
In Progress: cash counter backend integration, testing with staff.
Next: production rollout to all locations.
Challenges & Solutions
Challenge: Different payment methods need to appear in different table columns with specific tip handling rules.
Solution: Created helper functions (shouldShowInPOS, shouldShowInTenders, shouldShowPOSTips) that encapsulate business rules and keep components clean.
Challenge: Making 6+ payment methods with separate amounts, tips, and differences immediately understandable.
Solution: Colour-coded status system, clear icons, and organised table layout with distinct POS vs Tenders columns.
Challenge: Managing period status, open tables, open items, payment data, and location state efficiently.
Solution: React hooks (useState, useEffect, useCallback) with proper dependency arrays and memoisation for optimal performance.
Challenge: Coordinating frontend development with backend API development by Jerome.
Solution: Test mode flag for safe frontend development, clear API contract definition, and iterative integration testing.
Planned Enhancements
Complete cash counter API integration for direct submission to payment system.
Enhanced mobile layout for managers doing closing on tablets or phones.
Add charts showing reconciliation patterns over time to identify recurring issues.
Export reconciliation data to CSV for accounting software integration.