@@ -8,13 +8,22 @@ export class TemplateGenerator {
88 /**
99 * Generate complete HTML page from content blueprint
1010 */
11- static generate ( blueprint : ContentBlueprint , workerName : string , branding ?: import ( './types' ) . WorkerAnalysis [ 'branding' ] , footerLinks ?: import ( './types' ) . WorkerAnalysis [ 'links' ] [ 'footer' ] ) : string {
11+ static generate (
12+ blueprint : ContentBlueprint ,
13+ workerName : string ,
14+ branding ?: { icon : string ; displayName : string } ,
15+ footerLinks ?: Array < { text : string ; href : string } >
16+ ) : string {
17+ const brandIcon = branding ?. icon || '⚡' ;
18+ const brandName = branding ?. displayName || workerName ;
19+
1220 return `<!DOCTYPE html>
1321<html lang="en" class="scroll-smooth">
1422<head>
1523 <meta charset="UTF-8">
1624 <meta name="viewport" content="width=device-width, initial-scale=1.0">
17- <title>${ workerName } - Cloudflare Worker</title>
25+ <title>${ brandName } - Cloudflare Worker</title>
26+ <meta name="description" content="${ blueprint . hero . subheadline } ">
1827 <script src="https://cdn.tailwindcss.com"></script>
1928 <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
2029 <link rel="preconnect" href="https://fonts.googleapis.com">
@@ -78,7 +87,7 @@ export class TemplateGenerator {
7887</head>
7988<body class="bg-white text-slate-900" x-data="{ mobileMenuOpen: false }">
8089
81- ${ this . generateNav ( blueprint , branding ) }
90+ ${ this . generateNav ( blueprint , brandIcon , brandName ) }
8291
8392 ${ this . generateHero ( blueprint . hero ) }
8493
@@ -96,32 +105,33 @@ export class TemplateGenerator {
96105
97106 ${ this . generateCTA ( blueprint . cta ) }
98107
99- ${ this . generateFooter ( workerName , footerLinks ) }
108+ ${ this . generateFooter ( brandName , brandIcon , footerLinks ) }
100109
101110 ${ this . generateScrollScript ( ) }
102111
103112</body>
104113</html>` ;
105114 }
106115
107- private static generateNav ( blueprint : ContentBlueprint ) : string {
116+ private static generateNav ( blueprint : ContentBlueprint , brandIcon : string , brandName : string ) : string {
108117 return `
109118 <!-- Sticky Glass Navigation -->
110119 <nav class="glass-nav fixed top-0 left-0 right-0 z-50">
111120 <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
112121 <div class="flex justify-between items-center h-16">
113122 <div class="flex items-center space-x-2">
114- <div class="text-2xl">${ branding ?. icon || '⚡' } </div>
123+ <div class="text-2xl">${ brandIcon } </div>
115124 <span class="text-xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 bg-clip-text text-transparent">
116- ${ branding ?. displayName || workerName }
125+ ${ brandName }
117126 </span>
118127 </div>
119128
120129 <!-- Desktop Nav -->
121130 <div class="hidden md:flex items-center space-x-8">
122131 <a href="#problem" class="text-slate-600 hover:text-indigo-600 transition">Challenge</a>
123- <a href="#solution" class="text-slate-600 hover:text-indigo-600 transition">Solution </a>
132+ <a href="#solution" class="text-slate-600 hover:text-indigo-600 transition">Architecture </a>
124133 <a href="#features" class="text-slate-600 hover:text-indigo-600 transition">Features</a>
134+ <a href="#use-cases" class="text-slate-600 hover:text-indigo-600 transition">Use Cases</a>
125135 <a href="#roadmap" class="text-slate-600 hover:text-indigo-600 transition">Roadmap</a>
126136 <a href="${ blueprint . hero . primaryCTA . href } "
127137 class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
@@ -142,8 +152,9 @@ export class TemplateGenerator {
142152 x-transition
143153 class="md:hidden pb-4 space-y-2">
144154 <a href="#problem" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Challenge</a>
145- <a href="#solution" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Solution </a>
155+ <a href="#solution" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Architecture </a>
146156 <a href="#features" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Features</a>
157+ <a href="#use-cases" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Use Cases</a>
147158 <a href="#roadmap" class="block px-4 py-2 text-slate-600 hover:bg-slate-50 rounded">Roadmap</a>
148159 </div>
149160 </div>
@@ -312,14 +323,33 @@ export class TemplateGenerator {
312323 }
313324
314325 private static generateMetrics ( metrics : any ) : string {
315- const statsHTML = metrics . stats . map ( ( stat : any ) => `
326+ // Static class mapping for Tailwind JIT safety
327+ const colorClasses = {
328+ emerald : {
329+ bg : 'bg-emerald-100' ,
330+ text : 'text-emerald-600' ,
331+ } ,
332+ indigo : {
333+ bg : 'bg-indigo-100' ,
334+ text : 'text-indigo-600' ,
335+ } ,
336+ amber : {
337+ bg : 'bg-amber-100' ,
338+ text : 'text-amber-600' ,
339+ } ,
340+ } ;
341+
342+ const statsHTML = metrics . stats . map ( ( stat : any ) => {
343+ const classes = colorClasses [ stat . color as keyof typeof colorClasses ] || colorClasses . indigo ;
344+ return `
316345 <div class="fade-in-up text-center">
317- <div class="inline-block px-6 py-3 bg- ${ stat . color } -100 rounded-xl mb-3">
318- <div class="text-4xl md:text-5xl font-black text- ${ stat . color } -600 ">${ stat . value } </div>
346+ <div class="inline-block px-6 py-3 ${ classes . bg } rounded-xl mb-3">
347+ <div class="text-4xl md:text-5xl font-black ${ classes . text } ">${ stat . value } </div>
319348 </div>
320349 <div class="text-lg font-semibold text-slate-700">${ stat . label } </div>
321350 </div>
322- ` ) . join ( '' ) ;
351+ ` ;
352+ } ) . join ( '' ) ;
323353
324354 return `
325355 <!-- Metrics Section -->
@@ -363,37 +393,57 @@ export class TemplateGenerator {
363393 }
364394
365395 private static generateRoadmap ( roadmap : any ) : string {
396+ // Static class mapping for Tailwind JIT safety
397+ const statusColorClasses = {
398+ completed : {
399+ line : 'bg-emerald-200' ,
400+ badge : 'bg-emerald-600' ,
401+ border : 'border-emerald-100' ,
402+ bullet : 'text-emerald-600' ,
403+ status : 'bg-emerald-100 text-emerald-700' ,
404+ } ,
405+ 'in-progress' : {
406+ line : 'bg-indigo-200' ,
407+ badge : 'bg-indigo-600' ,
408+ border : 'border-indigo-100' ,
409+ bullet : 'text-indigo-600' ,
410+ status : 'bg-indigo-100 text-indigo-700' ,
411+ } ,
412+ planned : {
413+ line : 'bg-slate-200' ,
414+ badge : 'bg-slate-600' ,
415+ border : 'border-slate-100' ,
416+ bullet : 'text-slate-600' ,
417+ status : 'bg-slate-100 text-slate-700' ,
418+ } ,
419+ } ;
420+
366421 const milestonesHTML = roadmap . milestones . map ( ( milestone : any , index : number ) => {
367- const statusColors = {
368- completed : 'emerald' ,
369- 'in-progress' : 'indigo' ,
370- planned : 'slate' ,
371- } ;
372- const color = statusColors [ milestone . status ] ;
422+ const classes = statusColorClasses [ milestone . status as keyof typeof statusColorClasses ] || statusColorClasses . planned ;
373423
374424 return `
375425 <div class="fade-in-up relative">
376426 ${ index < roadmap . milestones . length - 1 ? `
377- <div class="hidden md:block absolute top-16 left-1/2 w-full h-0.5 bg- ${ color } -200 "></div>
427+ <div class="hidden md:block absolute top-16 left-1/2 w-full h-0.5 ${ classes . line } "></div>
378428 ` : '' }
379429
380430 <div class="relative z-10 text-center">
381- <div class="inline-block px-6 py-3 bg- ${ color } -600 text-white rounded-full font-bold text-lg mb-4">
431+ <div class="inline-block px-6 py-3 ${ classes . badge } text-white rounded-full font-bold text-lg mb-4">
382432 ${ milestone . version }
383433 </div>
384434 <h3 class="text-2xl font-bold text-slate-900 mb-4">${ milestone . title } </h3>
385- <div class="bg-white p-6 rounded-xl shadow-lg border border- ${ color } -100 ">
435+ <div class="bg-white p-6 rounded-xl shadow-lg border ${ classes . border } ">
386436 <ul class="space-y-2 text-left">
387437 ${ milestone . items . map ( ( item : string ) => `
388438 <li class="flex items-start space-x-2">
389- <span class="text- ${ color } -600 mt-1">•</span>
439+ <span class="${ classes . bullet } mt-1">•</span>
390440 <span class="text-slate-700">${ item } </span>
391441 </li>
392442 ` ) . join ( '' ) }
393443 </ul>
394444 </div>
395445 <div class="mt-4">
396- <span class="px-4 py-2 bg- ${ color } -100 text- ${ color } -700 rounded-full text-sm font-semibold uppercase">
446+ <span class="px-4 py-2 ${ classes . status } rounded-full text-sm font-semibold uppercase">
397447 ${ milestone . status . replace ( '-' , ' ' ) }
398448 </span>
399449 </div>
@@ -450,14 +500,26 @@ export class TemplateGenerator {
450500 </section>` ;
451501 }
452502
453- private static generateFooter ( workerName : string ) : string {
503+ private static generateFooter ( workerName : string , brandIcon : string , footerLinks ?: Array < { text : string ; href : string } > ) : string {
504+ // Default footer links if not provided
505+ const links = footerLinks || [
506+ { text : 'API Documentation' , href : '/doc' } ,
507+ { text : 'OpenAPI Spec' , href : '/openapi.json' } ,
508+ { text : 'OpenAPI YAML' , href : '/openapi.yaml' } ,
509+ ] ;
510+
511+ const linksHTML = links . map ( link => `
512+ <li><a href="${ link . href } " class="hover:text-white transition">${ link . text } </a></li>
513+ ` ) . join ( '' ) ;
514+
454515 return `
455516 <!-- Footer -->
456517 <footer class="bg-slate-900 text-slate-400 py-12">
457518 <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
458519 <div class="grid md:grid-cols-3 gap-8 mb-8">
459520 <div>
460521 <div class="flex items-center space-x-2 mb-4">
522+ <div class="text-2xl">${ brandIcon } </div>
461523 <span class="text-xl font-bold text-white">${ workerName } </span>
462524 </div>
463525 <p class="text-sm">Built on Cloudflare Workers, powered by edge computing.</p>
@@ -466,24 +528,23 @@ export class TemplateGenerator {
466528 <div>
467529 <h3 class="text-white font-semibold mb-4">Documentation</h3>
468530 <ul class="space-y-2 text-sm">
469- ${ footerLinks
470- ? footerLinks . map ( link => `<li><a href="${ link . href } " class="hover:text-white transition">${ link . text } </a></li>` ) . join ( '' )
471- : `<li><a href="/doc" class="hover:text-white transition">API Documentation</a></li>`
472- }
531+ ${ linksHTML }
473532 </ul>
474533 </div>
475534
476535 <div>
477536 <h3 class="text-white font-semibold mb-4">Resources</h3>
478537 <ul class="space-y-2 text-sm">
479538 <li><a href="https://developers.cloudflare.com/workers/" class="hover:text-white transition">Cloudflare Workers Docs</a></li>
480- <li><a href="https://workers.cloudflare.com" class="hover:text-white transition">Workers Platform</a></li>
539+ <li><a href="https://developers.cloudflare.com/durable-objects/" class="hover:text-white transition">Durable Objects Guide</a></li>
540+ <li><a href="https://developers.cloudflare.com/workers-ai/" class="hover:text-white transition">Workers AI Platform</a></li>
481541 </ul>
482542 </div>
483543 </div>
484544
485545 <div class="border-t border-slate-800 pt-8 text-center text-sm">
486- <p>© ${ new Date ( ) . getFullYear ( ) } ${ workerName } . Auto-generated landing page.</p>
546+ <p>© ${ new Date ( ) . getFullYear ( ) } ${ workerName } . Auto-generated cinematic landing page by Landing Page Generator.</p>
547+ <p class="mt-2 text-slate-500">Powered by Cloudflare Workers • Durable Objects • D1 • Workers AI</p>
487548 </div>
488549 </div>
489550 </footer>` ;
0 commit comments