ImportView.svelte raw
1 <script>
2 export let isLoggedIn = false;
3 export let currentEffectiveRole = "";
4 export let selectedFile = null;
5 export let aclMode = "";
6 export let importMessage = "";
7
8 import { createEventDispatcher } from "svelte";
9 const dispatch = createEventDispatcher();
10
11 // When ACL is "none", allow access without login
12 $: canImport = aclMode === "none" || (isLoggedIn && (currentEffectiveRole === "admin" || currentEffectiveRole === "owner"));
13
14 function handleFileSelect(event) {
15 dispatch("fileSelect", event);
16 }
17
18 function importEvents() {
19 dispatch("importEvents");
20 }
21
22 function openLoginModal() {
23 dispatch("openLoginModal");
24 }
25 </script>
26
27 <div class="import-section">
28 {#if canImport}
29 <h3>Import Events</h3>
30 <p>Upload a JSONL file to import events into the database.</p>
31 <div class="recovery-controls-card">
32 <input
33 type="file"
34 id="import-file"
35 accept=".jsonl,.txt"
36 on:change={handleFileSelect}
37 />
38 <div class="import-row">
39 <button
40 class="import-btn"
41 on:click={importEvents}
42 disabled={!selectedFile || importMessage === "Uploading..."}
43 >
44 Import Events
45 </button>
46 {#if importMessage}
47 <span class="import-message" class:uploading={importMessage === "Uploading..."} class:success={importMessage === "Upload complete"} class:error={importMessage.startsWith("Import failed") || importMessage.startsWith("Admin") || importMessage.startsWith("Please")}>{importMessage}</span>
48 {/if}
49 </div>
50 </div>
51 {:else if isLoggedIn}
52 <div class="permission-denied">
53 <h3 class="recovery-header">Import Events</h3>
54 <p class="recovery-description">
55 Admin or owner permission required for import functionality.
56 </p>
57 </div>
58 {:else}
59 <div class="login-prompt">
60 <h3 class="recovery-header">Import Events</h3>
61 <p class="recovery-description">
62 Please log in to access import functionality.
63 </p>
64 <button class="login-btn" on:click={openLoginModal}>Log In</button>
65 </div>
66 {/if}
67 </div>
68
69 <style>
70 .import-section {
71 background: transparent;
72 padding: 1em;
73 border-radius: 8px;
74 margin-bottom: 1.5rem;
75 width: 100%;
76 max-width: 32em;
77 box-sizing: border-box;
78 }
79
80 .import-section h3 {
81 margin: 0 0 1rem 0;
82 color: var(--text-color);
83 font-size: 1.2rem;
84 font-weight: 600;
85 }
86
87 .import-section p {
88 margin: 0 0 1.5rem 0;
89 color: var(--text-color);
90 opacity: 0.8;
91 line-height: 1.4;
92 }
93
94 .recovery-controls-card {
95 background-color: var(--card-bg);
96 padding: 1em;
97 border: 0;
98 display: flex;
99 flex-direction: column;
100 border-radius: 0.5em;
101 gap: 1em;
102 }
103
104 #import-file {
105 padding: 0.5em;
106 border: 0;
107 background: var(--input-bg);
108 color: var(--input-text-color);
109 }
110
111 .import-btn {
112 background-color: var(--primary);
113 color: var(--text-color);
114 border-radius: 0.5em;
115 padding: 0.75em 1.5em;
116 border: 0;
117 cursor: pointer;
118 font-weight: bold;
119 font-size: 0.9em;
120 transition: background-color 0.2s;
121 align-self: flex-start;
122 }
123
124 .import-btn:hover:not(:disabled) {
125 background-color: var(--accent-hover-color);
126 }
127
128 .import-btn:disabled {
129 background-color: var(--secondary);
130 cursor: not-allowed;
131 }
132
133 .import-row {
134 display: flex;
135 align-items: center;
136 gap: 1em;
137 }
138
139 .import-message {
140 font-size: 0.9em;
141 padding: 0.25em 0.5em;
142 border-radius: 0.25em;
143 }
144
145 .import-message.uploading {
146 color: var(--primary);
147 }
148
149 .import-message.success {
150 color: var(--success);
151 }
152
153 .import-message.error {
154 color: var(--danger);
155 }
156
157 .permission-denied,
158 .login-prompt {
159 text-align: center;
160 padding: 2em;
161 background-color: var(--card-bg);
162 border: 0;
163 }
164
165 .recovery-header {
166 margin: 0 0 1rem 0;
167 color: var(--text-color);
168 font-size: 1.2rem;
169 font-weight: 600;
170 }
171
172 .recovery-description {
173 margin: 0 0 1.5rem 0;
174 color: var(--text-color);
175 line-height: 1.4;
176 }
177
178 .login-btn {
179 background-color: var(--primary);
180 color: var(--text-color);
181 border: none;
182 padding: 0.75em 1.5em;
183 border: 0;
184 cursor: pointer;
185 font-weight: bold;
186 font-size: 0.9em;
187 transition: background-color 0.2s;
188 }
189
190 .login-btn:hover {
191 background-color: var(--accent-hover-color);
192 }
193 </style>
194