@page "/create-logo" @using BLAIzor.Components.Layout @attribute [Authorize] @layout AdminLayout @using System.Net.Http.Headers @using System.Text.Json @using BLAIzor.Services @using Microsoft.AspNetCore.Components.Authorization @using SixLabors.ImageSharp @using SixLabors.ImageSharp.Processing @inject IJSRuntime JS @inject IHttpClientFactory HttpClientFactory @inject WhisperTranscriptionService WhisperService @inject ReplicateService ReplicateService @inject AuthenticationStateProvider AuthenticationStateProvider @inject CustomAuthenticationStateProvider CustomAuthProvider

Let's build your website step by step

Step @CurrentStep of @Steps.Count (@(CurrentStep * 100 / Steps.Count)% complete)

@if (CurrentStep < Steps.Count) {

@Steps[CurrentStep].Description

} else {
Site Description Preview
@((MarkupString)generatedDescription)
} @if (ShowLogoStep) {
Would you like to upload a logo or generate one?
@* *@
@if (logoGenerationCount > 0 && logoGenerationCount < MaxLogoGenerations) {

You can regenerate the logo @(MaxLogoGenerations - logoGenerationCount) more time(s).

}
@if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl)) {
}
}
@code { public string UserId { get; set; } = string.Empty; private string userName = string.Empty; private AuthenticationState authState; private int CurrentStep = 0; private bool IsFirstStep => CurrentStep == 0; private bool ShowLogoStep = false; private string? GeneratedLogoUrl; private string? logoUrl; private int logoGenerationCount = 0; private const int MaxLogoGenerations = 10; private bool IsGeneratingLogo = false; private List Steps = new() { new("What is the name of your site?", "The domain name or the brand name"), new("Is it for a brand, a person, a cause, a blog, a service, a store, a beauty salon or something else?", "The entity that the site will introduce to the users. "), new("What kind of feel or atmosphere should the site have? (e.g. friendly, professional, mysterious, playful)", "How should your website communicate?"), new("What color(s) do you associate with your brand or prefer for the visuals?", "The colors you have in mind. This is needed for design suggestions and photo generation"), }; private string generatedDescription = ""; private string siteName = ""; private string entity = ""; private string persona = ""; private string colors = ""; protected override async Task OnInitializedAsync() { _instance = this; authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); if (authState.User.Identity?.IsAuthenticated == true) { UserId = CustomAuthProvider.GetUserId(); userName = CustomAuthProvider.GetUserName(); } } private void NextStep() { if (CurrentStep < Steps.Count) CurrentStep++; if (CurrentStep == Steps.Count) GenerateSiteDescription(); } private void PreviousStep() { if (CurrentStep > 0) CurrentStep--; } private void GenerateSiteDescription() { var name = Steps[0].Answer; var siteEntity = Steps[1].Answer; var feel = Steps[2].Answer; colors = Steps[3].Answer; siteName = name; entity = siteEntity; persona = feel; generatedDescription = $@"

{name} is a {entity.ToLower()}.

The logo should offer {feel.ToLower()} experience for its viewers.

The design should reflect {colors.ToLower()} tones for visual consistency.

"; } private void ProceedToLogoStep() { ShowLogoStep = true; } private async Task GenerateLogo() { if (logoGenerationCount >= MaxLogoGenerations) return; IsGeneratingLogo = true; var logoPrompt = $"Logo for a {entity} named {siteName}, with a {persona} tone, using {colors} colors. DO NOT ADD taglines, or any text other than the brand name: {siteName}."; GeneratedLogoUrl = await ReplicateService.GenerateLogoAsync(logoPrompt, true); logoUrl = GeneratedLogoUrl; logoGenerationCount++; IsGeneratingLogo = false; } private async Task SaveDescription() { if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl) && GeneratedLogoUrl.StartsWith("http")) { var savedPath = await DownloadAndSaveImage(GeneratedLogoUrl); if (!string.IsNullOrEmpty(savedPath)) { logoUrl = savedPath; } } string[] siteInfo = new string[6]; siteInfo[0] = siteName; siteInfo[1] = generatedDescription; siteInfo[2] = entity; siteInfo[3] = persona; siteInfo[5] = logoUrl; } private class QuestionStep { public string Question { get; } public string Description { get; } public string Answer { get; set; } = ""; public QuestionStep(string question, string description) { Question = question; Description = description; } } private string GetStepCircleClass(int index) { if (index < CurrentStep) return "step-circle completed"; else if (index == CurrentStep) return "step-circle current"; else return "step-circle"; } private async Task HandleFileUpload(InputFileChangeEventArgs e) { if (e.FileCount == 0) return; try { var uploadPath = Path.Combine("wwwroot", "uploads", UserId); foreach (var file in e.GetMultipleFiles()) { var folder = GetFolderForFile(file.ContentType); var folderPath = Path.Combine(uploadPath, folder); // Create target directory Directory.CreateDirectory(folderPath); var filePath = Path.Combine(folderPath, file.Name); await using (var stream = new FileStream(filePath, FileMode.Create)) { await file.OpenReadStream(50 * 1024 * 1024).CopyToAsync(stream); } var relativePath = $"/uploads/{UserId}/{folder}/{file.Name}"; AppendFilePathToContent(file.ContentType, relativePath); // Generate thumbnail if it's an image string? thumbnailRelativePath = null; if (file.ContentType.StartsWith("image/")) { var thumbnailFolder = Path.Combine(folderPath, "thumbnails"); Directory.CreateDirectory(thumbnailFolder); var thumbnailPath = Path.Combine(thumbnailFolder, file.Name); using var image = await Image.LoadAsync(file.OpenReadStream()); image.Mutate(x => x.Resize(new ResizeOptions { Size = new Size(300, 0), Mode = ResizeMode.Max })); await image.SaveAsync(thumbnailPath); thumbnailRelativePath = $"/uploads/{UserId}/{folder}/thumbnails/{file.Name}"; } AppendFilePathToContent(file.ContentType, relativePath, thumbnailRelativePath); } } catch (Exception ex) { Console.WriteLine($"Error uploading files: {ex.Message}"); } finally { //IsLoading = false; } } private string GetFolderForFile(string contentType) { return contentType switch { var type when type.StartsWith("image/") => "images", var type when type.StartsWith("video/") => "videos", var type when type.StartsWith("audio/") => "audio", _ => "others" }; } private void AppendFilePathToContent(string contentType, string relativePath, string? thumbnailPath = null) { if (contentType.StartsWith("image/")) { logoUrl = relativePath; GeneratedLogoUrl = relativePath; var ThumbnailUrl = thumbnailPath ?? string.Empty; } StateHasChanged(); } private async Task DownloadAndSaveImage(string imageUrl) { try { var uploadPath = Path.Combine("wwwroot", "uploads", UserId, "images"); Directory.CreateDirectory(uploadPath); var fileName = $"logo_{Guid.NewGuid().ToString().Substring(0, 8)}.jpg"; var filePath = Path.Combine(uploadPath, fileName); var httpClient = HttpClientFactory.CreateClient(); var imageBytes = await httpClient.GetByteArrayAsync(imageUrl); await File.WriteAllBytesAsync(filePath, imageBytes); // Generate thumbnail var thumbnailFolder = Path.Combine(uploadPath, "thumbnails"); Directory.CreateDirectory(thumbnailFolder); var thumbnailPath = Path.Combine(thumbnailFolder, fileName); using var image = Image.Load(imageBytes); image.Mutate(x => x.Resize(new ResizeOptions { Size = new Size(300, 0), Mode = ResizeMode.Max })); await image.SaveAsync(thumbnailPath); return $"/uploads/{UserId}/images/{fileName}"; } catch (Exception ex) { Console.WriteLine($"Error saving logo: {ex.Message}"); return null; } } // STT Hook private static LogoGenerator? _instance; }