{% extends "base.html" %} {% from "macros/icons.html" import icon_alert, icon_error %} {% block title %}{% if node %}{{ node.name or ('Node ' ~ public_key[:8] ~ '...') }} - {{ network_name }}{% else %}Node Not Found - {{ network_name }}{% endif %}{% endblock %} {% block extra_head %} {% endblock %} {% block content %} {% if api_error %}
{{ icon_alert("stroke-current shrink-0 h-6 w-6") }} Could not fetch data from API: {{ api_error }}
{% endif %} {% if node %} {# Get display name from tag or node.name #} {% set ns = namespace(tag_name=none) %} {% for tag in node.tags or [] %} {% if tag.key == 'name' %} {% set ns.tag_name = tag.value %} {% endif %} {% endfor %} {% set display_name = ns.tag_name or node.name or 'Unnamed Node' %} {# Get coordinates from node model first, then fall back to tags (bug fix) #} {% set ns_coords = namespace(lat=node.lat, lon=node.lon) %} {% if not ns_coords.lat or not ns_coords.lon %} {% for tag in node.tags or [] %} {% if tag.key == 'lat' and not ns_coords.lat %} {% set ns_coords.lat = tag.value|float %} {% elif tag.key == 'lon' and not ns_coords.lon %} {% set ns_coords.lon = tag.value|float %} {% endif %} {% endfor %} {% endif %} {% set has_coords = ns_coords.lat is not none and ns_coords.lon is not none %} {# Node type emoji #} {% set type_emoji = '📍' %} {% if node.adv_type %} {% if node.adv_type|lower == 'chat' %} {% set type_emoji = '💬' %} {% elif node.adv_type|lower == 'repeater' %} {% set type_emoji = '📡' %} {% elif node.adv_type|lower == 'room' %} {% set type_emoji = '🪧' %} {% endif %} {% endif %}

{{ type_emoji }} {{ display_name }}

{% if has_coords %}
{% else %}

Scan to add as contact

{% endif %}

Public Key

{{ node.public_key }}
First seen: {{ node.first_seen[:19].replace('T', ' ') if node.first_seen else '-' }}
Last seen: {{ node.last_seen[:19].replace('T', ' ') if node.last_seen else '-' }}
{% if has_coords %}
Location: {{ ns_coords.lat }}, {{ ns_coords.lon }}
{% endif %}

Recent Advertisements

{% if advertisements %}
{% for adv in advertisements %} {% endfor %}
Time Type Received By
{{ adv.received_at[:19].replace('T', ' ') if adv.received_at else '-' }} {% if adv.adv_type and adv.adv_type|lower == 'chat' %} 💬 {% elif adv.adv_type and adv.adv_type|lower == 'repeater' %} 📡 {% elif adv.adv_type and adv.adv_type|lower == 'room' %} 🪧 {% elif adv.adv_type %} 📍 {% else %} - {% endif %} {% if adv.received_by %} {% if adv.receiver_tag_name or adv.receiver_name %}
{{ adv.receiver_tag_name or adv.receiver_name }}
{{ adv.received_by[:16] }}...
{% else %} {{ adv.received_by[:16] }}... {% endif %}
{% else %} - {% endif %}
{% else %}

No advertisements recorded.

{% endif %}

Tags

{% if node.tags %}
{% for tag in node.tags %} {% endfor %}
Key Value Type
{{ tag.key }} {{ tag.value }} {{ tag.value_type or 'string' }}
{% else %}

No tags defined.

{% endif %} {% if admin_enabled and is_authenticated %} {% endif %}
{% else %}
{{ icon_error("stroke-current shrink-0 h-6 w-6") }} Node not found: {{ public_key }}
Back to Nodes {% endif %} {% endblock %} {% block extra_scripts %} {% if node %} {% set ns_qr = namespace(tag_name=none) %} {% for tag in node.tags or [] %} {% if tag.key == 'name' %} {% set ns_qr.tag_name = tag.value %} {% endif %} {% endfor %} {# Get coordinates from node model first, then fall back to tags #} {% set ns_map = namespace(lat=node.lat, lon=node.lon, name=none) %} {% if not ns_map.lat or not ns_map.lon %} {% for tag in node.tags or [] %} {% if tag.key == 'lat' and not ns_map.lat %} {% set ns_map.lat = tag.value|float %} {% elif tag.key == 'lon' and not ns_map.lon %} {% set ns_map.lon = tag.value|float %} {% endif %} {% endfor %} {% endif %} {% for tag in node.tags or [] %} {% if tag.key == 'name' %} {% set ns_map.name = tag.value %} {% endif %} {% endfor %} {% if ns_map.lat and ns_map.lon %} {% endif %} {% endif %} {% endblock %}