@silexlabs/silex-dashboard 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,176 +1,557 @@
1
- <!DOCTYPE html><html lang=""><head><link rel="stylesheet" href="/css/main.css">
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="">
4
+ <head>
5
+ <link rel="stylesheet" href="/css/websites.css" />
6
+
2
7
  <link
3
8
  rel="alternate"
4
9
  hreflang="fr"
5
- href="/fr/" /> <!--
6
- <div class="app">
7
- <div v-if="showLoginForm">
8
- <h2>Login</h2>
9
- <form @submit.prevent="login">
10
- <label>
11
- Username:
12
- <input type="text" v-model="username" required />
13
- </label>
14
- <label>
15
- Password:
16
- <input type="password" v-model="password" required />
17
- </label>
18
- <button type="submit">Login</button>
19
- </form>
20
- </div>
21
-
22
- <div v-if="loggedIn">
23
- <button @click="showLoginForm = true; loggedIn = false; websites = []">Logout</button>
24
- <h2>Websites</h2>
25
- <ul>
26
- <li v-for="(website, index) in websites" :key="index">
27
- <div v-text="website.name || website.id"></div>
28
- <button @click="deleteWebsite(website.id)">Delete</button>
29
- </li>
30
- </ul>
31
-
32
- <button @click="showCreationForm = true">Create Website</button>
33
-
34
- <div v-if="showCreationForm">
35
- <h2>Create Website</h2>
36
- <form @submit.prevent="createWebsite">
37
- <label>
38
- Website Name:
39
- <input type="text" v-model="newWebsiteName" required />
40
- </label>
41
- <button type="submit">Create</button>
42
- </form>
43
- </div>
44
- </div>
45
-
46
- <div v-if="error">
47
- <p>Error: </p>
48
- <button @click="error = null">Dismiss</button>
49
- </div>
50
-
51
- <div v-if="message">
52
- <p></p>
53
- <button @click="message = null">Dismiss</button>
54
- </div>
55
- </div>
56
- -->
57
- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
58
- <script>
59
- const { createApp, ref, onMounted, reactive } = Vue;
60
- const apiUrl = 'http://localhost:6805';
61
-
62
- const App = {
63
- data() {
64
- return {
65
- websites: [],
66
- newWebsiteName: '',
67
- showCreationForm: false,
68
- error: null,
69
- message: null,
70
- showLoginForm: false,
71
- username: '',
72
- password: '',
73
- loggedIn: true,
74
- loading: true,
75
- }
76
- },
77
- mounted() {
78
- if (this.loggedIn) this.fetchWebsites()
79
- else this.showLoginForm = true
80
- },
81
- methods: {
82
- openEditor(id, lang) {
83
- window.open(`${apiUrl}/?id=${id}&lang=${lang}`)
84
- },
85
- async fetchWebsites() {
86
- this.loading = true
87
- try {
88
- const response = await fetch(`${apiUrl}/website/`)
89
- if (!response.ok) {
90
- throw new Error(`HTTP error! status: ${response.status}`)
91
- }
92
- this.websites = await response.json();
93
- } catch (error) {
94
- this.error = 'Failed to fetch websites'
95
- }
96
- this.loading = false
97
- },
10
+ href="/fr/" />
98
11
 
99
- async login() {
100
- this.loading = true
101
- try {
102
- const response = await fetch(`${apiUrl}/me/`, {
103
- method: 'POST',
104
- headers: {
105
- 'Content-Type': 'application/json',
106
- },
107
- body: JSON.stringify({
108
- username: this.username,
109
- password: this.password,
110
- }),
111
- })
112
- if (!response.ok) {
113
- throw new Error(`HTTP error! status: ${response.status}`)
114
- }
115
- this.loggedIn = true;
116
- this.showLoginForm = false;
117
- await this.fetchWebsites()
118
- } catch (error) {
119
- this.error = 'Failed to log in'
120
- }
121
- this.loading = false
122
- },
12
+ <style>
13
+ .button { cursor: pointer; }
14
+ a { text-decoration: none; }
15
+ a:hover { text-decoration: underline; }
123
16
 
124
- async createWebsite() {
125
- if(!this.newWebsiteName) throw new Error('You need to provide a website name')
126
- this.loading = true
127
- try {
128
- const id = this.newWebsiteName.replace(/[/\\?%*:|"<>]/g, '_')
129
- const response = await fetch(`${apiUrl}/website/?id=${id}`, {
130
- method: 'POST',
131
- headers: {
132
- 'Content-Type': 'application/json',
133
- },
134
- body: JSON.stringify({
135
- name: this.newWebsiteName,
136
- }),
137
- })
138
- if (!response.ok) {
139
- throw new Error(`HTTP error! status: ${response.status}`)
140
- }
141
- this.message = 'Website created successfully'
142
- this.newWebsiteName = ''
143
- this.showCreationForm = false;
144
- await this.fetchWebsites()
145
- } catch (error) {
146
- this.error = 'Failed to create website'
147
- }
148
- this.loading = false
149
- },
17
+ .skeleton-anim:after {
18
+ width: 100%;
19
+ height: 100%;
20
+ position: absolute;
21
+ top: 0;
22
+ left: 0;
23
+ content: "";
24
+ background:
25
+ linear-gradient(0.25turn, transparent, rgba(255,255,255,.75), transparent),
26
+ linear-gradient(transparent, transparent),
27
+ radial-gradient(38px circle at 19px 19px, transparent 50%, transparent 51%),
28
+ linear-gradient(transparent, transparent);
29
+ background-repeat: no-repeat;
30
+ background-size: 315px 250px, 315px 180px, 100px 100px, 225px 30px;
31
+ background-position: -315px 0, 0 0, 0px 190px, 50px 195px;
32
+ animation: loading 1.5s infinite;
33
+ }
34
+
35
+ @keyframes loading {
36
+ to {
37
+ background-position: 200% 0, 0 0, 0 190px, 50px 195px;
38
+ }
39
+ }
40
+
41
+ </style>
42
+ <script src="/node_modules/vue/dist/vue.global.js"></script>
43
+ <script src="/js/main.js"></script>
44
+ <script type="module">
45
+ const CONNECTORS_PATH = '/connectors/'
46
+ window.addEventListener('load', function() {
47
+ const { createApp } = Vue;
48
+ const { api, constants, types } = silex;
49
+ const {
50
+ ConnectorType,
51
+ } = types
52
+ const {
53
+ getUser,
54
+ logout,
55
+ websiteDelete,
56
+ websiteList,
57
+ websiteCreate,
58
+ websiteMetaWrite,
59
+ } = api
60
+
61
+ const App = {
62
+ data() {
63
+ return {
64
+ websites: [],
65
+ newWebsiteName: '',
66
+ showCreationForm: false,
67
+ error: null,
68
+ message: null,
69
+ loggedIn: false,
70
+ loading: true,
71
+ storage: null,
72
+ user: null,
73
+ showMenu: false,
74
+ }
75
+ },
76
+ mounted() {
77
+ this.init()
78
+ },
79
+
80
+ methods: {
81
+ async init() {
82
+ try {
83
+ // Debug
84
+ window.app = this
85
+ const user = await getUser({type: ConnectorType.STORAGE})
86
+ if(user) {
87
+ this.user = user
88
+ this.loggedIn = true
89
+ this.websites = await websiteList({connectorId: this.user.storage.connectorId})
90
+ this.loading = false
91
+ } else {
92
+ this.openLogin()
93
+ }
94
+ } catch (error) {
95
+ console.error(error)
96
+ this.loading = false
97
+ if(error.code === 401 || error.httpStatusCode === 401) {
98
+ this.loggedIn = false
99
+ this.openLogin()
100
+ } else {
101
+ this.error = error
102
+ }
103
+ }
104
+ },
150
105
 
151
- async deleteWebsite(id) {
152
- const ok = confirm('Deleting a website? Are your sure? Really?')
153
- if(!ok) return
154
- this.loading = true
155
- try {
156
- const response = await fetch(`${apiUrl}/website/?id=${id}`, {
157
- method: 'DELETE',
158
- })
159
- if (!response.ok) {
160
- throw new Error(`HTTP error! status: ${response.status}`)
161
- }
162
- this.message = 'Website deleted successfully'
163
- await this.fetchWebsites()
164
- } catch (error) {
165
- this.error = 'Failed to delete website'
166
- }
167
- this.loading = false
106
+ openLogin(id, lang) {
107
+ //throw new Error('debug')
108
+ const path = `/en${CONNECTORS_PATH}`
109
+ console.log(window.location.pathname, window.location.path, path)
110
+ if(window.location.pathname === path) return
111
+ window.open(path, '_self')
112
+ },
113
+
114
+ openEditor(id, lang) {
115
+ window.open(`/?id=${id}&lang=${lang}&connectorId=${this.user.storage.connectorId}`, '_blank')
116
+ },
117
+
118
+ async logout() {
119
+ await logout({
120
+ type: ConnectorType.STORAGE,
121
+ connectorId: this.user.storage.connectorId,
122
+ })
123
+ window.location.reload()
124
+ },
125
+
126
+ async createWebsite() {
127
+ if (!this.newWebsiteName) throw new Error('You need to provide a website name')
128
+ this.loading = true
129
+ try {
130
+ const websiteId = this.newWebsiteName.replace(/[/\\?%*:|"<>]/g, '_')
131
+ const result = await websiteCreate({
132
+ websiteId,
133
+ data: {
134
+ name: this.newWebsiteName,
135
+ imageUrl: null,
168
136
  },
169
- },
170
- };
171
-
172
- window.addEventListener('load', () => {
173
- createApp(App).mount('.app');
174
- })
175
- </script>
176
- <style>.button{cursor:pointer}a{text-decoration:none}a:hover{text-decoration:underline}.skeleton-anim:after{width:100%;height:100%;position:absolute;top:0;left:0;content:"";background:linear-gradient(.25turn,transparent,rgba(255,255,255,.75),transparent),linear-gradient(transparent,transparent),radial-gradient(38px circle at 19px 19px,transparent 50%,transparent 51%),linear-gradient(transparent,transparent);background-repeat:no-repeat;background-size:315px 250px,315px 180px,100px 100px,225px 30px;background-position:-315px 0,0 0,0 190px,50px 195px;animation:loading 1.5s infinite}@keyframes loading{to{background-position:200% 0,0 0,0 190px,50px 195px}}</style><title>Silex Dashboard</title><link rel="icon" href=""><meta property="description" content=""><meta property="og:title" content=""><meta property="og:description" content=""><meta property="og:image" content=""></head><body id="ik0i" class="body loading"><header id="igrg" class="header padding-normal"><a id="igvu43" href="/"><img id="ir7s" src="/assets//silex-icon-2018@200px.png" href="" class="nav__logo"></a><nav id="i9jq" class="nav"><a id="iels" href="/" class="nav__item active" target="">Sites</a><a id="iels" href="http://docs.silex.me/" class="nav__item " target="_blank">Docs</a><a id="iels" href="https://www.silex.me/" class="nav__item " target="_blank">About</a><a id="iels" href="https://mail-list.silexlabs.org/subscription/cemnfkaVrK?locale=en-US&source=silex-dashboard" class="nav__item " target="_blank">News</a></nav><div id="i2red7" class="lang h-space"><a href="/en" id="iciz" class="lang__item nav__item active" hreflang="en">en</a><a href="/fr" id="iciz" class="lang__item nav__item " hreflang="fr">fr</a></div><div id="i24ew"><img id="idkdk" src="/assets//alex-small.jpg" src="${json.avatar.url}"></div></header><main id="iz63r" class="padding-normal section app"><h1 id="itp1f">Welcome back!</h1><div id="iyex8" class="subtitle color--light">Dive into your projects or kickstart a new one</div><div id="ickx4" class="button-bar margin-20"><button id="i2x0l" class="button button--primary rounded top-space-40" @click="showCreationForm = !showCreationForm" v-if="!showCreationForm"><span id="ibsgw" class="icon-font">+</span><span id="itl2n8">Create website</span></button><div id="i0ro3" class="button button--secondary rounded">Import</div></div><div id="ihwwxz" class="box top-space-40" v-if="showCreationForm"><h3 id="i3gd1b" class="box__header">Create a new website</h3><form method="get" id="i50acf" class="form" @submit.prevent="createWebsite"><div id="igtg1t" class="v-space"><label id="i1nmbc" class="v-space">Website name</label><input type="text" id="ij5iwh" placeholder="My project website" class="input full-width" v-model="newWebsiteName"></div><div id="ie0xes"><button type="submit" id="i021na" class="button rounded button--primary right-space">Create</button><button type="reset" class="button rounded button--secondary" @click="showCreationForm = !showCreationForm">Cancel</button></div></form></div><div id="if80m"><section id="idgvg" class="button-bar button-bar--full-width bg-white rounded loaded__item" v-if="!loading" v-for="(website, index) in websites" :key="index"><h3 id="i69a7" class="button-bar_item button-bar__item--main" v-text="website.name || website.id">My first website</h3><p id="i65hn" class="button-bar_item button-bar__item--secondary flex-no-shrink" v-text="'Updated ' + new Date(website.stats.mtime).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })">Updated 1h ago by lexoyo</p><p id="i64qa" class="button-bar_item button-bar__item--secondary flex-no-shrink" v-text="'Created ' + new Date(website.stats.birthtime).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })">Created 2023-02-16 by lexoyo</p><div id="i3b4tr" class="button-bar_item flex-no-shrink"><button id="ifyf6p" href="" class="button rounded button--primary button--small right-space" @click="openEditor(website.id, 'en')">Edit</button><button id="iol4h" class="button rounded button--secondary button--small" @click="deleteWebsite(website.id)" title="Delete">X</button></div></section><section id="i1fjn" class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper" v-if="loading"><h3 class="button-bar_item button-bar__item--main skeleton-text skeleton">My first websiteMy first websiteMy first websiteMy first</h3><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Updated 1h ago by lexoyo</p><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Created 2023-02-16 by lexoyo</p><div id="ixz6c" class="button-bar_item skeleton skeleton-button">Edit</div></section><section id="iwxxo5" class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper" v-if="loading"><h3 class="button-bar_item button-bar__item--main skeleton-text skeleton">My first websiteMy first websiteMy first websiteMy first</h3><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Updated 1h ago by lexoyo</p><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Created 2023-02-16 by lexoyo</p><div id="i9fx3l" class="button-bar_item skeleton skeleton-button">Edit</div></section><section id="isld3r" class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper" v-if="loading"><h3 class="button-bar_item button-bar__item--main skeleton-text skeleton">My first websiteMy first websiteMy first websiteMy first</h3><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Updated 1h ago by lexoyo</p><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Created 2023-02-16 by lexoyo</p><div id="i8oes3" class="button-bar_item skeleton skeleton-button">Edit</div></section><section id="iqmx38" class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper" v-if="loading"><h3 class="button-bar_item button-bar__item--main skeleton-text skeleton">My first websiteMy first websiteMy first websiteMy first</h3><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Updated 1h ago by lexoyo</p><p class="button-bar_item button-bar__item--secondary skeleton-text skeleton">Created 2023-02-16 by lexoyo</p><div id="ie83jl" class="button-bar_item skeleton skeleton-button">Edit</div></section></div><div id="i7ej6j" class="box horizontal" v-if="error"><div id="iv0eyi" class="full-width v-space h-space" v-text="error">Insert your text here</div><div id="i4656n" class="button rounded button--small button--tertiary" @click="error = null">Dismiss</div></div><div id="ilteie" class="box horizontal" v-if="message"><div id="i2d31v" class="full-width v-space h-space" v-text="message">Insert your text here</div><div id="i2urco" class="button rounded button--small button--tertiary" @click="message = null">Dismiss</div></div></main><footer id="ilzpl" class="header footer"><div id="i238z" class="section"></div></footer></body></html>
137
+ connectorId: this.user.storage.connectorId
138
+ })
139
+ this.message = 'Website created successfully'
140
+ this.newWebsiteName = ''
141
+ this.showCreationForm = false;
142
+ this.websites = await websiteList({connectorId: this.user.storage.connectorId})
143
+ this.loading = false
144
+ return result
145
+ } catch (error) {
146
+ this.loading = false
147
+ console.error(error)
148
+ this.error = 'Failed to create website'
149
+ }
150
+ },
151
+
152
+ async deleteWebsite(websiteId) {
153
+ const ok = confirm('Deleting a website? Are your sure? Really?')
154
+ if (!ok) return
155
+ this.loading = true
156
+ try {
157
+ const result = await websiteDelete({websiteId, connectorId: this.user.storage.connectorId})
158
+ this.message = 'Website deleted successfully'
159
+ this.websites = await websiteList({connectorId: this.user.storage.connectorId})
160
+ this.loading = false
161
+ return result
162
+ } catch (error) {
163
+ this.loading = false
164
+ this.error = 'Failed to delete website'
165
+ }
166
+ },
167
+
168
+ async renameWebsite(websiteId) {
169
+ const website = this.websites.find(w => w.websiteId === websiteId)
170
+ const name = prompt('New name for this website', website.name)
171
+ if (!name) return
172
+ this.loading = true
173
+ try {
174
+ const result = await websiteMetaWrite({websiteId, connectorId: this.user.storage.connectorId, data: { name }})
175
+ this.message = 'Website renamed successfully'
176
+ this.websites = await websiteList({connectorId: this.user.storage.connectorId})
177
+ this.loading = false
178
+ return result
179
+ } catch (error) {
180
+ this.loading = false
181
+ this.error = 'Failed to delete website'
182
+ }
183
+ },
184
+ },
185
+ };
186
+
187
+ // Start vue app
188
+ createApp(App).mount('.app');
189
+ })
190
+ </script>
191
+
192
+
193
+ <title>Silex Dashboard</title>
194
+ <link rel="icon" href="" />
195
+ <meta property="description" content=""/>
196
+ <meta property="og:title" content=""/>
197
+ <meta property="og:description" content=""/>
198
+ <meta property="og:image" content=""/>
199
+ </head>
200
+ <body
201
+ id="ik0i"
202
+ class="body loading app"
203
+
204
+
205
+ ><HEADER
206
+ id="igrg"
207
+ class="header padding-normal "
208
+
209
+
210
+ ><A
211
+ id="igvu43" href="/"
212
+
213
+
214
+
215
+ ><img
216
+ src="/assets/silex-icon-2018@200px.png" href="" id="iel80b-2"
217
+ class="nav__logo "
218
+
219
+
220
+ ></img></A><NAV
221
+ id="i9jq"
222
+ class="nav "
223
+
224
+
225
+ ><A
226
+ id="iels" href="/"
227
+ class="nav__item active"
228
+ target=""
229
+
230
+ >Sites</A><A
231
+ id="iels" href="http://docs.silex.me/"
232
+ class="nav__item "
233
+ target="_blank"
234
+
235
+ >Docs</A><A
236
+ id="iels" href="https://www.silex.me/"
237
+ class="nav__item "
238
+ target="_blank"
239
+
240
+ >About</A><A
241
+ id="iels" href="https://mail-list.silexlabs.org/subscription/cemnfkaVrK?locale=en-US&source=silex-dashboard"
242
+ class="nav__item "
243
+ target="_blank"
244
+
245
+ >News</A></NAV><div
246
+ id="i2red7"
247
+ class="lang h-space "
248
+
249
+
250
+ ><A
251
+ href="/en" id="iciz"
252
+ class="lang__item nav__item active"
253
+ hreflang="en"
254
+
255
+ >en</A><A
256
+ href="/fr" id="iciz"
257
+ class="lang__item nav__item "
258
+ hreflang="fr"
259
+
260
+ >fr</A></div><div
261
+ id="i24ew"
262
+ class="user__wrapper "
263
+ v-if="user && !user.storage.disableLogout" @NOmouseover="showMenu = true" @NOmouseout="showMenu = false" @click="showMenu = !showMenu"
264
+
265
+ ><div
266
+ id="i5xsbd"
267
+ class="user-icon__wrapper "
268
+ v-if="user" v-show="!showMenu || user.storage.disableLogout"
269
+
270
+ ><div
271
+ id="i5wlbq"
272
+ class="user-icon__image "
273
+ v-if="user" v-show="!showMenu || user.storage.disableLogout" :style='`background: url("${user.picture}"); background-repeat: no-repeat; background-size: contain;`'
274
+
275
+ ></div></div><div
276
+ id="ic9eoa"
277
+
278
+ v-show="showMenu && !user.storage.disableLogout"
279
+
280
+ ><div
281
+ id="iksw4d"
282
+ class="button button--secondary "
283
+ @click="logout()"
284
+
285
+ >Logout</div></div></div></HEADER><MAIN
286
+ id="iz63r"
287
+ class="padding-normal section "
288
+
289
+
290
+ ><H1
291
+ id="itp1f"
292
+ class="title "
293
+
294
+
295
+ >Welcome back!</H1><div
296
+ id="iyex8"
297
+ class="subtitle color--light "
298
+
299
+
300
+ >Dive into your projects or kickstart a new one</div><div
301
+ id="ickx4"
302
+ class="button-bar margin-20 "
303
+
304
+
305
+ ><BUTTON
306
+ id="i2x0l"
307
+ class="button button--primary rounded top-space-40 "
308
+ @click="showCreationForm = !showCreationForm" v-if="!showCreationForm"
309
+
310
+ ><span
311
+ id="ibsgw"
312
+ class="icon-font "
313
+
314
+
315
+ >+</span> <span
316
+ id="itl2n8"
317
+
318
+
319
+
320
+ >Create website</span></BUTTON><div
321
+ id="i0ro3"
322
+ class="button button--secondary rounded "
323
+
324
+
325
+ >Import</div></div><div
326
+ id="ihwwxz"
327
+ class="box top-space-40 "
328
+ v-if="showCreationForm"
329
+
330
+ ><H3
331
+ id="i3gd1b"
332
+ class="box__header "
333
+
334
+
335
+ >Create a new website</H3><form
336
+ method="get" id="i50acf"
337
+ class="form "
338
+ @submit.prevent="createWebsite"
339
+
340
+ ><div
341
+ id="igtg1t"
342
+ class="v-space "
343
+
344
+
345
+ ><label
346
+ id="i1nmbc"
347
+ class="v-space "
348
+
349
+
350
+ >Website name</label><input
351
+ type="text" id="ij5iwh" placeholder="My project website"
352
+ class="input full-width "
353
+ v-model="newWebsiteName"
354
+
355
+ ></input></div><div
356
+ id="ie0xes"
357
+
358
+
359
+
360
+ ><button
361
+ type="submit" id="i021na"
362
+ class="button rounded button--primary right-space "
363
+
364
+
365
+ >Create</button><button
366
+ type="reset"
367
+ class="button rounded button--secondary "
368
+ @click="showCreationForm = !showCreationForm"
369
+
370
+ >Cancel</button></div></form></div><div
371
+ id="if80m"
372
+
373
+
374
+
375
+ ><SECTION
376
+ id="idgvg"
377
+ class="button-bar button-bar--full-width bg-white rounded loaded__item "
378
+ v-if="!loading" v-for="(website, index) in websites" :key="index"
379
+
380
+ ><H3
381
+ id="i69a7"
382
+ class="button-bar_item button-bar__item--main "
383
+ v-text="website.name || website.id"
384
+
385
+ >My first website</H3><P
386
+ id="i65hn"
387
+ class="button-bar_item button-bar__item--secondary flex-no-shrink "
388
+ v-text="'Updated ' + new Date(website.updatedAt).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })"
389
+
390
+ >Updated 1h ago by lexoyo</P><P
391
+ id="i64qa"
392
+ class="button-bar_item button-bar__item--secondary flex-no-shrink "
393
+ v-text="'Created ' + new Date(website.createdAt).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })"
394
+
395
+ >Created 2023-02-16 by lexoyo</P><div
396
+ id="i3b4tr"
397
+ class="button-bar_item flex-no-shrink "
398
+
399
+
400
+ ><BUTTON
401
+ id="ifyf6p" href=""
402
+ class="button rounded button--primary button--small right-space "
403
+ @click="openEditor(website.websiteId, 'en')"
404
+
405
+ >Edit</BUTTON><BUTTON
406
+ href="" id="ihf6ew"
407
+ class="button rounded button--small right-space button--tertiary "
408
+ @click="renameWebsite(website.websiteId, 'en')"
409
+
410
+ >Rename</BUTTON><BUTTON
411
+ id="iol4h"
412
+ class="button rounded button--small button--tertiary "
413
+ @click="deleteWebsite(website.websiteId)" title="Delete"
414
+
415
+ >X</BUTTON></div></SECTION><SECTION
416
+ id="i1fjn"
417
+ class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper "
418
+ v-if="loading"
419
+
420
+ ><H3
421
+
422
+ class="button-bar_item button-bar__item--main skeleton-text skeleton "
423
+
424
+
425
+ >My first websiteMy first websiteMy first websiteMy first</H3><P
426
+
427
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
428
+
429
+
430
+ >Updated 1h ago by lexoyo</P><P
431
+
432
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
433
+
434
+
435
+ >Created 2023-02-16 by lexoyo</P><div
436
+ id="ixz6c"
437
+ class="button-bar_item skeleton skeleton-button "
438
+
439
+
440
+ >Edit</div></SECTION><SECTION
441
+ id="iwxxo5"
442
+ class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper "
443
+ v-if="loading"
444
+
445
+ ><H3
446
+
447
+ class="button-bar_item button-bar__item--main skeleton-text skeleton "
448
+
449
+
450
+ >My first websiteMy first websiteMy first websiteMy first</H3><P
451
+
452
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
453
+
454
+
455
+ >Updated 1h ago by lexoyo</P><P
456
+
457
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
458
+
459
+
460
+ >Created 2023-02-16 by lexoyo</P><div
461
+ id="i9fx3l"
462
+ class="button-bar_item skeleton skeleton-button "
463
+
464
+
465
+ >Edit</div></SECTION><SECTION
466
+ id="isld3r"
467
+ class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper "
468
+ v-if="loading"
469
+
470
+ ><H3
471
+
472
+ class="button-bar_item button-bar__item--main skeleton-text skeleton "
473
+
474
+
475
+ >My first websiteMy first websiteMy first websiteMy first</H3><P
476
+
477
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
478
+
479
+
480
+ >Updated 1h ago by lexoyo</P><P
481
+
482
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
483
+
484
+
485
+ >Created 2023-02-16 by lexoyo</P><div
486
+ id="i8oes3"
487
+ class="button-bar_item skeleton skeleton-button "
488
+
489
+
490
+ >Edit</div></SECTION><SECTION
491
+ id="iqmx38"
492
+ class="button-bar button-bar--full-width bg-white rounded loading__item skeleton-anim skeleton-wrapper "
493
+ v-if="loading"
494
+
495
+ ><H3
496
+
497
+ class="button-bar_item button-bar__item--main skeleton-text skeleton "
498
+
499
+
500
+ >My first websiteMy first websiteMy first websiteMy first</H3><P
501
+
502
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
503
+
504
+
505
+ >Updated 1h ago by lexoyo</P><P
506
+
507
+ class="button-bar_item button-bar__item--secondary skeleton-text skeleton "
508
+
509
+
510
+ >Created 2023-02-16 by lexoyo</P><div
511
+ id="ie83jl"
512
+ class="button-bar_item skeleton skeleton-button "
513
+
514
+
515
+ >Edit</div></SECTION></div><div
516
+ id="i7ej6j"
517
+ class="box horizontal "
518
+ v-if="error"
519
+
520
+ ><div
521
+ id="iv0eyi"
522
+ class="full-width v-space h-space "
523
+ v-text="error"
524
+
525
+ >Insert your text here</div><div
526
+ id="i4656n"
527
+ class="button rounded button--small button--tertiary "
528
+ @click="error = null"
529
+
530
+ >Dismiss</div></div><div
531
+ id="ilteie"
532
+ class="box horizontal "
533
+ v-if="message"
534
+
535
+ ><div
536
+ id="i2d31v"
537
+ class="full-width v-space h-space "
538
+ v-text="message"
539
+
540
+ >Insert your text here</div><div
541
+ id="i2urco"
542
+ class="button rounded button--small button--tertiary "
543
+ @click="message = null"
544
+
545
+ >Dismiss</div></div></MAIN><FOOTER
546
+ id="ilzpl"
547
+ class="header footer "
548
+
549
+
550
+ ><div
551
+ id="i238z"
552
+ class="section "
553
+
554
+
555
+ ></div></FOOTER></body>
556
+ </html>
557
+