---
id: w5/m8/t003
title: Databases list page + top-level nav item; status badges, loading/error/empty states
worker: worker5
status: done
estimate: 45m
depends_on: [w5/m8/t002]
---

## Objective

Ship the Databases list page wired to the live `databases` query and add the top-level nav item, making the dashboard a two-resource product (Services + Databases) the way Render's sidebar is.

## Context

- Follow the services-list conventions from w5/m4: skeleton rows while loading, explicit error card, "no databases yet" empty state, real data only — no sample arrays.
- Columns per the t001 Render capture, restricted to fields bex-api returns (Render `database` dashboard shape); gaps (e.g. region) omitted, not faked — the m4 rule.
- Status derivation: reuse/extend the `deriveStatus` idiom (`features/services/lib/status.ts`) if the Database phase set differs from Apps'.

## Steps

1. Add the route (`src/routes/databases.tsx` or per router conventions) + nav item with i18n strings (en + zh, per w5/m3).
2. Render the list from `useDatabases()` with status badges and the three states.
3. Row click navigates to the detail route (built in t005); create button placeholder wired in t004.

## Files

- `dashboard/src/routes/databases.tsx` (+ route tree updates)
- `dashboard/src/features/databases/components/`, `dashboard/src/features/databases/locales/{en,zh}.ts`
- shared nav component (top-level nav item)

## Acceptance criteria

- [ ] Databases nav item + list page render live `databases` data with loading/error/empty states.
- [ ] Columns match the t001 capture minus explicit gaps; no faked fields; strings localized (en/zh).

## Out of scope

- Create/delete flows (t004); detail page (t005).
