To all worksCase study

Ukraine Pooled Fund

A bilingual site for a fund that channels international donor money to Ukrainian NGOs, designed, built, and shipped by one person, with a CMS the fund's own team runs without me.

Team
One person: me, working directly with the fund's non-technical staff
Scope
Public multi-page site, custom admin, interactive partner map, bilingual content
Role
Design and build end to end: product design, front-end, CMS, deployment
Stack
Next.js, Payload CMS, PostgreSQL, Vercel

Founded in 2023, the Ukraine Pooled Fund is one of the first fully localised pooled funds in the country: five Ukrainian organisations run it as a consortium, splitting grant-making, verification, monitoring, and capacity-building between them, so the site had to answer to two audiences at once. International donors need to trust the fund before they read a single grant term. Ukrainian NGOs need a clear, practical path to apply. There was no site, no CMS, and no one on the team who could build either.

Ukraine Pooled Fund homepage hero section, bilingual site
The homepage hero. A clean look, nothing extra, calm and confident.

I took the project from a blank page to a deployed, editable product: information architecture, visual design, the Next.js front end, a Payload CMS admin, and the Vercel deployment. No handoff, no separate developer. What follows is four of the decisions that shaped it.


Decision log

Showing a nationwide fund without a list of logos

The clearest proof the fund could offer a donor is where its partner organisations actually are: 29 of them, spread across 12 oblasts, funded from grants that had already reached over 50,000 people. A homepage centrepiece was the obvious call; the question was what that centrepiece should be.

  1. A

    A static grid of partner logos, grouped by region

    Rejected

    Cheapest to build, and the honest first instinct. But a grid can't show that the fund's reach is nationwide. A donor scanning the homepage for ten seconds would see a logo wall, not a country.

  2. B

    An embedded third-party map widget

    Rejected

    Fast to wire up, but it meant shipping someone else's styling, someone else's language switching, and a dependency the team couldn't edit themselves. The map needed to feel like part of the site, not a plugin dropped into it.

  3. C

    A custom SVG map, pins driven by CMS data

    Shipped

    Each of Ukraine's regions is its own SVG shape, matched to partner records in the CMS. Adding an organisation in a new oblast is a form the team fills in, not a line of code I have to write for them.

Interactive map of Ukraine showing partner organisations by region
The partner map. Every region is its own shape, matched against partner records pulled live from the CMS: 29 partners across 12 oblasts at last count. Adding one in a new oblast needs no code.

Admin

An admin the team can run without waiting on me

Problem
The fund has no developer on staff. Every section of the site, every partner record, every report, every blog post needed a way to change without a pull request or a message to me.
Decision
I built the CMS admin so every editable part of the site, homepage sections, partner and report listings, blog posts, even shared header and footer content, has its own form. A role matrix decides who can view, edit, or publish each part, so the fund can add staff without me touching permissions.
Outcome
The team publishes a new report or a partner update themselves, the same afternoon it's ready, with no deploy and no ticket to me.
Payload CMS admin panel showing editable page sections
The admin panel. Every page is a set of editable blocks. Reports, blog posts, and partner records are separate collections the team manages on their own.

SEO

Editing how a page shows up in search, without a deploy

Problem
Search titles, descriptions, and share images needed to change often, a new report, a renamed partner, a share image that looked wrong on LinkedIn, and every one of those would otherwise mean a pull request to me before it could go live.
Decision
Every page carries its own SEO fields in the CMS, title, description, share image, editable the same way as any other content block. Saving one revalidates just that page, not the whole site.
Outcome
The team fixes a missing share image or rewrites a meta description themselves, live within seconds, with no deploy and no message to me.
Per-page SEO settings panel in the Ukraine Pooled Fund CMS admin
Per-page SEO, in the admin. Title, description, and share image, editable per page, the same as any other content block.

Blog

Publishing news and resources without a developer in the loop

Problem
The fund needed to publish news and resource materials for NGOs on an ongoing basis, and a page built by me for every post would have made that depend on my availability, not theirs.
Decision
Blog posts and resource materials are their own collection in the CMS, with the same field-level control as the rest of the site: draft, preview, and publish, no code and no template per post.
Outcome
The team publishes a new post or resource the day it's ready, on its own schedule, months after I shipped the last line of code.

The map earns a donor's trust in the first few seconds. The admin behind it is what keeps that trust current without me: the fund publishes, translates, and adds partners on its own schedule, months after I shipped the last line of code.