SeemGen/Components/Partials/GenerateSitePages - Copy.razor

196 lines
6.7 KiB
Plaintext

@* @page "/site/{SiteId:int}/generate" *@
@using BLAIzor.Models
@using BLAIzor.Services
@inject HttpClient Http
@inject ContentEditorAIService contentEditorAIService
@inject ContentEditorService contentEditorService
@inject NavigationManager Navigation
<div class="container-fluid">
@if (!string.IsNullOrEmpty(errorMessage))
{
<p class="text-red-600">Error: @errorMessage</p>
}
else if (isLoading || GeneratedItems.Any())
{
<RadzenLayout Style="grid-template-areas: 'rz-sidebar rz-header' 'rz-sidebar rz-body'">
<RadzenHeader>
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0">
<RadzenSidebarToggle Click="@(() => sidebarExpanded = !sidebarExpanded)" />
<RadzenLabel Text=@(totalItemsToGenerate.ToString() + " page(s)") />
</RadzenStack>
</RadzenHeader>
<RadzenSidebar @bind-Expanded="@sidebarExpanded">
<RadzenPanelMenu>
@foreach (var item in GeneratedItems)
{
<RadzenPanelMenuItem Text="@item.Title" Icon="account_box" Click="@(() => SelectContent(item.Title))" />
}
</RadzenPanelMenu>
<button class="btn btn-primary mt-4" @onclick="SaveContent">Save All</button>
</RadzenSidebar>
<RadzenBody Style="padding: 0px !important">
@if (isLoading)
{
<p class="text-muted">Generating... please wait.</p>
//progress bar
<RadzenProgressBar Value="@generationProgress" ShowValue="true" Style="width: 100%;" />
}
else
{
if (SelectedItem != null)
{
<textarea class="w-100 p-2 rounded text-white bg-panel-gradient" style="min-height:500px" @bind="SelectedItem.Content"></textarea>
}
}
</RadzenBody>
</RadzenLayout>
}
else
{
<button class="btn btn-success" @onclick="GeneratePageList">Start Generation</button>
}
</div>
@code {
[Parameter]
public int SiteId { get; set; }
[Parameter] public string SessionId { get; set; } = string.Empty;
private SiteInfo site;
private bool isLoading = false;
private string errorMessage = string.Empty;
private List<ContentItem> GeneratedItems = new();
private ContentGroup defaultGroup;
private ContentItem SelectedItem;
private double generationProgress = 0.0;
private int totalItemsToGenerate = 0;
bool sidebarExpanded = true;
protected override async Task OnInitializedAsync()
{
site = await contentEditorService.GetSiteInfoByIdAsync(SiteId);
var existingGroup = await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteId);
if (!existingGroup.Any(x => x.Name == "Pages"))
{
defaultGroup = new ContentGroup
{
SiteInfoId = SiteId,
Name = "Pages",
Slug = "pages",
Type = "Page",
VectorSize = 1536,
EmbeddingModel = "openai",
Version = 0
};
// Save ContentGroup to DB (if not already exists)
var response = await contentEditorService.CreateContentGroupAsync(defaultGroup);
defaultGroup = response;
}
else
{
defaultGroup = existingGroup.FirstOrDefault(x => x.Name == "Pages");
}
}
private void SelectContent(string title)
{
SelectedItem = GeneratedItems.Where(x => x.Title == title).FirstOrDefault();
StateHasChanged();
}
private async Task GeneratePageList()
{
isLoading = true;
errorMessage = string.Empty;
GeneratedItems.Clear();
try
{
var pageListPrompt = $"Based on the following site description, list the main website pages in {site.DefaultLanguage} as a comma-separated list. " +
"Only return the page titles." +
$"Site Description: {site.SiteDescription}";
var pageListText = await contentEditorAIService.GetMenuSuggestionsAsync(SessionId, pageListPrompt);
var pageTitles = pageListText
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim())
.Where(t => !string.IsNullOrWhiteSpace(t))
.Distinct()
.ToList();
totalItemsToGenerate = pageTitles.Count;
foreach (var title in pageTitles)
{
var itemPrompt = $"Write a full, well-structured website page text content in {site.DefaultLanguage} for a page titled {title}. " +
$"The tone should be {site.Persona}, and match the following site description: '{site.SiteDescription}' " +
"Include headers, clear sections, and persuasive copy.";
var content = await contentEditorAIService.GetGeneratedContentAsync(SessionId, itemPrompt);
GeneratedItems.Add(new ContentItem
{
Title = title,
Description = $"A {defaultGroup.Type} called {title} of a website called {site.SiteName}.",
Language = site.DefaultLanguage,
Content = content,
ContentGroupId = defaultGroup.Id,
Tags = title,
IsPublished = false,
Version = 0
});
generationProgress += 100.0 / totalItemsToGenerate;
// Refresh UI after each item is generated
StateHasChanged();
}
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
finally
{
SelectedItem = GeneratedItems.FirstOrDefault();
isLoading = false;
StateHasChanged();
}
}
private async Task SaveContent()
{
isLoading = true;
errorMessage = string.Empty;
try
{
foreach (var item in GeneratedItems)
{
//await Http.PostAsJsonAsync("/api/contentitem", item);
await contentEditorService.CreateContentItemAsync(item, site.VectorCollectionName);
}
Navigation.NavigateTo($"/site/{SiteId}/overview");
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
finally
{
isLoading = false;
}
}
}