|
| 1 | +<script> |
| 2 | + import { page } from '$app/stores'; |
| 3 | +
|
| 4 | + function handleRefresh() { |
| 5 | + window.location.reload(); |
| 6 | + } |
| 7 | +</script> |
| 8 | + |
| 9 | +<svelte:head> |
| 10 | + <title>Error | DevCard</title> |
| 11 | +</svelte:head> |
| 12 | + |
| 13 | +<div class="error-container"> |
| 14 | + <div class="error-card glass"> |
| 15 | + <div class="error-icon"> |
| 16 | + <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 17 | + <circle cx="12" cy="12" r="10"></circle> |
| 18 | + <line x1="12" y1="8" x2="12" y2="12"></line> |
| 19 | + <line x1="12" y1="16" x2="12.01" y2="16"></line> |
| 20 | + </svg> |
| 21 | + </div> |
| 22 | + |
| 23 | + <h1 class="gradient-text">Oops! Something went wrong</h1> |
| 24 | + |
| 25 | + <p class="error-message"> |
| 26 | + We encountered an unexpected error while loading this developer card. |
| 27 | + <br> |
| 28 | + {#if $page.error?.message} |
| 29 | + <span class="error-detail">{$page.status}: {$page.error.message}</span> |
| 30 | + {/if} |
| 31 | + </p> |
| 32 | + |
| 33 | + <div class="action-buttons"> |
| 34 | + <button class="btn-primary" onclick={handleRefresh}> |
| 35 | + Try Again |
| 36 | + </button> |
| 37 | + <a href="/" class="btn-secondary"> |
| 38 | + Go Home |
| 39 | + </a> |
| 40 | + </div> |
| 41 | + </div> |
| 42 | +</div> |
| 43 | + |
| 44 | +<style> |
| 45 | + .error-container { |
| 46 | + display: flex; |
| 47 | + align-items: center; |
| 48 | + justify-content: center; |
| 49 | + min-height: 100vh; |
| 50 | + padding: 1.5rem; |
| 51 | + background: var(--bg-page); |
| 52 | + } |
| 53 | +
|
| 54 | + .error-card { |
| 55 | + display: flex; |
| 56 | + flex-direction: column; |
| 57 | + align-items: center; |
| 58 | + text-align: center; |
| 59 | + max-width: 550px; |
| 60 | + width: 100%; |
| 61 | + padding: 3rem 2rem; |
| 62 | + border-radius: var(--radius-lg); |
| 63 | + animation: slideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1); |
| 64 | + } |
| 65 | +
|
| 66 | + .error-icon { |
| 67 | + color: #ef4444; |
| 68 | + margin-bottom: 1.5rem; |
| 69 | + background: rgba(239, 68, 68, 0.1); |
| 70 | + padding: 1.25rem; |
| 71 | + border-radius: 50%; |
| 72 | + box-shadow: 0 4px 14px -6px rgba(239, 68, 68, 0.4); |
| 73 | + } |
| 74 | +
|
| 75 | + h1 { |
| 76 | + font-size: 2.25rem; |
| 77 | + margin-bottom: 1rem; |
| 78 | + } |
| 79 | +
|
| 80 | + .error-message { |
| 81 | + color: var(--text-secondary); |
| 82 | + font-size: 1.1rem; |
| 83 | + line-height: 1.6; |
| 84 | + margin-bottom: 2.5rem; |
| 85 | + } |
| 86 | +
|
| 87 | + .error-detail { |
| 88 | + display: inline-block; |
| 89 | + margin-top: 1rem; |
| 90 | + font-size: 0.9rem; |
| 91 | + padding: 0.75rem 1rem; |
| 92 | + background: var(--bg-secondary); |
| 93 | + border: 1px solid var(--border); |
| 94 | + border-radius: var(--radius); |
| 95 | + color: var(--text-muted); |
| 96 | + font-family: monospace; |
| 97 | + word-break: break-word; |
| 98 | + } |
| 99 | +
|
| 100 | + .action-buttons { |
| 101 | + display: flex; |
| 102 | + gap: 1.25rem; |
| 103 | + flex-wrap: wrap; |
| 104 | + justify-content: center; |
| 105 | + } |
| 106 | +
|
| 107 | + @keyframes slideUp { |
| 108 | + from { |
| 109 | + opacity: 0; |
| 110 | + transform: translateY(20px); |
| 111 | + } |
| 112 | + to { |
| 113 | + opacity: 1; |
| 114 | + transform: translateY(0); |
| 115 | + } |
| 116 | + } |
| 117 | +
|
| 118 | + @media (max-width: 640px) { |
| 119 | + .error-card { |
| 120 | + padding: 2.5rem 1.5rem; |
| 121 | + } |
| 122 | + |
| 123 | + h1 { |
| 124 | + font-size: 1.75rem; |
| 125 | + } |
| 126 | + |
| 127 | + .action-buttons { |
| 128 | + width: 100%; |
| 129 | + flex-direction: column; |
| 130 | + gap: 1rem; |
| 131 | + } |
| 132 | + |
| 133 | + .action-buttons > * { |
| 134 | + width: 100%; |
| 135 | + } |
| 136 | + } |
| 137 | +</style> |
0 commit comments