2026-05-22 18:30:59 +02:00
|
|
|
|
{% extends "base.html" %}
|
|
|
|
|
|
{% block title %} — Step {{ step }}{% endblock %}
|
|
|
|
|
|
|
|
|
|
|
|
{% block stepper %}
|
|
|
|
|
|
<div class="bg-slate-900/60 border-b border-slate-800">
|
|
|
|
|
|
<div class="max-w-6xl mx-auto px-4 py-3">
|
|
|
|
|
|
<div class="flex items-center gap-1 overflow-x-auto">
|
|
|
|
|
|
{% set step_names = ["Auth", "Opret Bruger", "Tilslut Bank", "Konti", "Transaktioner", "Events"] %}
|
|
|
|
|
|
{% for i in range(1, 7) %}
|
|
|
|
|
|
<a href="/demo/step/{{ i }}"
|
|
|
|
|
|
class="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm whitespace-nowrap transition
|
|
|
|
|
|
{% if i == step %}bg-violet-600 text-white font-semibold
|
|
|
|
|
|
{% elif i < step %}text-slate-300 hover:text-white
|
|
|
|
|
|
{% else %}text-slate-600 hover:text-slate-400{% endif %}">
|
|
|
|
|
|
<span class="w-5 h-5 rounded-full text-xs font-bold flex items-center justify-center
|
|
|
|
|
|
{% if i < step %}bg-slate-700 text-slate-300
|
|
|
|
|
|
{% elif i == step %}bg-violet-500 text-white
|
|
|
|
|
|
{% else %}bg-slate-800 text-slate-600{% endif %}">{{ i }}</span>
|
|
|
|
|
|
{{ step_names[i-1] }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
{% if i < 6 %}
|
|
|
|
|
|
<span class="text-slate-700">›</span>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
{% endfor %}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-6">
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Left: info panel -->
|
|
|
|
|
|
<div class="lg:col-span-2 space-y-4">
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Step header -->
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div class="flex items-center gap-2 mb-2">
|
|
|
|
|
|
<span class="w-8 h-8 rounded-full bg-violet-600 text-white text-sm font-bold flex items-center justify-center">{{ step }}</span>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h2 class="text-xl font-bold text-white">{{ title }}</h2>
|
|
|
|
|
|
<p class="text-slate-400 text-sm">{{ subtitle }}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Endpoint badge -->
|
|
|
|
|
|
<div class="bg-slate-900 border border-slate-800 rounded-xl p-4">
|
|
|
|
|
|
<div class="flex items-center justify-between mb-2">
|
|
|
|
|
|
<span class="text-xs text-slate-500 uppercase tracking-wider">Endpoint</span>
|
|
|
|
|
|
<span class="text-xs px-2 py-0.5 rounded-full font-mono font-semibold
|
|
|
|
|
|
{% if 'v2' in api_version %}bg-violet-900/50 text-violet-300 border border-violet-700/40
|
|
|
|
|
|
{% else %}bg-slate-800 text-slate-400{% endif %}">
|
|
|
|
|
|
{{ api_version }}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<code class="text-sm text-emerald-400 font-mono break-all">{{ endpoint }}</code>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Description -->
|
|
|
|
|
|
<div class="bg-slate-900 border border-slate-800 rounded-xl p-4">
|
|
|
|
|
|
<p class="text-slate-300 text-sm leading-relaxed">{{ description }}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- curl example -->
|
|
|
|
|
|
<div class="bg-slate-900 border border-slate-800 rounded-xl p-4">
|
|
|
|
|
|
<div class="flex items-center justify-between mb-3">
|
|
|
|
|
|
<span class="text-xs text-slate-500 uppercase tracking-wider">cURL eksempel</span>
|
|
|
|
|
|
<button onclick="copyToClipboard('curl-{{ step }}')"
|
|
|
|
|
|
class="text-xs text-slate-400 hover:text-white transition px-2 py-1 rounded bg-slate-800 hover:bg-slate-700">
|
|
|
|
|
|
Kopier
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<pre id="curl-{{ step }}" class="text-xs text-amber-300 font-mono whitespace-pre-wrap leading-relaxed">{{ curl_example }}</pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Navigation -->
|
|
|
|
|
|
<div class="flex gap-3">
|
|
|
|
|
|
{% if prev_step %}
|
|
|
|
|
|
<a href="/demo/step/{{ prev_step }}"
|
|
|
|
|
|
class="flex-1 text-center px-4 py-2.5 border border-slate-700 text-slate-300 hover:text-white hover:border-slate-500 rounded-xl text-sm transition">
|
|
|
|
|
|
← Step {{ prev_step }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
{% if next_step %}
|
|
|
|
|
|
<a href="/demo/step/{{ next_step }}"
|
|
|
|
|
|
class="flex-1 text-center px-4 py-2.5 bg-violet-600 hover:bg-violet-500 text-white rounded-xl text-sm font-semibold transition">
|
|
|
|
|
|
Step {{ next_step }} →
|
|
|
|
|
|
</a>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Right: response panel -->
|
|
|
|
|
|
<div class="lg:col-span-3 space-y-4">
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tink Link special button (step 3) -->
|
|
|
|
|
|
{% if tink_link_url %}
|
|
|
|
|
|
|
|
|
|
|
|
{% if cb_success %}
|
|
|
|
|
|
<!-- Already connected — show success, hide connection UI -->
|
|
|
|
|
|
<div class="bg-emerald-950/60 border border-emerald-700/50 rounded-xl p-5 flex items-start gap-4">
|
|
|
|
|
|
<div class="w-10 h-10 rounded-full bg-emerald-900/60 flex items-center justify-center flex-shrink-0">
|
|
|
|
|
|
<svg class="w-5 h-5 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
<p class="text-emerald-300 font-semibold text-base">Bank forbundet!</p>
|
|
|
|
|
|
<p class="text-emerald-400/70 text-sm mt-0.5">User token gemt i session. Trin 4–6 er klar.</p>
|
|
|
|
|
|
<a href="/demo/reset"
|
|
|
|
|
|
class="inline-flex items-center gap-1.5 mt-3 text-xs text-slate-500 hover:text-slate-300 transition">
|
|
|
|
|
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
|
|
|
|
|
|
Start forfra
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{% else %}
|
|
|
|
|
|
<!-- Not yet connected — show connection UI -->
|
|
|
|
|
|
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<!-- PRIMARY: direct callback flow -->
|
2026-05-22 18:30:59 +02:00
|
|
|
|
<div class="bg-slate-900 border border-emerald-700/40 rounded-xl p-5 space-y-4">
|
|
|
|
|
|
<div class="flex items-start gap-3">
|
|
|
|
|
|
<div class="w-8 h-8 rounded-full bg-emerald-900/50 flex items-center justify-center flex-shrink-0">
|
|
|
|
|
|
<svg class="w-4 h-4 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h3 class="text-white font-semibold mb-1">Tilslut testbank</h3>
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<p class="text-slate-400 text-sm">Klik knappen, vælg Demo Bank og log ind — du redirectes automatisk tilbage.</p>
|
2026-05-22 18:30:59 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Instructions -->
|
|
|
|
|
|
<div class="bg-slate-800/60 border border-slate-700/50 rounded-lg p-4 text-sm space-y-2">
|
|
|
|
|
|
<p class="text-slate-300 font-semibold flex items-center gap-1.5">
|
|
|
|
|
|
<svg class="w-4 h-4 text-amber-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
2026-05-22 19:04:06 +02:00
|
|
|
|
Trin i Tink Link
|
2026-05-22 18:30:59 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
<ol class="text-slate-400 space-y-1.5 list-decimal list-inside leading-relaxed">
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<li>Vælg <span class="text-slate-300 font-medium">Tink Demo Bank</span></li>
|
|
|
|
|
|
<li>Vælg <span class="text-slate-300">Open Banking</span> → <span class="text-slate-300">Password And OTP</span></li>
|
|
|
|
|
|
<li>Hent credentials: <span class="font-mono text-amber-300 text-xs bg-slate-900 px-1.5 py-0.5 rounded">Console → Demo Bank → Transactions → DK</span></li>
|
|
|
|
|
|
<li>Indtast username + password → OTP vises på siden → Continue</li>
|
|
|
|
|
|
<li>Vælg en konto → du redirectes automatisk tilbage her ✓</li>
|
2026-05-22 18:30:59 +02:00
|
|
|
|
</ol>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-3">
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<a href="{{ tink_link_url }}"
|
2026-05-22 18:30:59 +02:00
|
|
|
|
class="inline-flex items-center gap-2 px-5 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-lg transition">
|
|
|
|
|
|
Åbn Tink Link
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>
|
2026-05-22 18:30:59 +02:00
|
|
|
|
</a>
|
|
|
|
|
|
<a href="/demo/reset"
|
|
|
|
|
|
class="inline-flex items-center gap-1.5 px-4 py-2.5 border border-slate-700 text-slate-400 hover:text-white hover:border-slate-500 rounded-lg text-sm transition">
|
|
|
|
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
|
|
|
|
|
|
Start forfra
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<!-- FALLBACK: console.tink.com/callback + manual code paste -->
|
2026-05-22 18:30:59 +02:00
|
|
|
|
<details class="bg-slate-900 border border-slate-700/30 rounded-xl overflow-hidden">
|
|
|
|
|
|
<summary class="px-5 py-3 cursor-pointer text-slate-500 hover:text-slate-400 text-xs flex items-center gap-2 select-none">
|
|
|
|
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
2026-05-22 19:04:06 +02:00
|
|
|
|
Alternativ: manuel kode-indsætning via console.tink.com
|
2026-05-22 18:30:59 +02:00
|
|
|
|
<span class="ml-auto">▾</span>
|
|
|
|
|
|
</summary>
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<div class="px-5 pb-4 pt-3 border-t border-slate-800 space-y-3">
|
|
|
|
|
|
<a href="{{ dev_tink_link_url }}" target="_blank"
|
2026-05-22 18:30:59 +02:00
|
|
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-slate-700 hover:bg-slate-600 text-slate-300 text-sm rounded-lg transition">
|
2026-05-22 19:04:06 +02:00
|
|
|
|
Åbn med console callback
|
2026-05-22 18:30:59 +02:00
|
|
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
|
|
|
|
|
</a>
|
2026-05-22 19:04:06 +02:00
|
|
|
|
<form method="POST" action="/demo/step/3" class="flex gap-2 items-stretch">
|
|
|
|
|
|
<input type="text" name="code" placeholder="Indsæt code=XXXX fra console.tink.com/callback..."
|
|
|
|
|
|
class="flex-1 bg-slate-800 border border-slate-700 text-slate-200 rounded-lg px-3 py-2 text-sm font-mono placeholder-slate-600 focus:outline-none focus:border-emerald-600" required>
|
|
|
|
|
|
<button type="submit"
|
|
|
|
|
|
class="px-4 py-2 bg-emerald-700 hover:bg-emerald-600 text-white text-sm font-semibold rounded-lg transition whitespace-nowrap">
|
|
|
|
|
|
Brug kode
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</form>
|
2026-05-22 18:30:59 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
|
|
{% endif %}{# end not cb_success #}
|
|
|
|
|
|
|
|
|
|
|
|
{% endif %}{# end tink_link_url #}
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Error state -->
|
|
|
|
|
|
{% if error %}
|
|
|
|
|
|
<div class="bg-red-950/50 border border-red-800/50 rounded-xl p-5">
|
|
|
|
|
|
<div class="flex items-start gap-3">
|
|
|
|
|
|
<span class="text-red-400 text-xl flex-shrink-0">✕</span>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h3 class="text-red-300 font-semibold mb-1">Fejl</h3>
|
|
|
|
|
|
<pre class="text-red-400 text-sm font-mono whitespace-pre-wrap">{{ error }}</pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
|
|
<!-- JSON response -->
|
|
|
|
|
|
{% if result %}
|
|
|
|
|
|
<div class="bg-slate-900 border border-slate-800 rounded-xl overflow-hidden">
|
|
|
|
|
|
<div class="flex items-center justify-between px-4 py-3 border-b border-slate-800">
|
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
|
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
|
|
|
|
|
|
<span class="text-sm text-slate-300 font-semibold">Response</span>
|
|
|
|
|
|
<span class="text-xs text-emerald-400 font-mono">200 OK</span>
|
|
|
|
|
|
{% if is_demo %}
|
|
|
|
|
|
<span class="text-xs px-2 py-0.5 rounded-full font-semibold bg-amber-900/60 text-amber-300 border border-amber-700/40">⚠ Sample Data</span>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button onclick="copyToClipboard('json-{{ step }}')"
|
|
|
|
|
|
class="text-xs text-slate-400 hover:text-white transition px-2 py-1 rounded bg-slate-800 hover:bg-slate-700">
|
|
|
|
|
|
Kopier JSON
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="p-4 max-h-[520px] overflow-y-auto">
|
|
|
|
|
|
<pre id="json-{{ step }}" class="raw-json">{{ result | tojson(indent=2) }}</pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{% elif not error %}
|
|
|
|
|
|
<!-- Waiting state -->
|
|
|
|
|
|
<div class="bg-slate-900 border border-slate-800 rounded-xl p-10 flex flex-col items-center justify-center gap-3 text-center">
|
|
|
|
|
|
<div class="w-12 h-12 rounded-full bg-slate-800 flex items-center justify-center">
|
|
|
|
|
|
<svg class="w-6 h-6 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p class="text-slate-400 text-sm">Klik på knappen ovenfor for at køre dette API-kald og se svaret her.</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{% endblock %}
|