import type { InterfaceType, DesignStyle, AnalysisResult } from '../utils/types.js';
import { INTERFACE_TEMPLATES } from '../resources/templates.js';
const INTERFACE_KEYWORDS: Record<InterfaceType, string[]> = {
'website-landing': ['landing', 'conversion', 'lead', 'signup', 'waitlist', 'launch', 'coming soon', 'one page', 'single page'],
'website-saas': ['saas', 'software', 'platform', 'subscription', 'b2b', 'startup', 'tool', 'service', 'pricing'],
'website-portfolio': ['portfolio', 'showcase', 'creative', 'agency', 'freelance', 'personal', 'work samples', 'projects'],
'website-ecommerce': ['shop', 'store', 'ecommerce', 'e-commerce', 'products', 'cart', 'checkout', 'buy', 'sell', 'marketplace'],
'dashboard': ['dashboard', 'analytics', 'metrics', 'data', 'charts', 'reports', 'monitoring', 'admin', 'statistics'],
'mobile-app': ['mobile', 'app', 'ios', 'android', 'native', 'phone', 'smartphone', 'tablet'],
'desktop-app': ['desktop', 'windows', 'mac', 'linux', 'electron', 'native app', 'software application'],
'cli-terminal': ['cli', 'terminal', 'command line', 'console', 'shell', 'command-line', 'text interface'],
'presentation': ['presentation', 'slides', 'deck', 'powerpoint', 'keynote', 'pitch', 'talk', 'slideshow'],
'admin-panel': ['admin', 'cms', 'backend', 'management', 'control panel', 'backoffice'],
'social-platform': ['social', 'community', 'network', 'feed', 'posts', 'messaging', 'chat', 'forum'],
'custom': []
};
const STYLE_KEYWORDS: Record<DesignStyle, string[]> = {
'minimalist': ['minimal', 'clean', 'simple', 'whitespace', 'less is more', 'elegant', 'understated'],
'bold-experimental': ['bold', 'experimental', 'creative', 'unique', 'innovative', 'avant-garde', 'cutting edge', 'unconventional'],
'corporate-professional': ['corporate', 'professional', 'business', 'enterprise', 'formal', 'trustworthy', 'serious'],
'playful-creative': ['playful', 'fun', 'colorful', 'vibrant', 'energetic', 'youthful', 'friendly', 'whimsical'],
'luxury-elegant': ['luxury', 'premium', 'elegant', 'sophisticated', 'high-end', 'exclusive', 'refined'],
'tech-futuristic': ['tech', 'futuristic', 'modern', 'digital', 'cyber', 'neon', 'sci-fi', 'advanced'],
'organic-natural': ['organic', 'natural', 'earthy', 'sustainable', 'eco', 'green', 'wellness', 'holistic'],
'brutalist': ['brutalist', 'raw', 'industrial', 'edgy', 'stark', 'unconventional', 'anti-design'],
'retro-vintage': ['retro', 'vintage', 'nostalgic', 'classic', '80s', '90s', 'throwback', 'old school'],
'glassmorphic': ['glass', 'frosted', 'transparent', 'blur', 'translucent', 'glassmorphism'],
'neumorphic': ['neumorphic', 'soft ui', 'soft shadows', '3d buttons', 'extruded'],
'custom': []
};
function detectInterfaceType(prompt: string): InterfaceType {
const lowerPrompt = prompt.toLowerCase();
let bestMatch: InterfaceType = 'custom';
let highestScore = 0;
for (const [type, keywords] of Object.entries(INTERFACE_KEYWORDS)) {
const score = keywords.filter(kw => lowerPrompt.includes(kw)).length;
if (score > highestScore) {
highestScore = score;
bestMatch = type as InterfaceType;
}
}
return bestMatch;
}
function detectStyles(prompt: string): DesignStyle[] {
const lowerPrompt = prompt.toLowerCase();
const detectedStyles: DesignStyle[] = [];
for (const [style, keywords] of Object.entries(STYLE_KEYWORDS)) {
if (keywords.some(kw => lowerPrompt.includes(kw))) {
detectedStyles.push(style as DesignStyle);
}
}
return detectedStyles.length > 0 ? detectedStyles : ['minimalist', 'bold-experimental'];
}
function extractKeyComponents(prompt: string, interfaceType: InterfaceType): string[] {
const template = INTERFACE_TEMPLATES[interfaceType];
const baseComponents = [...template.keyComponents];
const additionalComponents: string[] = [];
const componentPatterns = [
{ pattern: /hero/i, component: 'Hero section' },
{ pattern: /nav(igation)?/i, component: 'Navigation system' },
{ pattern: /form/i, component: 'Form components' },
{ pattern: /card/i, component: 'Card layouts' },
{ pattern: /modal/i, component: 'Modal dialogs' },
{ pattern: /table/i, component: 'Data tables' },
{ pattern: /chart|graph/i, component: 'Data visualizations' },
{ pattern: /search/i, component: 'Search functionality' },
{ pattern: /filter/i, component: 'Filter controls' },
{ pattern: /notification/i, component: 'Notification system' },
{ pattern: /sidebar/i, component: 'Sidebar navigation' },
{ pattern: /footer/i, component: 'Footer section' },
{ pattern: /pricing/i, component: 'Pricing components' },
{ pattern: /testimonial/i, component: 'Testimonial section' },
{ pattern: /gallery/i, component: 'Image gallery' },
{ pattern: /carousel|slider/i, component: 'Carousel/Slider' },
{ pattern: /timeline/i, component: 'Timeline display' },
{ pattern: /faq/i, component: 'FAQ accordion' },
{ pattern: /contact/i, component: 'Contact form' },
{ pattern: /auth|login|signup/i, component: 'Authentication flows' }
];
for (const { pattern, component } of componentPatterns) {
if (pattern.test(prompt) && !baseComponents.includes(component)) {
additionalComponents.push(component);
}
}
return [...new Set([...baseComponents, ...additionalComponents])];
}
function inferUserPersonas(prompt: string, interfaceType: InterfaceType): string[] {
const personas: string[] = [];
const lowerPrompt = prompt.toLowerCase();
const personaPatterns = [
{ pattern: /developer|engineer|technical/i, persona: 'Technical professionals' },
{ pattern: /business|enterprise|corporate/i, persona: 'Business decision-makers' },
{ pattern: /creative|designer|artist/i, persona: 'Creative professionals' },
{ pattern: /consumer|customer|shopper/i, persona: 'End consumers' },
{ pattern: /student|learn|education/i, persona: 'Students and learners' },
{ pattern: /admin|manager|operator/i, persona: 'System administrators' },
{ pattern: /startup|founder|entrepreneur/i, persona: 'Startup founders' },
{ pattern: /mobile|on.the.go/i, persona: 'Mobile-first users' },
{ pattern: /professional|expert/i, persona: 'Industry professionals' }
];
for (const { pattern, persona } of personaPatterns) {
if (pattern.test(lowerPrompt)) {
personas.push(persona);
}
}
if (personas.length === 0) {
const defaultPersonas: Record<InterfaceType, string[]> = {
'website-landing': ['Potential customers', 'First-time visitors'],
'website-saas': ['Business users', 'Decision makers', 'End users'],
'website-portfolio': ['Potential clients', 'Recruiters', 'Collaborators'],
'website-ecommerce': ['Online shoppers', 'Price-conscious buyers'],
'dashboard': ['Data analysts', 'Managers', 'Power users'],
'mobile-app': ['Mobile users', 'On-the-go professionals'],
'desktop-app': ['Power users', 'Professional users'],
'cli-terminal': ['Developers', 'System administrators'],
'presentation': ['Conference attendees', 'Stakeholders'],
'admin-panel': ['Administrators', 'Content managers'],
'social-platform': ['Community members', 'Content creators'],
'custom': ['General users']
};
return defaultPersonas[interfaceType];
}
return personas;
}
function suggestDesignPatterns(interfaceType: InterfaceType, styles: DesignStyle[]): string[] {
const patterns: string[] = [];
const typePatterns: Record<InterfaceType, string[]> = {
'website-landing': ['Hero with social proof', 'Feature grid', 'Testimonial carousel', 'Sticky CTA'],
'website-saas': ['Feature comparison', 'Pricing tiers', 'Integration showcase', 'Use case tabs'],
'website-portfolio': ['Project masonry', 'Case study template', 'Skills visualization', 'Contact CTA'],
'website-ecommerce': ['Product quick view', 'Filter sidebar', 'Cart drawer', 'Checkout stepper'],
'dashboard': ['Metric cards', 'Data tables', 'Chart widgets', 'Activity feed'],
'mobile-app': ['Tab navigation', 'Pull to refresh', 'Floating action button', 'Bottom sheets'],
'desktop-app': ['Multi-panel layout', 'Command palette', 'Context menus', 'Keyboard shortcuts'],
'cli-terminal': ['Progress indicators', 'Interactive prompts', 'Colored output', 'Help system'],
'presentation': ['Title patterns', 'Two-column layouts', 'Full-bleed images', 'Quote slides'],
'admin-panel': ['CRUD tables', 'Form wizards', 'Bulk actions', 'Audit logs'],
'social-platform': ['Infinite feed', 'Story carousels', 'Comment threads', 'Reaction system'],
'custom': ['Modular components', 'Flexible layouts']
};
patterns.push(...typePatterns[interfaceType]);
if (styles.includes('glassmorphic')) {
patterns.push('Frosted glass cards', 'Layered transparency');
}
if (styles.includes('bold-experimental')) {
patterns.push('Broken grid layouts', 'Overlapping elements', 'Custom cursor');
}
if (styles.includes('minimalist')) {
patterns.push('Generous whitespace', 'Type-focused hierarchy');
}
return [...new Set(patterns)];
}
function determineComplexity(prompt: string, components: string[]): 'simple' | 'moderate' | 'complex' | 'enterprise' {
const componentCount = components.length;
const wordCount = prompt.split(/\s+/).length;
const complexityIndicators = [
/real.?time/i, /authentication/i, /multi.?tenant/i, /integration/i,
/dashboard/i, /analytics/i, /notification/i, /search/i, /filter/i,
/role.?based/i, /permission/i, /workflow/i, /automation/i
];
const complexityScore = complexityIndicators.filter(pattern => pattern.test(prompt)).length;
if (componentCount > 15 || complexityScore > 5 || wordCount > 200) return 'enterprise';
if (componentCount > 10 || complexityScore > 3 || wordCount > 100) return 'complex';
if (componentCount > 5 || complexityScore > 1 || wordCount > 50) return 'moderate';
return 'simple';
}
export function analyzeInterface(rawPrompt: string, providedType?: InterfaceType): AnalysisResult {
const interfaceType = providedType || detectInterfaceType(rawPrompt);
const suggestedStyles = detectStyles(rawPrompt);
const keyComponents = extractKeyComponents(rawPrompt, interfaceType);
const userPersonas = inferUserPersonas(rawPrompt, interfaceType);
const designPatterns = suggestDesignPatterns(interfaceType, suggestedStyles);
const complexity = determineComplexity(rawPrompt, keyComponents);
return {
interfaceType,
suggestedStyles,
keyComponents,
userPersonas,
designPatterns,
complexity
};
}
export function generateAnalysisOutput(analysis: AnalysisResult, rawPrompt: string): string {
return `# Interface Analysis
## Original Request
"${rawPrompt}"
## Detected Interface Type
**${analysis.interfaceType.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}**
## Complexity Level
**${analysis.complexity.charAt(0).toUpperCase() + analysis.complexity.slice(1)}**
## Suggested Design Styles
${analysis.suggestedStyles.map(s => `- ${s.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}`).join('\n')}
## Key Components Identified
${analysis.keyComponents.map(c => `- ${c}`).join('\n')}
## Target User Personas
${analysis.userPersonas.map(p => `- ${p}`).join('\n')}
## Recommended Design Patterns
${analysis.designPatterns.map(p => `- ${p}`).join('\n')}
---
*This analysis forms the foundation for the refined design prompt.*
`;
}