App.svelte raw
1 <script>
2 import { onMount } from 'svelte';
3 import Header from './components/Header.svelte';
4 import LoginModal from './LoginModal.svelte';
5 import Dashboard from './pages/Dashboard.svelte';
6 import Config from './pages/Config.svelte';
7 import Update from './pages/Update.svelte';
8 import { isLoggedIn, userPubkey, userSigner, authMethod } from './stores.js';
9
10 let currentPage = 'dashboard';
11 let showLoginModal = false;
12 let isDarkTheme = false;
13
14 onMount(() => {
15 // Check for stored auth
16 const storedMethod = localStorage.getItem('launcher_auth_method');
17 const storedPubkey = localStorage.getItem('launcher_pubkey');
18
19 if (storedMethod === 'extension' && storedPubkey) {
20 // Try to restore extension session
21 if (window.nostr) {
22 window.nostr.getPublicKey().then(pk => {
23 if (pk === storedPubkey) {
24 $isLoggedIn = true;
25 $userPubkey = pk;
26 $userSigner = window.nostr;
27 $authMethod = 'extension';
28 }
29 }).catch(() => {
30 // Extension not available, clear stored auth
31 localStorage.removeItem('launcher_auth_method');
32 localStorage.removeItem('launcher_pubkey');
33 });
34 }
35 }
36
37 // Check for dark theme preference
38 isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
39 });
40
41 function handleLogin(event) {
42 const { method, pubkey, signer, privateKey } = event.detail;
43
44 $isLoggedIn = true;
45 $userPubkey = pubkey;
46 $userSigner = signer;
47 $authMethod = method;
48
49 localStorage.setItem('launcher_auth_method', method);
50 localStorage.setItem('launcher_pubkey', pubkey);
51
52 if (method === 'nsec' && privateKey) {
53 // Store encrypted key (handled by LoginModal)
54 }
55
56 showLoginModal = false;
57 }
58
59 function handleLogout() {
60 $isLoggedIn = false;
61 $userPubkey = '';
62 $userSigner = null;
63 $authMethod = '';
64
65 localStorage.removeItem('launcher_auth_method');
66 localStorage.removeItem('launcher_pubkey');
67 localStorage.removeItem('launcher_privkey_encrypted');
68 }
69
70 function navigateTo(page) {
71 currentPage = page;
72 }
73 </script>
74
75 <main class:dark-theme={isDarkTheme}>
76 <Header
77 {currentPage}
78 isLoggedIn={$isLoggedIn}
79 userPubkey={$userPubkey}
80 on:navigate={(e) => navigateTo(e.detail)}
81 on:login={() => showLoginModal = true}
82 on:logout={handleLogout}
83 />
84
85 <div class="content">
86 {#if !$isLoggedIn}
87 <div class="login-prompt">
88 <h2>ORLY Launcher Admin</h2>
89 <p>Please login to manage the relay services.</p>
90 <button class="login-btn" on:click={() => showLoginModal = true}>
91 Login with Nostr
92 </button>
93 </div>
94 {:else if currentPage === 'dashboard'}
95 <Dashboard />
96 {:else if currentPage === 'config'}
97 <Config />
98 {:else if currentPage === 'update'}
99 <Update />
100 {/if}
101 </div>
102
103 <LoginModal
104 bind:showModal={showLoginModal}
105 {isDarkTheme}
106 on:login={handleLogin}
107 on:close={() => showLoginModal = false}
108 />
109 </main>
110
111 <style>
112 :global(*) {
113 box-sizing: border-box;
114 margin: 0;
115 padding: 0;
116 }
117
118 :global(body) {
119 font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
120 background: var(--bg-color);
121 color: var(--text-color);
122 min-height: 100vh;
123 }
124
125 main {
126 --bg-color: #f5f5f5;
127 --card-bg: #ffffff;
128 --text-color: #333333;
129 --muted-color: #666666;
130 --border-color: #e0e0e0;
131 --primary: #00bcd4;
132 --primary-hover: #00acc1;
133 --success: #4caf50;
134 --error: #f44336;
135 --warning: #ff9800;
136
137 min-height: 100vh;
138 background: var(--bg-color);
139 }
140
141 main.dark-theme {
142 --bg-color: #1a1a1a;
143 --card-bg: #2d2d2d;
144 --text-color: #e0e0e0;
145 --muted-color: #999999;
146 --border-color: #444444;
147 }
148
149 .content {
150 max-width: 1200px;
151 margin: 0 auto;
152 padding: 20px;
153 }
154
155 .login-prompt {
156 text-align: center;
157 padding: 60px 20px;
158 }
159
160 .login-prompt h2 {
161 font-size: 2rem;
162 margin-bottom: 16px;
163 color: var(--text-color);
164 }
165
166 .login-prompt p {
167 color: var(--muted-color);
168 margin-bottom: 24px;
169 }
170
171 .login-btn {
172 padding: 12px 32px;
173 font-size: 1rem;
174 background: var(--primary);
175 color: white;
176 border: none;
177 border-radius: 6px;
178 cursor: pointer;
179 transition: background 0.2s;
180 }
181
182 .login-btn:hover {
183 background: var(--primary-hover);
184 }
185 </style>
186