wireframe

This commit is contained in:
string 2025-05-24 15:25:53 +05:30
parent 7b855d6553
commit 3757f3d24a
7 changed files with 228 additions and 8642 deletions

View File

@ -9,7 +9,6 @@ import { Design_lbrarycardvariable } from './Design_lbrary_cardvariable';
import { UserInfoService } from 'src/app/services/user-info.service';
import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
import { COMMON_CSS } from '../WireframesUi/common-css';
import { Download_Css } from '../WireframesUi/download-css';
import { ActivatedRoute } from '@angular/router';
// import { Download_Css } from '../WireframesUi/download-css';
declare var JsBarcode: any;
@ -284,7 +283,7 @@ export class Design_lbraryComponent implements OnInit {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Preview</title>
<style>
${Download_Css}
${COMMON_CSS}
/* Additional styles for controls */
.preview-controls {
@ -381,7 +380,7 @@ export class Design_lbraryComponent implements OnInit {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Downloaded HTML</title>
<style>
${Download_Css}
${COMMON_CSS}
</style>
</head>
<body>

View File

@ -10,6 +10,8 @@ export class SiteTreeservice {
private baseURL = "SiteTree/SiteTree";
private dlfbaseURL = environment.builderUrl + "/entityBuilder";
private nodeURL = environment.nodeUrl;
private geminiURL = environment.ollamaUrl;
constructor(
@ -56,6 +58,11 @@ export class SiteTreeservice {
return this.http.post(`${this.nodeURL}/chatMemory`, data);
}
callGemini(data: any): Observable<any> {
return this.http.post(`${this.geminiURL}/api/gemini`, data);
}
generateHtml(data: any): Observable<any> {
return this.apiRequest.post(`api/html/generate`, data);

View File

@ -2012,120 +2012,7 @@ input:focus, textarea:focus, select:focus {
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1) !important;
}
/* Testimonial Styling */
testimonial {
display: block !important;
max-width: 800px !important;
margin: 40px auto !important;
padding: 35px !important;
background-color: #fff !important;
border-radius: 10px !important;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08) !important;
font-style: italic !important;
color: #444 !important;
position: relative !important;
line-height: 1.8 !important;
font-size: 1.1rem !important;
border-left: 5px solid #0066cc !important;
}
testimonial::before {
content: '"' !important;
font-size: 5rem !important;
color: #0066cc !important;
position: absolute !important;
left: 15px !important;
top: -10px !important;
opacity: 0.2 !important;
font-family: Georgia, serif !important;
}
section:nth-child(even) testimonial {
background-color: #fff !important;
}
/* Custom styles container */
styles {
display: none !important;
}
/* Responsive Adjustments */
@media (max-width: 992px) {
h1 {
font-size: 2rem !important;
}
h2 {
font-size: 1.75rem !important;
}
section {
padding: 60px 0 !important;
}
}
@media (max-width: 768px) {
section {
padding: 50px 0 !important;
}
.hero-1-two-column, .split-8-section, .split-10-section {
flex-direction: column !important;
}
.btn, button {
width: 100% !important;
}
.hero-1-button-group, .hero-2-button-group {
flex-direction: column !important;
width: 100% !important;
}
}
@media (max-width: 576px) {
body {
font-size: 15px !important;
}
h1 {
font-size: 1.75rem !important;
}
h2 {
font-size: 1.5rem !important;
}
section {
padding: 40px 0 !important;
}
testimonial {
padding: 25px !important;
font-size: 1rem !important;
}
}
/* Animations and Transitions */
.fade-in {
animation: fadeIn 1s ease-in-out !important;
}
@keyframes fadeIn {
from {
opacity: 0 !important;
transform: translateY(20px) !important;
}
to {
opacity: 1 !important;
transform: translateY(0) !important;
}
}
/* Ensure smooth scrolling */
html {
scroll-behavior: smooth !important;
}
`;

View File

@ -1,5 +1,5 @@
import { Component, Input, OnInit, SecurityContext, ChangeDetectorRef } from '@angular/core';
import { Component, Input, OnInit, SecurityContext, ChangeDetectorRef, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
@ -8,13 +8,14 @@ import { ToastrService } from 'ngx-toastr';
import * as sha256 from 'crypto-js/sha256';
import SHA256 from 'crypto-js/sha256';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Download_Css } from './download-css';
import { trigger, transition, style, animate, state } from '@angular/animations';
@Component({
selector: 'app-wireframe-renderer',
templateUrl: './wireframe-renderer.component.html',
styleUrls: ['./wireframe-renderer.component.scss'],
encapsulation: ViewEncapsulation.Emulated, // This is default; optional to write
animations: [
trigger('fadeIn', [
transition(':enter', [
@ -471,7 +472,7 @@ HTML Only. No CSS.
return resolve(this.promptHashCache[hash]);
}
// const enhanced = await this.callLlm(enhancedPrompt);
// const enhanced = await this.callAi(enhancedPrompt);
// console.log('enhanced prmpt ',enhanced);
// this.promptHashCache[hash] = enhanced;
@ -962,7 +963,7 @@ return new Promise((resolve) => {
}
// Call LLM
async callLlm(data): Promise<string> {
async callAi(data): Promise<string> {
return new Promise((resolve, reject) => {
console.log('call Llm Start');
const payload = {
@ -970,7 +971,7 @@ return new Promise((resolve) => {
conversationId: '677'
};
console.log('query:', payload.query);
this.siteTreeService.callLlm(payload).subscribe({
this.siteTreeService.callGemini(payload).subscribe({
next: (res) => {
console.log('response', res);
if (res && res.responseContent) {

View File

@ -145,41 +145,222 @@ export class TreeVisualizerComponent {
}
// Add these properties to your component class
isLoading = false;
showError = false;
// Add these properties to your component class
isLoading = false;
showError = false;
// Method to handle the enhanced generate flow
generateJsonWithLoading() {
this.isLoading = true;
this.showError = false;
// Method to handle the enhanced generate flow
generateJsonWithLoading() {
this.isLoading = true;
this.showError = false;
console.log('🔄 Starting generateJsonWithLoading...');
// Call the actual generateJson method
const suffix = `You are a JSON structure generator for website page hierarchies.
You are a JSON structure generator for website UI and sitemap hierarchy.
Generate a strictly hierarchical JSON tree that represents the entire page flow of a website. The root of the tree must always be the "Home" page. All other pages (like Login, Sign Up, Projects, Dashboard, etc.) must be nested as subpages using a "Children" key under their logical parent based on the described user flow not all pages should be flat or at root level.
Each page must include meaningful UI sections as keys like "Navbar", "Header Section", "Feature Section", "Form Section", "Footer", etc.
Each section must include a short and clear description of its purpose or content to assist in frontend UI development.
Analyze the flow implied in the prompt:
- Pages that are accessed after some action (e.g., "after login", "inside a project", "upon click") must be nested as children.
- Reuse common sections like "Navbar" or "Footer" wherever needed.
- Pages like "Privacy Policy" or "Terms and Conditions" can remain at root or in Footer reference if needed.
The following standard pages must always be included with detailed section-level breakdown:
- **Home**: General overview of the website, with call-to-action, features, testimonials, and a footer.
- **About**: Brief company history, mission/vision, and team member highlights.
- **Services**: List of services offered, with description, icons, or pricing cards.
- **Contact**: Contact form (name, email, message), business info, phone, map.
- **FAQ**: Accordion or expandable list of common questions and answers.
- **Blog**: List of articles or posts, with title, thumbnail, and excerpt.
- **Login**: Form section with input fields for email/username and password, login button, forgot password link.
- **Sign Up**: Form section with full name, email, password, confirm password, sign-up button.
- **Privacy Policy**: Legal text describing how user data is handled.
- **Terms and Conditions**: Legal text outlining site usage policies.
Do not include:
- Any explanation before or after the JSON
- Any markdown formatting like \`\`\` or json
- Any natural language response
- Return only pure JSON no explanation, no headings, no markdown formatting.
// Your existing generateJson logic here
// Replace with your actual API call
setTimeout(() => {
// Success case
Output JSON example structure should look like this:
{
"Home": {
"Navbar": "Top navigation with logo, links to all main pages, and call-to-action button",
"Header Section": "Headline with subheading and call-to-action button",
"Feature Section": "Three features highlighted with icons and descriptions",
"Testimonial Section": "Customer reviews in carousel layout",
"Footer": "Footer with navigation links, social icons, and legal page links",
"Children": {
"About": {
"Header Section": "Intro about company mission and values",
"Team Section": "Photos and bios of core team members"
},
"Services": {
"Header Section": "List of core services offered",
"Pricing Section": "Cards with service pricing and features"
},
"Contact": {
"Header Section": "Contact form with name, email, and message fields",
"Map Section": "Google Maps iframe showing location"
},
...
}
},
"Privacy Policy": {
"Content Section": "Full legal description of data usage and user rights"
},
"Terms and Conditions": {
"Content Section": "Rules and legal terms for using the site or service"
}
}`;
const payload = {
query: this.rawInputText + ' ' + suffix,
conversationId: '677'
};
console.log('🚀 Calling LLM with payload:', payload.query);
this.siteTreeService.callGemini(payload).subscribe({
next: (res) => {
console.log('✅ LLM response received:', res);
if (res && res.responseContent) {
try {
let parsedJson = JSON.parse(res.responseContent);
const topLevelPages = Object.keys(parsedJson);
let pendingCalls = topLevelPages.length;
// If no pages to process, just complete
if (pendingCalls === 0) {
this.completeGeneration(parsedJson);
return;
}
topLevelPages.forEach(pageName => {
this.siteTreeService.getDesignLibraryByheader(2, 'template 1', pageName).subscribe({
next: (designResponse) => {
if (designResponse && Object.keys(designResponse).length > 0) {
console.log(`✅ Design library found for "${pageName}":`, designResponse.htmljson);
try {
let raw = designResponse.htmljson;
const parsed = typeof raw === 'string' ? JSON.parse(`{${raw}}`) : raw;
const firstKey = Object.keys(parsed)[0];
const extractedValue = parsed[firstKey];
// Preserve existing Children
const existingPageData = parsedJson[pageName] || {};
const preservedChildren = existingPageData['Children'];
// Merge design + preserve Children
parsedJson[pageName] = {
...extractedValue,
...(preservedChildren ? { Children: preservedChildren } : {})
};
console.log(`✅ Merged design for "${pageName}"`);
} catch (parseErr) {
console.warn(`⚠️ Could not parse design library JSON for "${pageName}":`, parseErr);
}
} else {
console.log(` No design library found for "${pageName}"`);
}
this.checkAndCompleteGeneration(parsedJson, --pendingCalls);
},
error: (err) => {
console.error(`❌ Error fetching design library for "${pageName}":`, err);
this.checkAndCompleteGeneration(parsedJson, --pendingCalls);
}
});
});
} catch (err) {
console.error('❌ Failed to parse LLM JSON:', err);
this.handleGenerationError('Invalid JSON received from AI');
}
} else {
this.handleGenerationError('No response content received');
}
},
error: (err) => {
console.error('❌ LLM API Error:', err);
this.handleGenerationError('Failed to generate site structure');
}
});
}
// Helper method to check if all calls are complete
private checkAndCompleteGeneration(parsedJson: any, pendingCalls: number) {
if (pendingCalls === 0) {
this.completeGeneration(parsedJson);
}
}
// Helper method to complete the generation process
private completeGeneration(parsedJson: any) {
this.inputJson = JSON.stringify(parsedJson);
const updatePayload = {
prompt: this.rawInputText + ' ',
model: this.inputJson
};
console.log('✅ Final merged JSON ready, updating server...');
this.siteTreeService.update(this.id, updatePayload).subscribe({
next: (resp) => {
console.log('✅ Successfully updated server:', resp);
// Success - close popup and show results
this.isLoading = false;
this.showPopup = false;
this.activeTab = 'sitemap';
// Convert and display the tree
this.convertJson();
console.log('🎉 Generation completed successfully!');
},
error: (err) => {
console.error('❌ Failed to update server:', err);
this.handleGenerationError('Failed to save site structure');
}
});
}
// Helper method to handle errors
private handleGenerationError(message: string) {
console.error('❌ Generation failed:', message);
this.isLoading = false;
this.showError = true;
// Don't close popup so user can retry
}
// Enhanced close method
closePopup() {
this.showPopup = false;
this.activeTab = 'sitemap';
// For error case, use this instead:
// this.isLoading = false;
// this.showError = true;
}, 3000);
}
this.isLoading = false;
this.showError = false;
}
// Enhanced close method
closePopup() {
this.showPopup = false;
this.isLoading = false;
this.showError = false;
}
// Retry method for error state
retryGeneration() {
this.showError = false;
this.generateJsonWithLoading();
}
// Retry method for error state
retryGeneration() {
this.showError = false;
this.generateJsonWithLoading();
}
convertJson() {
try {
const parsed = JSON.parse(this.inputJson);
@ -231,6 +412,7 @@ retryGeneration() {
generateWireframe() {
this.activeTab = 'wireframe';
this.isWireframeLoaded = true;
}
getSections(data: any): { title: string, description: string }[] {
@ -335,7 +517,7 @@ retryGeneration() {
console.log(' query : ', payload.query)
this.siteTreeService.callLlm(payload).subscribe({
this.siteTreeService.callGemini(payload).subscribe({
next: (res) => {
console.log('llm response ', res)