refactor(timeline): remove map pin icon from timeline title
Position is already shown as a clickable detail row in the card body, making the title icon redundant. Also removes the unused map_link field from TimelineEventView.
This commit is contained in:
parent
fff11b0512
commit
3ab1c50cc8
4 changed files with 35 additions and 1 deletions
|
|
@ -1266,6 +1266,13 @@ WHERE entity_type = 'cafe' AND entity_id = (SELECT id FROM cafes WHERE name = 'F
|
||||||
UPDATE timeline_events SET occurred_at = datetime('2026-01-11 14:00:00')
|
UPDATE timeline_events SET occurred_at = datetime('2026-01-11 14:00:00')
|
||||||
WHERE entity_type = 'cafe' AND entity_id = (SELECT id FROM cafes WHERE name = 'Small Street Espresso');
|
WHERE entity_type = 'cafe' AND entity_id = (SELECT id FROM cafes WHERE name = 'Small Street Espresso');
|
||||||
|
|
||||||
|
-- Rebuild cafe timeline details_json to include Position field
|
||||||
|
UPDATE timeline_events SET details_json = (
|
||||||
|
SELECT '[{"label":"City","value":"' || c.city || '"},{"label":"Country","value":"' || c.country || '"},{"label":"Website","value":"' || COALESCE(NULLIF(c.website, ''), '—') || '"},{"label":"Position","value":"https://www.google.com/maps?q=' || c.latitude || ',' || c.longitude || '"}]'
|
||||||
|
FROM cafes c WHERE c.id = timeline_events.entity_id
|
||||||
|
)
|
||||||
|
WHERE entity_type = 'cafe';
|
||||||
|
|
||||||
-- Bag timeline events (match bag created_at)
|
-- Bag timeline events (match bag created_at)
|
||||||
UPDATE timeline_events SET occurred_at = datetime('2025-09-28 10:00:00')
|
UPDATE timeline_events SET occurred_at = datetime('2025-09-28 10:00:00')
|
||||||
WHERE entity_type = 'bag' AND entity_id = (SELECT id FROM bags WHERE roast_id = (SELECT id FROM roasts WHERE name = 'Gatomboya'));
|
WHERE entity_type = 'bag' AND entity_id = (SELECT id FROM bags WHERE roast_id = (SELECT id FROM roasts WHERE name = 'Gatomboya'));
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,13 @@ impl SqlCafeRepository {
|
||||||
label: "Website".to_string(),
|
label: "Website".to_string(),
|
||||||
value: website_value,
|
value: website_value,
|
||||||
},
|
},
|
||||||
|
TimelineEventDetail {
|
||||||
|
label: "Position".to_string(),
|
||||||
|
value: format!(
|
||||||
|
"https://www.google.com/maps?q={},{}",
|
||||||
|
cafe.latitude, cafe.longitude
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
serde_json::to_string(&details).map_err(|err| {
|
serde_json::to_string(&details).map_err(|err| {
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,7 @@ impl RoastView {
|
||||||
pub struct TimelineEventDetailView {
|
pub struct TimelineEventDetailView {
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
|
pub link: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raw brew data for repeating a brew from the timeline.
|
/// Raw brew data for repeating a brew from the timeline.
|
||||||
|
|
@ -541,15 +542,30 @@ impl TimelineEventView {
|
||||||
let mut mapped_details = Vec::new();
|
let mut mapped_details = Vec::new();
|
||||||
let mut external_link = None;
|
let mut external_link = None;
|
||||||
for detail in details {
|
for detail in details {
|
||||||
if detail.label.eq_ignore_ascii_case("homepage") {
|
if detail.label.eq_ignore_ascii_case("homepage")
|
||||||
|
|| detail.label.eq_ignore_ascii_case("website")
|
||||||
|
{
|
||||||
let trimmed = detail.value.trim();
|
let trimmed = detail.value.trim();
|
||||||
if !trimmed.is_empty() && trimmed != "—" {
|
if !trimmed.is_empty() && trimmed != "—" {
|
||||||
external_link = Some(trimmed.to_string());
|
external_link = Some(trimmed.to_string());
|
||||||
}
|
}
|
||||||
|
} else if detail.label.eq_ignore_ascii_case("position") {
|
||||||
|
let trimmed = detail.value.trim();
|
||||||
|
if !trimmed.is_empty() {
|
||||||
|
let display = trimmed
|
||||||
|
.strip_prefix("https://www.google.com/maps?q=")
|
||||||
|
.unwrap_or(trimmed);
|
||||||
|
mapped_details.push(TimelineEventDetailView {
|
||||||
|
label: detail.label,
|
||||||
|
value: display.to_string(),
|
||||||
|
link: Some(trimmed.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mapped_details.push(TimelineEventDetailView {
|
mapped_details.push(TimelineEventDetailView {
|
||||||
label: detail.label,
|
label: detail.label,
|
||||||
value: detail.value,
|
value: detail.value,
|
||||||
|
link: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,11 @@
|
||||||
{% for detail in event.details %}
|
{% for detail in event.details %}
|
||||||
<div class="flex justify-between gap-2">
|
<div class="flex justify-between gap-2">
|
||||||
<dt class="font-medium text-stone-500">{{ detail.label }}</dt>
|
<dt class="font-medium text-stone-500">{{ detail.label }}</dt>
|
||||||
|
{% if let Some(url) = detail.link %}
|
||||||
|
<dd class="text-right"><a href="{{ url }}" target="_blank" rel="noreferrer noopener" class="text-amber-700 hover:text-amber-500">{{ detail.value }}</a></dd>
|
||||||
|
{% else %}
|
||||||
<dd class="text-right">{{ detail.value }}</dd>
|
<dd class="text-right">{{ detail.value }}</dd>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue