refactor(tables): standardise Added column as first column across all tables
Move the Added/Date column to first position in brew, gear, and bag list templates and apply consistent text-xs font-medium text-stone-600 styling. Document the pattern in CLAUDE.md.
This commit is contained in:
parent
57a6736b9a
commit
2d27228059
4 changed files with 27 additions and 11 deletions
12
CLAUDE.md
12
CLAUDE.md
|
|
@ -354,6 +354,18 @@ Three macros are available:
|
|||
- **`pagination_header(items, navigator, target_selector)`** — prev/next buttons, page count, rows-per-page selector; hidden on mobile via `pagination-controls hidden md:flex`
|
||||
- **`sortable_header(label, key, navigator, target_selector)`** — clickable column header with sort direction arrows
|
||||
|
||||
### "Added" Column
|
||||
|
||||
Every table has a sortable "Added" column as its **first column**, sorted by `created-at`. It uses a distinct smaller style to visually separate it from content columns:
|
||||
|
||||
```html
|
||||
<td data-label="Added" class="whitespace-nowrap px-4 py-3 text-xs font-medium text-stone-600">
|
||||
{{ item.created_at }}
|
||||
</td>
|
||||
```
|
||||
|
||||
The `text-xs font-medium text-stone-600` classes give it a muted, compact appearance compared to the default `text-sm` body text.
|
||||
|
||||
### Responsive Table Pattern
|
||||
|
||||
Tables use the `responsive-table` CSS class which converts rows to card-style layout on mobile (`max-width: 767px`). The CSS in `styles.css` hides `<thead>` and uses `data-label` attributes on `<td>` elements to show field labels.
|
||||
|
|
|
|||
|
|
@ -102,22 +102,24 @@
|
|||
<table class="responsive-table min-w-full divide-y divide-amber-200 text-left text-sm text-stone-700">
|
||||
<thead class="bg-amber-200/60 text-xs font-semibold tracking-wide text-amber-900">
|
||||
<tr>
|
||||
{% call table::sortable_header("Roaster", "roaster", navigator, "#bag-list") %} {%
|
||||
call table::sortable_header("Roast", "roast", navigator, "#bag-list") %}
|
||||
{% call table::sortable_header("Added", "created-at", navigator, "#bag-list") %}
|
||||
{% call table::sortable_header("Roaster", "roaster", navigator, "#bag-list") %}
|
||||
{% call table::sortable_header("Roast", "roast", navigator, "#bag-list") %}
|
||||
<th scope="col" class="px-4 py-3">Weight</th>
|
||||
{% call table::sortable_header("Added", "created-at", navigator, "#bag-list") %} {%
|
||||
call table::sortable_header("Finished", "finished-at", navigator, "#bag-list") %}
|
||||
{% call table::sortable_header("Finished", "finished-at", navigator, "#bag-list") %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-amber-200/70">
|
||||
{% for bag in bags.items %}
|
||||
<tr class="bg-amber-50/40 transition hover:bg-amber-50">
|
||||
<td data-label="Added" class="whitespace-nowrap px-4 py-3 text-xs font-medium text-stone-600">
|
||||
{{ bag.created_at }}
|
||||
</td>
|
||||
<td data-label="Roaster" class="px-4 py-3 whitespace-nowrap font-medium text-stone-600">
|
||||
{{ bag.roaster_name }}
|
||||
</td>
|
||||
<td data-label="Roast" class="px-4 py-3 whitespace-nowrap">{{ bag.roast_name }}</td>
|
||||
<td data-label="Weight" class="px-4 py-3 whitespace-nowrap">{{ bag.amount }}g</td>
|
||||
<td data-label="Added" class="px-4 py-3 whitespace-nowrap">{{ bag.created_at }}</td>
|
||||
<td data-label="Finished" class="px-4 py-3 whitespace-nowrap">{{ bag.finished_at }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@
|
|||
<table class="responsive-table min-w-full divide-y divide-amber-200 text-left text-sm text-stone-700">
|
||||
<thead class="bg-amber-200/60 text-xs font-semibold tracking-wide text-amber-900">
|
||||
<tr>
|
||||
{% call table::sortable_header("Added", "created-at", navigator, "#brew-list") %}
|
||||
<th scope="col" class="px-4 py-3">Coffee</th>
|
||||
<th scope="col" class="px-4 py-3">Grind</th>
|
||||
<th scope="col" class="px-4 py-3">Recipe</th>
|
||||
<th scope="col" class="px-4 py-3">Temp</th>
|
||||
<th scope="col" class="px-4 py-3">Brewer</th>
|
||||
{% call table::sortable_header("Date", "created-at", navigator, "#brew-list") %}
|
||||
{% if is_authenticated %}
|
||||
<th scope="col" class="px-4 py-3 text-center">Actions</th>
|
||||
{% endif %}
|
||||
|
|
@ -24,6 +24,9 @@
|
|||
<tbody class="divide-y divide-amber-200/70">
|
||||
{% for brew in brews.items %}
|
||||
<tr class="bg-amber-50/40 transition hover:bg-amber-50">
|
||||
<td data-label="Added" class="whitespace-nowrap px-4 py-3 text-xs font-medium text-stone-600">
|
||||
{{ brew.created_at }}
|
||||
</td>
|
||||
<td data-label="Coffee" class="px-4 py-3 whitespace-nowrap">
|
||||
<div class="font-medium text-stone-800">
|
||||
<a href="/roasters/{{ brew.roaster_slug }}/roasts/{{ brew.roast_slug }}" class="hover:text-amber-700 hover:underline">
|
||||
|
|
@ -61,7 +64,6 @@
|
|||
{% if let Some(fp_name) = brew.filter_paper_name %}
|
||||
<td data-label="Filter" class="px-4 py-3 whitespace-nowrap md:hidden">{{ fp_name }}</td>
|
||||
{% endif %}
|
||||
<td data-label="Date" class="px-4 py-3 whitespace-nowrap text-stone-500">{{ brew.created_at }}</td>
|
||||
{% if is_authenticated %}
|
||||
<td data-label="" class="px-4 py-3 text-right">
|
||||
<form class="inline" data-on:submit="@post('/api/v1/brews?{{ navigator.query() }}', {contentType: 'form', responseOverrides: {selector: '#brew-list', mode: 'replace'}})">
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@
|
|||
<table class="responsive-table min-w-full divide-y divide-amber-200 text-left text-sm text-stone-700">
|
||||
<thead class="bg-amber-200/60 text-xs font-semibold tracking-wide text-amber-900">
|
||||
<tr>
|
||||
{% call table::sortable_header("Added", "created-at", navigator, "#gear-list") %}
|
||||
{% call table::sortable_header("Category", "category", navigator, "#gear-list") %}
|
||||
{% call table::sortable_header("Make", "make", navigator, "#gear-list") %}
|
||||
{% call table::sortable_header("Model", "model", navigator, "#gear-list") %}
|
||||
{% call table::sortable_header("Added", "created-at", navigator, "#gear-list") %}
|
||||
{% if is_authenticated %}
|
||||
<th scope="col" class="px-4 py-3 text-right">Actions</th>
|
||||
{% endif %}
|
||||
|
|
@ -30,6 +30,9 @@
|
|||
<tbody class="divide-y divide-amber-200/70">
|
||||
{% for item in gear.items %}
|
||||
<tr class="bg-amber-50/40 transition hover:bg-amber-50">
|
||||
<td data-label="Added" class="whitespace-nowrap px-4 py-3 text-xs font-medium text-stone-600">
|
||||
{{ item.created_at }}
|
||||
</td>
|
||||
<td data-label="Category" class="px-4 py-3 whitespace-nowrap">
|
||||
<span class="inline-flex rounded-full bg-amber-100 px-2 py-1 text-xs font-medium text-amber-800">
|
||||
{{ item.category_label }}
|
||||
|
|
@ -41,9 +44,6 @@
|
|||
<td data-label="Model" class="px-4 py-3 whitespace-nowrap">
|
||||
{{ item.model }}
|
||||
</td>
|
||||
<td data-label="Added" class="px-4 py-3 whitespace-nowrap">
|
||||
{{ item.created_at }}
|
||||
</td>
|
||||
{% if is_authenticated %}
|
||||
<td data-label="" class="px-4 py-3 text-right">
|
||||
<button
|
||||
|
|
|
|||
Loading…
Reference in a new issue