SeemGen/Components/Pages/Sites.razor

289 lines
14 KiB
Plaintext

@page "/sites"
@attribute [Authorize]
@using BLAIzor.Components.Layout
@using BLAIzor.Models
@using BLAIzor.Services
@using Microsoft.AspNetCore.Components.Authorization
@layout AdminLayout
@inject ScopedContentService SiteInfoService
@inject ContentEditorService _contentEditorService
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject CustomAuthenticationStateProvider CustomAuthProvider
@inject IJSRuntime JSRuntime
<h1>Your Sites</h1>
<div class="row g-0">
<AnimateOnRender CssClass="animate__animated animate__backInUp">
<RadzenPanel Collapsed="true" AllowCollapse="true" class="rz-my-5 rz-mx-auto" Style="width: 100%"
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
<HeaderTemplate>
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
<RadzenIcon Icon="note_add" class="rz-me-1" /><b>New site</b>
</RadzenText>
</HeaderTemplate>
<ChildContent>
<CreateSiteWizard OnDescriptionFinalized="HandleDescriptionGenerated" UserId="@userId" />
@* <RadzenCard class="rz-mt-4">
<EditForm Model="newSite" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-12 col-md-3 mb-3">
<label for="siteName" class="form-label">Site Name</label>
<InputText id="siteName" placeholder="Site name" class="form-control" @bind-Value="newSite.SiteName" />
</div>
<div class="col-12 col-md-3 mb-3">
<label for="brandLogoUrl" class="form-label">Brand Logo URL</label>
<InputText id="brandLogoUrl" placeholder="Logo url" class="form-control" @bind-Value="newSite.BrandLogoUrl" />
</div>
<div class="col-12 col-md-3 mb-3">
<label for="defaultColor" class="form-label">Default Color</label>
<InputText id="defaultColor" placeholder="Default color" class="form-control" @bind-Value="newSite.DefaultColor" />
</div>
<div class="col-12 col-md-3">
<label for="domainUrl">Domain URL</label>
<InputText id="domainUrl" placeholder="Domain url" class="form-control" @bind-Value="newSite.DomainUrl" />
</div>
<div class="col-12 col-md-12 mb-3">
<label for="siteName" class="form-label">Site description</label>
<InputText id="siteDescription" placeholder="A description so AI will know what is this site about" class="form-control" @bind-Value="newSite.SiteDescription" />
</div>
<div class="col-12 col-md-12 mb-3">
<label for="siteName" class="form-label">Site language</label>
<InputText id="siteLanguage" placeholder="The default language of the website" class="form-control" @bind-Value="newSite.DefaultLanguage" />
</div>
</div>
<button type="submit" class="btn btn-primary">Create Site</button>
</EditForm>
</RadzenCard>*@
</ChildContent>
</RadzenPanel>
@if (siteInfoList.Any())
{
<RadzenPanel AllowCollapse="true" class="rz-my-5 rz-mx-auto" Style="width: 100%"
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
<HeaderTemplate>
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
<RadzenIcon Icon="account_box" class="rz-me-1" /><b>Sites created</b>
</RadzenText>
</HeaderTemplate>
<ChildContent>
@{
if(siteInfoList.Count() > 0)
{
<AnimateOnRender CssClass="animate__animated animate__backInUp">
<RadzenCard class="rz-mt-4">
<RadzenDataList Density="Density.Compact" PageSize="4" WrapItems="true"
AllowPaging="false"
Data="@siteInfoList" TItem="SiteInfo">
<Template Context="site">
<RadzenCard class="admin-rz-card" Style="width: 250px;">
<RadzenRow JustifyContent="@JustifyContent.SpaceBetween">
<RadzenColumn Size="4" class="rz-text-truncate">
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text=@($"{site.Id}") class="rz-me-1" />
<b>@(site.SiteName)</b>
</RadzenColumn>
<RadzenColumn Size="8" class="rz-text-align-end">
<RadzenBadge BadgeStyle="BadgeStyle.Success" Text=@($"new") />
</RadzenColumn>
</RadzenRow>
<hr style="border: none; background-color: var(--rz-text-disabled-color); height: 1px; margin: 1rem 0;" />
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Gap="1rem">
<RadzenImage Path="@site.BrandLogoUrl" class="img-fluid" Style="max-height: 100px;" AlternateText="@(site.SiteName)" />
<RadzenStack Gap="0">
<RadzenText TextStyle="TextStyle.H6" class="rz-mb-0">@(site.SiteName)</RadzenText>
<RadzenText TextStyle="TextStyle.Body1">@site.DefaultUrl</RadzenText>
<RadzenText TextStyle="TextStyle.Body2">Fefault color: @(site.DefaultColor)</RadzenText>
<RadzenText TextStyle="TextStyle.Body2">Theme: @(site.TemplateId)</RadzenText>
</RadzenStack>
</RadzenStack>
<RadzenStack Orientation="@Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Center" AlignItems="@AlignItems.Center" Wrap="@FlexWrap.Wrap" Style="height: fit-content">
<a href="/site-info/@site.Id" class="btn btn-secondary">Edit</a>
<InputText @bind-Value="collectionName" class="form-control" style="width: 100%;" placeholder="Site name" />
<a style="font-size: 14px;" @onclick="()=>Migrate(site.Id, collectionName)" class="btn btn-secondary">Migrate</a>
<a style="font-size: 14px;" href="/generate-content/@site.Id" class="btn btn-secondary">Manage content</a>
<a style="font-size: 14px;" @onclick="()=>Preview(site)" class="btn btn-secondary"> Preview</a>
</RadzenStack>
</RadzenCard>
</Template>
</RadzenDataList>
</RadzenCard>
</AnimateOnRender>
}
else
{
<RadzenCard class="rz-mt-4">
<p>Let1s create your first website!</p>
</RadzenCard>
}
}
</ChildContent>
<SummaryTemplate>
<RadzenCard class="rz-mt-4">
<b>@siteInfoList.Count() Sites</b>
</RadzenCard>
</SummaryTemplate>
</RadzenPanel>
@* foreach (var item in siteInfoList)
{
<div class="col-xs-12 col-md-4">
<div class="card m-2">
<div class="card-header">
<h5 class="card-title">@item.SiteName</h5>
</div>
<div class="card-body">
<a @onclick="()=>visit(item)">
<div style="width: 100%; height: 150px;">
<img src="@item.BrandLogoUrl" class="img-fluid rounded-start" style="max-height:150px;" alt="Brand Logo">
</div>
<p class="card-text"><small class="text-muted">Owner: @userName</small></p>
<p class="card-text"><small class="text-muted">Url: @item.DefaultUrl</small></p>
</a>
</div>
<div class="card-footer">
<a href="/site-info/@item.Id" class="btn btn-secondary">Edit</a>
<a href="/generate-content/@item.Id" class="btn btn-secondary">Manage content</a>
<a @onclick="()=>Preview(item)" class="btn btn-secondary"> Preview</a>
</div>
</div>
</div>
} *@
}
else
{
<p>No sites created yet.</p>
}
</AnimateOnRender>
</div>
@code {
private IEnumerable<SiteInfo> siteInfoList = new List<SiteInfo>();
private SiteInfo newSite = new();
private string? userId;
private string? userName;
private AuthenticationState? authState;
int position = 1;
public string SessionId;
//TEMPORARY
private string collectionName = "seemgen-collection";
private string FinalSiteDescription;
private async Task HandleDescriptionGenerated(string[] desc)
{
newSite.UserId = userId;
FinalSiteDescription = desc[1];
newSite.SiteDescription = desc[1];
newSite.SiteName = desc[0];
newSite.Entity = desc[2];
newSite.Persona = desc[3];
newSite.DefaultLanguage = desc[4];
newSite.BrandLogoUrl = desc[5];
newSite.FacebookUrl = desc[6];
await HandleValidSubmit();
// You can now store it in SiteInfo.SiteDescription
// or prefill the full form with the rest of the properties
}
void Change(string text)
{
Console.Write($"{text}");
}
private void visit(SiteInfo site)
{
SiteInfoService.SelectedBrandName = site.SiteName;
SiteInfoService.SelectedSiteId = site.Id;
NavigationManager.NavigateTo(site.DefaultUrl, true);
}
private async Task Migrate(int siteId, string collectionName)
{
var result = await _contentEditorService.MigrateQdrantToContentItemsAsync(siteId, collectionName);
Console.WriteLine($"Migration result: {result}");
}
private async Task Preview(SiteInfo site)
{
string myUrl = $"/preview/{site.Id}";
try
{
await JSRuntime.InvokeVoidAsync("open", myUrl, "_blank");
}
catch (Exception ex)
{
Console.WriteLine($"Error opening new tab: {ex.Message}");
}
}
protected override async Task OnInitializedAsync()
{
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (authState.User.Identity?.IsAuthenticated == true)
{
userId = CustomAuthProvider.GetUserId();
userName = CustomAuthProvider.GetUserName();
}
siteInfoList = await _contentEditorService.GetUserSitesAsync(userId!);
SessionId = SiteInfoService.SessionId;
// SiteInfoService.SessionId = SessionId;
}
private async Task HandleValidSubmit()
{
newSite.UserId = userId;
newSite.TemplateId = 1;
newSite.DefaultUrl = await GenerateSubdomainAsync(newSite.SiteName);
newSite.VectorCollectionName = _contentEditorService.GetGeneratedVectorCollectionName(newSite);
var result = await _contentEditorService.AddSiteInfoAsync(newSite);
siteInfoList = await _contentEditorService.GetUserSitesAsync(userId!);
newSite = new(); // Reset the form
if(result != null)
{
NavigationManager.NavigateTo($"/generate-content/{result.Id}");
}
}
public async Task<string> GenerateSubdomainAsync(string siteName)
{
var normalizedSiteName = siteName.ToLower()
.Replace(" ", "-")
.Replace("_", "-")
.Replace(".", "-");
var subdomain = $"{normalizedSiteName}.seemgen.com";
// var site = await SiteInfoService.GetSiteInfoByIdAsync(siteId);
// if (site != null)
// {
// site.DefaultUrl = subdomain;
// await SiteInfoService.UpdateSiteInfoAsync(site);
// }
return subdomain;
}
}