Menu fix, do not modify fix content fix, simplified content display from static menuitems

This commit is contained in:
Adam 2025-05-18 10:20:49 +02:00
parent fb6283628f
commit 03b1995771
59 changed files with 5169 additions and 817 deletions

View File

@ -1,6 +1,7 @@
@page @page
@using Sidio.Sitemap.Blazor
@model LoginModel @model LoginModel
@attribute [Sitemap]
@{ @{
ViewData["Title"] = "Log in"; ViewData["Title"] = "Log in";
} }

View File

@ -1,5 +1,7 @@
@page @page
@using Sidio.Sitemap.Blazor
@model RegisterModel @model RegisterModel
@attribute [Sitemap]
@{ @{
ViewData["Title"] = "Register"; ViewData["Title"] = "Register";
} }

View File

@ -31,6 +31,7 @@
<PackageReference Include="PdfPig" Version="0.1.10" /> <PackageReference Include="PdfPig" Version="0.1.10" />
<PackageReference Include="Qdrant.Client" Version="1.13.0" /> <PackageReference Include="Qdrant.Client" Version="1.13.0" />
<PackageReference Include="Radzen.Blazor" Version="6.4.0" /> <PackageReference Include="Radzen.Blazor" Version="6.4.0" />
<PackageReference Include="Sidio.Sitemap.Blazor" Version="1.1.2" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.3" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.3" />
</ItemGroup> </ItemGroup>
@ -41,7 +42,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="wwwroot\video\GR Production Services.mp4" /> <None Include="wwwroot\video\GR Production Services.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -60,6 +63,189 @@
<Content Update="wwwroot\default.css"> <Content Update="wwwroot\default.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\10262403.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\267111581_6537457352993553_2093941074766316375_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\464609293_8553833781365611_797678058825756959_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\464702374_8571192746296381_2492674641604205759_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\464847960_8560471694035153_8000699131803786124_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\464867041_8570940996321556_6613785466010075519_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\464947949_8580789888670000_2158336133679231152_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\5.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\58441485_2159856217430098_8842486812262793216_n.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\all moods.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\article-1-header-cover.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\article-in-content-image.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Collaboration_1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Collections22-23.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Daige_logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\darkstar.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\growtika-nGoCBxiaRO0-unsplash.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\halfscreen-parallax-img-1.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\halfscreen-parallax-img-2.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\hero-image-03_b.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\knitwear.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\linkedin-sales-solutions-oFMI6CdD7yU-unsplash.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\logo_social.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\makita4190D.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\makita4190D_figure_1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Melinda.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Multicategory brand.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\original_prints.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_3.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_4.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_5.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\press_6.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\ribi1_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\ribi1_brighter.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\ribi1_front.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\salespower_2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\salespower_logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\stocklist.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\The_atelier.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-1.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-10.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-11.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-12.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-13.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-14.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-2.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-3.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-4.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-6.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-8.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-9.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-news-1.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-news-2.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-news-3-b.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-news-3.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe-news-4.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\Vhembe_logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\images\webshop.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\uploads\0988758e-e16c-4c2c-8c1e-efa3ac5f0274\videos\Lovereels.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\VG3law.css"> <Content Update="wwwroot\VG3law.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@ -105,6 +291,57 @@
<Content Update="wwwroot\ToyoTanso.css"> <Content Update="wwwroot\ToyoTanso.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="wwwroot\video\adamg.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\ai.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\ai_old.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\Arts.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\Cleary Gottlieb.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\default.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\fratellino.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\lovebits.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\LoveBits_2.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\poppixel.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\salespower.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\salespower_old.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\TNS Corporation.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\toyotanso.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\vg3law.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\vhembe.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\video\video %2855%29.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -48,6 +48,18 @@
}; };
</script> </script>
<script>
function collapseNavbar() {
const navbar = document.getElementById('navbarSupportedContent');
if (navbar && navbar.classList.contains('show')) {
const bsCollapse = bootstrap.Collapse.getInstance(navbar);
if (bsCollapse) {
bsCollapse.hide();
}
}
}
</script>
@code{ @code{
} }

View File

@ -140,8 +140,8 @@ else
await JSRuntime.InvokeVoidAsync("setSessionId", SessionId); await JSRuntime.InvokeVoidAsync("setSessionId", SessionId);
await JSRuntime.InvokeVoidAsync("setHtmlEditorSourceMode"); await JSRuntime.InvokeVoidAsync("setHtmlEditorSourceMode");
await LoadTemplate(); await LoadTemplate();
var cssPath = await CssTemplateService.SaveTempCssFileAsync(currentCssTemplate.CssContent, SessionId); //var cssPath = await CssTemplateService.SaveTempCssFileAsync(currentCssTemplate.CssContent, SessionId);
await JSRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath); //await JSRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath);
} }
} }

View File

@ -6,6 +6,7 @@
@using Microsoft.AspNetCore.Identity.UI.Services @using Microsoft.AspNetCore.Identity.UI.Services
@using System.Text @using System.Text
@using System.Text.Json @using System.Text.Json
@using Sidio.Sitemap.Blazor
@inject AIService ChatGptService @inject AIService ChatGptService
@rendermode InteractiveServer @rendermode InteractiveServer
@inject IJSRuntime jsRuntime; @inject IJSRuntime jsRuntime;
@ -19,7 +20,7 @@
@inject DesignTemplateService DesignTemplateService @inject DesignTemplateService DesignTemplateService
@inject CssTemplateService CssTemplateService @inject CssTemplateService CssTemplateService
@inject CssInjectorService CssService @inject CssInjectorService CssService
@attribute [Sitemap]
<div class="page" style="z-index: 1"> <div class="page" style="z-index: 1">
<NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu> <NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu>
@ -31,7 +32,7 @@
@* <HeadContent> @* <HeadContent>
<style id="seemgen-style">@dynamicallyLoadedCss</style> <style id="seemgen-style">@dynamicallyLoadedCss</style>
</HeadContent> *@ </HeadContent> *@
<div id="maincontrol"> <div id="maincontrol">
@ -516,14 +517,22 @@
{ {
HtmlContent.Clear(); HtmlContent.Clear();
var menu = await GetMenuList(); var menu = await GetMenuList();
await ChatGptService.ProcessContentRequest(sessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified); var menuItem = (await GetMenuItems()).Where(m => m.Name == input).FirstOrDefault();
if(menuItem == null)
{
await ChatGptService.ProcessContentRequest(sessionId, input, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
}
else
{
await ChatGptService.ProcessContentRequest(sessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
}
UserInput = string.Empty; UserInput = string.Empty;
} }
} }
private async Task<string> GetMenuList() private async Task<string> GetMenuList()
{ {
List<MenuItem> menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId); List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
string menuList = ""; string menuList = "";
foreach (MenuItem item in menuItems) foreach (MenuItem item in menuItems)
{ {
@ -532,6 +541,12 @@
return menuList; return menuList;
} }
private async Task<List<MenuItem>> GetMenuItems()
{
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
return menuItems;
}
private async void HandleBrandNameChanged() private async void HandleBrandNameChanged()
{ {
selectedBrandName = _scopedContentService.SelectedBrandName; selectedBrandName = _scopedContentService.SelectedBrandName;

View File

@ -289,7 +289,7 @@
if (_instances.TryGetValue(sessionId, out var instance)) if (_instances.TryGetValue(sessionId, out var instance))
{ {
await instance.HandleJsCall("Please search for me: " + input, sessionId, forceUnmodified); await instance.HandleJsCall(input, sessionId, forceUnmodified);
} }
Console.Write("Button clicked:" + input); Console.Write("Button clicked:" + input);
} }
@ -505,14 +505,22 @@
{ {
HtmlContent.Clear(); HtmlContent.Clear();
var menu = await GetMenuList(); var menu = await GetMenuList();
await ChatGptService.ProcessContentRequest(sessionId, UserInput, siteid, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified); var menuItem = (await GetMenuItems()).Where(m => m.Name == input).FirstOrDefault();
if (menuItem == null)
{
await ChatGptService.ProcessContentRequest(sessionId, input, siteid, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
}
else
{
await ChatGptService.ProcessContentRequest(sessionId, menuItem, siteid, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
}
UserInput = string.Empty; UserInput = string.Empty;
} }
} }
private async Task<string> GetMenuList() private async Task<string> GetMenuList()
{ {
List<MenuItem> menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(siteid); List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(siteid)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
string menuList = ""; string menuList = "";
foreach (MenuItem item in menuItems) foreach (MenuItem item in menuItems)
{ {
@ -521,6 +529,12 @@
return menuList; return menuList;
} }
private async Task<List<MenuItem>> GetMenuItems()
{
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(siteid)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
return menuItems;
}
private async void HandleBrandNameChanged() private async void HandleBrandNameChanged()
{ {
selectedBrandName = _scopedContentService.SelectedBrandName; selectedBrandName = _scopedContentService.SelectedBrandName;

View File

@ -0,0 +1,220 @@
@page "/reordergridtest/{siteId:int}"
@using BLAIzor.Components.Layout
@using BLAIzor.Components.Partials
@using BLAIzor.Models
@using BLAIzor.Services
@using System.Collections.ObjectModel
@using Microsoft.JSInterop
@using Newtonsoft.Json
@inject ScopedContentService scopedContentService
@inject ContentEditorService contentEditorService
@inject QDrantService qDrantService
@layout AdminLayout
@* @inherits DbContextPage *@
@inject IJSRuntime JSRuntime;
<style>
.my-class td {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
@if (menuItems == null)
{
<p><em>Loading...</em></p>
}
else
{
<RadzenRow Gap="1rem">
<RadzenColumn Size="12" SizeMD="2">
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Right">
@{
<RadzenButton Click="ToggleReorder">
@(allowReorder? "Cancel" : "Reorder")
</RadzenButton>
}
</RadzenStack>
<RadzenDataGrid @ref="dataGrid" TItem="MenuItem" RowSelect=@OnRowSelect AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.Advanced" AllowSorting="true" PageSize="@pagesize" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
Data="@menuItems" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"
@bind-Value=@selectedMenuItems RowRender="@RowRender">
<Columns>
<RadzenDataGridColumn Property="@nameof(MenuItem.SortOrder)" Title="Sort order" Width="30px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.Id)" Filterable="false" Title="ID" Frozen="true" Width="55px" TextAlign="TextAlign.Center" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.Name)" Title="Name" Frozen="true" Width="130px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.PointId)" Title="Point Id" Width="200px" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.ShowInMainMenu)" Title="Show in menu" Width="30px" />
</Columns>
</RadzenDataGrid>
</RadzenColumn>
<RadzenColumn Size="12" SizeMD="10">
<RadzenCard Variant="Variant.Outlined" Style="height: 100%;">
<RadzenStack Gap="1rem">
<RadzenCard Variant="Variant.Text" class="rz-background-color-primary-lighter rz-color-on-primary-lighter">
Site:
@* <b>@selectedMenuItems.FirstOrDefault()?.SiteInfo.SiteName</b> *@
</RadzenCard>
<RadzenTabs>
<Tabs>
<RadzenTabsItem Text="MenuItems Details">
<MenuItemContentEditor Subject=@subject MenuItem="SelectedMenuItemModel" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
@* <RadzenDataGrid AllowFiltering="true" AllowPaging="true" AllowSorting="true" Data="@(selectedMenuItems.FirstOrDefault()?.Content)">
<Columns>
<RadzenDataGridColumn Property="Order.CustomerID" Title="Order" />
<RadzenDataGridColumn Property="Product.ProductName" Title="Product" />
<RadzenDataGridColumn Property="UnitPrice" Title="Unit Price">
<Template Context="detail">
@String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", detail.UnitPrice)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="@nameof(OrderDetail.Quantity)" Title="Quantity" />
<RadzenDataGridColumn Property="@nameof(OrderDetail.Discount)" Title="Discount">
<Template Context="detail">
@String.Format("{0}%", detail.Discount * 100)
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid> *@
</RadzenTabsItem>
</Tabs>
</RadzenTabs>
</RadzenStack>
</RadzenCard>
</RadzenColumn>
</RadzenRow>
}
@code {
[Parameter]
public int siteId { get; set; }
ObservableCollection<MenuItem> menuItems;
IList<MenuItem> selectedMenuItems;
private string document = "";
private string subject = "";
public bool hasCollection = false;
public bool MenuItemsSaved = false;
private bool allowReorder = false;
private int pagesize = 5;
private List<MenuItemModel> ExtractedMenuItems = new();
MenuItem draggedItem;
MenuItemModel SelectedMenuItemModel = new("");
private RadzenDataGrid<MenuItem> dataGrid;
protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
var siteInfo = await scopedContentService.GetSiteInfoByIdAsync(siteId);
// var menuItems1 = await contentEditorService.GetMenuItemsBySiteIdAsync(1);
menuItems = new ObservableCollection<MenuItem>(await contentEditorService.GetMenuItemsBySiteIdAsync(siteId));
selectedMenuItems = new List<MenuItem>() { menuItems.FirstOrDefault() };
var collectionResult = await qDrantService.GetCollectionBySiteIdAsync(siteId);
if (!string.IsNullOrEmpty(collectionResult))
{
//create colection
hasCollection = true;
Console.Write("Has collection already");
}
if (menuItems.Count() > 0)
{
foreach (var menuItem in menuItems)
{
string content;
MenuItemModel model = new MenuItemModel("");
//try to get content from qDrant
if (menuItem.QdrantPointId != null)
{
content = await qDrantService.GetContentAsync(siteId, menuItem.SortOrder);
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
if (selectedPoint != null)
{
model.Content = selectedPoint.result.payload.content;
Console.Write($"Found point: {selectedPoint.result.payload.content}");
}
}
model.MenuItem.Name = menuItem.Name;
ExtractedMenuItems.Add(model);
// UpdateMenuItem(model);
}
SelectedMenuItemModel.MenuItem.Name = selectedMenuItems.FirstOrDefault().Name;
SelectedMenuItemModel.Content = (ExtractedMenuItems.Where(x => x.MenuItem.Name == selectedMenuItems.FirstOrDefault().Name).FirstOrDefault()).Content;
MenuItemsSaved = true;
}
}
async void ToggleReorder()
{
if (!allowReorder)
{
pagesize = 20;
}
else
{
pagesize = 5;
}
allowReorder = !allowReorder;
}
void Select(MenuItem menuItem)
{
SelectedMenuItemModel.MenuItem.Name = menuItem.Name;
SelectedMenuItemModel.Content = ExtractedMenuItems.Where(x => x.MenuItem.Name == menuItem.Name).FirstOrDefault().Content;
}
void OnRowSelect(MenuItem menuItem)
{
Select(menuItem);
}
private void UpdateMenuItem(MenuItemModel updatedItem)
{
var item = ExtractedMenuItems!.FirstOrDefault(i => i.MenuItem.Name == updatedItem.MenuItem.Name);
if (item != null)
{
item.Content = updatedItem.Content;
}
}
void RowRender(RowRenderEventArgs<MenuItem> args)
{
if(allowReorder)
{
args.Attributes.Add("title", "Drag row to reorder");
args.Attributes.Add("style", "cursor:grab");
args.Attributes.Add("draggable", "true");
args.Attributes.Add("ondragover", "event.preventDefault();event.target.closest('.rz-data-row').classList.add('my-class')");
args.Attributes.Add("ondragleave", "event.target.closest('.rz-data-row').classList.remove('my-class')");
args.Attributes.Add("ondragstart", EventCallback.Factory.Create<DragEventArgs>(this, () => draggedItem = args.Data));
args.Attributes.Add("ondrop", EventCallback.Factory.Create<DragEventArgs>(this, () =>
{
var draggedIndex = menuItems.IndexOf(draggedItem);
var droppedIndex = menuItems.IndexOf(args.Data);
menuItems.Remove(draggedItem);
menuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedItem);
foreach (var menuItemToReorder in menuItems)
{
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
}
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
}));
}
}
}

View File

@ -2,9 +2,11 @@
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using BLAIzor.Services @using BLAIzor.Services
@using Newtonsoft.Json @using Newtonsoft.Json
@using System.Collections.ObjectModel
@inject ContentEditorService ContentEditorService @inject ContentEditorService ContentEditorService
@inject HtmlSnippetProcessor HtmlSnippetProcessor @inject HtmlSnippetProcessor HtmlSnippetProcessor
@inject QDrantService QDrantService @inject QDrantService QDrantService
@inject IJSRuntime JSRuntime
<h3>Upload Document to Generate Menu Items</h3> <h3>Upload Document to Generate Menu Items</h3>
@ -19,78 +21,57 @@
} }
else if (ExtractedMenuItems.Any()) else if (ExtractedMenuItems.Any())
{ {
<h4>Suggested Menu Items</h4> <h4>Menu Items</h4>
<div class="row"> <div class="row">
<div class="rz-p-sm-12"> <div class="rz-p-sm-12">
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Right">
@{
<RadzenButton Click="ToggleReorder">
@(allowReorder ? "Done" : "Reorder")
</RadzenButton>
}
<RadzenPanel AllowCollapse="true" class="rz-my-10 rz-mx-auto" Style="width: 100%" </RadzenStack>
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))> @if(allowReorder)
<HeaderTemplate> {
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0"> <RadzenDataGrid @ref="dataGrid" TItem="MenuItem" RowSelect=@OnRowSelect AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.Advanced" AllowSorting="true" PageSize="20" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
<RadzenIcon Icon="account_box" class="rz-me-1" /><b>Orders</b> Data="@menuItems" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"
</RadzenText> @bind-Value=@selectedMenuItems RowRender="@RowRender">
</HeaderTemplate> <Columns>
<ChildContent> <RadzenDataGridColumn Property="@nameof(MenuItem.SortOrder)" Title="Sort order" Width="30px" />
<RadzenCard class="rz-mt-4"> @* <RadzenDataGridColumn Property="@nameof(MenuItem.Id)" Filterable="false" Title="ID" Frozen="true" Width="55px" TextAlign="TextAlign.Center" /> *@
<RadzenDataList PageSize="1" WrapItems="true" AllowPaging="true" <RadzenDataGridColumn Property="@nameof(MenuItem.Name)" Title="Name" Frozen="true" Width="130px" />
Data="@ExtractedMenuItems" TItem="MenuItemModel"> @* <RadzenDataGridColumn Property="@nameof(MenuItem.PointId)" Title="Point Id" Width="200px" /> *@
<Template Context="item"> <RadzenDataGridColumn Property="@nameof(MenuItem.ShowInMainMenu)" Title="Show in menu" Width="30px" />
<RadzenCard Style="width: 100%"> </Columns>
<h3>@item.Name</h3> </RadzenDataGrid>
<hr style="border: none; background-color: var(--rz-text-disabled-color); height: 1px; margin: 1rem 0;" /> }
@{ else
if (MenuItemsSaved) {
{ <RadzenAccordion Multiple="true">
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Gap="1rem"> <Items>
@foreach (var item in ExtractedMenuItems)
<input @bind="item.Name" class="form-control border-0" placeholder="Menu item name" /> {
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" /> <RadzenAccordionItem Text="@item.MenuItem.Name" Icon="account_balance_wallet">
</RadzenStack> @{
} if (MenuItemsSaved)
<RadzenStack Orientation="@Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Center" AlignItems="@AlignItems.Center" Wrap="@FlexWrap.Wrap" Style="height: fit-content"> {
<input @bind="item.MenuItem.Name" class="form-control border-0" placeholder="Menu item name" />
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button> <MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
</RadzenStack>
} }
<div class="card-footer">
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
</RadzenCard> <button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
</Template> </div>
</RadzenDataList>
</RadzenCard>
</ChildContent>
<SummaryTemplate>
<RadzenCard class="rz-mt-4">
<b>@ExtractedMenuItems.Count() menu items</b>
</RadzenCard>
</SummaryTemplate>
</RadzenPanel>
@* <RadzenAccordion Multiple="true">
<Items>
@foreach (var item in ExtractedMenuItems)
{
<RadzenAccordionItem Text="@item.Name" Icon="account_balance_wallet">
@{
if (MenuItemsSaved)
{
<input @bind="item.Name" class="form-control border-0" placeholder="Menu item name" />
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
} }
<div class="card-footer"> </RadzenAccordionItem>
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
</div>
}
</RadzenAccordionItem>
} }
</Items>
</RadzenAccordion>
}
</Items>
</RadzenAccordion> *@
</div> </div>
@* @foreach (var item in menuItems) @* @foreach (var item in menuItems)
{ {
@ -121,7 +102,7 @@ else if (ExtractedMenuItems.Any())
</div> </div>
<button class="btn btn-success mt-3" @onclick="SaveMenuItems">Save All</button> <button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
} }
else if (!string.IsNullOrEmpty(ErrorMessage)) else if (!string.IsNullOrEmpty(ErrorMessage))
{ {
@ -137,11 +118,20 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
private bool IsLoading = false; private bool IsLoading = false;
private string? ErrorMessage; private string? ErrorMessage;
private bool MenuItemsSaved = false; private bool MenuItemsSaved = false;
ObservableCollection<MenuItem> menuItems;
IList<MenuItem> selectedMenuItems;
private string subject; private string subject;
private string document; private string document;
private bool hasCollection; private bool hasCollection;
private List<MenuItemModel> ExtractedMenuItems = new(); private List<MenuItemModel> ExtractedMenuItems = new();
private bool allowReorder = false;
private RadzenDataGrid<MenuItem> dataGrid;
MenuItem draggedItem;
MenuItemModel SelectedMenuItemModel = new("");
void Change(string text) void Change(string text)
{ {
Console.Write($"{text}"); Console.Write($"{text}");
@ -150,7 +140,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
//get menu items from DB //get menu items from DB
List<MenuItem> Site = await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId); menuItems = new ObservableCollection<MenuItem>((await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).OrderBy(x => x.SortOrder));
var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId); var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId);
if (!string.IsNullOrEmpty(collectionResult)) if (!string.IsNullOrEmpty(collectionResult))
{ {
@ -158,13 +148,13 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
hasCollection = true; hasCollection = true;
Console.Write("Has collection already"); Console.Write("Has collection already");
} }
if (Site.Count() > 0) if (menuItems.Count() > 0)
{ {
foreach (var menuItem in Site) foreach (var menuItem in menuItems)
{ {
string content; string content;
MenuItemModel model = new MenuItemModel(); MenuItemModel model = new MenuItemModel("");
//try to get content from qDrant //try to get content from qDrant
if (menuItem.QdrantPointId != null) if (menuItem.QdrantPointId != null)
{ {
@ -177,8 +167,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
} }
} }
model.Name = menuItem.Name; model.MenuItem = menuItem;
ExtractedMenuItems.Add(model); ExtractedMenuItems.Add(model);
// UpdateMenuItem(model); // UpdateMenuItem(model);
} }
@ -219,7 +208,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
{ {
var prompt2 = $"Analyze the following text and based on the sections suggest a list of menu items for a website. Do not attach any explanation. Text:\n\n`{document}`."; var prompt2 = $"Analyze the following text and based on the sections suggest a list of menu items for a website. Do not attach any explanation. Text:\n\n`{document}`.";
var response2 = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt2); var response2 = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt2);
ExtractedMenuItems = response2.Select(name => new MenuItemModel { Name = name }).ToList(); ExtractedMenuItems = response2.Select(name => new MenuItemModel(name)).ToList();
} }
// Send the content to ChatGPT // Send the content to ChatGPT
} }
@ -244,23 +233,25 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
IsLoading = true; IsLoading = true;
ErrorMessage = null; ErrorMessage = null;
ExtractedMenuItems.Add(new MenuItemModel { Name = "New menu item", Content = "" }); ExtractedMenuItems.Add(new MenuItemModel ("New menu item", "" ));
IsLoading = false; IsLoading = false;
} }
private void UpdateMenuItem(MenuItemModel updatedItem) private void UpdateMenuItem(MenuItemModel updatedItem)
{ {
var item = ExtractedMenuItems!.FirstOrDefault(i => i.Name == updatedItem.Name); var item = ExtractedMenuItems!.FirstOrDefault(i => i.MenuItem.Id == updatedItem.MenuItem.Id);
if (item != null) if (item != null)
{ {
//item.MenuItem.
item.Content = updatedItem.Content; item.Content = updatedItem.Content;
} }
} }
private async Task SaveMenuItems() private async Task SaveMenuItems(bool updateVectorDatabase)
{ {
var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, ExtractedMenuItems, subject, MenuItemsSaved); //bool valami = updateVectorDatabase;
var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, ExtractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
if (result == "OK") if (result == "OK")
{ {
MenuItemsSaved = true; MenuItemsSaved = true;
@ -271,4 +262,61 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
//Error //Error
} }
} }
void RowRender(RowRenderEventArgs<MenuItem> args)
{
if (allowReorder)
{
args.Attributes.Add("title", "Drag row to reorder");
args.Attributes.Add("style", "cursor:grab");
args.Attributes.Add("draggable", "true");
args.Attributes.Add("ondragover", "event.preventDefault();event.target.closest('.rz-data-row').classList.add('my-class')");
args.Attributes.Add("ondragleave", "event.target.closest('.rz-data-row').classList.remove('my-class')");
args.Attributes.Add("ondragstart", EventCallback.Factory.Create<DragEventArgs>(this, () => draggedItem = args.Data));
args.Attributes.Add("ondrop", EventCallback.Factory.Create<DragEventArgs>(this, () =>
{
var draggedIndex = menuItems.IndexOf(draggedItem);
MenuItemModel draggedExtractedMenuItem = ExtractedMenuItems[draggedIndex];
var droppedIndex = menuItems.IndexOf(args.Data);
menuItems.Remove(draggedItem);
menuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedItem);
ExtractedMenuItems.Remove(draggedExtractedMenuItem);
ExtractedMenuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedExtractedMenuItem);
foreach (var menuItemToReorder in menuItems)
{
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
}
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
{
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
}
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
}));
}
}
void Select(MenuItem menuItem)
{
SelectedMenuItemModel.MenuItem.Name = menuItem.Name;
SelectedMenuItemModel.Content = ExtractedMenuItems.Where(x => x.MenuItem.Name == menuItem.Name).FirstOrDefault().Content;
SelectedMenuItemModel.MenuItem.SortOrder = menuItem.SortOrder;
SelectedMenuItemModel.MenuItem.ShowInMainMenu = menuItem.ShowInMainMenu;
}
void OnRowSelect(MenuItem menuItem)
{
Select(menuItem);
}
async void ToggleReorder()
{
if(allowReorder)
{
await SaveMenuItems(false);
}
allowReorder = !allowReorder;
await InvokeAsync(StateHasChanged);
}
} }

View File

@ -2,9 +2,11 @@
@using BLAIzor.Services @using BLAIzor.Services
@using Newtonsoft.Json @using Newtonsoft.Json
@using BLAIzor.Components.Partials @using BLAIzor.Components.Partials
@using System.Collections.ObjectModel
@inject ContentEditorService ContentEditorService @inject ContentEditorService ContentEditorService
@inject HtmlSnippetProcessor HtmlSnippetProcessor @inject HtmlSnippetProcessor HtmlSnippetProcessor
@inject QDrantService QDrantService @inject QDrantService QDrantService
@inject IJSRuntime JSRuntime
<div> <div>
<label for="subject">Enter the subject of your website:</label> <label for="subject">Enter the subject of your website:</label>
@ -16,39 +18,68 @@
{ {
<p>Loading suggestions...</p> <p>Loading suggestions...</p>
} }
else if (menuItems.Any()) else if (extractedMenuItems.Any())
{ {
<h4>Suggested Menu Items</h4> <h4>Suggested Menu Items</h4>
<div class="row"> <div class="row">
<div class="rz-p-sm-12"> <div class="rz-p-sm-12">
<RadzenAccordion Multiple="true">
<Items> <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Right">
@foreach (var item in menuItems) @{
{ <RadzenButton Click="ToggleReorder">
<RadzenAccordionItem Text="@item.Name" Icon="account_balance_wallet"> @(allowReorder ? "Done" : "Reorder")
@{ </RadzenButton>
if (MenuItemsSaved) }
{
<input @bind="item.Name" class="form-control border-0" placeholder="Menu item name" /> </RadzenStack>
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" /> @if (allowReorder)
<div class="card-footer"> {
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button> <RadzenDataGrid @ref="dataGrid" TItem="MenuItem" RowSelect=@OnRowSelect AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.Advanced" AllowSorting="true" PageSize="20" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button> Data="@menuItems" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"
</div> @bind-Value=@selectedMenuItems RowRender="@RowRender">
<Columns>
<RadzenDataGridColumn Property="@nameof(MenuItem.SortOrder)" Title="Sort order" Width="30px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.Id)" Filterable="false" Title="ID" Frozen="true" Width="55px" TextAlign="TextAlign.Center" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.Name)" Title="Name" Frozen="true" Width="130px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.PointId)" Title="Point Id" Width="200px" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.ShowInMainMenu)" Title="Show in menu" Width="30px" />
</Columns>
</RadzenDataGrid>
}
else
{
<RadzenAccordion Multiple="true">
<Items>
@foreach (var item in extractedMenuItems)
{
<RadzenAccordionItem Text="@item.MenuItem.Name" Icon="account_balance_wallet">
@{
if (MenuItemsSaved)
{
<input @bind="item.MenuItem.Name" class="form-control border-0" placeholder="Menu item name" />
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
<div class="card-footer">
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
</div>
}
} }
} </RadzenAccordionItem>
</RadzenAccordionItem>
} }
</Items> </Items>
</RadzenAccordion> </RadzenAccordion>
}
</div> </div>
</div> </div>
<button class="btn btn-success mt-3" @onclick="SaveAllContent">Save All</button> <button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
} }
else if (!string.IsNullOrEmpty(errorMessage)) else if (!string.IsNullOrEmpty(errorMessage))
{ {
@ -61,15 +92,24 @@ else if (!string.IsNullOrEmpty(errorMessage))
[Parameter] [Parameter]
public string SessionId { get; set; } public string SessionId { get; set; }
private string subject = string.Empty; private string subject = string.Empty;
private List<MenuItemModel> menuItems = new();
ObservableCollection<MenuItem> menuItems;
IList<MenuItem> selectedMenuItems;
private List<MenuItemModel> extractedMenuItems = new();
private bool MenuItemsSaved = false; private bool MenuItemsSaved = false;
private bool isLoading = false; private bool isLoading = false;
private string? errorMessage; private string? errorMessage;
private bool hasCollection = false; private bool hasCollection = false;
private bool allowReorder = false;
private RadzenDataGrid<MenuItem> dataGrid;
MenuItem draggedItem;
MenuItemModel SelectedMenuItemModel = new("");
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
List<MenuItem> Site = await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId); menuItems = new ObservableCollection<MenuItem>((await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).OrderBy(x => x.SortOrder));
var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId); var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId);
if (!string.IsNullOrEmpty(collectionResult)) if (!string.IsNullOrEmpty(collectionResult))
{ {
@ -77,13 +117,13 @@ else if (!string.IsNullOrEmpty(errorMessage))
hasCollection = true; hasCollection = true;
Console.Write("Has collection already"); Console.Write("Has collection already");
} }
if (Site.Count() > 0) if (menuItems.Count() > 0)
{ {
foreach (var menuItem in Site) foreach (var menuItem in menuItems)
{ {
string content; string content;
MenuItemModel model = new MenuItemModel(); MenuItemModel model = new MenuItemModel("");
//try to get content from qDrant //try to get content from qDrant
if (menuItem.QdrantPointId != null) if (menuItem.QdrantPointId != null)
{ {
@ -97,9 +137,9 @@ else if (!string.IsNullOrEmpty(errorMessage))
} }
} }
model.Name = menuItem.Name; model.MenuItem = menuItem;
menuItems.Add(model); extractedMenuItems.Add(model);
// UpdateMenuItem(model); // UpdateMenuItem(model);
} }
MenuItemsSaved = true; MenuItemsSaved = true;
@ -122,7 +162,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
{ {
var prompt = $"Suggest a list of menu items for a website about: {subject}. Please do not attach any explanation."; var prompt = $"Suggest a list of menu items for a website about: {subject}. Please do not attach any explanation.";
var response = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt); var response = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt);
menuItems = response.Select(name => new MenuItemModel { Name = name }).ToList(); extractedMenuItems = response.Select(name => new MenuItemModel(name)).ToList();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -139,31 +179,32 @@ else if (!string.IsNullOrEmpty(errorMessage))
isLoading = true; isLoading = true;
errorMessage = null; errorMessage = null;
menuItems.Add(new()); extractedMenuItems.Add(new("New menu item"));
} }
private void RemoveMenuItem(MenuItemModel item) private void RemoveMenuItem(MenuItemModel item)
{ {
menuItems.Remove(item); extractedMenuItems.Remove(item);
} }
private void UpdateMenuItem(MenuItemModel updatedItem) private void UpdateMenuItem(MenuItemModel updatedItem)
{ {
Console.Write("Updating menu item"); Console.Write("Updating menu item");
var item = menuItems.FirstOrDefault(i => i.Name == updatedItem.Name); var item = extractedMenuItems.FirstOrDefault(i => i.MenuItem.Name == updatedItem.MenuItem.Name);
if (item != null) if (item != null)
{ {
item.Content = updatedItem.Content; item.Content = updatedItem.Content;
} }
else{ else
{
Console.Write("Not found"); Console.Write("Not found");
} }
} }
private async Task SaveAllContent() private async Task SaveMenuItems(bool updateVectorDatabase)
{ {
var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, menuItems, subject, MenuItemsSaved); var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, extractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
if (result == "OK") if (result == "OK")
{ {
MenuItemsSaved = true; MenuItemsSaved = true;
@ -176,4 +217,60 @@ else if (!string.IsNullOrEmpty(errorMessage))
} }
} }
void RowRender(RowRenderEventArgs<MenuItem> args)
{
if (allowReorder)
{
args.Attributes.Add("title", "Drag row to reorder");
args.Attributes.Add("style", "cursor:grab");
args.Attributes.Add("draggable", "true");
args.Attributes.Add("ondragover", "event.preventDefault();event.target.closest('.rz-data-row').classList.add('my-class')");
args.Attributes.Add("ondragleave", "event.target.closest('.rz-data-row').classList.remove('my-class')");
args.Attributes.Add("ondragstart", EventCallback.Factory.Create<DragEventArgs>(this, () => draggedItem = args.Data));
args.Attributes.Add("ondrop", EventCallback.Factory.Create<DragEventArgs>(this, () =>
{
var draggedIndex = menuItems.IndexOf(draggedItem);
MenuItemModel draggedExtractedMenuItem = extractedMenuItems[draggedIndex];
var droppedIndex = menuItems.IndexOf(args.Data);
menuItems.Remove(draggedItem);
menuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedItem);
extractedMenuItems.Remove(draggedExtractedMenuItem);
extractedMenuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedExtractedMenuItem);
foreach (var menuItemToReorder in menuItems)
{
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
}
foreach (var extractedMenuItemToReorder in extractedMenuItems)
{
extractedMenuItemToReorder.MenuItem.SortOrder = extractedMenuItems.IndexOf(extractedMenuItemToReorder);
}
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
}));
}
}
void Select(MenuItem menuItem)
{
SelectedMenuItemModel.MenuItem.Name = menuItem.Name;
SelectedMenuItemModel.Content = extractedMenuItems.Where(x => x.MenuItem.Name == menuItem.Name).FirstOrDefault().Content;
SelectedMenuItemModel.MenuItem.SortOrder = menuItem.SortOrder;
SelectedMenuItemModel.MenuItem.ShowInMainMenu = menuItem.ShowInMainMenu;
}
void OnRowSelect(MenuItem menuItem)
{
Select(menuItem);
}
async void ToggleReorder()
{
if (allowReorder)
{
await SaveMenuItems(false);
}
allowReorder = !allowReorder;
await InvokeAsync(StateHasChanged);
}
} }

View File

@ -35,7 +35,7 @@
[Parameter] public string Subject { get; set; } = string.Empty; [Parameter] public string Subject { get; set; } = string.Empty;
[Parameter] public string WordFile { get; set; } = string.Empty; [Parameter] public string WordFile { get; set; } = string.Empty;
[Parameter] public string SessionId { get; set; } = string.Empty; [Parameter] public string SessionId { get; set; } = string.Empty;
[Parameter] public MenuItemModel MenuItem { get; set; } = new(); [Parameter] public MenuItemModel MenuItem { get; set; } = new("");
[Parameter] public EventCallback<MenuItemModel> OnContentUpdated { get; set; } [Parameter] public EventCallback<MenuItemModel> OnContentUpdated { get; set; }
private bool IsLoading = false; private bool IsLoading = false;
@ -63,7 +63,7 @@
try try
{ {
Console.Write($"Subject: {Subject}"); Console.Write($"Subject: {Subject}");
var prompt = $"Generate website content for a page titled '{MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation."; var prompt = $"Generate website content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt); GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt);
MenuItem.Content = GeneratedContent; MenuItem.Content = GeneratedContent;
await OnContentUpdated.InvokeAsync(MenuItem); await OnContentUpdated.InvokeAsync(MenuItem);
@ -84,7 +84,7 @@
try try
{ {
Console.Write($"Subject: {Subject}"); Console.Write($"Subject: {Subject}");
var prompt = $"This is the provided text: {WordFile}. Look for the relevant content for a page titled '{MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation."; var prompt = $"This is the provided text: {WordFile}. Look for the relevant content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt); GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt);
MenuItem.Content = GeneratedContent; MenuItem.Content = GeneratedContent;
await OnContentUpdated.InvokeAsync(MenuItem); await OnContentUpdated.InvokeAsync(MenuItem);

View File

@ -29,7 +29,7 @@
{ {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" aria-current="page" @onclick="()=>MenuClicked(menu)">@menu</a> <a class="nav-link active" aria-current="page" @onclick="()=>MenuClickedAsync(menu)">@menu</a>
</li> </li>
} }
} }
@ -70,9 +70,10 @@
"Hungarian", "English", "German" "Hungarian", "English", "German"
}; };
public void MenuClicked(string menuName) public async Task MenuClickedAsync(string menuName)
{ {
OnMenuClicked?.Invoke(menuName); OnMenuClicked?.Invoke(menuName);
await JS.InvokeVoidAsync("collapseNavbar");
} }
public void HomeClick() public void HomeClick()
@ -102,34 +103,7 @@
MenuList = MenuString.Split(","); MenuList = MenuString.Split(",");
} }
await base.OnParametersSetAsync(); await base.OnParametersSetAsync();
} }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
// var subdomain = HttpContextAccessor.HttpContext?.Items["Subdomain"]?.ToString();
// var SiteInfo = await _scopedContentService.GetSiteInfoByNameAsync(subdomain);
// if (SiteInfo != null && SiteInfo.IsPublished)
// {
// SiteId = SiteInfo.Id;
// }
// else
// {
// SiteId = 1;
// }
// MenuString = await GetMenuList();
// if (MenuString != null)
// {
// MenuList = MenuString.Split(",");
// }
}
await base.OnAfterRenderAsync(firstRender);
}
public void OnLanguageSelected(ChangeEventArgs e) public void OnLanguageSelected(ChangeEventArgs e)
{ {
@ -140,19 +114,6 @@
Console.WriteLine($"Language selected: {SelectedLanguage}"); Console.WriteLine($"Language selected: {SelectedLanguage}");
_scopedContentService.SelectedLanguage = SelectedLanguage; _scopedContentService.SelectedLanguage = SelectedLanguage;
} }
} }
// private async Task<string> GetMenuList()
// {
// RenderCounter++;
// Console.Write($"\n \n Render:{RenderCounter} \n \n");
// List<MenuItem> menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId);
// string menuList = "";
// foreach (MenuItem item in menuItems)
// {
// menuList += item.Name + ",";
// }
// return menuList;
// }
} }

View File

@ -1,6 +1,25 @@
<video style="opacity:0.3; z-index: -1" autoplay muted loop id="myVideo" @key="SelectedBrandName"> <style>
<source src="@("/video/" + SelectedBrandName + ".mp4")" type="video/mp4"> .parent-element-to-video {
</video> overflow: hidden;
width: 120vw;
height: auto;
}
video {
position: fixed;
right: 0;
top: 0;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
</style>
<div class="parent-element-to-video">
<video style="opacity:0.3; z-index: -1" autoplay muted loop id="myVideo" @key="SelectedBrandName">
<source src="@("/video/" + SelectedBrandName + ".mp4")" type="video/mp4">
</video>
</div>
<script> <script>
$(document).ready(function () { $(document).ready(function () {

View File

@ -0,0 +1,610 @@
// <auto-generated />
using System;
using BLAIzor.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BLAIzor.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250429074005_FixSortOrder")]
partial class FixSortOrder
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("CssContent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("DesignTemplateId")
.HasColumnType("int");
b.Property<DateTime>("LastUpdated")
.HasColumnType("datetime2");
b.HasKey("Id");
b.HasIndex("DesignTemplateId")
.IsUnique();
b.ToTable("CssTemplates");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeprecated")
.HasColumnType("bit");
b.Property<bool>("IsPrivate")
.HasColumnType("bit");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("QDrandCollectionName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Tags")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplateName")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplatePhotoUrl")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("DesignTemplates");
b.HasData(
new
{
Id = 1,
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Description = "The default template",
IsDeprecated = false,
IsPrivate = false,
IsPublished = false,
QDrandCollectionName = "html_snippets",
Status = "Draft",
Tags = "system",
TemplateName = "Default Site",
TemplatePhotoUrl = "/images/default-logo.png",
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
Version = 1
});
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("JsonDefinition")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId", "Slug")
.IsUnique();
b.ToTable("FormDefinitions");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PointId")
.HasColumnType("int");
b.Property<Guid?>("QdrantPointId")
.HasColumnType("uniqueidentifier");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId");
b.ToTable("MenuItems");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("BrandLogoUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultColor")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("DomainUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("SiteName")
.HasColumnType("nvarchar(max)");
b.Property<int?>("TemplateId")
.HasColumnType("int");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("TemplateId");
b.HasIndex("UserId");
b.ToTable("SiteInfos");
b.HasData(
new
{
Id = 1,
BrandLogoUrl = "/images/default-logo.png",
DefaultColor = "#FFFFFF",
DefaultUrl = "https://ai.poppixel.cloud",
DomainUrl = "poppixel.cloud",
IsPublished = false,
SiteName = "Default Site",
TemplateId = 1,
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
b.HasData(
new
{
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
AccessFailedCount = 0,
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
Email = "adam.g@aycode.com",
EmailConfirmed = true,
LockoutEnabled = false,
NormalizedEmail = "ADAM.G@AYCODE.COM",
NormalizedUserName = "ADAM.G@AYCODE.COM",
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
PhoneNumberConfirmed = false,
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
TwoFactorEnabled = false,
UserName = "adam.g@aycode.com"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Name")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
.WithOne("CssTemplate")
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("DesignTemplate");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("FormDefinitions")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("MenuItems")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
.WithMany("Sites")
.HasForeignKey("TemplateId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Template");
b.Navigation("User");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Navigation("CssTemplate")
.IsRequired();
b.Navigation("Sites");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Navigation("FormDefinitions");
b.Navigation("MenuItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BLAIzor.Migrations
{
/// <inheritdoc />
public partial class FixSortOrder : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "PointId",
table: "MenuItems",
type: "int",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PointId",
table: "MenuItems");
}
}
}

View File

@ -0,0 +1,610 @@
// <auto-generated />
using System;
using BLAIzor.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BLAIzor.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250429121256_AddShowInMainMenu")]
partial class AddShowInMainMenu
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("CssContent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("DesignTemplateId")
.HasColumnType("int");
b.Property<DateTime>("LastUpdated")
.HasColumnType("datetime2");
b.HasKey("Id");
b.HasIndex("DesignTemplateId")
.IsUnique();
b.ToTable("CssTemplates");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeprecated")
.HasColumnType("bit");
b.Property<bool>("IsPrivate")
.HasColumnType("bit");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("QDrandCollectionName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Tags")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplateName")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplatePhotoUrl")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("DesignTemplates");
b.HasData(
new
{
Id = 1,
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Description = "The default template",
IsDeprecated = false,
IsPrivate = false,
IsPublished = false,
QDrandCollectionName = "html_snippets",
Status = "Draft",
Tags = "system",
TemplateName = "Default Site",
TemplatePhotoUrl = "/images/default-logo.png",
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
Version = 1
});
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("JsonDefinition")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId", "Slug")
.IsUnique();
b.ToTable("FormDefinitions");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PointId")
.HasColumnType("int");
b.Property<Guid?>("QdrantPointId")
.HasColumnType("uniqueidentifier");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId");
b.ToTable("MenuItems");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("BrandLogoUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultColor")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("DomainUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("SiteName")
.HasColumnType("nvarchar(max)");
b.Property<int?>("TemplateId")
.HasColumnType("int");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("TemplateId");
b.HasIndex("UserId");
b.ToTable("SiteInfos");
b.HasData(
new
{
Id = 1,
BrandLogoUrl = "/images/default-logo.png",
DefaultColor = "#FFFFFF",
DefaultUrl = "https://ai.poppixel.cloud",
DomainUrl = "poppixel.cloud",
IsPublished = false,
SiteName = "Default Site",
TemplateId = 1,
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
b.HasData(
new
{
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
AccessFailedCount = 0,
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
Email = "adam.g@aycode.com",
EmailConfirmed = true,
LockoutEnabled = false,
NormalizedEmail = "ADAM.G@AYCODE.COM",
NormalizedUserName = "ADAM.G@AYCODE.COM",
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
PhoneNumberConfirmed = false,
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
TwoFactorEnabled = false,
UserName = "adam.g@aycode.com"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Name")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
.WithOne("CssTemplate")
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("DesignTemplate");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("FormDefinitions")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("MenuItems")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
.WithMany("Sites")
.HasForeignKey("TemplateId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Template");
b.Navigation("User");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Navigation("CssTemplate")
.IsRequired();
b.Navigation("Sites");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Navigation("FormDefinitions");
b.Navigation("MenuItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BLAIzor.Migrations
{
/// <inheritdoc />
public partial class AddShowInMainMenu : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -0,0 +1,613 @@
// <auto-generated />
using System;
using BLAIzor.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BLAIzor.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250429121857_FixingWrongMigrations")]
partial class FixingWrongMigrations
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("CssContent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("DesignTemplateId")
.HasColumnType("int");
b.Property<DateTime>("LastUpdated")
.HasColumnType("datetime2");
b.HasKey("Id");
b.HasIndex("DesignTemplateId")
.IsUnique();
b.ToTable("CssTemplates");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeprecated")
.HasColumnType("bit");
b.Property<bool>("IsPrivate")
.HasColumnType("bit");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("QDrandCollectionName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Tags")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplateName")
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplatePhotoUrl")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("DesignTemplates");
b.HasData(
new
{
Id = 1,
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Description = "The default template",
IsDeprecated = false,
IsPrivate = false,
IsPublished = false,
QDrandCollectionName = "html_snippets",
Status = "Draft",
Tags = "system",
TemplateName = "Default Site",
TemplatePhotoUrl = "/images/default-logo.png",
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
Version = 1
});
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("JsonDefinition")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId", "Slug")
.IsUnique();
b.ToTable("FormDefinitions");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PointId")
.HasColumnType("int");
b.Property<Guid?>("QdrantPointId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("ShowInMainMenu")
.HasColumnType("bit");
b.Property<int>("SiteInfoId")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SiteInfoId");
b.ToTable("MenuItems");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("BrandLogoUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultColor")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("DomainUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsPublished")
.HasColumnType("bit");
b.Property<string>("SiteName")
.HasColumnType("nvarchar(max)");
b.Property<int?>("TemplateId")
.HasColumnType("int");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("TemplateId");
b.HasIndex("UserId");
b.ToTable("SiteInfos");
b.HasData(
new
{
Id = 1,
BrandLogoUrl = "/images/default-logo.png",
DefaultColor = "#FFFFFF",
DefaultUrl = "https://ai.poppixel.cloud",
DomainUrl = "poppixel.cloud",
IsPublished = false,
SiteName = "Default Site",
TemplateId = 1,
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
b.HasData(
new
{
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
AccessFailedCount = 0,
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
Email = "adam.g@aycode.com",
EmailConfirmed = true,
LockoutEnabled = false,
NormalizedEmail = "ADAM.G@AYCODE.COM",
NormalizedUserName = "ADAM.G@AYCODE.COM",
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
PhoneNumberConfirmed = false,
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
TwoFactorEnabled = false,
UserName = "adam.g@aycode.com"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Name")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
.WithOne("CssTemplate")
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("DesignTemplate");
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("FormDefinitions")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
{
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
.WithMany("MenuItems")
.HasForeignKey("SiteInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SiteInfo");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
.WithMany("Sites")
.HasForeignKey("TemplateId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Template");
b.Navigation("User");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
{
b.Navigation("CssTemplate")
.IsRequired();
b.Navigation("Sites");
});
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
{
b.Navigation("FormDefinitions");
b.Navigation("MenuItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BLAIzor.Migrations
{
/// <inheritdoc />
public partial class FixingWrongMigrations : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "ShowInMainMenu",
table: "MenuItems",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ShowInMainMenu",
table: "MenuItems");
}
}
}

View File

@ -177,9 +177,15 @@ namespace BLAIzor.Migrations
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<int>("PointId")
.HasColumnType("int");
b.Property<Guid?>("QdrantPointId") b.Property<Guid?>("QdrantPointId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<bool>("ShowInMainMenu")
.HasColumnType("bit");
b.Property<int>("SiteInfoId") b.Property<int>("SiteInfoId")
.HasColumnType("int"); .HasColumnType("int");

View File

@ -12,8 +12,11 @@ namespace BLAIzor.Models
[Required] [Required]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public int PointId { get; set; }
public int SortOrder { get; set; } public int SortOrder { get; set; }
public bool ShowInMainMenu { get; set; } = false;
public Guid? QdrantPointId { get; set; } public Guid? QdrantPointId { get; set; }
[ForeignKey("SiteInfo")] [ForeignKey("SiteInfo")]

View File

@ -5,7 +5,21 @@ namespace BLAIzor.Models
{ {
public class MenuItemModel public class MenuItemModel
{ {
public string Name { get; set; } = string.Empty; public MenuItem MenuItem { get; set; }
public string Content { get; set; } = string.Empty; public string Content { get; set; } = string.Empty;
public MenuItemModel(string name)
{
MenuItem = new MenuItem();
MenuItem.Name = name;
}
public MenuItemModel(string name, string content)
{
MenuItem = new MenuItem();
MenuItem.Name = name;
Content = content;
}
} }
} }

View File

@ -9,6 +9,9 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Radzen; using Radzen;
using Sidio.Sitemap.AspNetCore;
using Sidio.Sitemap.Blazor;
using Sidio.Sitemap.Core.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration; var configuration = builder.Configuration;
@ -46,7 +49,9 @@ builder.Services.AddScoped<ScopedContentService>();
builder.Services.AddScoped<QDrantService>(); builder.Services.AddScoped<QDrantService>();
builder.Services.AddScoped<OpenAIEmbeddingService>(); builder.Services.AddScoped<OpenAIEmbeddingService>();
builder.Services.AddScoped<HtmlSnippetProcessor>(); builder.Services.AddScoped<HtmlSnippetProcessor>();
builder.Services.AddHttpContextAccessor(); builder.Services
.AddHttpContextAccessor()
.AddDefaultSitemapServices<HttpContextBaseUrlProvider>();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>(); builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
builder.Services.AddScoped<CustomAuthenticationStateProvider>(); builder.Services.AddScoped<CustomAuthenticationStateProvider>();
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp")); builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
@ -86,5 +91,5 @@ app.MapRazorPages();
app.MapRazorComponents<App>() app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(); .AddInteractiveServerRenderMode();
app.UseMiddleware<SubdomainMiddleware>(); app.UseMiddleware<SubdomainMiddleware>();
app.UseSitemap();
app.Run(); app.Run();

View File

@ -222,48 +222,78 @@ namespace BLAIzor.Services
/// <param name="collectionName"></param> /// <param name="collectionName"></param>
/// <param name="menuList"></param> /// <param name="menuList"></param>
/// <returns></returns> /// <returns></returns>
public async Task ProcessContentRequest(string sessionId, string requestedMenuName, int siteId, int templateId, string collectionName, string menuList = "", bool forceUnmodified = false) public async Task ProcessContentRequest(string sessionId, MenuItem requestedMenu, int siteId, int templateId, string collectionName, string menuList = "", bool forceUnmodified = false)
{ {
Console.Write($"\n\n SessionId: {sessionId}\n\n"); Console.Write($"\n\n SessionId: {sessionId}\n\n");
//string rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "wwwroot/Documents/" + _contentService.SelectedDocument); //string rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "wwwroot/Documents/" + _contentService.SelectedDocument);
float[] vector = [];
OnStatusChangeReceived?.Invoke(sessionId, "Determining search vectors");
vector = await _openAIEmbeddingService.GenerateEmbeddingAsync(requestedMenuName);
OnStatusChangeReceived?.Invoke(sessionId, "Looking up content in the knowledge database");
var pointId = await _qDrantService.QueryContentAsync(siteId, vector, 1);
string extractedText = ""; string extractedText = "";
if (pointId.Length > 0)
{
foreach (var item in pointId) if (requestedMenu != null) {
string qDrantData = await _qDrantService.GetContentAsync(siteId, requestedMenu.PointId);
QDrantGetContentPointResult _selectedPoint = new QDrantGetContentPointResult();
if (qDrantData != null)
{ {
string qDrantData = await _qDrantService.GetContentAsync(siteId, item); _selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(qDrantData)!;
QDrantGetContentPointResult _selectedPoint = new QDrantGetContentPointResult();
if (qDrantData != null)
{
_selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(qDrantData)!;
}
extractedText += _selectedPoint.result.payload.name + ": " + _selectedPoint.result.payload.content + ", ";
} }
extractedText = _selectedPoint.result.payload.name + ": " + _selectedPoint.result.payload.content + ", ";
} }
else
{ string contentJson = await GetContentFromQuery(sessionId,
extractedText = "VECTOR ERROR: ZERO INFORMATION FOUND"; "Enhance this text if needed, making its style and grammar suitable to be displayed as the content of a webpage",
} extractedText,
forceUnmodified);
string contentJson = await GetContentFromQuery(sessionId,
"Enhance this text if needed, making its style and grammar suitable to be displayed as the content of a webpage",
extractedText,
forceUnmodified);
await ProcessContent(sessionId, contentJson, templateId, collectionName); await ProcessContent(sessionId, contentJson, templateId, collectionName);
} }
public async Task ProcessContentRequest(string sessionId, string requestedMenu, int siteId, int templateId, string collectionName, string menuList = "", bool forceUnmodified = false)
{
Console.Write($"\n\n SessionId: {sessionId}\n\n");
//string rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "wwwroot/Documents/" + _contentService.SelectedDocument);
string extractedText = "";
float[] vector = [];
OnStatusChangeReceived?.Invoke(sessionId, "Determining search vectors");
vector = await _openAIEmbeddingService.GenerateEmbeddingAsync(requestedMenu);
OnStatusChangeReceived?.Invoke(sessionId, "Looking up content in the knowledge database");
var pointId = await _qDrantService.QueryContentAsync(siteId, vector, 1);
if (pointId.Length > 0)
{
foreach (var item in pointId)
{
string qDrantData = await _qDrantService.GetContentAsync(siteId, item);
QDrantGetContentPointResult _selectedPoint = new QDrantGetContentPointResult();
if (qDrantData != null)
{
_selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(qDrantData)!;
}
extractedText += _selectedPoint.result.payload.name + ": " + _selectedPoint.result.payload.content + ", ";
}
}
else
{
extractedText = "VECTOR ERROR: ZERO INFORMATION FOUND";
}
string contentJson = await GetContentFromQuery(sessionId,
"Enhance this text if needed, making its style and grammar suitable to be displayed as the content of a webpage",
extractedText,
forceUnmodified);
await ProcessContent(sessionId, contentJson, templateId, collectionName);
}
// Refactored helper methods // Refactored helper methods
@ -441,8 +471,9 @@ namespace BLAIzor.Services
"Step 1: Start with defining above mentioned key topics of the initial document, and making the list of them. " + "Step 1: Start with defining above mentioned key topics of the initial document, and making the list of them. " +
"Step 2: After that add the above mentioned relevant image urls list." + "Step 2: After that add the above mentioned relevant image urls list." +
"Step 3: " + "Step 3: " +
"- Turn the following content into a nice informative webpage content. " + "- Turn the following content into a nice informative webpage content.\r\n " +
"- Structure it nicely without leaving out any information. " + "- Start with the page title.\r\n" +
"- Structure it nicely without leaving out any information.\r\n " +
"*** CONTENT START *** {" + extractedText + "} *** CONTENT END ***.\r\n" + "*** CONTENT START *** {" + extractedText + "} *** CONTENT END ***.\r\n" +
"**Style and Image Handling**:\r\n" + "**Style and Image Handling**:\r\n" +
"- Make sure the json is valid json." + "- Make sure the json is valid json." +
@ -840,7 +871,7 @@ namespace BLAIzor.Services
{ {
foreach (var vector in vectorsList) foreach (var vector in vectorsList)
{ {
var qDrantresult = await _qDrantService.QuerySnippetAsync(vector, 1, collectionName); var qDrantresult = await _qDrantService.QuerySnippetAsync(vector, 3, collectionName);
pointIds.Add(qDrantresult); pointIds.Add(qDrantresult);
} }
@ -978,7 +1009,8 @@ namespace BLAIzor.Services
"### Using Provided Snippets:\n" + "### Using Provided Snippets:\n" +
"- You have been given **multiple HTML snippets**:\n \n " + htmlToUse + ". \n \n **DO NOT merge them into one**.\n" + "- You have been given **multiple HTML snippets**:\n \n " + htmlToUse + ". \n \n **DO NOT merge them into one**.\n" +
"- Use each snippet **as a separate section** inside its own `div.row`.\n" + "- Use each snippet **as a separate section** inside its own `div.row`.\n" +
"- Maintain their order and **DO NOT omit any snippet**.\n" + "- Using the snippets is NOT mandatory, use them only if you identified content that fits in a specific snippet.\n" +
//"- Maintain their order and **DO NOT omit any snippet**.\n" +
"- Example structure:\n\n" + "- Example structure:\n\n" +
" ```html\n" + " ```html\n" +
" <div class='container'>\n" + " <div class='container'>\n" +
@ -1018,8 +1050,8 @@ namespace BLAIzor.Services
"### Generating Topic Buttons:\n" + "### Generating Topic Buttons:\n" +
"Start this section with a title `Related` " + "Start this section with a title `Related` " +
"- Create a **separate button** for each topic.\n" + "- Create a **separate button** for each topic.\n" +
$"- Make sure the topics are in {_scopedContentService.SelectedLanguage}, if not, translate them." + $"- Make sure the topics are in {_scopedContentService.SelectedLanguage}, if not, translate the name of them." +
"- Each button should use `btn btn-primary` and call `callAI('{topicName}')` on click.\n" + "- Each button should use `btn btn-primary` and call `callAI('{original_non_translated_topicName}')` on click.\n" +
"- List of topics:\n" + "- List of topics:\n" +
" " + string.Join(", ", topics) + "\n\n" + " " + string.Join(", ", topics) + "\n\n" +
"- Example:\n" + "- Example:\n" +

View File

@ -115,6 +115,8 @@ namespace BLAIzor.Services
existingMenuItem.Name = menuItem.Name; existingMenuItem.Name = menuItem.Name;
existingMenuItem.QdrantPointId = menuItem.QdrantPointId; existingMenuItem.QdrantPointId = menuItem.QdrantPointId;
existingMenuItem.SortOrder = menuItem.SortOrder;
existingMenuItem.ShowInMainMenu = menuItem.ShowInMainMenu;
_context.MenuItems.Update(existingMenuItem); _context.MenuItems.Update(existingMenuItem);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
@ -146,7 +148,7 @@ namespace BLAIzor.Services
} }
public async Task<string> ProcessMenuItems(int SiteId, bool hasCollection, List<MenuItemModel> ExtractedMenuItems, string subject, bool menuItemsSaved) public async Task<string> ProcessMenuItems(int SiteId, bool hasCollection, List<MenuItemModel> ExtractedMenuItems, string subject, bool menuItemsSaved, bool updateVectorDatabase)
{ {
try try
{ {
@ -163,42 +165,54 @@ namespace BLAIzor.Services
for (int i = 0; i < ExtractedMenuItems.Count(); i++) for (int i = 0; i < ExtractedMenuItems.Count(); i++)
{ {
MenuItem menuItem = new MenuItem(); MenuItem menuItem = new MenuItem();
if (!string.IsNullOrEmpty(ExtractedMenuItems[i].Content)) if (!string.IsNullOrEmpty(ExtractedMenuItems[i].Content)) //if we have content in the menuItem, let's update the vector DB
{ {
Guid guid = Guid.NewGuid(); if(updateVectorDatabase)
WebPageContent content = new WebPageContent(); {
content.Id = i; Guid guid = Guid.NewGuid();
content.UId = guid.ToString(); WebPageContent content = new WebPageContent();
content.Type = "page"; content.Id = i;
content.SiteId = SiteId; content.UId = guid.ToString();
content.Name = ExtractedMenuItems[i].Name; content.Type = "page";
content.Description = $"A section called {ExtractedMenuItems[i].Name} of a website of {subject}"; content.SiteId = SiteId;
content.Content = ExtractedMenuItems[i].Content; content.Name = ExtractedMenuItems[i].MenuItem.Name;
content.LastUpdated = DateTime.UtcNow; content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
content.Content = ExtractedMenuItems[i].Content;
content.LastUpdated = DateTime.UtcNow;
menuItem.QdrantPointId = guid; menuItem.QdrantPointId = guid;
await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(i, content, SiteId); await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(i, content, SiteId);
}
else
{
menuItem.QdrantPointId = ExtractedMenuItems[i].MenuItem.QdrantPointId;
}
} }
if (!menuItemsSaved) if (!menuItemsSaved) //menuItems just extracted, no content yet because that can be generated only after menuItems have been saved first
{ {
menuItem.Name = ExtractedMenuItems[i].Name; menuItem.Name = ExtractedMenuItems[i].MenuItem.Name;
menuItem.SortOrder = i; menuItem.SortOrder = i;
menuItem.SiteInfoId = SiteId; menuItem.SiteInfoId = SiteId;
menuItem.ShowInMainMenu = true;
await AddMenuItemAsync(menuItem); await AddMenuItemAsync(menuItem);
} }
else else //menuItems available already
{ {
var menuItems = await GetMenuItemsBySiteIdAsync(SiteId); var menuItems = await GetMenuItemsBySiteIdAsync(SiteId);
var thisItem = menuItems.FirstOrDefault(x => x.SiteInfoId == SiteId && x.Name == ExtractedMenuItems[i].Name); var thisItem = menuItems.FirstOrDefault(x => x.SiteInfoId == SiteId && x.Id == ExtractedMenuItems[i].MenuItem.Id);
if (thisItem == null) if (thisItem == null)
{ {
//new menu item? //new menu item?
await AddMenuItemAsync(menuItem);
} }
else else
{ {
thisItem.QdrantPointId = menuItem.QdrantPointId; thisItem.QdrantPointId = menuItem.QdrantPointId;
thisItem.SortOrder = ExtractedMenuItems[i].MenuItem.SortOrder;
thisItem.ShowInMainMenu = ExtractedMenuItems[i].MenuItem.ShowInMainMenu;
await UpdateMenuItemAsync(thisItem); await UpdateMenuItemAsync(thisItem);
} }
} }

View File

@ -25,28 +25,32 @@ namespace BLAIzor.Services
private string GetApiKey() => private string GetApiKey() =>
_configuration?.GetSection("OpenAI")?.GetValue<string>("ApiKey") ?? string.Empty; _configuration?.GetSection("OpenAI")?.GetValue<string>("ApiKey") ?? string.Empty;
private string GetModelName() =>
_configuration?.GetSection("OpenAI")?.GetValue<string>("Model") ?? string.Empty;
public void RegisterCallback(Action<string, string> callback, Action<string> onCompleteCallback, Action<string, string> onErrorCallback) public void RegisterCallback(Action<string, string> callback, Action<string> onCompleteCallback, Action<string, string> onErrorCallback)
{ {
_callback = callback; _callback = callback;
_onComplete = onCompleteCallback; _onComplete = onCompleteCallback;
_onError = onErrorCallback; _onError = onErrorCallback;
} }
public async Task<string> GetSimpleChatGPTResponse(string sessionId, string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1) public async Task<string> GetSimpleChatGPTResponse(string sessionId, string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1)
{ {
string modelName = ""; string modelName = GetModelName();
if (mode >= 0) //string modelName = "";
{ //if (mode >= 0)
if (mode == 0) //{
{ // if (mode == 0)
modelName = "gpt-4o"; // {
} // modelName = "gpt-4o";
} // }
else //}
{ //else
modelName = "gpt-4o-mini"; //{
} // modelName = "gpt-4o-mini";
//}
var requestBody = new ChatGPTRequest var requestBody = new ChatGPTRequest
{ {
@ -89,18 +93,19 @@ namespace BLAIzor.Services
public async Task<string> GetSimpleChatGPTResponseNoSession(string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1) public async Task<string> GetSimpleChatGPTResponseNoSession(string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1)
{ {
string modelName = ""; string modelName = GetModelName();
if (mode >= 0) //string modelName = "";
{ //if (mode >= 0)
if (mode == 0) //{
{ // if (mode == 0)
modelName = "gpt-4o"; // {
} // modelName = "gpt-4o";
} // }
else //}
{ //else
modelName = "gpt-4o-mini"; //{
} // modelName = "gpt-4o-mini";
//}
var requestBody = new ChatGPTRequest var requestBody = new ChatGPTRequest
{ {
@ -143,37 +148,38 @@ namespace BLAIzor.Services
public async Task<string> GetChatGPTStreamedResponse(string sessionId, string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1) public async Task<string> GetChatGPTStreamedResponse(string sessionId, string systemMessage, string userMessage, string? assistantMessage = null, int mode = -1)
{ {
string modelName = ""; string modelName = GetModelName();
if(mode >= 0) //string modelName = "";
{ //if(mode >= 0)
if(mode == 0) //{
{ // if(mode == 0)
modelName = "gpt-4o"; // {
} // modelName = "gpt-4o";
} // }
else //}
{ //else
modelName = "gpt-4o-mini"; //{
} // modelName = "gpt-4o-mini";
//}
var requestBody = new ChatGPTRequest var requestBody = new ChatGPTRequest
{ {
Model = modelName, Model = modelName,
Temperature = 0.2, Temperature = 0.2,
Messages = assistantMessage == null Messages = assistantMessage == null
? new[] ? new[]
{ {
new Message { Role = "system", Content = systemMessage }, new Message { Role = "system", Content = systemMessage },
new Message { Role = "user", Content = userMessage } new Message { Role = "user", Content = userMessage }
} }
: new[] : new[]
{ {
new Message { Role = "system", Content = systemMessage }, new Message { Role = "system", Content = systemMessage },
new Message { Role = "assistant", Content = assistantMessage }, new Message { Role = "assistant", Content = assistantMessage },
new Message { Role = "user", Content = userMessage } new Message { Role = "user", Content = userMessage }
}, },
Stream = true Stream = true
}; };
var requestJson = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions var requestJson = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
{ {

View File

@ -31,11 +31,16 @@
"ApiKey": "csk-3pwm3pjjrpcmmt6rm6k8f43n6rhh3h5pjn6jn9m9j4pyevrp", "ApiKey": "csk-3pwm3pjjrpcmmt6rm6k8f43n6rhh3h5pjn6jn9m9j4pyevrp",
"Model": "llama-3.3-70b" "Model": "llama-3.3-70b"
//"Model": "llama-4-scout-17b-16e-instruct" //"Model": "llama-4-scout-17b-16e-instruct"
//"Model": "qwen-3-32b"
//"Model": "llama3.1-8b"
}, },
"OpenAI": { "OpenAI": {
//"CredentialsPath": "D:\\GOOGLECREDENTIALS\\client_secret_359861037120-m3mjvr3kg51i2c2qb38dav62uuqoqs5k.apps.googleusercontent.com.json" //"CredentialsPath": "D:\\GOOGLECREDENTIALS\\client_secret_359861037120-m3mjvr3kg51i2c2qb38dav62uuqoqs5k.apps.googleusercontent.com.json"
"ApiKey": "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" "ApiKey": "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",
//"ApiKey": "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" //VG3Law //"ApiKey": "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" //VG3Law
//"Model": "gpt-4.1-mini"
//"Model": "gpt-4o-mini"
"Model": "gpt-4.1-nano"
}, },
"QDrant": { "QDrant": {
//"CredentialsPath": "D:\\GOOGLECREDENTIALS\\client_secret_359861037120-m3mjvr3kg51i2c2qb38dav62uuqoqs5k.apps.googleusercontent.com.json" //"CredentialsPath": "D:\\GOOGLECREDENTIALS\\client_secret_359861037120-m3mjvr3kg51i2c2qb38dav62uuqoqs5k.apps.googleusercontent.com.json"

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -56,7 +56,7 @@ h1 {
font-style: bold; font-style: bold;
padding-top: 30px; padding-top: 30px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.986rem; font-size: 2.488rem;
} }
h2 { h2 {
@ -66,7 +66,7 @@ h2 {
font-style: normal; font-style: normal;
padding-top: 15px; padding-top: 15px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.488rem; font-size: 2.288rem;
} }
h3 { h3 {
@ -82,6 +82,15 @@ h3 {
p { p {
color: #fff; color: #fff;
font-size: x-large; font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
} }
.btn-primary { .btn-primary {
@ -97,4 +106,39 @@ p {
.row { .row {
padding-bottom: 30px; padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
} }

View File

@ -1,23 +1,11 @@
/*@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');*/ @import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
@import url('https://fonts.googleapis.com/css?family=Comfortaa:400,700,300');
.rz-html-editor-content {
background-color: #00000033;
}
.form-group {
margin-bottom: 5px;
}
/*search*/ /*search*/
p {
font-size: large;
/*text-align: justify;*/
}
li { p {
list-style: none; font-size: x-large;
} }
label { label {
@ -31,22 +19,17 @@ label {
/* width: 98%; */ /* width: 98%; */
font-weight: bold; font-weight: bold;
border-radius: 20px; border-radius: 20px;
/*min-height: 50px;*/ min-height: 50px;
transition: all 0.2s ease; transition: all 0.2s ease;
padding: 10px; padding: 10px;
margin-top: 10px; margin-top: 10px;
} }
.btn:hover{
background: #e5b984;
color:#000000;
}
.menubtn { .menubtn {
background: rgba(255, 255, 255, 0.5); background: rgba(255, 255, 255, 0.5);
border: 0; border: 0;
color: #000000; color: #000000;
width: fit-content; /* width: 98%; */
font-weight: bold; font-weight: bold;
border-radius: 20px; border-radius: 20px;
height: 40px; height: 40px;
@ -243,6 +226,14 @@ input[type=search]::-webkit-search-cancel-button {
cursor: pointer; cursor: pointer;
} }
.btn:hover {
background: #441CFF;
}
.btn:focus {
background: #441CFF;
outline: 0;
}
/*card design*/ /*card design*/
/*bg*/ /*bg*/
@ -253,14 +244,14 @@ input[type=search]::-webkit-search-cancel-button {
} }
body { body {
font-family: 'Comfortaa', 'Arial Narrow', Arial, sans-serif;
/*font-family: 'Quicksand', sans-serif;*/ font-family: 'Quicksand', sans-serif;
margin: 0; margin: 0;
min-height: 100vh; min-height: 100vh;
background-color: #e493d0; background-color: #e6e6e6;
background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0)); /*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax; /*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax; /*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
background-repeat: no-repeat; background-repeat: no-repeat;
/*animation: 10s movement linear infinite;*/ /*animation: 10s movement linear infinite;*/
} }
@ -320,9 +311,9 @@ body {
background-color: rgba(255, 255, 255, 0.3); background-color: rgba(255, 255, 255, 0.3);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
padding: 10px; padding: 10px;
border-radius: 25px !important; border-radius: 10px;
border-width: 0px; border-width: 0px;
height: unset !important; height: unset !important;
} }
.mytextarea:active { .mytextarea:active {
@ -344,6 +335,7 @@ body {
.navbar-brand { .navbar-brand {
font-size: 1.7rem; font-size: 1.7rem;
color: #000;
} }
.form-select { .form-select {
@ -370,10 +362,14 @@ body {
.form-control { .form-control {
background-color: rgba(255,255,255,0.4); background-color: rgba(255,255,255,0.4);
border-radius: 25px; border-radius: 5px;
height: 50px; height: 50px;
} }
.form-control::placholder {
color: #fff;
}
.contactform-close-overlay { .contactform-close-overlay {
position: relative; position: relative;
height: 10vh; height: 10vh;
@ -426,11 +422,6 @@ body {
min-width: 100%; min-width: 100%;
min-height: 100%; min-height: 100%;
} }
.form-select {
display: unset !important;
}
.navbar-collapse { .navbar-collapse {
height: 100vh; height: 100vh;
/*display: flex; /*display: flex;
@ -438,7 +429,6 @@ body {
justify-content: center;*/ justify-content: center;*/
text-align: center !important; text-align: center !important;
align-content: center; align-content: center;
overflow-y: scroll;
} }
.navbar-collapse .nav-link { .navbar-collapse .nav-link {
@ -447,12 +437,12 @@ body {
} }
.navbar-collapse .nav-item:not(:last-child) { .navbar-collapse .nav-item:not(:last-child) {
border-bottom: 1px solid gray; border-bottom: 0px solid white;
padding: 0.2em 4em; padding: 0.2em 4em;
} }
.navbar { .navbar {
background-color: #ffffff; background-color: #fff;
color: #000; color: #000;
} }
@ -460,10 +450,6 @@ body {
color: #000; color: #000;
} }
.voicebutton {
width: 42.5px;
}
.content { .content {
top: 60px; top: 60px;
} }

View File

@ -483,4 +483,8 @@ body {
.content { .content {
top: 60px; top: 60px;
}
.row {
margin-bottom: 10px;
} }

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
margin: 5px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
margin: 5px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
margin: 5px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -483,4 +483,8 @@ body {
.content { .content {
top: 60px; top: 60px;
}
.row {
margin-bottom: 10px;
} }

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -1,5 +1,10 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table { .table {
color: #f2d8bb !important; color: #f2d8bb !important;
} }
@ -56,7 +61,7 @@ h1 {
font-style: bold; font-style: bold;
padding-top: 30px; padding-top: 30px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.986rem; font-size: 2.488rem;
} }
h2 { h2 {
@ -66,7 +71,7 @@ h2 {
font-style: normal; font-style: normal;
padding-top: 15px; padding-top: 15px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.488rem; font-size: 2.288rem;
} }
h3 { h3 {
@ -82,6 +87,15 @@ h3 {
p { p {
color: #fff; color: #fff;
font-size: x-large; font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
} }
.btn-primary { .btn-primary {
@ -93,8 +107,49 @@ p {
color: #fff; color: #fff;
background-color: #086262; background-color: #086262;
border: 0px; border: 0px;
margin: 5px;
} }
.row { .row {
padding-bottom: 30px; padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
} }

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

View File

@ -1,486 +0,0 @@
/*@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
@import url('https://fonts.googleapis.com/css?family=Comfortaa:400,700,300');*/
/*search*/
p {
font-size: x-large;
}
li {
list-style: none;
}
label {
color: #000;
/* display: none; */
}
.btn {
background: rgba(255, 255, 255, 0.5);
border: 0;
color: #000000;
width: fit-content;
font-weight: bold;
transition: all 0.2s ease;
margin: 15px;
}
.voicebutton {
border-radius: 50% !important;
padding: 10px !important;
width: 40px;
height:40px;
}
.menubtn {
background: rgba(255, 255, 255, 0.5);
border: 0;
color: #000000;
/* width: 98%; */
font-weight: bold;
border-radius: 20px;
height: 40px;
transition: all 0.2s ease;
padding: 10px;
margin: 10px;
}
.btn:active {
background: rgba(255, 255, 255, 1);
}
.btn:hover {
background: rgba(255, 255, 255, 0.8);
}
img {
border-radius: 20px !important;
}
input.search_bar{
border: none;
outline: none;
width: 75px;
border-radius: 55px;
margin: 0 auto;
font-size: 1.3em;
color: #0d2840;
padding: 15px 30px 15px 45px;
transition: all .3s cubic-bezier(0,0,.5,1.5);
box-shadow: 0 3px 10px -2px rgba(0,0,0,.1);
background: rgba(255, 255, 255, 0.3) url(https://i.imgur.com/seveWIw.png) no-repeat center center;
}
input.search_bar:focus{
width: 100%;
background-position: calc(100% - 35px) center
}
/*Removes default x in search fields (webkit only i guess)*/
input[type=search]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
/*Changes the color of the placeholder*/
::-webkit-input-placeholder {
color: #0d2840;
opacity: .5;
}
:-moz-placeholder {
color: #0d2840;
opacity: .5;
}
::-moz-placeholder {
color: #0d2840;
opacity: .5;
}
:-ms-input-placeholder {
color: #0d2840;
opacity: .5;
}
/*search*/
/*Search2*/
.searchBox {
width: 60px;
background: rgba(255, 255, 255, 0.3);
height: 60px;
border-radius: 40px;
padding: 10px;
margin: 0 auto;
transition: 0.8s;
}
.searchInput:active > .searchBox{
width:100%
}
.searchInput:focus > .searchBox {
width: 100%
}
.searchInput::placeholder {
color:#fff;
}
.searchBox:hover {
width: 100%;
}
.searchBox:hover > .searchInput {
width: calc(100% - 60px);
padding: 0 6px;
}
.searchBox:hover > .searchButton {
background: white;
color: #2f3640;
}
.searchButton {
color: white;
float: right;
width: 40px;
height: 40px;
border-radius: 50px;
background-color: #e493d0;
background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
background-repeat: no-repeat;
animation: 10s movement linear infinite;
display: flex;
justify-content: center;
align-items: center;
}
.searchInput {
border: none;
background: none;
outline: none;
font-size: 1.3em !important;
color: #0d2840 !important;
float: left;
padding: 0;
color: white;
font-size: 16px;
transition: 0.4s;
line-height: 40px;
width: 0px;
}
/*Search2*/
.event {
border-radius: 20px !important;
background-color: rgba(255, 255, 255, 0.2) !important;
backdrop-filter: blur(20px);
border: 0;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
transition: all 0.15s ease;
}
/*card design*/
.card {
border-radius: 20px !important;
overflow: hidden;
background-color: rgba(255, 255, 255, 0.2) !important;
backdrop-filter: blur(20px);
border: 0;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
transition: all 0.15s ease;
}
.card:hover {
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1), 0 10px 8px rgba(0, 0, 0, 0.015);
}
.card-body .card-title {
font-family: 'Lato', sans-serif;
font-weight: 700;
letter-spacing: 0.3px;
font-size: 24px;
color: #121212;
}
.card-text {
font-family: 'Lato', sans-serif;
font-weight: 400;
font-size: 15px;
letter-spacing: 0.3px;
color: #4E4E4E;
}
.card .container {
width: 88%;
/*background: #F0EEF8;*/
border-radius: 30px;
/*height: 140px;*/
display: flex;
align-items: center;
justify-content: center;
}
.container:hover > img {
transform: scale(1.2);
}
.container img {
/*padding: 75px;*/
/*margin-top: -40px;
margin-bottom: -40px;*/
transition: 0.4s ease;
cursor: pointer;
}
.btn:hover {
background-color: #e493d0;
background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
background-repeat: no-repeat;
animation: 10s movement linear infinite;
}
.btn:focus {
background-color: #e493d0;
background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
background-repeat: no-repeat;
animation: 10s movement linear infinite;
}
/*card design*/
/*bg*/
:root {
font-size: 15px;
}
body {
/*font-family: 'Comfortaa', 'Arial Narrow', Arial, sans-serif;*/
/*font-family: 'Quicksand', sans-serif;*/
color: #fff !important;
margin: 0;
min-height: 100vh;
background-color: #000;
/*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
/*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
/*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
background-repeat: no-repeat;
/*animation: 10s movement linear infinite;*/
}
body::after {
content: '';
display: block;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.myspan {
position: relative;
z-index: 10;
display: flex;
min-height: 100vh;
width: 100%;
justify-content: center;
align-items: center;
font-size: 5rem;
color: transparent;
text-shadow: 0px 0px 1px rgba(255, 255, 255, .6), 0px 4px 4px rgba(0, 0, 0, .05);
letter-spacing: .2rem;
}
@keyframes movement {
0%, 100% {
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
}
25% {
background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax;
background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax;
}
50% {
background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax;
background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax;
}
75% {
background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax;
background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax;
}
}
/*bg*/
.mytextarea {
background-color: rgba(255, 255, 255, 0.3);
backdrop-filter: blur(20px);
padding: 10px;
border-radius: 10px;
border-width: 0px;
height: unset !important;
}
.mytextarea:active {
border-width: 0px;
}
.mytextarea:focus-visible {
background-color: rgba(255, 255, 255, 0.5);
border-width: 0px !important;
outline: -webkit-focus-ring-color auto 0px;
outline-color: transparent;
}
.navbar-toggler {
color: #fff;
}
.navbar-brand {
font-size: 1.7rem;
color:#fff;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.form-select > option {
background-color: rgba(255, 255, 255, 0.2)
}
.contactform-overlay {
position: fixed;
z-index: 100;
height: 100vh;
width: 100%;
padding: 100px;
top: 0px;
left: 0px;
/* padding-top: 10vh; */
backdrop-filter: blur(20px);
/* background-color: rgba(1, 1, 1, .4); */
}
.form-control {
background-color: rgba(255,255,255,0.4);
border-radius: 5px;
height: 50px;
}
.form-control::placeholder {
color:#fff;
}
.contactform-close-overlay {
position: relative;
height: 10vh;
}
.contactform-popup-content {
height: 80vh;
margin: 0px;
padding: 0px;
}
.contactform-popup-close {
position: relative;
height: 10vh;
z-index: 80;
}
.calendly-overlay {
position: absolute;
z-index: 100;
height: 100vh;
width: 100%;
top: 0px;
/* padding-top: 10vh; */
backdrop-filter: blur(20px);
/* background-color: rgba(1, 1, 1, .4); */
}
.calendly-close-overlay {
position: relative;
height: 10vh;
}
.calendly-popup-content {
height: 80vh;
margin: 0px;
padding: 0px;
}
.calendly-popup-close {
position: relative;
height: 10vh;
z-index: 80;
}
#myVideo {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
opacity: 0.2;
}
.table {
color: #fff !important;
padding-top: 10px;
padding-bottom: 10px;
background-color: transparent;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.5em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 4em;
}
.navbar {
background-color: #040206;
color: #fff;
}
.nav-link {
color: #fff !important;
}
.content {
top: 60px;
}

View File

@ -1,5 +1,10 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table { .table {
color: #f2d8bb !important; color: #f2d8bb !important;
} }
@ -56,7 +61,7 @@ h1 {
font-style: bold; font-style: bold;
padding-top: 30px; padding-top: 30px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.986rem; font-size: 2.488rem;
} }
h2 { h2 {
@ -66,7 +71,7 @@ h2 {
font-style: normal; font-style: normal;
padding-top: 15px; padding-top: 15px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.488rem; font-size: 2.288rem;
} }
h3 { h3 {
@ -82,6 +87,15 @@ h3 {
p { p {
color: #fff; color: #fff;
font-size: x-large; font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
} }
.btn-primary { .btn-primary {
@ -97,4 +111,44 @@ p {
.row { .row {
padding-bottom: 30px; padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
} }

View File

@ -483,4 +483,8 @@ body {
.content { .content {
top: 60px; top: 60px;
}
.row {
margin-bottom: 10px;
} }

View File

@ -1,5 +1,10 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table { .table {
color: #f2d8bb !important; color: #f2d8bb !important;
} }
@ -56,7 +61,7 @@ h1 {
font-style: bold; font-style: bold;
padding-top: 30px; padding-top: 30px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.986rem; font-size: 2.488rem;
} }
h2 { h2 {
@ -66,7 +71,7 @@ h2 {
font-style: normal; font-style: normal;
padding-top: 15px; padding-top: 15px;
padding-bottom: 10px; padding-bottom: 10px;
font-size: 2.488rem; font-size: 2.288rem;
} }
h3 { h3 {
@ -82,6 +87,15 @@ h3 {
p { p {
color: #fff; color: #fff;
font-size: x-large; font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
} }
.btn-primary { .btn-primary {
@ -97,4 +111,44 @@ p {
.row { .row {
padding-bottom: 30px; padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
} }

View File

@ -483,4 +483,8 @@ body {
.content { .content {
top: 60px; top: 60px;
}
.row {
margin-bottom: 10px;
} }

View File

@ -0,0 +1,160 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.card {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.table {
color: #f2d8bb !important;
}
.navbar-collapse {
height: 100vh;
/*display: flex;
align-items: center;
justify-content: center;*/
text-align: center !important;
align-content: center;
}
.navbar-collapse .nav-link {
font-size: 1.4em;
letter-spacing: 2px;
}
.navbar-collapse .nav-item:not(:last-child) {
border-bottom: 0px solid white;
padding: 0.2em 1em;
}
.navbar {
background-color: #022c28;
color: #d0eae9;
}
.nav-link {
color: #d0eae9 !important;
}
.content {
top: 60px;
}
body {
/*background-image: url('/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/ribi1_brighter.png') !important;*/
background-color: #022c28;
background-attachment: fixed;
background-position: center;
background-size: cover;
color: aqua;
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
}
h1 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 700;
font-style: bold;
padding-top: 30px;
padding-bottom: 10px;
font-size: 2.488rem;
}
h2 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
padding-top: 15px;
padding-bottom: 10px;
font-size: 2.288rem;
}
h3 {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
padding-top: 10px;
padding-bottom: 10px;
font-size: 2.074rem;
}
p {
color: #fff;
font-size: x-large;
text-align: justify;
text-justify: auto;
}
li {
color: #fff;
font-size: large;
text-align: center;
text-justify: auto;
}
.btn-primary {
color: #d0eae9;
background-color: #014d4e;
border: 0px;
margin: 5px;
}
.btn-primary:hover {
color: #fff;
background-color: #086262;
border: 0px;
}
.row {
padding-bottom: 30px;
}
.searchInput::placeholder {
color:#d0eae9;
}
#myVideo {
position: fixed;
right: 0;
top: -100px;
min-width: 100%;
min-height: 100%;
transform: translateX(calc((100% - 100vw) / 2));
}
.img-fluid {
max-height: 50vh;
width: auto;
border-radius: 5px;
}
.col {
align-items: center;
display: flex;
}
.form-select {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: unset !important;
color: #fff;
}
.list-group-item {
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(2px);
}
.bg-light {
background-color: rgba(255,255,255,0.3) !important;
backdrop-filter: blur(2px) !important;
}
.text-primary {
--bs-text-opacity: 1;
color: aqua;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

Binary file not shown.

85
wwwroot/vjs.html Normal file
View File

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<!-- Add this where you want AI responses to appear -->
<div id="aiResponseContainer" class="container my-4"></div>
<!-- Sticky Input Area -->
<style>
#aiStickyInputArea {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px;
background: #f8f9fa;
border-top: 1px solid #ccc;
display: flex;
z-index: 9999;
box-shadow: 0 -2px 5px rgba(0,0,0,0.05);
}
#aiUserInput {
flex: 1;
border: 1px solid #ced4da;
padding: 10px;
font-size: 16px;
border-radius: 4px;
margin-right: 8px;
}
#aiSendBtn {
background-color: #0d6efd;
color: white;
border: none;
padding: 10px 16px;
border-radius: 4px;
cursor: pointer;
}
</style>
<div id="aiStickyInputArea">
<input type="text" id="aiUserInput" placeholder="Ask something..." />
<button id="aiSendBtn">Send</button>
</div>
<script>
const input = document.getElementById('aiUserInput');
const sendBtn = document.getElementById('aiSendBtn');
const responseContainer = document.getElementById('aiResponseContainer');
sendBtn.onclick = async () => {
const msg = input.value.trim();
if (!msg) return;
input.value = '';
// Optional: Show loading state
const loadingDiv = document.createElement('div');
loadingDiv.innerHTML = `<div class="text-muted">⏳ Thinking...</div>`;
responseContainer.appendChild(loadingDiv);
responseContainer.scrollIntoView({ behavior: 'smooth', block: 'end' });
try {
const res = await fetch('https://your-backend.com/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: msg })
});
const data = await res.json(); // expecting { response: "<div class='card'>...</div>" }
// Replace loading div with the actual HTML response
loadingDiv.outerHTML = data.response || "<div class='text-danger'>❌ Error: No response from AI.</div>";
} catch (err) {
loadingDiv.outerHTML = "<div class='text-danger'>❌ Failed to contact server.</div>";
}
};
</script>
</body>
</html>