
Bridge
An internal tool for updating water restriction data via the Water Restrictions API. Built with Nuxt.
I built Bridge to simplify updating water restriction data, which I had previously been doing with manual API calls. It also gave me the chance to brush up on my front-end skills and to try out Nuxt and Vue.js, which I hadn’t used before.
Implementation ⚙️
Tech stack
This project uses my standard platform setup.
Frontend:
Backend:
- NuxtAuth - Authentication
- AWS Cognito - Authorization for the Water Restrictions API
Infrastructure:
- Cloudflare Access - Access control
- DigitalOcean App Platform - Hosting
- Terraform - Infrastructure as code for managing the project’s resources
- GitHub Actions - CI/CD for automated deployment and infra workflows
Entities and relationships
The Water Restrictions API is the gatekeeper for all water restriction data. Bridge interacts with it to manage the data. For some context on the content of this page, here are the main entities and their relationships:
- Organisations are responsible for setting water restrictions for one or more areas. Typically, this is a local council or water entity.
- Areas are geographical locations, such as a region, city or town, where water restrictions can apply.
- Schemes are defined sets of water restriction stages. They can apply to one or more areas.
- Stages represent levels of water restrictions, typically increasing in severity (eg. Level 1, Level 2, etc.).
Presenting Data and Actions 💻
Using PrimeVue for the UI components allowed me to focus on building the functionality of the app rather than designing UI components from scratch. It provides a large number of components out of the box and is relatively easy to use.
Bridge is mainly a data management app so most of the data is presented in tables. It was interesting playing around with the different table functionality that PrimeVue provides - like filtering, sorting, and grouping of data.
I added a dropdown menu for modifying an organisation, which helped keep the table UI clean by avoiding an overload of action icons.

Building the area entity’s page was slightly different as there are more details to show. Areas are the most complex entity because they are the connecting point between organisations and schemes, and have interactivity with stages.

Modals for Explicit Actions 🎯
All important actions take place in modals. This keeps the interface clean and focused, and prevents accidental changes from simple button clicks.
Below is the modal for editing an area’s details with a dropdown to select the scheme it uses.

And here is the modal for “activating” an area’s stage (setting what water restrictions are currently in place).The orange “warning” color of the button reinforces that this is a critical action that should be taken with care.

Functionality for schemes and stages is very similar to organisations and areas.
When editing a stage, there is a larger text box as descriptions can be quite long. This is a simple text box, which means the text is still machine-readable when the API is called directly, but in future I would like to introduce a rich text editor to make website presentation easier.

Reflections 💭
Bridge was a great learning experience. It gave me the chance to try Nuxt and Vue.js, which felt a little more intuitive to me than React. I also explored Cloudflare Access, which I’m now a big fan of for securing private apps.
That said, there were some pain points — slow dev server startup times, occasional crashes, and challenges finding a well maintained authentication solution with the features I wanted out of the box. These gave me some insights into where Nuxt still has rough edges.