Designing a cargo schedule assistant

Figma

Service Architecture

UX/UI Design

I designed a container cargo scheduling feature for the Trizy Web Platform, originally built to retain a major client that was on the verge of cancelling their contract. The feature shipped, kept the account, and was later rebuilt as a fully configurable module that became a sales asset and brought in new clients.

Overview

About the product

Trizy Web is a Transportation Management System used to create and manage cargo loading schedules and freights, manage cargo inventory and client contracts, and run a yard management system. The platform integrates directly with the Trizy mobile app, so every appointment, freight, and route assigned to a driver is notified and accessible from their phone.

About the team

The project required coordination across multiple roles. I worked as the Product Designer, alongside the Development team, the Product Manager, and the Logistics Operations representative from the client company.

My role

I led product design end to end:

  • Service architecture: mapped the conditional logic that defines a container schedule (cargo type, situation, temperature requirements, document dependencies) and designed the configuration layer that exposes these rules through Company Settings.

  • UX: drafted and validated the flow for adding container cargo to a schedule, including the integration with the existing contract selection step.

  • UI: designed every screen of the new flow, including the container detail modal, the cargo type renderer, and the validation states tied to async checks against the container database.

The Product Manager owned scope and stakeholder alignment with the client. The Development team implemented the service and the configuration layer. The Logistics Operations representative provided domain expertise on container handling.

About the user persona

The primary user is the logistics operator, responsible for scheduling trucks and managing the yard, ensuring efficient flow of loading and unloading. The role works under constant pressure: last-minute changes, delays, late drivers, missing documents. Time spent on a single schedule entry is time the yard is idle, so any friction in the scheduling tool has a direct operational cost.

The platform supports hierarchical access, ranging from spectator (view-only, monitoring) through junior and senior operators, to manager and coordinator levels. The container scheduling feature is accessible from junior operator and above. Spectator role is excluded by design, since this is a write-heavy tool. Every screen and component had to behave correctly across these permission tiers.

Discovery

The problem

Container cargo carries a layer of metadata that standard freight does not: legal certifications, refrigeration requirements, dimensional standards, customs documentation. The existing scheduling tool was built for general freight, with predefined fields that worked for tanker and semi-trailer cargo but not for containers.

The platform had partially solved customization through flex-fields at the bottom of the schedule form, but flex-fields had two structural limitations:

  • The information stored in them was not filterable, breaking yard reports and search.

  • Some flex-field data did not propagate correctly to the driver's mobile app, so drivers showed up at loading docks missing key details.

This was creating friction with one of the company's largest clients, who had repeatedly raised the issue and was on the verge of cancelling their contract.

The solution

The plan was to build a scheduling flow specifically for container cargo, with first-class support for the metadata containers require, full propagation to the driver's app, and proper filterability across the platform.

We started by mapping what the operator actually needed: what information, when, in what order, and with what dependencies. That research shaped the entire flow.

Delivery

The logistics flow starts when a shipping company buys or sells a product and manages the transportation. Each operation generates a contract: product details, shipping information, and container specifications. Contracts can be created directly on Trizy Web or imported from another terminal TMS through our integration API.

A container schedule needs two layers of information:

  • The cargo: product name, ID, category, and Mercosul Index number (the standard freight schema).

  • The container: model, make, size, whether it is high cube or heavy tested, boarding details, booking number, situation (empty or full), tax invoice, type (dry, reefer for refrigerated cargo, or isotank for liquids), and temperature set point if the type is reefer.

The information flow is conditional. If the situation is "full", the tax invoice is required and the container ID is optional. If the type is "reefer", the temperature is required. Each operation surfaces a different subset of fields. The system needed to handle this without overwhelming the operator with every possible field at once.

When the user selected a contract where the cargo type was "container" and added a quota, the form rendered a dedicated component that aggregated the information common to all containers of that contract.



This component captured the shared metadata (type, boarding instructions, etc.) and exposed an "Add container" action that opened a modal for entering each container individually, including identification, boarding details, and the tax invoice upload.



After all required fields were filled, the system checked whether the container ID was already registered in the platform's database. If registered, prior shipment metadata was pulled in to speed up subsequent entries. If not, the container ID became a new record, available for filtering and future schedules.

The async check had its own loading and error states to handle network failures and ambiguous matches.


Interface decisions

A few choices shaped the new UI:

  • Conditional fields revealed progressively. Operators only see the fields relevant to the current selection (situation, type, etc.), reducing cognitive load on a form that could otherwise have 15+ inputs at once.

  • Container entries as a list, not a flat form. Each container gets its own card inside the parent component, so an operator scheduling a multi-container load can see at a glance which entries are complete and which still need attention.

  • Validation framed as guidance. Async failures show a clear message and a recovery action, rather than a generic error. Given the operational cost of a stuck schedule, this was a deliberate priority.

  • Document uploads inline. The tax invoice upload sits where it logically belongs (inside the container modal), not in a separate "documents" tab, so the operator never loses context.

The first version was scoped to the requesting client. Mid-build, the team recognized that other clients on the platform had different rules: some required the tax invoice on empty containers too, some used a different document type, some had distinct workflows for refrigerated cargo.

We made a structural decision: every step, every field requirement, and every validation rule moved out of code and into Company Settings. The form would read its schema from the client's configuration at runtime.

This added scope to the project, but transformed the feature from a one-client deliverable into a platform capability. The cost of that decision paid back when a second major client signed on, and onboarding took adjusting parameters instead of rebuilding the flow.

Results

After rollout, the Data team and I monitored adoption and operator feedback:

  • Client retention: the original client kept their contract and increased usage of the scheduling tool.

  • New client signed: 4 months after launch, a second major client signed in part because of this feature. Configuration took a few business days versus the months a hard-coded rebuild would have required.

  • Integration with the mobile app: drivers received complete container metadata in their assignments, eliminating the missing-information complaints that had been an ongoing issue.

Conclusion

This was the project where I learned that designing for one stakeholder and designing for a platform are different problems with different answers. The first version of the feature would have satisfied the client and shipped on time. The second version, the configurable one, took longer but turned a defensive build into an offensive asset.

Three things I took from this work:

  • Conditional schemas are user interface. The rules that decide which fields appear are part of the design, not just back-end logic. Done well, the operator feels the form anticipating their needs. Done poorly, every selection feels like a quiz.

  • Configuration is a feature, not infrastructure. A field that says "this rule lives in settings" is a strategic choice that affects sales, onboarding, and product positioning, not just engineering.

  • Domain depth pays off. Time spent with the logistics operations team learning what a reefer is, what high cube means, when an empty container needs a tax invoice, was time that paid back at every design decision.

If I were to do this again, I would invest in the configuration layer from the start, instead of building a fixed version first and refactoring mid-project. The cost of the refactor was visible in the timeline.

Matheus Gomes / 2025

Create a free website with Framer, the website builder loved by startups, designers and agencies.