@leadertechie/personal-site-kit 0.1.0-alpha.8 → 0.1.0-alpha.9

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.
Files changed (93) hide show
  1. package/dist/api/content-utils.d.ts +27 -0
  2. package/dist/api/content-utils.d.ts.map +1 -0
  3. package/dist/api/handlers/content-api.d.ts +0 -1
  4. package/dist/api/handlers/content-api.d.ts.map +1 -1
  5. package/dist/api.js +2 -2
  6. package/dist/chunks/{index-CYd_Pe2U.js → index-CnSEOZse.js} +81 -121
  7. package/dist/chunks/{template-D1uGvdWZ.js → template-DWcsZW22.js} +1 -1
  8. package/dist/chunks/{website-api-FLejlWxJ.js → website-api-BEYGOsT3.js} +90 -131
  9. package/dist/index.js +3 -3
  10. package/dist/shared.js +1 -1
  11. package/dist/ui/admin/index.d.ts +8 -0
  12. package/dist/ui/admin/index.d.ts.map +1 -1
  13. package/dist/ui.js +1 -1
  14. package/package.json +4 -4
  15. package/src/api/__tests__/info.test.ts +0 -44
  16. package/src/api/__tests__/utils.test.ts +0 -78
  17. package/src/api/handlers/about-me.ts +0 -109
  18. package/src/api/handlers/auth-handler.ts +0 -204
  19. package/src/api/handlers/auth.ts +0 -157
  20. package/src/api/handlers/content-api.ts +0 -268
  21. package/src/api/handlers/content.ts +0 -139
  22. package/src/api/handlers/home.ts +0 -79
  23. package/src/api/handlers/info.ts +0 -12
  24. package/src/api/handlers/logo.ts +0 -55
  25. package/src/api/handlers/static-details.ts +0 -48
  26. package/src/api/index.ts +0 -9
  27. package/src/api/utils.ts +0 -16
  28. package/src/api/website-api.ts +0 -142
  29. package/src/index.ts +0 -4
  30. package/src/prerender/__tests__/page-content.test.ts +0 -44
  31. package/src/prerender/__tests__/template.test.ts +0 -54
  32. package/src/prerender/data-fetcher.ts +0 -93
  33. package/src/prerender/index.ts +0 -7
  34. package/src/prerender/page-content.ts +0 -266
  35. package/src/prerender/page-generators/about.ts +0 -38
  36. package/src/prerender/page-generators/base.ts +0 -77
  37. package/src/prerender/page-generators/blog-detail.ts +0 -35
  38. package/src/prerender/page-generators/blogs-list.ts +0 -43
  39. package/src/prerender/page-generators/home.ts +0 -54
  40. package/src/prerender/page-generators/index.ts +0 -8
  41. package/src/prerender/page-generators/not-found.ts +0 -36
  42. package/src/prerender/page-generators/stories-list.ts +0 -43
  43. package/src/prerender/page-generators/story-detail.ts +0 -35
  44. package/src/prerender/prerender.ts +0 -25
  45. package/src/prerender/template.ts +0 -65
  46. package/src/prerender/website-prerender.ts +0 -152
  47. package/src/shared/config/api.ts +0 -16
  48. package/src/shared/config/index.ts +0 -43
  49. package/src/shared/config/types.ts +0 -16
  50. package/src/shared/core/__tests__/theme-toggle.test.ts +0 -204
  51. package/src/shared/core/site-store.ts +0 -38
  52. package/src/shared/core/theme-toggle.ts +0 -118
  53. package/src/shared/index.ts +0 -17
  54. package/src/shared/interfaces/ifooter-link.ts +0 -4
  55. package/src/shared/interfaces/iroute.ts +0 -4
  56. package/src/shared/models/theme-variables.css +0 -25
  57. package/src/shared/page-content.ts +0 -210
  58. package/src/shared/router.ts +0 -250
  59. package/src/shared/runtime.ts +0 -11
  60. package/src/shared/template.ts +0 -35
  61. package/src/shared/website-ui.ts +0 -92
  62. package/src/styles/markdown.css +0 -129
  63. package/src/ui/about-me/api.ts +0 -12
  64. package/src/ui/about-me/index.ts +0 -121
  65. package/src/ui/about-me/styles.ts +0 -85
  66. package/src/ui/admin/api.ts +0 -93
  67. package/src/ui/admin/components/AboutMeSection.ts +0 -47
  68. package/src/ui/admin/components/AdminSection.ts +0 -134
  69. package/src/ui/admin/components/BlogsSection.ts +0 -62
  70. package/src/ui/admin/components/HomeSection.ts +0 -47
  71. package/src/ui/admin/components/ImagesSection.ts +0 -54
  72. package/src/ui/admin/components/LoginForm.ts +0 -116
  73. package/src/ui/admin/components/LogoSection.ts +0 -51
  74. package/src/ui/admin/components/ProfileSection.ts +0 -47
  75. package/src/ui/admin/components/StaticSection.ts +0 -67
  76. package/src/ui/admin/components/StoriesSection.ts +0 -62
  77. package/src/ui/admin/components/index.ts +0 -10
  78. package/src/ui/admin/index.ts +0 -413
  79. package/src/ui/admin/styles.ts +0 -270
  80. package/src/ui/admin/types.ts +0 -26
  81. package/src/ui/banner/index.ts +0 -38
  82. package/src/ui/banner/styles.ts +0 -95
  83. package/src/ui/blog-viewer/__tests__/blogviewer.test.ts +0 -7
  84. package/src/ui/blog-viewer/index.ts +0 -127
  85. package/src/ui/blog-viewer/styles.ts +0 -23
  86. package/src/ui/footer/index.ts +0 -37
  87. package/src/ui/footer/styles.ts +0 -50
  88. package/src/ui/index.ts +0 -13
  89. package/src/ui/story-viewer/__tests__/storyviewer.test.ts +0 -7
  90. package/src/ui/story-viewer/index.ts +0 -123
  91. package/src/ui/story-viewer/styles.ts +0 -54
  92. /package/{src/shared → dist}/styles/markdown.css +0 -0
  93. /package/{src → dist}/styles/theme.css +0 -0
@@ -1,47 +0,0 @@
1
- import { html } from 'lit';
2
- import { customElement } from 'lit/decorators.js';
3
- import { AdminSection } from './AdminSection';
4
-
5
- @customElement('admin-profile-section')
6
- export class AdminProfileSection extends AdminSection {
7
- private async handleUpload() {
8
- const input = this.shadowRoot?.querySelector('#profileFile') as HTMLInputElement;
9
- if (input.files?.[0]) {
10
- try {
11
- await this.onUpload('profile.json', input.files[0]);
12
- this.onStatusMessage('Upload successful!');
13
- } catch (e) {
14
- this.onStatusMessage('Upload failed.');
15
- }
16
- }
17
- }
18
-
19
- private async handleDelete() {
20
- if (!confirm('Delete profile.json?')) return;
21
- try {
22
- await this.onDelete('profile.json');
23
- } catch (e) {
24
- this.onStatusMessage('Delete failed.');
25
- }
26
- }
27
-
28
- render() {
29
- const profile = this.getContent('profile.json');
30
- return html`
31
- <div class="section">
32
- <h3>Profile <span class="required-badge">Required</span></h3>
33
- <p class="help-text">This file contains your profile information (name, title, experience).</p>
34
-
35
- ${profile ? html`
36
- <div class="current-file">
37
- <strong>Current:</strong> profile.json (${profile.size} bytes)
38
- <button class="btn-danger" @click=${this.handleDelete}>Delete</button>
39
- </div>
40
- ` : ''}
41
-
42
- <input type="file" id="profileFile" accept=".json" />
43
- <button class="btn-primary" @click=${this.handleUpload}>Upload profile.json</button>
44
- </div>
45
- `;
46
- }
47
- }
@@ -1,67 +0,0 @@
1
- import { html } from 'lit';
2
- import { customElement, state } from 'lit/decorators.js';
3
- import { AdminSection } from './AdminSection';
4
-
5
- @customElement('admin-static-section')
6
- export class AdminStaticSection extends AdminSection {
7
- @state()
8
- accessor localDetails = { ...this.staticDetails };
9
-
10
- private async handleSave() {
11
- const siteTitle = (this.shadowRoot?.querySelector('#siteTitle') as HTMLInputElement)?.value;
12
- const copyright = (this.shadowRoot?.querySelector('#copyright') as HTMLInputElement)?.value;
13
- const linkedin = (this.shadowRoot?.querySelector('#linkedin') as HTMLInputElement)?.value;
14
- const github = (this.shadowRoot?.querySelector('#github') as HTMLInputElement)?.value;
15
- const email = (this.shadowRoot?.querySelector('#email') as HTMLInputElement)?.value;
16
-
17
- const data: Record<string, string> = {};
18
- if (siteTitle) data.siteTitle = siteTitle;
19
- if (copyright) data.copyright = copyright;
20
- if (linkedin) data.linkedin = linkedin;
21
- if (github) data.github = github;
22
- if (email) data.email = email;
23
-
24
- try {
25
- await this.onUpload('staticdetails.json', new File([JSON.stringify(data)], 'staticdetails.json', { type: 'application/json' }));
26
- this.onStatusMessage('Settings saved!');
27
- } catch (e) {
28
- this.onStatusMessage('Failed to save settings.');
29
- }
30
- }
31
-
32
- render() {
33
- return html`
34
- <div class="section">
35
- <h3>Site Settings</h3>
36
- <p class="help-text">Manage your site's static details like title, footer links, etc.</p>
37
-
38
- <div class="mb-1">
39
- <label style="display:block;margin-bottom:4px;font-weight:500">Site Title</label>
40
- <input type="text" id="siteTitle" .value=${this.staticDetails?.siteTitle || ''} />
41
- </div>
42
-
43
- <div class="mb-1">
44
- <label style="display:block;margin-bottom:4px;font-weight:500">Copyright Text</label>
45
- <input type="text" id="copyright" .value=${this.staticDetails?.copyright || ''} />
46
- </div>
47
-
48
- <div class="mb-1">
49
- <label style="display:block;margin-bottom:4px;font-weight:500">LinkedIn URL</label>
50
- <input type="text" id="linkedin" .value=${this.staticDetails?.linkedin || ''} />
51
- </div>
52
-
53
- <div class="mb-1">
54
- <label style="display:block;margin-bottom:4px;font-weight:500">GitHub URL</label>
55
- <input type="text" id="github" .value=${this.staticDetails?.github || ''} />
56
- </div>
57
-
58
- <div class="mb-1">
59
- <label style="display:block;margin-bottom:4px;font-weight:500">Email</label>
60
- <input type="text" id="email" .value=${this.staticDetails?.email || ''} />
61
- </div>
62
-
63
- <button class="btn-primary" @click=${this.handleSave}>Save Settings</button>
64
- </div>
65
- `;
66
- }
67
- }
@@ -1,62 +0,0 @@
1
- import { html } from 'lit';
2
- import { customElement } from 'lit/decorators.js';
3
- import { AdminSection } from './AdminSection';
4
-
5
- @customElement('admin-stories-section')
6
- export class AdminStoriesSection extends AdminSection {
7
- private async handleUpload() {
8
- const metaInput = this.shadowRoot?.querySelector('#storyMetaFile') as HTMLInputElement;
9
- const contentInput = this.shadowRoot?.querySelector('#storyContentFile') as HTMLInputElement;
10
- const slugInput = this.shadowRoot?.querySelector('#storySlug') as HTMLInputElement;
11
-
12
- if (metaInput.files?.[0] && contentInput.files?.[0] && slugInput.value) {
13
- try {
14
- await this.onUpload(`stories/${slugInput.value}.json`, metaInput.files[0]);
15
- await this.onUpload(`stories/${slugInput.value}.md`, contentInput.files[0]);
16
- this.onStatusMessage('Upload successful!');
17
- } catch (e) {
18
- this.onStatusMessage('Upload failed.');
19
- }
20
- }
21
- }
22
-
23
- private async handleDelete(slug: string) {
24
- if (!confirm(`Delete story ${slug}?`)) return;
25
- try {
26
- await this.onDelete(`stories/${slug}.json`);
27
- await this.onDelete(`stories/${slug}.md`);
28
- } catch (e) {
29
- this.onStatusMessage('Delete failed.');
30
- }
31
- }
32
-
33
- render() {
34
- const stories = this.getSectionFiles('stories/').filter(s => s.key.endsWith('.json'));
35
- return html`
36
- <div class="section">
37
- <h3>Stories</h3>
38
- <p class="help-text">Each story needs 2 files: a JSON (metadata) and MD (content) file.</p>
39
-
40
- <h4>Upload New Story</h4>
41
- <input type="file" id="storyMetaFile" accept=".json" />
42
- <input type="file" id="storyContentFile" accept=".md" />
43
- <input type="text" id="storySlug" placeholder="Slug (e.g., my-story)" class="mt-1" />
44
- <button class="btn-primary" @click=${this.handleUpload}>Upload Story (JSON + MD)</button>
45
-
46
- <div class="file-list">
47
- <h4>Current Stories (${stories.length})</h4>
48
- ${stories.map(s => {
49
- const slug = s.key.replace('stories/', '').replace('.json', '');
50
- return html`
51
- <div class="file-item">
52
- <span>${s.key.replace('.json', '')}</span>
53
- <button class="btn-danger" @click=${() => this.handleDelete(slug)}>Delete</button>
54
- </div>
55
- `;
56
- })}
57
- ${stories.length === 0 ? html`<p>No stories yet.</p>` : ''}
58
- </div>
59
- </div>
60
- `;
61
- }
62
- }
@@ -1,10 +0,0 @@
1
- export * from './AdminSection';
2
- export * from './LoginForm';
3
- export * from './HomeSection';
4
- export * from './ProfileSection';
5
- export * from './AboutMeSection';
6
- export * from './BlogsSection';
7
- export * from './StoriesSection';
8
- export * from './ImagesSection';
9
- export * from './LogoSection';
10
- export * from './StaticSection';
@@ -1,413 +0,0 @@
1
- import { LitElement, html, css } from 'lit';
2
- import { customElement, state } from 'lit/decorators.js';
3
-
4
- import { adminStyles } from './styles';
5
- import { AdminApiService } from './api';
6
- import type { ContentItem, StaticDetails } from './types';
7
- import { SiteStore } from '../../shared/core/site-store';
8
- import {
9
- AdminLoginForm,
10
- AdminHomeSection,
11
- AdminProfileSection,
12
- AdminAboutMeSection,
13
- AdminBlogsSection,
14
- AdminStoriesSection,
15
- AdminImagesSection,
16
- AdminLogoSection,
17
- AdminStaticSection
18
- } from './components';
19
-
20
- export {
21
- AdminLoginForm,
22
- AdminHomeSection,
23
- AdminProfileSection,
24
- AdminAboutMeSection,
25
- AdminBlogsSection,
26
- AdminStoriesSection,
27
- AdminImagesSection,
28
- AdminLogoSection,
29
- AdminStaticSection
30
- };
31
-
32
- @customElement('admin-portal')
33
- export class AdminPortal extends LitElement {
34
- static styles = adminStyles;
35
-
36
- @state()
37
- accessor isAuthenticated = false;
38
-
39
- @state()
40
- accessor isSetup = false;
41
-
42
- @state()
43
- accessor isLoading = true;
44
-
45
- @state()
46
- accessor contentList: ContentItem[] = [];
47
-
48
- @state()
49
- accessor statusMessage = '';
50
-
51
- @state()
52
- accessor activeSection = 'profile';
53
-
54
- @state()
55
- accessor staticDetails: StaticDetails = {};
56
-
57
- @state()
58
- accessor loginError = '';
59
-
60
- private apiService: AdminApiService;
61
-
62
- constructor() {
63
- super();
64
- const apiUrl = window.location.origin;
65
- this.apiService = new AdminApiService(apiUrl);
66
- }
67
-
68
- private hasSessionCookie(): boolean {
69
- return document.cookie.includes('session=');
70
- }
71
-
72
- async connectedCallback() {
73
- super.connectedCallback();
74
- await this.checkAuthStatus();
75
- this.requestUpdate();
76
- }
77
-
78
- async checkAuthStatus() {
79
- try {
80
- const status = await this.apiService.checkAuthStatus();
81
- this.isSetup = status.configured;
82
- if (status.configured && this.hasSessionCookie()) {
83
- await this.tryAutoLogin();
84
- }
85
- } catch (e) {
86
- console.error('Auth status check failed:', e);
87
- } finally {
88
- this.isLoading = false;
89
- }
90
- }
91
-
92
- async tryAutoLogin() {
93
- try {
94
- this.contentList = await this.apiService.tryAutoLogin();
95
- this.isAuthenticated = true;
96
- } catch (e) {
97
- console.error('Auto login failed:', e);
98
- }
99
- }
100
-
101
- async handleLogin(e: CustomEvent) {
102
- const { username, password } = e.detail;
103
- this.loginError = '';
104
-
105
- if (!username || !password) {
106
- this.loginError = 'Username and password required';
107
- return;
108
- }
109
-
110
- try {
111
- await this.apiService.login(username, password);
112
- this.isAuthenticated = true;
113
- await this.fetchContent();
114
- } catch (e) {
115
- this.loginError = (e as Error).message;
116
- }
117
- }
118
-
119
- async handleSetup(e: CustomEvent) {
120
- const { username, password, confirmPassword } = e.detail;
121
- this.loginError = '';
122
-
123
- if (!username || !password) {
124
- this.loginError = 'Username and password required';
125
- return;
126
- }
127
-
128
- if (username.length < 3) {
129
- this.loginError = 'Username must be at least 3 characters';
130
- return;
131
- }
132
-
133
- if (password.length < 8) {
134
- this.loginError = 'Password must be at least 8 characters';
135
- return;
136
- }
137
-
138
- if (password !== confirmPassword) {
139
- this.loginError = 'Passwords do not match';
140
- return;
141
- }
142
-
143
- try {
144
- await this.apiService.setup(username, password);
145
- this.isAuthenticated = true;
146
- this.isSetup = true;
147
- await this.fetchContent();
148
- } catch (e) {
149
- this.loginError = (e as Error).message;
150
- }
151
- }
152
-
153
- async handleLogout() {
154
- try {
155
- await this.apiService.logout();
156
- } catch (e) {}
157
- this.isAuthenticated = false;
158
- this.contentList = [];
159
- }
160
-
161
- async fetchContent() {
162
- try {
163
- this.contentList = await this.apiService.fetchContent();
164
- } catch (e) {
165
- this.statusMessage = 'Error fetching content.';
166
- }
167
- }
168
-
169
- async fetchStaticDetails() {
170
- try {
171
- this.staticDetails = await this.apiService.fetchStaticDetails();
172
- } catch (e) {}
173
- }
174
-
175
- async handleUpload(key: string, file: File) {
176
- try {
177
- this.statusMessage = 'Uploading...';
178
- await this.apiService.uploadContent(key, file);
179
- this.statusMessage = 'Upload successful!';
180
- await this.fetchContent();
181
- } catch (e) {
182
- this.statusMessage = 'Error uploading.';
183
- }
184
- }
185
-
186
- async handleClearCache() {
187
- try {
188
- this.statusMessage = 'Clearing cache...';
189
- await this.apiService.clearCache();
190
- this.statusMessage = 'Cache cleared!';
191
- } catch (e) {
192
- this.statusMessage = 'Error clearing cache.';
193
- }
194
- }
195
-
196
- async handleDelete(key: string) {
197
- try {
198
- await this.apiService.deleteContent(key);
199
- await this.fetchContent();
200
- } catch (e) {
201
- this.statusMessage = 'Error deleting.';
202
- }
203
- }
204
-
205
- private handleStatusMessage(message: string) {
206
- this.statusMessage = message;
207
- }
208
-
209
- renderLoginForm() {
210
- return html`
211
- <admin-login-form
212
- .errorMessage=${this.loginError}
213
- .isSetup=${false}
214
- @login-submit=${this.handleSetup}
215
- ></admin-login-form>
216
- `;
217
- }
218
-
219
- renderLogin() {
220
- return html`
221
- <admin-login-form
222
- .errorMessage=${this.loginError}
223
- .isSetup=${true}
224
- @login-submit=${this.handleLogin}
225
- ></admin-login-form>
226
- `;
227
- }
228
-
229
- render() {
230
- if (this.isLoading) {
231
- return html`<div class="container"><div class="loading">Loading...</div></div>`;
232
- }
233
-
234
- if (!this.isSetup) {
235
- return this.renderLoginForm();
236
- }
237
-
238
- if (!this.isAuthenticated) {
239
- return this.renderLogin();
240
- }
241
-
242
- return html`
243
- <div class="container">
244
- <div class="header">
245
- <h1>Content Manager</h1>
246
- <button class="btn-secondary" @click=${() => this.handleLogout()}>Logout</button>
247
- <button class="btn-secondary" @click=${() => this.handleClearCache()}>Clear Cache</button>
248
- </div>
249
-
250
- <div class="nav-tabs">
251
- <button class="nav-tab ${this.activeSection === 'home' ? 'active' : ''}"
252
- @click=${() => this.activeSection = 'home'}>Home</button>
253
- <button class="nav-tab ${this.activeSection === 'profile' ? 'active' : ''}"
254
- @click=${() => this.activeSection = 'profile'}>Profile</button>
255
- <button class="nav-tab ${this.activeSection === 'aboutme' ? 'active' : ''}"
256
- @click=${() => this.activeSection = 'aboutme'}>About Me</button>
257
- <button class="nav-tab ${this.activeSection === 'blogs' ? 'active' : ''}"
258
- @click=${() => this.activeSection = 'blogs'}>Blogs</button>
259
- <button class="nav-tab ${this.activeSection === 'stories' ? 'active' : ''}"
260
- @click=${() => this.activeSection = 'stories'}>Stories</button>
261
- <button class="nav-tab ${this.activeSection === 'images' ? 'active' : ''}"
262
- @click=${() => this.activeSection = 'images'}>Images</button>
263
- <button class="nav-tab ${this.activeSection === 'logo' ? 'active' : ''}"
264
- @click=${() => this.activeSection = 'logo'}>Logo</button>
265
- <button class="nav-tab ${this.activeSection === 'static' ? 'active' : ''}"
266
- @click=${() => { this.activeSection = 'static'; this.fetchStaticDetails(); }}>Site Settings</button>
267
- </div>
268
-
269
- ${this.statusMessage ? html`
270
- <div class="status-message ${this.statusMessage.includes('successful') || this.statusMessage.includes('cleared') ? 'success' : this.statusMessage.includes('failed') || this.statusMessage.includes('Error') ? 'error' : ''}">
271
- ${this.statusMessage}
272
- </div>
273
- ` : ''}
274
-
275
- ${this.activeSection === 'home' ? html`
276
- <admin-home-section
277
- .contentList=${this.contentList}
278
- .onUpload=${this.handleUpload.bind(this)}
279
- .onDelete=${this.handleDelete.bind(this)}
280
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
281
- ></admin-home-section>
282
- ` : ''}
283
-
284
- ${this.activeSection === 'profile' ? html`
285
- <admin-profile-section
286
- .contentList=${this.contentList}
287
- .onUpload=${this.handleUpload.bind(this)}
288
- .onDelete=${this.handleDelete.bind(this)}
289
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
290
- ></admin-profile-section>
291
- ` : ''}
292
-
293
- ${this.activeSection === 'aboutme' ? html`
294
- <admin-about-me-section
295
- .contentList=${this.contentList}
296
- .onUpload=${this.handleUpload.bind(this)}
297
- .onDelete=${this.handleDelete.bind(this)}
298
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
299
- ></admin-about-me-section>
300
- ` : ''}
301
-
302
- ${this.activeSection === 'blogs' ? html`
303
- <admin-blogs-section
304
- .contentList=${this.contentList}
305
- .onUpload=${this.handleUpload.bind(this)}
306
- .onDelete=${this.handleDelete.bind(this)}
307
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
308
- ></admin-blogs-section>
309
- ` : ''}
310
-
311
- ${this.activeSection === 'stories' ? html`
312
- <admin-stories-section
313
- .contentList=${this.contentList}
314
- .onUpload=${this.handleUpload.bind(this)}
315
- .onDelete=${this.handleDelete.bind(this)}
316
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
317
- ></admin-stories-section>
318
- ` : ''}
319
-
320
- ${this.activeSection === 'images' ? html`
321
- <admin-images-section
322
- .contentList=${this.contentList}
323
- .onUpload=${this.handleUpload.bind(this)}
324
- .onDelete=${this.handleDelete.bind(this)}
325
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
326
- ></admin-images-section>
327
- ` : ''}
328
-
329
- ${this.activeSection === 'logo' ? html`
330
- <admin-logo-section
331
- .contentList=${this.contentList}
332
- .onUpload=${this.handleUpload.bind(this)}
333
- .onDelete=${this.handleDelete.bind(this)}
334
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
335
- ></admin-logo-section>
336
- ` : ''}
337
-
338
- ${this.activeSection === 'static' ? html`
339
- <admin-static-section
340
- .contentList=${this.contentList}
341
- .staticDetails=${this.staticDetails}
342
- .onUpload=${this.handleUpload.bind(this)}
343
- .onDelete=${this.handleDelete.bind(this)}
344
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
345
- ></admin-static-section>
346
- ` : ''}
347
- </div>
348
- `;
349
- }
350
-
351
- render() {
352
- if (this.isLoading) {
353
- return html`<div class="container"><div class="loading">Loading...</div></div>`;
354
- }
355
-
356
- if (!this.isSetup) {
357
- return this.renderLoginForm();
358
- }
359
-
360
- if (!this.isAuthenticated) {
361
- return this.renderLogin();
362
- }
363
-
364
- return html`
365
- <div class="container">
366
- <div class="header">
367
- <h1>Content Manager</h1>
368
- <button class="btn-secondary" @click=${() => this.handleLogout()}>Logout</button>
369
- <button class="btn-secondary" @click=${() => this.handleClearCache()}>Clear Cache</button>
370
- </div>
371
-
372
- <div class="nav-tabs">
373
- <button class="nav-tab ${this.activeSection === 'home' ? 'active' : ''}"
374
- @click=${() => this.activeSection = 'home'}>Home</button>
375
- <button class="nav-tab ${this.activeSection === 'profile' ? 'active' : ''}"
376
- @click=${() => this.activeSection = 'profile'}>Profile</button>
377
- <button class="nav-tab ${this.activeSection === 'aboutme' ? 'active' : ''}"
378
- @click=${() => this.activeSection = 'aboutme'}>About Me</button>
379
- <button class="nav-tab ${this.activeSection === 'blogs' ? 'active' : ''}"
380
- @click=${() => this.activeSection = 'blogs'}>Blogs</button>
381
- <button class="nav-tab ${this.activeSection === 'stories' ? 'active' : ''}"
382
- @click=${() => this.activeSection = 'stories'}>Stories</button>
383
- <button class="nav-tab ${this.activeSection === 'images' ? 'active' : ''}"
384
- @click=${() => this.activeSection = 'images'}>Images</button>
385
- <button class="nav-tab ${this.activeSection === 'logo' ? 'active' : ''}"
386
- @click=${() => this.activeSection = 'logo'}>Logo</button>
387
- <button class="nav-tab ${this.activeSection === 'static' ? 'active' : ''}"
388
- @click=${() => {
389
- this.activeSection = 'static';
390
- this.fetchStaticDetails();
391
- }}>Site Settings</button>
392
- </div>
393
-
394
- ${this.statusMessage ? html`
395
- <div class="status-message ${this.statusMessage.includes('successful') || this.statusMessage.includes('cleared') ? 'success' : this.statusMessage.includes('failed') || this.statusMessage.includes('Error') ? 'error' : ''}">
396
- ${this.statusMessage}
397
- </div>
398
- ` : ''}
399
-
400
- ${this.activeSection === 'home' ? this.renderHomeSection() : ''}
401
- ${this.activeSection === 'profile' ? this.renderProfileSection() : ''}
402
- ${this.activeSection === 'aboutme' ? this.renderAboutMeSection() : ''}
403
- ${this.activeSection === 'blogs' ? this.renderBlogsSection() : ''}
404
- ${this.activeSection === 'stories' ? this.renderStoriesSection() : ''}
405
- ${this.activeSection === 'images' ? this.renderImagesSection() : ''}
406
- ${this.activeSection === 'logo' ? this.renderLogoSection() : ''}
407
- ${this.activeSection === 'static' ? this.renderStaticSection() : ''}
408
- </div>
409
- `;
410
- }
411
- }
412
-
413
- export const adminLoaded = true;