|
27 | 27 | <div class="alert alert-warn">A bank connection expires in {{ days_left }} day{{ 's' if days_left != 1 else '' }}. <a href="/connect" style="color:inherit;font-weight:600;">Manage banks →</a></div> |
28 | 28 | {% endif %} |
29 | 29 |
|
| 30 | +{% if show_review_prompt %} |
| 31 | +<div class="card" style="border-color:#3b82f6; border-width:1px;"> |
| 32 | + <div class="card-title" style="margin-bottom:0.25rem;">How's Bridge Bank working for you?</div> |
| 33 | + <div class="card-sub" style="margin-bottom:1rem;">Your feedback helps other users find Bridge Bank.</div> |
| 34 | + <form method="POST" action="/review/submit" id="review-form"> |
| 35 | + <div style="margin-bottom:1rem;"> |
| 36 | + <div id="star-rating" style="display:flex;gap:4px;font-size:28px;cursor:pointer;user-select:none;"> |
| 37 | + <span class="review-star" data-val="1">☆</span> |
| 38 | + <span class="review-star" data-val="2">☆</span> |
| 39 | + <span class="review-star" data-val="3">☆</span> |
| 40 | + <span class="review-star" data-val="4">☆</span> |
| 41 | + <span class="review-star" data-val="5">☆</span> |
| 42 | + </div> |
| 43 | + <input type="hidden" name="rating" id="review-rating" value="" required> |
| 44 | + </div> |
| 45 | + <textarea name="review" placeholder="What do you like about Bridge Bank? Anything we could improve?" rows="3" required style="width:100%;box-sizing:border-box;background:#1a2235;border:1px solid #1e2a40;border-radius:8px;color:#e2e8f0;padding:0.75rem;font-size:13px;font-family:inherit;resize:vertical;margin-bottom:0.75rem;"></textarea> |
| 46 | + <input type="text" name="name" placeholder="Your name (optional)" style="width:100%;box-sizing:border-box;background:#1a2235;border:1px solid #1e2a40;border-radius:8px;color:#e2e8f0;padding:0.75rem;font-size:13px;font-family:inherit;margin-bottom:1rem;"> |
| 47 | + <div style="display:flex;align-items:center;gap:1rem;"> |
| 48 | + <button type="submit" class="btn" id="review-submit-btn" disabled style="background:linear-gradient(135deg,#3b82f6,#6366f1);color:#fff;border:none;border-radius:8px;padding:10px 20px;font-size:13px;font-weight:600;cursor:pointer;opacity:0.5;">Submit review</button> |
| 49 | + <a href="/review/dismiss" onclick="event.preventDefault();fetch('/review/dismiss',{method:'POST'}).then(()=>location.reload());" style="font-size:13px;color:#64748b;text-decoration:none;">Maybe later</a> |
| 50 | + </div> |
| 51 | + </form> |
| 52 | +</div> |
| 53 | +<script> |
| 54 | +(function() { |
| 55 | + var stars = document.querySelectorAll('.review-star'); |
| 56 | + var ratingInput = document.getElementById('review-rating'); |
| 57 | + var submitBtn = document.getElementById('review-submit-btn'); |
| 58 | + var currentRating = 0; |
| 59 | + function setStars(n, hover) { |
| 60 | + stars.forEach(function(s, i) { |
| 61 | + s.innerHTML = (i < n) ? '★' : '☆'; |
| 62 | + s.style.color = (i < n) ? '#f59e0b' : '#4a5568'; |
| 63 | + }); |
| 64 | + } |
| 65 | + stars.forEach(function(star) { |
| 66 | + star.addEventListener('click', function() { |
| 67 | + currentRating = parseInt(this.dataset.val); |
| 68 | + ratingInput.value = currentRating; |
| 69 | + setStars(currentRating, false); |
| 70 | + submitBtn.disabled = false; |
| 71 | + submitBtn.style.opacity = '1'; |
| 72 | + }); |
| 73 | + star.addEventListener('mouseenter', function() { |
| 74 | + setStars(parseInt(this.dataset.val), true); |
| 75 | + }); |
| 76 | + star.addEventListener('mouseleave', function() { |
| 77 | + setStars(currentRating, false); |
| 78 | + }); |
| 79 | + }); |
| 80 | + setStars(0, false); |
| 81 | +})(); |
| 82 | +</script> |
| 83 | +{% endif %} |
| 84 | + |
30 | 85 | <div class="card"> |
31 | 86 | <div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:1.5rem;"> |
32 | 87 | <div> |
|
37 | 92 | </div> |
38 | 93 | <div class="stat-row"> |
39 | 94 | <span class="stat-label">Last sync</span> |
40 | | - <span class="stat-value">{{ last_sync or 'Never' }}</span> |
| 95 | + <span class="stat-value utc-time">{{ last_sync or 'Never' }}</span> |
41 | 96 | </div> |
42 | 97 | <div class="stat-row"><span class="stat-label">Notifications</span><span class="stat-value">{{ notify_email or 'Disabled' }}</span></div> |
43 | 98 | {% if total_tx >= 0 %} |
|
112 | 167 | <tbody> |
113 | 168 | {% for s in syncs %} |
114 | 169 | <tr> |
115 | | - <td>{{ s.ran_at }}</td> |
| 170 | + <td class="utc-time">{{ s.ran_at }}</td> |
116 | 171 | <td><span class="badge {% if s.status == 'success' %}badge-success{% else %}badge-fail{% endif %}">{{ s.status }}</span></td> |
117 | 172 | <td>{{ s.tx_count }}</td> |
118 | 173 | <td style="max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="{{ s.message }}">{{ s.message or '—' }}</td> |
|
245 | 300 | btn.disabled = false; |
246 | 301 | } |
247 | 302 | } |
| 303 | +document.querySelectorAll('.utc-time').forEach(function(el) { |
| 304 | + var raw = el.textContent.trim(); |
| 305 | + if (!raw || raw === 'Never') return; |
| 306 | + var d = new Date(raw + 'Z'); |
| 307 | + if (isNaN(d)) return; |
| 308 | + el.textContent = d.toLocaleString(undefined, {year:'numeric',month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}); |
| 309 | +}); |
248 | 310 | </script> |
249 | 311 | {% endblock %} |
0 commit comments