FintechFrontendIn Progress

Villeto

Spend Management Platform

Villeto spend management dashboard showing expense tracking interface with transaction list and analytics

Role

Frontend Engineer

Category

Fintech · Frontend

Status

In Progress

Outcome

Production platform actively powering Villeto's business operations

Tech Stack

Next.jsTypeScriptZustandReact QueryTailwind CSSShadcn/ui

Overview

Villeto is a fintech startup building spend management tools for businesses. As their Frontend Engineer, I own the full dashboard — the primary interface through which business clients control their spending, cards, and vendor operations.

The Problem

Businesses using Villeto needed a single interface to manage their entire financial stack: virtual cards, expense tracking, vendor payments, and team permissions. Existing solutions were either too complex for SMBs or too limited for growing teams. The product needed to be fast, clear, and trustworthy — finance software earns trust through precision.

Process

I worked directly with the design and backend teams to define API contracts before any UI was built. This upfront alignment prevented the most common source of frontend rework. I chose Zustand over Redux for global state — the spend dashboard has deeply nested state across cards, transactions, and user permissions, and Zustand's flat store model kept things manageable without boilerplate overhead.

Technical Deep-Dive

The most interesting technical challenge was optimistic updates for transaction state. When a user freezes a virtual card, the UI must reflect that immediately — before the API confirms it — while gracefully handling failures. I built a custom hook that manages pending states as a Set of IDs, enabling per-item optimism without global loading flags.

Code Sample

Custom optimistic update hook — used throughout Villeto's card operations

typescript
// hooks/useOptimisticTransaction.ts — from Villeto codebase
export function useOptimisticTransaction<T extends { id: string }>(
  mutationFn: (item: T) => Promise<void>
) {
  const [pending, setPending] = useState<Set<string>>(new Set());

  const execute = useCallback(async (item: T) => {
    setPending(prev => new Set(prev).add(item.id));
    try {
      await mutationFn(item);
    } finally {
      setPending(prev => {
        const next = new Set(prev);
        next.delete(item.id);
        return next;
      });
    }
  }, [mutationFn]);

  return { execute, isPending: (id: string) => pending.has(id) };
}

Results

The dashboard is in production, actively used by Villeto's business clients. The optimistic update pattern reduced perceived latency on card operations, and the role-based access system handles the full permission matrix without performance impact.