@leadertechie/personal-site-kit 0.1.0-alpha.7 → 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 (129) 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/about-me.d.ts.map +1 -1
  4. package/dist/api/handlers/content-api.d.ts +0 -1
  5. package/dist/api/handlers/content-api.d.ts.map +1 -1
  6. package/dist/api/website-api.d.ts.map +1 -1
  7. package/dist/api.js +2 -2
  8. package/dist/chunks/index-CGvOrVf8.js +213 -0
  9. package/dist/chunks/{index-Bq8WDk9L.js → index-CnSEOZse.js} +1285 -477
  10. package/dist/chunks/{template-Boh_MKY5.js → template-DWcsZW22.js} +8 -7
  11. package/dist/chunks/{website-api-XoeLwo_N.js → website-api-BEYGOsT3.js} +137 -156
  12. package/dist/index.js +19 -9
  13. package/dist/prerender/data-fetcher.d.ts +19 -0
  14. package/dist/prerender/data-fetcher.d.ts.map +1 -0
  15. package/dist/prerender/page-content.d.ts.map +1 -1
  16. package/dist/prerender/page-generators/about.d.ts +16 -0
  17. package/dist/prerender/page-generators/about.d.ts.map +1 -0
  18. package/dist/prerender/page-generators/base.d.ts +26 -0
  19. package/dist/prerender/page-generators/base.d.ts.map +1 -0
  20. package/dist/prerender/page-generators/blog-detail.d.ts +15 -0
  21. package/dist/prerender/page-generators/blog-detail.d.ts.map +1 -0
  22. package/dist/prerender/page-generators/blogs-list.d.ts +17 -0
  23. package/dist/prerender/page-generators/blogs-list.d.ts.map +1 -0
  24. package/dist/prerender/page-generators/home.d.ts +19 -0
  25. package/dist/prerender/page-generators/home.d.ts.map +1 -0
  26. package/dist/prerender/page-generators/index.d.ts +9 -0
  27. package/dist/prerender/page-generators/index.d.ts.map +1 -0
  28. package/dist/prerender/page-generators/not-found.d.ts +14 -0
  29. package/dist/prerender/page-generators/not-found.d.ts.map +1 -0
  30. package/dist/prerender/page-generators/stories-list.d.ts +17 -0
  31. package/dist/prerender/page-generators/stories-list.d.ts.map +1 -0
  32. package/dist/prerender/page-generators/story-detail.d.ts +15 -0
  33. package/dist/prerender/page-generators/story-detail.d.ts.map +1 -0
  34. package/dist/prerender.js +109 -102
  35. package/dist/shared.js +1 -1
  36. package/dist/ui/about-me/index.d.ts +2 -10
  37. package/dist/ui/about-me/index.d.ts.map +1 -1
  38. package/dist/ui/admin/api.d.ts +16 -0
  39. package/dist/ui/admin/api.d.ts.map +1 -0
  40. package/dist/ui/admin/components/AboutMeSection.d.ts +7 -0
  41. package/dist/ui/admin/components/AboutMeSection.d.ts.map +1 -0
  42. package/dist/ui/admin/components/AdminSection.d.ts +13 -0
  43. package/dist/ui/admin/components/AdminSection.d.ts.map +1 -0
  44. package/dist/ui/admin/components/BlogsSection.d.ts +7 -0
  45. package/dist/ui/admin/components/BlogsSection.d.ts.map +1 -0
  46. package/dist/ui/admin/components/HomeSection.d.ts +7 -0
  47. package/dist/ui/admin/components/HomeSection.d.ts.map +1 -0
  48. package/dist/ui/admin/components/ImagesSection.d.ts +7 -0
  49. package/dist/ui/admin/components/ImagesSection.d.ts.map +1 -0
  50. package/dist/ui/admin/components/LoginForm.d.ts +9 -0
  51. package/dist/ui/admin/components/LoginForm.d.ts.map +1 -0
  52. package/dist/ui/admin/components/LogoSection.d.ts +7 -0
  53. package/dist/ui/admin/components/LogoSection.d.ts.map +1 -0
  54. package/dist/ui/admin/components/ProfileSection.d.ts +7 -0
  55. package/dist/ui/admin/components/ProfileSection.d.ts.map +1 -0
  56. package/dist/ui/admin/components/StaticSection.d.ts +13 -0
  57. package/dist/ui/admin/components/StaticSection.d.ts.map +1 -0
  58. package/dist/ui/admin/components/StoriesSection.d.ts +7 -0
  59. package/dist/ui/admin/components/StoriesSection.d.ts.map +1 -0
  60. package/dist/ui/admin/components/index.d.ts +11 -0
  61. package/dist/ui/admin/components/index.d.ts.map +1 -0
  62. package/dist/ui/admin/index.d.ts +18 -26
  63. package/dist/ui/admin/index.d.ts.map +1 -1
  64. package/dist/ui/admin/types.d.ts +24 -0
  65. package/dist/ui/admin/types.d.ts.map +1 -0
  66. package/dist/ui/blog-viewer/index.d.ts.map +1 -1
  67. package/dist/ui/index.d.ts.map +1 -1
  68. package/dist/ui/story-viewer/index.d.ts.map +1 -1
  69. package/dist/ui.js +14 -4
  70. package/package.json +4 -4
  71. package/dist/ui/about-me/renderer.d.ts +0 -6
  72. package/dist/ui/about-me/renderer.d.ts.map +0 -1
  73. package/src/api/__tests__/info.test.ts +0 -44
  74. package/src/api/__tests__/utils.test.ts +0 -78
  75. package/src/api/handlers/about-me.ts +0 -99
  76. package/src/api/handlers/auth-handler.ts +0 -194
  77. package/src/api/handlers/auth.ts +0 -157
  78. package/src/api/handlers/content-api.ts +0 -268
  79. package/src/api/handlers/content.ts +0 -139
  80. package/src/api/handlers/home.ts +0 -79
  81. package/src/api/handlers/info.ts +0 -12
  82. package/src/api/handlers/logo.ts +0 -55
  83. package/src/api/handlers/static-details.ts +0 -48
  84. package/src/api/index.ts +0 -9
  85. package/src/api/utils.ts +0 -16
  86. package/src/api/website-api.ts +0 -138
  87. package/src/index.ts +0 -4
  88. package/src/prerender/__tests__/page-content.test.ts +0 -54
  89. package/src/prerender/__tests__/template.test.ts +0 -54
  90. package/src/prerender/index.ts +0 -7
  91. package/src/prerender/page-content.ts +0 -263
  92. package/src/prerender/prerender.ts +0 -25
  93. package/src/prerender/template.ts +0 -65
  94. package/src/prerender/website-prerender.ts +0 -152
  95. package/src/shared/config/api.ts +0 -16
  96. package/src/shared/config/index.ts +0 -43
  97. package/src/shared/config/types.ts +0 -16
  98. package/src/shared/core/__tests__/theme-toggle.test.ts +0 -204
  99. package/src/shared/core/site-store.ts +0 -38
  100. package/src/shared/core/theme-toggle.ts +0 -118
  101. package/src/shared/index.ts +0 -17
  102. package/src/shared/interfaces/ifooter-link.ts +0 -4
  103. package/src/shared/interfaces/iroute.ts +0 -4
  104. package/src/shared/models/theme-variables.css +0 -25
  105. package/src/shared/page-content.ts +0 -210
  106. package/src/shared/router.ts +0 -250
  107. package/src/shared/runtime.ts +0 -11
  108. package/src/shared/template.ts +0 -35
  109. package/src/shared/website-ui.ts +0 -92
  110. package/src/styles/markdown.css +0 -129
  111. package/src/ui/about-me/api.ts +0 -12
  112. package/src/ui/about-me/index.ts +0 -164
  113. package/src/ui/about-me/renderer.ts +0 -23
  114. package/src/ui/about-me/styles.ts +0 -85
  115. package/src/ui/admin/index.ts +0 -655
  116. package/src/ui/admin/styles.ts +0 -270
  117. package/src/ui/banner/index.ts +0 -38
  118. package/src/ui/banner/styles.ts +0 -95
  119. package/src/ui/blog-viewer/__tests__/blogviewer.test.ts +0 -7
  120. package/src/ui/blog-viewer/index.ts +0 -124
  121. package/src/ui/blog-viewer/styles.ts +0 -23
  122. package/src/ui/footer/index.ts +0 -37
  123. package/src/ui/footer/styles.ts +0 -50
  124. package/src/ui/index.ts +0 -6
  125. package/src/ui/story-viewer/__tests__/storyviewer.test.ts +0 -7
  126. package/src/ui/story-viewer/index.ts +0 -120
  127. package/src/ui/story-viewer/styles.ts +0 -54
  128. /package/{src/shared → dist}/styles/markdown.css +0 -0
  129. /package/{src → dist}/styles/theme.css +0 -0
@@ -0,0 +1,27 @@
1
+ export interface ContentMetadata {
2
+ slug: string;
3
+ title: string;
4
+ description: string;
5
+ summary?: string;
6
+ date: string;
7
+ imageUrl?: string;
8
+ tags?: string[];
9
+ author?: string;
10
+ }
11
+ export interface BlogPost extends ContentMetadata {
12
+ content: string;
13
+ }
14
+ export interface StoryPost extends ContentMetadata {
15
+ content: string;
16
+ }
17
+ export declare function getCachedOrFetch<T>(key: string, fetchFn: () => Promise<T>): Promise<T>;
18
+ export declare function clearContentCache(prefix?: string): void;
19
+ export declare function parseFrontmatter(content: string): {
20
+ metadata: ContentMetadata;
21
+ content: string;
22
+ };
23
+ export declare function checkContentBucket(env: any): Response | null;
24
+ export declare function fetchContentItem(bucket: any, type: 'blogs' | 'stories', slug: string): Promise<BlogPost | StoryPost>;
25
+ export declare function fetchContentList(bucket: any, type: 'blogs' | 'stories', latest?: number): Promise<ContentMetadata[]>;
26
+ export declare function searchContent(bucket: any, query: string): Promise<(BlogPost | StoryPost)[]>;
27
+ //# sourceMappingURL=content-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-utils.d.ts","sourceRoot":"","sources":["../../src/api/content-utils.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAS,SAAQ,eAAe;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAStF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAUvD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA6BhG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,GAAG,IAAI,CAK5D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAqB1H;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAiB1H;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CA2BjG"}
@@ -1 +1 @@
1
- {"version":3,"file":"about-me.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/about-me.ts"],"names":[],"mappings":"AA4CA,wBAAgB,iBAAiB,SAEhC;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkDhE"}
1
+ {"version":3,"file":"about-me.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/about-me.ts"],"names":[],"mappings":"AA4CA,wBAAgB,iBAAiB,SAEhC;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4DhE"}
@@ -1,5 +1,4 @@
1
1
  export declare function handleBlogs(env?: any, slug?: string, latest?: number): Promise<Response>;
2
2
  export declare function handleStories(env?: any, slug?: string, latest?: number): Promise<Response>;
3
3
  export declare function handleSearch(env?: any, query?: string): Promise<Response>;
4
- export declare function clearContentCache(): void;
5
4
  //# sourceMappingURL=content-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-api.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content-api.ts"],"names":[],"mappings":"AA8EA,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgE9F;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8DhG;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuD/E;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
1
+ {"version":3,"file":"content-api.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content-api.ts"],"names":[],"mappings":"AAcA,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmB9F;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmBhG;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkB/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3E,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiC;IAEhD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IAIzD,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,UAAU;IAgBL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAmFlE"}
1
+ {"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3E,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiC;IAEhD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IAIzD,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,UAAU;IAgBL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAuFlE"}
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { W as WebsiteAPI } from "./chunks/website-api-XoeLwo_N.js";
2
- import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-XoeLwo_N.js";
1
+ import { W as WebsiteAPI } from "./chunks/website-api-BEYGOsT3.js";
2
+ import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-BEYGOsT3.js";
3
3
  const defaultAPI = new WebsiteAPI();
4
4
  export {
5
5
  A as AUTH_KV,
@@ -0,0 +1,213 @@
1
+ class BasePageGenerator {
2
+ generateBanner(routes, siteTitle, logo) {
3
+ const navLinks = routes.map((r) => `<a href="${r.link}" class="nav-link" data-route="${r.link === "/" ? "home" : r.text.toLowerCase()}">${r.text}</a>`).join("");
4
+ return `
5
+ <my-banner header="${siteTitle}" logo="${logo}">
6
+ <theme-toggle slot="theme-switcher"></theme-toggle>
7
+ <nav slot="nav-links">
8
+ ${navLinks}
9
+ </nav>
10
+ </my-banner>`;
11
+ }
12
+ generateFooter(footerLinks, copyright) {
13
+ return `
14
+ <my-footer
15
+ copyright="${copyright}"
16
+ footerlinks='${JSON.stringify(footerLinks)}'>
17
+ </my-footer>`;
18
+ }
19
+ generateMeta(title, description, canonicalUrl) {
20
+ }
21
+ wrapContent(banner, mainContent, footer) {
22
+ return `${banner}${mainContent}${footer}`;
23
+ }
24
+ generatePage(pathname, routes, footerLinks, staticDetails, apiUrl, baseUrl, mainContent, title, description) {
25
+ const logo = "/api/logo";
26
+ const banner = this.generateBanner(routes, staticDetails.siteTitle || "My Personal Website", logo);
27
+ const footer = this.generateFooter(footerLinks, staticDetails.copyright || "2026 My Personal Website");
28
+ const canonicalUrl = new URL(pathname, baseUrl).toString();
29
+ const content = this.wrapContent(banner, mainContent, footer);
30
+ return {
31
+ title,
32
+ description,
33
+ canonicalUrl,
34
+ content
35
+ };
36
+ }
37
+ }
38
+ class HomePageGenerator extends BasePageGenerator {
39
+ generate(data) {
40
+ const { profile, homeContent, latestBlogs, latestStories, staticDetails, ...baseData } = data;
41
+ const name = profile?.name || "User";
42
+ const title = profile?.title || "Professional";
43
+ const homeHtml = homeContent || `<h1>Welcome to ${name}</h1><p>Upload home.md to customize this page.</p>`;
44
+ const blogGists = latestBlogs.map((b) => `<div class="gist-card"><a href="/blogs/${b.slug}"><h4>${b.title}</h4></a><p>${b.summary}</p><small>${b.date}</small></div>`).join("");
45
+ const storyGists = latestStories.map((s) => `<div class="gist-card"><a href="/stories/${s.slug}"><h4>${s.title}</h4></a><p>${s.summary}</p><small>${s.date}</small></div>`).join("");
46
+ const mainContent = `
47
+ <main class="container container-wide column-layout">
48
+ <div class="main-column">
49
+ ${homeHtml}
50
+ </div>
51
+ <div class="sidebar-column">
52
+ <h3>Recent Blogs</h3>
53
+ ${blogGists || "<p>No blogs yet.</p>"}
54
+ <h3 class="mt-2">Recent Stories</h3>
55
+ ${storyGists || "<p>No stories yet.</p>"}
56
+ </div>
57
+ </main>`;
58
+ return this.generatePage(
59
+ baseData.pathname,
60
+ baseData.routes,
61
+ baseData.footerLinks,
62
+ staticDetails,
63
+ baseData.apiUrl,
64
+ baseData.baseUrl,
65
+ mainContent,
66
+ `${name} – ${title}`,
67
+ `Welcome to ${name}'s personal website. Professional portfolio and content.`
68
+ );
69
+ }
70
+ }
71
+ class AboutPageGenerator extends BasePageGenerator {
72
+ generate(data) {
73
+ const { profile, staticDetails, ...baseData } = data;
74
+ const name = profile?.name || "User";
75
+ const mainContent = `
76
+ <main class="container container-narrow">
77
+ <my-aboutme base-url="${baseData.apiUrl}"></my-aboutme>
78
+ </main>`;
79
+ return this.generatePage(
80
+ baseData.pathname,
81
+ baseData.routes,
82
+ baseData.footerLinks,
83
+ staticDetails,
84
+ baseData.apiUrl,
85
+ baseData.baseUrl,
86
+ mainContent,
87
+ `About - ${name}`,
88
+ `Learn more about ${name}'s experience and skills.`
89
+ );
90
+ }
91
+ }
92
+ class BlogsListPageGenerator extends BasePageGenerator {
93
+ generate(data) {
94
+ const { latestBlogs, name, staticDetails, ...baseData } = data;
95
+ const blogGists = latestBlogs.map((b) => `<div class="gist-card"><a href="/blogs/${b.slug}"><h4>${b.title}</h4></a><p>${b.summary}</p><small>${b.date}</small></div>`).join("");
96
+ const mainContent = `
97
+ <main class="container container-wide">
98
+ <h1>Blogs</h1>
99
+ <input type="text" placeholder="Search blogs..." class="search-input" />
100
+ <div class="blog-list">
101
+ ${blogGists || "<p>No blogs yet.</p>"}
102
+ </div>
103
+ </main>`;
104
+ return this.generatePage(
105
+ baseData.pathname,
106
+ baseData.routes,
107
+ baseData.footerLinks,
108
+ staticDetails,
109
+ baseData.apiUrl,
110
+ baseData.baseUrl,
111
+ mainContent,
112
+ `Blogs – ${name}`,
113
+ "Read the latest blog posts."
114
+ );
115
+ }
116
+ }
117
+ class StoriesListPageGenerator extends BasePageGenerator {
118
+ generate(data) {
119
+ const { latestStories, name, staticDetails, ...baseData } = data;
120
+ const storyGists = latestStories.map((s) => `<div class="gist-card"><a href="/stories/${s.slug}"><h4>${s.title}</h4></a><p>${s.summary}</p><small>${s.date}</small></div>`).join("");
121
+ const mainContent = `
122
+ <main class="container container-wide">
123
+ <h1>Stories</h1>
124
+ <input type="text" placeholder="Search stories..." class="search-input" />
125
+ <div class="story-list">
126
+ ${storyGists || "<p>No stories yet.</p>"}
127
+ </div>
128
+ </main>`;
129
+ return this.generatePage(
130
+ baseData.pathname,
131
+ baseData.routes,
132
+ baseData.footerLinks,
133
+ staticDetails,
134
+ baseData.apiUrl,
135
+ baseData.baseUrl,
136
+ mainContent,
137
+ `Stories – ${name}`,
138
+ "Read the latest stories."
139
+ );
140
+ }
141
+ }
142
+ class BlogDetailPageGenerator extends BasePageGenerator {
143
+ generate(data) {
144
+ const { slug, staticDetails, ...baseData } = data;
145
+ const mainContent = `
146
+ <main class="container container-narrow">
147
+ <my-blog-viewer slug="${slug}"></my-blog-viewer>
148
+ </main>`;
149
+ return this.generatePage(
150
+ baseData.pathname,
151
+ baseData.routes,
152
+ baseData.footerLinks,
153
+ staticDetails,
154
+ baseData.apiUrl,
155
+ baseData.baseUrl,
156
+ mainContent,
157
+ `Blog: ${slug}`,
158
+ "Blog post"
159
+ );
160
+ }
161
+ }
162
+ class StoryDetailPageGenerator extends BasePageGenerator {
163
+ generate(data) {
164
+ const { slug, staticDetails, ...baseData } = data;
165
+ const mainContent = `
166
+ <main class="container container-narrow">
167
+ <my-story-viewer slug="${slug}"></my-story-viewer>
168
+ </main>`;
169
+ return this.generatePage(
170
+ baseData.pathname,
171
+ baseData.routes,
172
+ baseData.footerLinks,
173
+ staticDetails,
174
+ baseData.apiUrl,
175
+ baseData.baseUrl,
176
+ mainContent,
177
+ `Story: ${slug}`,
178
+ "Story post"
179
+ );
180
+ }
181
+ }
182
+ class NotFoundPageGenerator extends BasePageGenerator {
183
+ generate(data) {
184
+ const { staticDetails, ...baseData } = data;
185
+ const mainContent = `
186
+ <main class="container container-narrow text-center">
187
+ <h1>Page Not Found</h1>
188
+ <p>The page you're looking for doesn't exist.</p>
189
+ <p><a href="/">Return to home</a></p>
190
+ </main>`;
191
+ return this.generatePage(
192
+ baseData.pathname,
193
+ baseData.routes,
194
+ baseData.footerLinks,
195
+ staticDetails,
196
+ baseData.apiUrl,
197
+ baseData.baseUrl,
198
+ mainContent,
199
+ "404 Not Found",
200
+ "The page you requested could not be found."
201
+ );
202
+ }
203
+ }
204
+ export {
205
+ AboutPageGenerator,
206
+ BasePageGenerator,
207
+ BlogDetailPageGenerator,
208
+ BlogsListPageGenerator,
209
+ HomePageGenerator,
210
+ NotFoundPageGenerator,
211
+ StoriesListPageGenerator,
212
+ StoryDetailPageGenerator
213
+ };