button clicks further development, admin area developments and fixes, snippet preview, create form
This commit is contained in:
parent
8bf5c1c787
commit
fb6283628f
|
|
@ -49,7 +49,7 @@
|
|||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||||
</div> *@
|
||||
|
||||
<article class="content container-fluid px-4 text-center">
|
||||
<article class="content container-fluid text-center">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
@using BLAIzor.Services
|
||||
@inherits LayoutComponentBase
|
||||
@inject ScopedContentService _scopedContentService;
|
||||
@inject NavigationManager _navigationManager;
|
||||
<!-- The video -->
|
||||
|
||||
<div class="page" style="z-index: 1">
|
||||
|
||||
<main>
|
||||
@* <div class="top-row px-4" style="z-index: 2">
|
||||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||||
</div> *@
|
||||
|
||||
<article class="content container-fluid text-center">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
An unhandled error has occurred.
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
var video = document.getElementById("myVideo");
|
||||
video.oncanplaythrough = function () {
|
||||
video.muted = true;
|
||||
video.play();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function setHtmlEditorSourceMode() {
|
||||
let retries = 10; // Max retries
|
||||
let interval = setInterval(() => {
|
||||
let sourceButton = document.querySelector('.rz-html-editor-button');
|
||||
if (sourceButton) {
|
||||
sourceButton.click();
|
||||
clearInterval(interval); // Stop checking once clicked
|
||||
}
|
||||
if (--retries === 0) {
|
||||
clearInterval(interval); // Stop trying after 10 attempts
|
||||
}
|
||||
}, 300); // Check every 300ms
|
||||
}
|
||||
</script>
|
||||
|
||||
@code{
|
||||
|
||||
public void HomeClick()
|
||||
{
|
||||
_navigationManager.Refresh(true);
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
@page "/createform/{SiteId:int}"
|
||||
@using System.IO
|
||||
@using BLAIzor.Models
|
||||
@using BLAIzor.Services
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using System.Text
|
||||
@using UglyToad.PdfPig
|
||||
@using BLAIzor.Components.Layout
|
||||
@attribute [Authorize]
|
||||
@layout AdminLayout
|
||||
@inject ContentEditorService ContentEditorService
|
||||
|
||||
<h3>Create a new from from pdf or word</h3>
|
||||
|
||||
<InputFile OnChange="HandleFileSelected" />
|
||||
|
||||
@if (ExtractedFields.Any())
|
||||
{
|
||||
<h5>Extracted Fields:</h5>
|
||||
<ul>
|
||||
@foreach (var field in ExtractedFields)
|
||||
{
|
||||
<li><strong>@field.GroupName:</strong> @field.Fields.Count (@(field.Repeatable?"Repeatable":"Non repeateble"))</li>
|
||||
}
|
||||
</ul>
|
||||
<div class="col-12">
|
||||
<FormDescriptionEditor Groups="@ExtractedFields" TitleString="Form preview" isEditing=true></FormDescriptionEditor>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int SiteId { get; set; }
|
||||
private string PdfText = string.Empty;
|
||||
private List<FormFieldGroup> ExtractedFields = new();
|
||||
|
||||
private async Task HandleFileSelected(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
if (file == null || !file.ContentType.Contains("pdf")) return;
|
||||
|
||||
var tempPath = Path.Combine(Path.GetTempPath(), file.Name);
|
||||
|
||||
await using (var stream = file.OpenReadStream())
|
||||
await using (var fileStream = File.Create(tempPath))
|
||||
{
|
||||
await stream.CopyToAsync(fileStream);
|
||||
}
|
||||
|
||||
PdfText = ExtractPdfText(tempPath);
|
||||
|
||||
// Call OpenAI to analyze and extract structured fields
|
||||
ExtractedFields = await CallAiForFieldExtraction(PdfText);
|
||||
}
|
||||
|
||||
private string ExtractPdfText(string filePath)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
using (var document = PdfDocument.Open(filePath))
|
||||
{
|
||||
foreach (var page in document.GetPages())
|
||||
{
|
||||
sb.AppendLine(page.Text);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private async Task<List<FormFieldGroup>> CallAiForFieldExtraction(string plainText)
|
||||
{
|
||||
var jsonResult = await ContentEditorService.AnalyzeGroupedFormFieldsFromText(plainText);
|
||||
Console.WriteLine($"📄 PDF form AI response: {jsonResult}");
|
||||
|
||||
try
|
||||
{
|
||||
var groups = System.Text.Json.JsonSerializer.Deserialize<List<FormFieldGroup>>(jsonResult, new System.Text.Json.JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
return groups ?? new List<FormFieldGroup>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Error parsing AI JSON: {ex.Message}");
|
||||
return new List<FormFieldGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -15,13 +15,7 @@
|
|||
|
||||
<h3>Edit Design Template</h3>
|
||||
|
||||
<HeadContent>
|
||||
@* <link rel="stylesheet" href="@(selectedBrandName+".css")" /> *@
|
||||
@if (!string.IsNullOrEmpty(currentCssTemplate.CssContent))
|
||||
{
|
||||
<style>@currentCssTemplate.CssContent</style>
|
||||
}
|
||||
</HeadContent>
|
||||
|
||||
|
||||
@if (isLoading)
|
||||
{
|
||||
|
|
@ -32,15 +26,21 @@ else
|
|||
<EditForm Model="currentTemplate" OnValidSubmit="SaveTemplate">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="row">
|
||||
<div class="form-group col-md-4">
|
||||
<label>Template Name</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplateName" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplateName" />
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label>Template photo url</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplatePhotoUrl" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template photo url</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplatePhotoUrl" />
|
||||
<div class="form-group col-md-4">
|
||||
<label>Tags (comma-separated)</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.Tags" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -48,26 +48,20 @@ else
|
|||
<InputTextArea class="form-control" @bind-Value="currentTemplate.Description" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags (comma-separated)</label>
|
||||
<InputText class="form-control" @bind-Value="currentTemplate.Tags" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>CSS Content</label>
|
||||
<RadzenHtmlEditor
|
||||
@bind-Value=@currentCssTemplate.CssContent
|
||||
style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)"
|
||||
Input=@OnInput
|
||||
Change=@OnChange
|
||||
Paste=@OnPaste
|
||||
UploadComplete=@OnUploadComplete
|
||||
Execute=@OnExecute
|
||||
UploadUrl="upload/image" >
|
||||
<RadzenHtmlEditor @bind-Value=@currentCssTemplate.CssContent
|
||||
style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)"
|
||||
Input=@OnInput
|
||||
Change=@OnChange
|
||||
Paste=@OnPaste
|
||||
UploadComplete=@OnUploadComplete
|
||||
Execute=@OnExecute
|
||||
UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
@* <InputTextArea class="form-control" @bind-Value="currentCssTemplate.CssContent" /> *@
|
||||
</div>
|
||||
|
||||
|
|
@ -78,18 +72,46 @@ else
|
|||
|
||||
<button class="btn btn-danger" @onclick="DeleteTemplate">Delete Template</button>
|
||||
|
||||
foreach(var snippet in SnippetList)
|
||||
{
|
||||
<TemplateSnippetEditor Snippet="snippet" OnContentUpdated="UpdateSnippet"></TemplateSnippetEditor>
|
||||
}
|
||||
<div class="rz-p-sm-12">
|
||||
<RadzenAccordion>
|
||||
<Items>
|
||||
|
||||
@{
|
||||
foreach (var snippet in SnippetList)
|
||||
{
|
||||
<RadzenAccordionItem Text="@snippet.Name" Icon="account_balance_wallet" CollapseTitle="Collapse snippet."
|
||||
ExpandTitle="Expand snippet." CollapseAriaLabel="Collapse the snippet details."
|
||||
ExpandAriaLabel="Expand the snippet details.">
|
||||
<TemplateSnippetEditor TemplateId="@TemplateId" Snippet="@snippet" OnContentUpdated="UpdateSnippet"></TemplateSnippetEditor>
|
||||
</RadzenAccordionItem>
|
||||
}
|
||||
}
|
||||
|
||||
</Items>
|
||||
</RadzenAccordion>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<button class="btn btn-primary mt-3" @onclick="AddSnippet">Add new html snippets</button>
|
||||
<button class="btn btn-success mt-3" @onclick="SaveSnippets">Save html snippets</button>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
<script>
|
||||
var sessionId = null;
|
||||
|
||||
function setSessionId(id) {
|
||||
sessionId = id;
|
||||
console.log("Session ID set:", sessionId);
|
||||
}
|
||||
</script>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int TemplateId { get; set; }
|
||||
|
|
@ -100,17 +122,27 @@ else
|
|||
private bool hasCss = false;
|
||||
private bool hasCollection = false;
|
||||
private List<HtmlSnippet> SnippetList = [];
|
||||
private string SessionId;
|
||||
private static readonly Dictionary<string, EditTemplate> _instances = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadTemplate();
|
||||
SessionId = Guid.NewGuid().ToString();
|
||||
_instances[SessionId] = this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("setSessionId", SessionId);
|
||||
await JSRuntime.InvokeVoidAsync("setHtmlEditorSourceMode");
|
||||
await LoadTemplate();
|
||||
var cssPath = await CssTemplateService.SaveTempCssFileAsync(currentCssTemplate.CssContent, SessionId);
|
||||
await JSRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,21 +155,21 @@ else
|
|||
currentCssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync(TemplateId);
|
||||
var currentCollection = await QDrantService.GetCollectionByNameAsync(currentTemplate.QDrandCollectionName);
|
||||
Console.Write(currentCollection);
|
||||
if(currentCssTemplate == null)
|
||||
if (currentCssTemplate == null)
|
||||
{
|
||||
hasCss = false;
|
||||
currentCssTemplate = new();
|
||||
currentCssTemplate.DesignTemplateId = TemplateId;
|
||||
currentCssTemplate.DesignTemplateId = TemplateId;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasCss = true;
|
||||
}
|
||||
if(!string.IsNullOrEmpty(currentCollection))
|
||||
if (!string.IsNullOrEmpty(currentCollection))
|
||||
{
|
||||
hasCollection = true;
|
||||
var collectionCount = await QDrantService.GetCollectionCount(currentTemplate.QDrandCollectionName);
|
||||
for(int i=1; i <= collectionCount; i++)
|
||||
for (int i = 1; i <= collectionCount; i++)
|
||||
{
|
||||
var snippet = await QDrantService.GetSnippetAsync(i, currentTemplate.QDrandCollectionName);
|
||||
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetPointResult>(snippet)!;
|
||||
|
|
@ -149,11 +181,12 @@ else
|
|||
}
|
||||
else
|
||||
{
|
||||
//let's create a collection
|
||||
//let's create a collection
|
||||
var result = QDrantService.CreateQdrantCollectionAsync(currentTemplate.QDrandCollectionName);
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task SaveTemplate()
|
||||
|
|
@ -161,7 +194,7 @@ else
|
|||
isLoading = true;
|
||||
currentCssTemplate.CssContent = currentCssTemplate.CssContent.Trim();
|
||||
|
||||
if(hasCss)
|
||||
if (hasCss)
|
||||
{
|
||||
// Update the CSS template content
|
||||
currentCssTemplate.LastUpdated = DateTime.UtcNow;
|
||||
|
|
@ -214,11 +247,11 @@ else
|
|||
private async Task SaveSnippets()
|
||||
{
|
||||
//I want to update all items without gaps in the ids always 1 to x
|
||||
for (int i=1; i<=SnippetList.Count(); i++)
|
||||
for (int i = 1; i <= SnippetList.Count(); i++)
|
||||
{
|
||||
SnippetList[i-1].Id = i;
|
||||
SnippetList[i - 1].Id = i;
|
||||
|
||||
}
|
||||
}
|
||||
await HtmlSnippetProcessor.ProcessAndStoreTemplateSnippetAsync(currentTemplate.QDrandCollectionName, SnippetList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
<input @oninput="(e) => UserInput = e.Value.ToString()"
|
||||
@onkeydown="@Enter" class="searchInput" type="text" name="" value="@UserInput" placeholder="Ask any question">
|
||||
<button class="searchButton border-0" @onclick="ProcessWordFile" href="#">
|
||||
<button class="searchButton border-0" @onclick="SendUserQuery" href="#">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -114,7 +114,7 @@
|
|||
|
||||
function callAI(inputString) {
|
||||
console.log(sessionId);
|
||||
DotNet.invokeMethodAsync('BLAIzor', 'CallCSharpMethod2', inputString, sessionId)
|
||||
DotNet.invokeMethodAsync('BLAIzor', 'CallCSharpMethod2', inputString, sessionId, false)
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@
|
|||
|
||||
public async void MenuClick(string menuName)
|
||||
{
|
||||
await CallCSharpMethod2(menuName, sessionId);
|
||||
await CallCSharpMethod2(menuName, sessionId, true);
|
||||
}
|
||||
|
||||
public void HomeClick()
|
||||
|
|
@ -333,7 +333,7 @@
|
|||
|
||||
|
||||
[JSInvokable("CallCSharpMethod2")]
|
||||
public static async Task CallCSharpMethod2(string input, string sessionId)
|
||||
public static async Task CallCSharpMethod2(string input, string sessionId, bool forceUnModified = false)
|
||||
{
|
||||
// if (myHome != null)
|
||||
// {
|
||||
|
|
@ -342,7 +342,7 @@
|
|||
|
||||
if (_instances.TryGetValue(sessionId, out var instance))
|
||||
{
|
||||
await instance.HandleJsCall("Please tell me more about: " + input, sessionId);
|
||||
await instance.HandleJsCall(input, sessionId, forceUnModified);
|
||||
}
|
||||
Console.Write("Button clicked:" + input);
|
||||
}
|
||||
|
|
@ -485,21 +485,21 @@
|
|||
UserInput = input;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await ProcessWordFile();
|
||||
await SendUserQuery();
|
||||
//UserInput = string.Empty;
|
||||
}
|
||||
|
||||
public async Task HandleJsCall(string input, string sessionId)
|
||||
public async Task HandleJsCall(string input, string sessionId, bool forceUnmodified)
|
||||
{
|
||||
HtmlContent.Clear();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
UserInput = input;
|
||||
await ProcessWordFile();
|
||||
await DisplayMenuContent(input, forceUnmodified);
|
||||
UserInput = string.Empty;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task ProcessWordFile()
|
||||
private async Task SendUserQuery()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(UserInput))
|
||||
{
|
||||
|
|
@ -510,6 +510,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DisplayMenuContent(string input, bool forceUnmodified)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(UserInput))
|
||||
{
|
||||
HtmlContent.Clear();
|
||||
var menu = await GetMenuList();
|
||||
await ChatGptService.ProcessContentRequest(sessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetMenuList()
|
||||
{
|
||||
List<MenuItem> menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,34 @@
|
|||
<button class="btn btn-primary" type="submit">Save</button>
|
||||
</EditForm>
|
||||
|
||||
<hr />
|
||||
<h4 class="mt-4">Forms linked to this site</h4>
|
||||
|
||||
@if (siteInfo.FormDefinitions?.Count > 0)
|
||||
{
|
||||
<ul class="list-group mb-3">
|
||||
@foreach (var form in siteInfo.FormDefinitions)
|
||||
{
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span>
|
||||
<strong>@form.Title</strong><br />
|
||||
<small class="text-muted">@form.CreatedAt.ToString("yyyy-MM-dd HH:mm")</small>
|
||||
</span>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="/form-editor/@form.Id">Edit</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-muted">No forms added yet.</p>
|
||||
}
|
||||
|
||||
<a class="btn btn-success" href="/createform/@SiteId">
|
||||
<i class="fas fa-plus-circle"></i> Add New Form
|
||||
</a>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int SiteId { get; set; }
|
||||
|
|
@ -55,7 +83,7 @@
|
|||
userId = CustomAuthProvider.GetUserId();
|
||||
userName = CustomAuthProvider.GetUserName();
|
||||
}
|
||||
siteInfo = await SiteInfoService.GetSiteInfoByIdAsync(SiteId) ?? new SiteInfo();
|
||||
siteInfo = await SiteInfoService.GetSiteInfoWithFormsByIdAsync(SiteId) ?? new SiteInfo();
|
||||
}
|
||||
|
||||
private async Task SaveSiteInfo()
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<input @oninput="(e) => UserInput = e.Value.ToString()"
|
||||
@onkeydown="@Enter" class="searchInput" type="text" name="" value="@UserInput" placeholder="Ask any question">
|
||||
<button class="searchButton border-0" @onclick="ProcessWordFile" href="#">
|
||||
<button class="searchButton border-0" @onclick="SendUserQuery" href="#">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -114,7 +114,7 @@
|
|||
|
||||
function callAI(inputString) {
|
||||
console.log(sessionId);
|
||||
DotNet.invokeMethodAsync('BLAIzor', 'CallCSharpMethod3', inputString, sessionId)
|
||||
DotNet.invokeMethodAsync('BLAIzor', 'CallCSharpMethod3', inputString, sessionId, false)
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
|
||||
public async void MenuClick(string menuName)
|
||||
{
|
||||
await CallCSharpMethod3(menuName, sessionId);
|
||||
await CallCSharpMethod3(menuName, sessionId, true);
|
||||
}
|
||||
|
||||
public void HomeClick()
|
||||
|
|
@ -284,12 +284,12 @@
|
|||
|
||||
|
||||
[JSInvokable("CallCSharpMethod3")]
|
||||
public static async Task CallCSharpMethod3(string input, string sessionId)
|
||||
public static async Task CallCSharpMethod3(string input, string sessionId, bool forceUnmodified)
|
||||
{
|
||||
|
||||
if (_instances.TryGetValue(sessionId, out var instance))
|
||||
{
|
||||
await instance.HandleJsCall("Please search for me: " + input, sessionId);
|
||||
await instance.HandleJsCall("Please search for me: " + input, sessionId, forceUnmodified);
|
||||
}
|
||||
Console.Write("Button clicked:" + input);
|
||||
}
|
||||
|
|
@ -471,22 +471,22 @@
|
|||
UserInput = input;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await ProcessWordFile();
|
||||
await SendUserQuery();
|
||||
//UserInput = string.Empty;
|
||||
}
|
||||
|
||||
public async Task HandleJsCall(string input, string sessionId)
|
||||
public async Task HandleJsCall(string input, string sessionId, bool forceUnmodified)
|
||||
{
|
||||
HtmlContent.Clear();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
UserInput = input;
|
||||
Console.Write($"\n\n Input: {input} \n\n");
|
||||
await ProcessWordFile();
|
||||
await DisplayMenuContent(input, forceUnmodified);
|
||||
UserInput = string.Empty;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task ProcessWordFile()
|
||||
private async Task SendUserQuery()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(UserInput))
|
||||
{
|
||||
|
|
@ -498,6 +498,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DisplayMenuContent(string input, bool forceUnmodified)
|
||||
{
|
||||
Console.WriteLine($"DisplayMenuContent 1: {input}");
|
||||
if (!string.IsNullOrEmpty(UserInput))
|
||||
{
|
||||
HtmlContent.Clear();
|
||||
var menu = await GetMenuList();
|
||||
await ChatGptService.ProcessContentRequest(sessionId, UserInput, siteid, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetMenuList()
|
||||
{
|
||||
List<MenuItem> menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(siteid);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
@page "/preview-snippet/{TemplateId:int}/{Snippet}"
|
||||
@using BLAIzor.Components.Layout
|
||||
@using BLAIzor.Models
|
||||
@using BLAIzor.Services
|
||||
@using Newtonsoft.Json
|
||||
@using BLAIzor.Components.Partials
|
||||
@attribute [Authorize]
|
||||
@layout PreviewLayout
|
||||
@inject DesignTemplateService DesignTemplateService
|
||||
@inject CssTemplateService CssTemplateService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject QDrantService QDrantService
|
||||
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
@((MarkupString)CurrentSnippet.SampleHtml)
|
||||
|
||||
<script>
|
||||
var sessionId = null;
|
||||
|
||||
function setSessionId(id) {
|
||||
sessionId = id;
|
||||
console.log("Session ID set:", sessionId);
|
||||
}
|
||||
</script>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int TemplateId { get; set; }
|
||||
[Parameter]
|
||||
public string Snippet { get; set; } = "";
|
||||
|
||||
|
||||
private bool isLoading = true;
|
||||
private DesignTemplate currentTemplate = new();
|
||||
private CssTemplate currentCssTemplate = new();
|
||||
private bool hasCss = false;
|
||||
private bool hasCollection = false;
|
||||
private List<HtmlSnippet> SnippetList = [];
|
||||
private HtmlSnippet CurrentSnippet = new();
|
||||
private string SessionId = "";
|
||||
private static readonly Dictionary<string, PreviewSnippet> _instances = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
SessionId = Guid.NewGuid().ToString();
|
||||
_instances[SessionId] = this;
|
||||
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("setSessionId", SessionId);
|
||||
await JSRuntime.InvokeVoidAsync("setHtmlEditorSourceMode");
|
||||
await LoadTemplate();
|
||||
var cssPath = await CssTemplateService.SaveTempCssFileAsync(currentCssTemplate.CssContent, SessionId);
|
||||
await JSRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadTemplate()
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
// Load the design template and its associated CSS template from the database
|
||||
currentTemplate = await DesignTemplateService.GetByIdAsync(TemplateId);
|
||||
currentCssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync(TemplateId);
|
||||
var currentCollection = await QDrantService.GetCollectionByNameAsync(currentTemplate.QDrandCollectionName);
|
||||
Console.Write(currentCollection);
|
||||
if(currentCssTemplate == null)
|
||||
{
|
||||
hasCss = false;
|
||||
currentCssTemplate = new();
|
||||
currentCssTemplate.DesignTemplateId = TemplateId;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasCss = true;
|
||||
}
|
||||
if(!string.IsNullOrEmpty(currentCollection))
|
||||
{
|
||||
hasCollection = true;
|
||||
var collectionCount = await QDrantService.GetCollectionCount(currentTemplate.QDrandCollectionName);
|
||||
for(int i=1; i <= collectionCount; i++)
|
||||
{
|
||||
var snippetItem = await QDrantService.GetSnippetAsync(i, currentTemplate.QDrandCollectionName);
|
||||
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetPointResult>(snippetItem)!;
|
||||
|
||||
|
||||
Console.Write($"Id: {selectedPoint.result.id}, html: {selectedPoint.result.payload.Html}");
|
||||
SnippetList.Add(selectedPoint.result.payload);
|
||||
}
|
||||
|
||||
CurrentSnippet = SnippetList.Where(x => x.Name == Snippet).FirstOrDefault();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//let's create a collection
|
||||
var result = QDrantService.CreateQdrantCollectionAsync(currentTemplate.QDrandCollectionName);
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
@using BLAIzor.Models
|
||||
@using Radzen
|
||||
|
||||
@if (isEditing)
|
||||
{
|
||||
<EditForm EditContext="@editContext" OnValidSubmit="@HandleValidSubmit">
|
||||
|
||||
|
||||
|
||||
<div class="card p-4">
|
||||
<h4 class="mb-3">@TitleString</h4>
|
||||
|
||||
@foreach (var group in Groups)
|
||||
{
|
||||
|
||||
<RadzenCard class="rz-p-3">
|
||||
|
||||
<h5 class="mt-4"> GROUP: @group.GroupName</h5>
|
||||
|
||||
@for (int entryIndex = 0; entryIndex < group.EntryCount; entryIndex++)
|
||||
{
|
||||
var entryPrefix = $"{group.GroupName}_{entryIndex}";
|
||||
<RadzenStack Orientation="Orientation.Vertical" Style="width: 100%" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Normal" AlignItems="@AlignItems.Start" Wrap="@FlexWrap.Wrap">
|
||||
@foreach (var field in group.Fields)
|
||||
{
|
||||
|
||||
var label = $"FIELD: {entryPrefix}_{field.Label}";
|
||||
<RadzenStack Orientation="Orientation.Vertical" Style="width: 100%" Gap="5px" Reverse="false" JustifyContent="@JustifyContent.Normal" AlignItems="@AlignItems.Normal" Wrap="@FlexWrap.Wrap">
|
||||
<RadzenStack Orientation="Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Center" AlignItems="@AlignItems.Center" Wrap="@FlexWrap.Wrap">
|
||||
<p>
|
||||
Field type: @field.Type
|
||||
</p>
|
||||
<p>Field label: @field.Label</p>
|
||||
</RadzenStack>
|
||||
|
||||
|
||||
<RadzenCard Variant="@Variant.Filled" class="rz-my-1 rz-mx-auto" Style="width: 100%">
|
||||
<p>Preview:</p>
|
||||
<RadzenStack Orientation="Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Normal" AlignItems="@AlignItems.Normal" Wrap="@FlexWrap.Wrap">
|
||||
<label class="form-label">@field.Label</label>
|
||||
|
||||
@switch (field.Type?.ToLower())
|
||||
{
|
||||
case "textarea":
|
||||
<RadzenTextArea Style="width:100%"
|
||||
Disabled=true
|
||||
Value="@GetValue(label)"
|
||||
Change="@(args => SetValue(label, args))" />
|
||||
break;
|
||||
|
||||
case "number":
|
||||
<RadzenNumeric TValue="int"
|
||||
Disabled=true
|
||||
Value="@(Convert.ToInt32(GetValue(label)))"
|
||||
Change="@(args => SetValue(label, args.ToString()))" />
|
||||
break;
|
||||
|
||||
case "date":
|
||||
<RadzenDatePicker TValue="DateTime?"
|
||||
Disabled=true
|
||||
Value="@GetDate(label)"
|
||||
Change="@(args => SetDate(label, args))" />
|
||||
break;
|
||||
|
||||
case "checkbox":
|
||||
<RadzenCheckBox TValue="bool"
|
||||
Disabled=true
|
||||
Value="@GetCheckboxValue(label)"
|
||||
Change="@(args => SetCheckboxValue(label, args))" />
|
||||
break;
|
||||
|
||||
case "radio":
|
||||
<RadzenRadioButtonList TValue="int"
|
||||
Disabled=true
|
||||
Value="@GetRadioValue(label)"
|
||||
Change="@(args => SetRadioValue(label, args))">
|
||||
<Items>
|
||||
@foreach (var option in field.Options ?? new())
|
||||
{
|
||||
var split = option.Split(':');
|
||||
var text = split[0];
|
||||
var val = split.Length > 1 && int.TryParse(split[1], out var parsedVal) ? parsedVal : 0;
|
||||
<RadzenRadioButtonListItem Text="@text" Value="@val" />
|
||||
}
|
||||
</Items>
|
||||
</RadzenRadioButtonList>
|
||||
break;
|
||||
|
||||
case "select":
|
||||
<RadzenDropDown TValue="string"
|
||||
Disabled=true
|
||||
Data="@field.Options"
|
||||
Value="@GetDropdownValue(label)"
|
||||
Change="@(args => SetDropdownValue(label, args?.ToString()))" />
|
||||
break;
|
||||
|
||||
default:
|
||||
<RadzenTextBox Style="width:100%"
|
||||
Disabled=true
|
||||
Value="@GetValue(label)"
|
||||
Change="@(args => SetValue(label, args?.ToString()))" />
|
||||
break;
|
||||
}
|
||||
</RadzenStack>
|
||||
</RadzenCard>
|
||||
</RadzenStack>
|
||||
|
||||
}
|
||||
</RadzenStack>
|
||||
}
|
||||
|
||||
@if (group.Repeatable)
|
||||
{
|
||||
<RadzenButton Icon="add_circle"
|
||||
Disabled=true
|
||||
ButtonStyle="ButtonStyle.Light"
|
||||
Text="Add Another"
|
||||
Click="@(() => AddGroupEntry(group))" />
|
||||
}
|
||||
|
||||
|
||||
|
||||
</RadzenCard>
|
||||
|
||||
<hr />
|
||||
|
||||
}
|
||||
|
||||
<RadzenButton ButtonStyle="ButtonStyle.Primary" Text="@ButtonTextString" Type="Submit" />
|
||||
</div>
|
||||
</EditForm>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card p-4">
|
||||
<h4 class="mb-3">Details</h4>
|
||||
@foreach (var kvp in formValues)
|
||||
{
|
||||
<p><strong>@kvp.Key:</strong> @kvp.Value</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<p class="mt-2">@FormSubmitResult</p>
|
||||
|
||||
@code {
|
||||
[Parameter] public List<FormFieldGroup> Groups { get; set; } = new();
|
||||
[Parameter] public List<string> IgnoreReflection { get; set; } = new();
|
||||
[Parameter] public EventCallback<Dictionary<string, string>> OnSubmit { get; set; }
|
||||
[Parameter] public bool isEditing { get; set; }
|
||||
[Parameter] public string TitleString { get; set; } = "Edit your details";
|
||||
[Parameter] public string ButtonTextString { get; set; } = "Submit";
|
||||
|
||||
private EditContext editContext;
|
||||
private Dictionary<string, string> formValues = new();
|
||||
private Dictionary<string, DateTime?> formDates = new();
|
||||
private string FormSubmitResult = "";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
if (group.EntryCount == 0)
|
||||
{
|
||||
group.EntryCount = 1; // Always have at least one entry
|
||||
}
|
||||
|
||||
for (int i = 0; i < group.EntryCount; i++)
|
||||
{
|
||||
foreach (var field in group.Fields)
|
||||
{
|
||||
var key = $"{group.GroupName}_{i}_{field.Label}";
|
||||
|
||||
if (!formValues.ContainsKey(key))
|
||||
{
|
||||
if (field.Type?.ToLower() == "radio" && field.Options?.Count > 0)
|
||||
{
|
||||
var defaultVal = field.Options.FirstOrDefault()?.Split(':').LastOrDefault() ?? "0";
|
||||
formValues[key] = defaultVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
formValues[key] = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
if (field.Type?.ToLower() == "date" && !formDates.ContainsKey(key))
|
||||
{
|
||||
formDates[key] = DateTime.Today;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editContext = new EditContext(formValues);
|
||||
}
|
||||
|
||||
private string GetValue(string label) => formValues.TryGetValue(label, out var value) ? value : "";
|
||||
private void SetValue(string label, string? value) => formValues[label] = value ?? "";
|
||||
|
||||
private DateTime? GetDate(string label) => formDates.TryGetValue(label, out var date) ? date : null;
|
||||
private void SetDate(string label, DateTime? value) => formDates[label] = value;
|
||||
|
||||
private string GetDropdownValue(string label) => formValues.TryGetValue(label, out var value) ? value : "";
|
||||
private void SetDropdownValue(string label, string? value) => formValues[label] = value ?? "";
|
||||
|
||||
private bool GetCheckboxValue(string label) => formValues.TryGetValue(label, out var value) && bool.TryParse(value, out var result) && result;
|
||||
private void SetCheckboxValue(string label, bool? value) => formValues[label] = (value ?? false).ToString();
|
||||
|
||||
private int GetRadioValue(string label) => formValues.TryGetValue(label, out var value) && int.TryParse(value, out var intValue) ? intValue : 0;
|
||||
private void SetRadioValue(string label, int? value) => formValues[label] = value?.ToString() ?? "0";
|
||||
|
||||
private void AddGroupEntry(FormFieldGroup group)
|
||||
{
|
||||
group.EntryCount++;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task HandleValidSubmit()
|
||||
{
|
||||
foreach (var dateField in formDates)
|
||||
{
|
||||
formValues[dateField.Key] = dateField.Value?.ToString("yyyy-MM-dd") ?? "";
|
||||
}
|
||||
|
||||
FormSubmitResult = "Success!";
|
||||
await OnSubmit.InvokeAsync(formValues);
|
||||
isEditing = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
@inject NavigationManager _navigationManager;
|
||||
@inject ContentEditorService _contentEditorService
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IJSRuntime JS
|
||||
|
||||
|
||||
|
||||
|
|
@ -79,10 +80,19 @@
|
|||
_navigationManager.Refresh(true);
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
SelectedLanguage = "English";
|
||||
_scopedContentService.SelectedLanguage = "English";
|
||||
var lang = await JS.InvokeAsync<string>("getUserLanguage");
|
||||
|
||||
// Normalize and match to one of your supported languages
|
||||
if (lang.StartsWith("hu", StringComparison.OrdinalIgnoreCase))
|
||||
SelectedLanguage = "Hungarian";
|
||||
else if (lang.StartsWith("de", StringComparison.OrdinalIgnoreCase))
|
||||
SelectedLanguage = "German";
|
||||
else
|
||||
SelectedLanguage = "English";
|
||||
|
||||
_scopedContentService.SelectedLanguage = SelectedLanguage;
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
|
|
|
|||
|
|
@ -4,29 +4,66 @@
|
|||
@inject ContentEditorService ContentEditorService
|
||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
||||
@inject NavigationManager navigationManager
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="menu-item-editor">
|
||||
<div class="form-group">
|
||||
<label>Template Name</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Name" />
|
||||
<div class="row">
|
||||
<h4>Snippet info</h4>
|
||||
<p>The basic information about the code-block</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-2">
|
||||
<label>Snippet name</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Name" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label>Variant</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Variant" />
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4">
|
||||
<label>Type (comma-separated)</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Type" />
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label>Tags (comma-separated)</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Tags" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label>Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Snippet.Description" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Snippet.Description" />
|
||||
<div class="row">
|
||||
<h5>Snippet parametrized code</h5>
|
||||
<p>Your parametrized html template for a specific block, like article, card, hero or such</p>
|
||||
<div class="form-group">
|
||||
<label>Template</label>
|
||||
<RadzenHtmlEditor @bind-Value=@Snippet.Html style="height: 450px; color:#000; background-color: rgba(255,255,255,0) !important" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags (comma-separated)</label>
|
||||
<InputText class="form-control" @bind-Value="Snippet.Type" />
|
||||
<div class="row">
|
||||
<h5>Snippet sample code</h5>
|
||||
<p>Your sample html template for a specific block, like article, card, hero or such. Here you can use sample data in the snippet, to see if your css is working well</p>
|
||||
<div class="form-group">
|
||||
<label>Sample</label><RadzenButton Click="@(() => ShowSnippetPreview(Snippet))">Preview snippet</RadzenButton>
|
||||
<RadzenHtmlEditor @bind-Value=@Snippet.SampleHtml style="height: 450px; color:#000; background-color: rgba(255,255,255,0) !important" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RadzenHtmlEditor @bind-Value=@Snippet.Html style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
|
||||
<EventConsole @ref=@console />
|
||||
@if (IsLoading)
|
||||
{
|
||||
|
|
@ -35,28 +72,49 @@
|
|||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public HtmlSnippet Snippet { get; set; } = new HtmlSnippet();
|
||||
|
||||
[Parameter] public HtmlSnippet Snippet { get; set; } = new HtmlSnippet();
|
||||
[Parameter] public EventCallback<HtmlSnippet> OnContentUpdated { get; set; }
|
||||
[Parameter] public int TemplateId { get; set; }
|
||||
|
||||
private bool IsLoading = false;
|
||||
|
||||
|
||||
private string? userId;
|
||||
private string? userName;
|
||||
private AuthenticationState? authState;
|
||||
|
||||
EventConsole console;
|
||||
|
||||
public async void ShowSnippetPreview(HtmlSnippet snippet)
|
||||
{
|
||||
//navigationManager.NavigateTo($"/preview-snippet/{TemplateId}/{snippet.Name}");
|
||||
// await JSRuntime.InvokeAsync<object>("open", $"/preview-snippet/{TemplateId}/{snippet.Name}", "_blank");
|
||||
await JSRuntime.InvokeVoidAsync("open", $"/preview-snippet/{TemplateId}/{snippet.Name}", "_blank");
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
{
|
||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
if (authState.User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
userId = CustomAuthProvider.GetUserId();
|
||||
userName = CustomAuthProvider.GetUserName();
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(Snippet.Tags))
|
||||
{
|
||||
Snippet.Tags = Snippet.Name;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(Snippet.SampleHtml))
|
||||
{
|
||||
Snippet.SampleHtml = Snippet.Html;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(Snippet.Variant))
|
||||
{
|
||||
Snippet.Variant = "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
||||
{
|
||||
console.Log($"Paste: {args.Html}");
|
||||
|
|
@ -66,13 +124,13 @@
|
|||
async Task OnChange(string html)
|
||||
{
|
||||
console.Log($"Change: {html}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
async Task OnInput(string html)
|
||||
{
|
||||
console.Log($"Input: {html}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||
|
|
|
|||
|
|
@ -18,13 +18,15 @@ namespace BLAIzor.Data
|
|||
|
||||
public DbSet<CssTemplate> CssTemplates { get; set; }
|
||||
|
||||
public DbSet<FormDefinition> FormDefinitions { get; set; }
|
||||
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// SiteInfo configuration
|
||||
|
||||
|
||||
|
||||
modelBuilder.Entity<IdentityUser>().HasData(new IdentityUser
|
||||
{
|
||||
|
|
@ -54,7 +56,7 @@ namespace BLAIzor.Data
|
|||
QDrandCollectionName = "html_snippets"
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
modelBuilder.Entity<SiteInfo>().HasData(new SiteInfo
|
||||
{
|
||||
|
|
@ -99,6 +101,16 @@ namespace BLAIzor.Data
|
|||
.WithOne(dt => dt.CssTemplate) // Assuming DesignTemplate can have multiple CSS templates
|
||||
.HasForeignKey<CssTemplate>(ct => ct.DesignTemplateId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<FormDefinition>()
|
||||
.HasOne(fd => fd.SiteInfo)
|
||||
.WithMany(s => s.FormDefinitions)
|
||||
.HasForeignKey(fd => fd.SiteInfoId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<FormDefinition>()
|
||||
.HasIndex(fd => new { fd.SiteInfoId, fd.Slug })
|
||||
.IsUnique(); // Ensure each form slug is unique per site
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,606 @@
|
|||
// <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("20250413175505_AddFormDefinition")]
|
||||
partial class AddFormDefinition
|
||||
{
|
||||
/// <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");
|
||||
|
||||
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<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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BLAIzor.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddFormDefinition : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FormDefinitions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
SiteInfoId = table.Column<int>(type: "int", nullable: false),
|
||||
Title = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
Slug = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||
Description = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
JsonDefinition = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Version = table.Column<int>(type: "int", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FormDefinitions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FormDefinitions_SiteInfos_SiteInfoId",
|
||||
column: x => x.SiteInfoId,
|
||||
principalTable: "SiteInfos",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FormDefinitions_SiteInfoId",
|
||||
table: "FormDefinitions",
|
||||
column: "SiteInfoId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "FormDefinitions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,607 @@
|
|||
// <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("20250413231424_AddFormDefinition2")]
|
||||
partial class AddFormDefinition2
|
||||
{
|
||||
/// <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<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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BLAIzor.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddFormDefinition2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_FormDefinitions_SiteInfoId",
|
||||
table: "FormDefinitions");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FormDefinitions_SiteInfoId_Slug",
|
||||
table: "FormDefinitions",
|
||||
columns: new[] { "SiteInfoId", "Slug" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_FormDefinitions_SiteInfoId_Slug",
|
||||
table: "FormDefinitions");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FormDefinitions_SiteInfoId",
|
||||
table: "FormDefinitions",
|
||||
column: "SiteInfoId");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ namespace BLAIzor.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.0")
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
|
@ -123,6 +123,48 @@ namespace BLAIzor.Migrations
|
|||
});
|
||||
});
|
||||
|
||||
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")
|
||||
|
|
@ -451,6 +493,17 @@ namespace BLAIzor.Migrations
|
|||
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")
|
||||
|
|
@ -541,6 +594,8 @@ namespace BLAIzor.Migrations
|
|||
|
||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||
{
|
||||
b.Navigation("FormDefinitions");
|
||||
|
||||
b.Navigation("MenuItems");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace BLAIzor.Models
|
||||
{
|
||||
public class FormDefinition
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int SiteInfoId { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(100)]
|
||||
public string Title { get; set; } = "";
|
||||
|
||||
[Required]
|
||||
[MaxLength(100)]
|
||||
public string Slug { get; set; } = ""; // URL-friendly ID like "contact-form"
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Required]
|
||||
public string JsonDefinition { get; set; } = ""; // serialized List<FormFieldGroup>
|
||||
|
||||
public int Version { get; set; } = 1;
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[ForeignKey(nameof(SiteInfoId))]
|
||||
public SiteInfo SiteInfo { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,25 @@
|
|||
namespace BLAIzor.Models
|
||||
{
|
||||
//public class HtmlSnippet
|
||||
//{
|
||||
// public int Id { get; set; }
|
||||
// public string Type { get; set; }
|
||||
// public string Name { get; set; }
|
||||
// public string Description { get; set; }
|
||||
// public string Html { get; set; }
|
||||
//}
|
||||
|
||||
public class HtmlSnippet
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Html { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public string Type { get; set; } // e.g. "article", "form", "gallery"
|
||||
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
||||
public string SampleHtml { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@ namespace BLAIzor.Models
|
|||
[Url(ErrorMessage = "The DefaultUrl field must be a valid URL.")]
|
||||
public string DefaultUrl { get; set; } // For generated subdomains
|
||||
public bool IsPublished { get; set; } // For generated subdomains
|
||||
public int? TemplateId { get; set; }
|
||||
|
||||
// Navigation property for IdentityUser
|
||||
public IdentityUser User { get; set; }
|
||||
|
||||
// Navigation property for Menu items
|
||||
public ICollection<MenuItem> MenuItems { get; set; } = new List<MenuItem>();
|
||||
public int? TemplateId { get; set; }
|
||||
public DesignTemplate Template { get; set; }
|
||||
public List<FormDefinition> FormDefinitions { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using NuGet.Packaging;
|
|||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Google.Api;
|
||||
using System.CodeDom;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace BLAIzor.Services
|
||||
{
|
||||
|
|
@ -61,7 +62,7 @@ namespace BLAIzor.Services
|
|||
public static event Action<string>? OnContentReceiveFinished;
|
||||
public static event Action<string, string>? OnContentReceivedError;
|
||||
public static event Action<string, string>? OnStatusChangeReceived;
|
||||
public string Mood = "and professional";
|
||||
public string Mood = "cool, and professional";
|
||||
private string _workingContent = null;
|
||||
public bool UseWebsocket = false;
|
||||
private string AiProvider = "";
|
||||
|
|
@ -118,7 +119,7 @@ namespace BLAIzor.Services
|
|||
}
|
||||
|
||||
|
||||
string systemMessage = "You are a helpful " + Mood + " assistant that welcomes the user on a website of " + _scopedContentService.SelectedBrandName + " in " + _scopedContentService.SelectedLanguage + ". Use the following content: `" +
|
||||
string systemMessage = "You are a helpful, " + Mood + " assistant that welcomes the user in the name of the brand or person described by the content, on a website of " + _scopedContentService.SelectedBrandName + " in " + _scopedContentService.SelectedLanguage + ". Use the following content: `" +
|
||||
extractedText + "` " +
|
||||
//"and generate a short" +Mood+ "but kind marketing-oriented welcome message and introduction of the brand for the user, constructed as simple Bootstrap HTML codeblock with a <h1> tagged title and a paragraph." +
|
||||
"and generate a" + Mood + " marketing-oriented welcome message and a summary of the content and introduction of the brand for the user, aiming to explain clearly, what does the company/person offer, constructed as simple Bootstrap HTML codeblock with a <h1> tagged title and a paragraph." +
|
||||
|
|
@ -211,6 +212,59 @@ namespace BLAIzor.Services
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No reasoning needed just content retrieved and displayed as html
|
||||
/// </summary>
|
||||
/// <param name="sessionId"></param>
|
||||
/// <param name="userPrompt"></param>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="templateId"></param>
|
||||
/// <param name="collectionName"></param>
|
||||
/// <param name="menuList"></param>
|
||||
/// <returns></returns>
|
||||
public async Task ProcessContentRequest(string sessionId, string requestedMenuName, 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);
|
||||
|
||||
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 = "";
|
||||
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
|
||||
|
||||
private async Task ProcessMethodResult(string sessionId, string resultJson)
|
||||
|
|
@ -231,7 +285,7 @@ namespace BLAIzor.Services
|
|||
if (fixedResult != null)
|
||||
{
|
||||
string contentJson = await GetContentFromQuery(sessionId, fixedResult.Text, _workingContent);
|
||||
//validate and fix json object?
|
||||
Console.Write("\r \n ProcessTextResult: Content: " + contentJson + "\r \n");
|
||||
await ProcessContent(sessionId, contentJson, templateId, collectionName);
|
||||
}
|
||||
}
|
||||
|
|
@ -360,7 +414,7 @@ namespace BLAIzor.Services
|
|||
/// </summary>
|
||||
/// <param name="userPrompt"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetContentFromQuery(string sessionId, string userPrompt, string content = null)
|
||||
public async Task<string> GetContentFromQuery(string sessionId, string userPrompt, string content = null, bool forceUnmodified = false)
|
||||
{
|
||||
string extractedText;
|
||||
if (content == null)
|
||||
|
|
@ -373,31 +427,62 @@ namespace BLAIzor.Services
|
|||
_apiKey = GetApiKey();
|
||||
|
||||
//Console.Write("GetJSONResult called: " +extractedText);
|
||||
|
||||
var systemMessage = "You are a helpful assistant forming JSON objects on request. Respond strictly in " + _scopedContentService.SelectedLanguage + " with a plain JSON object in the following format:\r\n\r\n1. " +
|
||||
//"**chatGPTContentResult**:\r\n " +
|
||||
"- `type`: A string with value `contentresult`.\r\n " +
|
||||
"- `text`: A string with the actual response.\r\n " +
|
||||
"- `topics`: A list of sections of the initial document." +
|
||||
"- `photos`: A dictionary of string key and string values, where the keys are the name of the subject that the photo is related to (like a person's name, or a section)," +
|
||||
" and the value is the actual, unmodified photo url.\r\n" +
|
||||
"**Document-Specific Instructions**:\r\n- Base responses solely on the initial document: {" + extractedText + "}.\r\n" +
|
||||
"- Start with defining above mentioned key topics of the initial document, and making the list of them. " +
|
||||
"- After that add the above mentioned relevant image urls list." +
|
||||
"- For missing information: Inform the user and provide a clarification. " +
|
||||
//"- Do not generate lengthy answers." +
|
||||
"- If the user prompt is clear and they ask specific, well defined question, do not add other infromation or welcome message." +
|
||||
"- If the user prompt is unclear, or makes no sense, ask for clarification." +
|
||||
"You can decorate your clarification" +
|
||||
"request with this image URL: `https://www.reactiongifs.com/r/martin.gif` added to the photo dictionary.\r\n\r\n" +
|
||||
"- For compliments from the user: Express our happiness about it " +
|
||||
"and apply this image URL: `https://www.reactiongifs.com/r/review.gif` in the photo dictionary.\r\n\r\n" +
|
||||
"**Style and Image Handling**:\r\n" +
|
||||
"- Make sure the json is valid json." +
|
||||
"- Do NOT include extraneous text outside the JSON structure.\r\n\r\n" +
|
||||
"When you understand the input, follow these rules strictly. Otherwise, seek clarification.\r\n" +
|
||||
"Do not include linebreaks or any formatting, just the plain json string. Make sure it is valid json, and every objects is closed properly" +
|
||||
"Do NOT mark your answer with anything like `````json, and do not add any explanation.";
|
||||
string systemMessage = "";
|
||||
if(forceUnmodified)
|
||||
{
|
||||
systemMessage = "You are a helpful assistant of a website. Respond in the name of the brand or person in the content, strictly in " + _scopedContentService.SelectedLanguage + " with a plain JSON object in the following format:\r\n\r\n1. " +
|
||||
//"**chatGPTContentResult**:\r\n " +
|
||||
"- `type`: A string with value `contentresult`.\r\n " +
|
||||
"- `text`: A string with the actual response.\r\n " +
|
||||
"- `topics`: A list of sections of the initial document." +
|
||||
"- `photos`: A dictionary of string key and string values, where the keys are the name of the subject that the photo is related to (like a person's name, or a section)," +
|
||||
" and the value is the actual, unmodified photo url.\r\n" +
|
||||
"**Document-Specific Instructions**:\r\n" +
|
||||
"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 3: " +
|
||||
"- Turn the following content into a nice informative webpage content. " +
|
||||
"- Structure it nicely without leaving out any information. " +
|
||||
"*** CONTENT START *** {" + extractedText + "} *** CONTENT END ***.\r\n" +
|
||||
"**Style and Image Handling**:\r\n" +
|
||||
"- Make sure the json is valid json." +
|
||||
"- Do NOT include extraneous text outside the JSON structure.\r\n\r\n" +
|
||||
"When you understand the input, follow these rules strictly. Otherwise, seek clarification.\r\n" +
|
||||
"Do not include linebreaks or any formatting, just the plain json string. Make sure it is valid json, and every objects is closed properly" +
|
||||
"Do NOT mark your answer with anything like `````json, and do not add any explanation.";
|
||||
}
|
||||
else
|
||||
{
|
||||
systemMessage = "You are a helpful assistant of a website. Respond in the name of the brand or person in the content, strictly in " + _scopedContentService.SelectedLanguage + " with a plain JSON object in the following format:\r\n\r\n1. " +
|
||||
//"**chatGPTContentResult**:\r\n " +
|
||||
"- `type`: A string with value `contentresult`.\r\n " +
|
||||
"- `text`: A string with the actual response.\r\n " +
|
||||
"- `topics`: A list of sections of the initial document." +
|
||||
"- `photos`: A dictionary of string key and string values, where the keys are the name of the subject that the photo is related to (like a person's name, or a section)," +
|
||||
" and the value is the actual, unmodified photo url.\r\n" +
|
||||
"**Document-Specific Instructions**:\r\n" +
|
||||
"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 3: " +
|
||||
"- Base a detailed, but not lengthy response solely on the initial document provided below. " +
|
||||
"- In your response, summarize all relevant information in the document, that is connected to the question." +
|
||||
"*** CONTENT START *** {" + extractedText + "} *** CONTENT END ***.\r\n" +
|
||||
"- For missing information: Inform the user and provide a clarification. " +
|
||||
//"- Do not generate lengthy answers." +
|
||||
"- If the user prompt is clear and they ask specific, well defined question, do not add other infromation or welcome message." +
|
||||
"- If the user prompt is unclear, or makes no sense, ask for clarification." +
|
||||
//"You can decorate your clarification" +
|
||||
//"request with this image URL: `https://www.reactiongifs.com/r/martin.gif` added to the photo dictionary.\r\n\r\n" +
|
||||
//"- For compliments from the user: Express our happiness about it " +
|
||||
//"and apply this image URL: `https://www.reactiongifs.com/r/review.gif` in the photo dictionary.\r\n\r\n" +
|
||||
"**Style and Image Handling**:\r\n" +
|
||||
"- Make sure the json is valid json." +
|
||||
"- Do NOT include extraneous text outside the JSON structure.\r\n\r\n" +
|
||||
"When you understand the input, follow these rules strictly. Otherwise, seek clarification.\r\n" +
|
||||
"Do not include linebreaks or any formatting, just the plain json string. Make sure it is valid json, and every objects is closed properly" +
|
||||
"Do NOT mark your answer with anything like `````json, and do not add any explanation.";
|
||||
}
|
||||
|
||||
OnStatusChangeReceived?.Invoke(sessionId, "Constructing the answer");
|
||||
string interMediateResult = string.Empty;
|
||||
if (!UseWebsocket)
|
||||
|
|
@ -425,7 +510,7 @@ namespace BLAIzor.Services
|
|||
interMediateResult = await _openAIRealtimeService.GetFullChatGPTResponseAsync(sessionId, systemMessage, userPrompt);
|
||||
}
|
||||
OnStatusChangeReceived?.Invoke(sessionId, "Mkay, I know now");
|
||||
Console.Write("Result decision: " + interMediateResult);
|
||||
Console.Write("GetContentFromQuery: Result decision: " + interMediateResult);
|
||||
return interMediateResult;
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +577,7 @@ namespace BLAIzor.Services
|
|||
interMediateResult = await _openAIRealtimeService.GetFullChatGPTResponseAsync(sessionId, systemMessage, userPrompt);
|
||||
}
|
||||
OnStatusChangeReceived?.Invoke(sessionId, "Mkay, I know now");
|
||||
Console.Write("Result decision: " + interMediateResult);
|
||||
Console.Write("GetExaminationResult: Result decision: " + interMediateResult);
|
||||
return interMediateResult;
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +661,7 @@ namespace BLAIzor.Services
|
|||
OnStatusChangeReceived?.Invoke(sessionId, "Looking up content in the knowledge database");
|
||||
var pointId = await _qDrantService.QueryContentAsync(siteId, vector, 3);
|
||||
|
||||
string extractedText = "";
|
||||
string extractedText = "Sections: ";
|
||||
if (pointId.Length > 0)
|
||||
{
|
||||
foreach (var item in pointId)
|
||||
|
|
@ -598,7 +683,7 @@ namespace BLAIzor.Services
|
|||
}
|
||||
|
||||
_workingContent = extractedText;
|
||||
|
||||
Console.Write("\r \n GetJsonResultFromQuery: Working content: " + _workingContent + "\r \n");
|
||||
//string extractedText = WordFileReader.ExtractText(rootpath);
|
||||
|
||||
Console.Write("GetJSONResult called!");
|
||||
|
|
@ -677,7 +762,7 @@ namespace BLAIzor.Services
|
|||
interMediateResult = await _openAIRealtimeService.GetFullChatGPTResponseAsync(sessionId, systemMessage, userPrompt);
|
||||
}
|
||||
|
||||
Console.Write("\r \n Result decision: " + interMediateResult + "\r \n");
|
||||
Console.Write("\r \n GetJsonResultFromQuery: Result decision: " + interMediateResult + "\r \n");
|
||||
return interMediateResult;
|
||||
}
|
||||
|
||||
|
|
@ -873,10 +958,7 @@ namespace BLAIzor.Services
|
|||
Console.WriteLine($"DISPLAYHTML Photos: {photos} \n\n");
|
||||
Console.WriteLine($"DISPLAYHTML Topics: {topics} \n\n");
|
||||
|
||||
|
||||
|
||||
_apiKey = GetApiKey();
|
||||
StringBuilder lst = new StringBuilder("You are a helpful assistant generating HTML responses in " + _scopedContentService.SelectedLanguage + " using Bootstrap. \n\n" +
|
||||
StringBuilder lst = new StringBuilder("You are a helpful assistant generating HTML content in " + _scopedContentService.SelectedLanguage + " using Bootstrap. \n\n" +
|
||||
"### Rules to Follow: \n" +
|
||||
"- Please generate clean and structured HTML that fits inside a Bootstrap container.\n" +
|
||||
"- DO NOT include `<head>`, `<body>`, or `<script>` tags—only content inside the Bootstrap container.\n" +
|
||||
|
|
@ -910,7 +992,7 @@ namespace BLAIzor.Services
|
|||
" </div>\n" +
|
||||
" ```\n\n" +
|
||||
"- Use Bootstrap classes to ensure proper spacing and alignment.\n" +
|
||||
" - Use 'row justify-content-center' for layout, 'col-xs-12 col-sm-6 col-md-3 text-center' for product cards, and 'img-fluid' for images. \r\n" +
|
||||
" - Use 'row justify-content-center' for layout, 'col-xx-x' classes for columns (IF multiple columns are needed), and always use 'img-fluid' class for images. \r\n" +
|
||||
"- If a snippet contains a button, ensure it is placed inside a `div.text-center` for proper alignment.\n");
|
||||
}
|
||||
|
||||
|
|
@ -933,15 +1015,16 @@ namespace BLAIzor.Services
|
|||
if (topics != null && topics.Any())
|
||||
{
|
||||
lst.AppendLine(
|
||||
"### Generating Topic Buttons:\n" +
|
||||
"### Generating Topic Buttons:\n" +
|
||||
"Start this section with a title `Related` " +
|
||||
"- Create a **separate button** for each topic.\n" +
|
||||
$"- Make sure the topics are in {_scopedContentService.SelectedLanguage}, if not, translate them." +
|
||||
"- Each button should use `btn btn-primary` and call `callAI('{topicName}')` on click.\n" +
|
||||
"- List of topics:\n" +
|
||||
" " + string.Join(", ", topics) + "\n\n" +
|
||||
"- Example:\n" +
|
||||
"- Example:\n" +
|
||||
" <button class='btn btn-primary' onclick='callAI(\"" + topics.FirstOrDefault() + "\")'>" + topics.FirstOrDefault() + "</button>\n" +
|
||||
"Put this section always as last, on the bottom of the page.\n"
|
||||
"Put this section always as last, on the bottom of the page.\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -954,12 +1037,13 @@ namespace BLAIzor.Services
|
|||
lst.AppendLine(
|
||||
"- DO **NOT** merge different content sections.\n" +
|
||||
"- DO **NOT** wrap the entire content in a single `div`—use separate `row` divs.\n" +
|
||||
"- Do **NOT** generate or assume image URLs.\n" +
|
||||
"- DO **NOT** modify the photo urls in any way." +
|
||||
"- Do **NOT** generate or assume new image URLs.\n" +
|
||||
"- If the snippet contains an image, but there is no photo url available, skip the image element." +
|
||||
"- **Never** add explanations or start with ```html syntax markers.\n");
|
||||
|
||||
string systemMessage = lst.ToString();
|
||||
string userMessage = "Make a nice Bootstrap 5 page content from the provided text, please.";
|
||||
string userMessage = "Create a perfect, production ready, structured Bootstrap 5 page content from the provided text, please.";
|
||||
string assistantMessage = "`Provided text to display as HTML`: `" + interMediateResult + "`";
|
||||
//int mode = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using BLAIzor.Models;
|
|||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||
using Google.Protobuf.Collections;
|
||||
using Google.Type;
|
||||
using Microsoft.CodeAnalysis.Completion;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
|
|
@ -93,8 +94,13 @@ namespace BLAIzor.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
|
||||
// Combine details to generate the embedding
|
||||
var combinedText = $"{snippet.Name}: {snippet.Description} - {snippet.Html}";
|
||||
var combinedText = $"{snippet.Name}: {snippet.Description}. " +
|
||||
$"Type: {snippet.Type}. " +
|
||||
$"Variant: {snippet.Variant ?? "default"}. " +
|
||||
$"Tags: {snippet.Tags}. " +
|
||||
$"HTML: {snippet.Html}";
|
||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
|
||||
// Add data for batch insertion
|
||||
|
|
@ -104,8 +110,11 @@ namespace BLAIzor.Services
|
|||
{
|
||||
["type"] = snippet.Type,
|
||||
["name"] = snippet.Name,
|
||||
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant)? "" : snippet.Variant,
|
||||
["tags"] = snippet.Tags,
|
||||
["description"] = snippet.Description,
|
||||
["html"] = snippet.Html
|
||||
["html"] = snippet.Html,
|
||||
["sampleHtml"] = snippet.SampleHtml
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ namespace BLAIzor.Services
|
|||
Payload = { payloads[i] }
|
||||
|
||||
});
|
||||
Console.WriteLine($"{pointStructList[i].Id} val bekerült {pointStructList[i].Payload["html"]}");
|
||||
Console.WriteLine($"{pointStructList[i].Id} val bekerül {pointStructList[i].Payload["name"]}");
|
||||
}
|
||||
|
||||
Console.WriteLine(pointStructList.Count);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,27 @@ namespace BLAIzor.Services
|
|||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<SiteInfo?> GetSiteInfoWithFormsByIdAsync(int siteId)
|
||||
{
|
||||
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var _context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
|
||||
// Now use dbContext safely without violating DI rules
|
||||
var result = await _context.SiteInfos.Include(s => s.FormDefinitions).FirstOrDefaultAsync(s => s.Id == siteId);
|
||||
if (result == null)
|
||||
{
|
||||
return new SiteInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task<SiteInfo> GetSiteInfoByNameAsync(string siteName)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Hero Block with Image -->
|
||||
<section class="hero-section py-5 bg-light">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-6">
|
||||
<h1>{{title}}</h1>
|
||||
<p class="lead">{{subtitle}}</p>
|
||||
<a href="{{cta_link}}" class="btn btn-primary">{{cta_text}}</a>
|
||||
</div>
|
||||
<div class="col-md-6 text-center">
|
||||
<img src="{{image_url}}" class="img-fluid" alt="Hero Image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Feature 3-Column Block -->
|
||||
<section class="features-section py-5">
|
||||
<div class="container">
|
||||
<div class="row text-center">
|
||||
{{#each features}}
|
||||
<div class="col-md-4 mb-4">
|
||||
<i class="bi {{icon}} display-4 text-primary"></i>
|
||||
<h5 class="mt-3">{{title}}</h5>
|
||||
<p>{{description}}</p>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Testimonial Block -->
|
||||
<section class="testimonials py-5 bg-white border-top">
|
||||
<div class="container">
|
||||
<h2 class="text-center mb-4">What people are saying</h2>
|
||||
<div class="row">
|
||||
{{#each testimonials}}
|
||||
<div class="col-md-4">
|
||||
<blockquote class="blockquote">
|
||||
<p class="mb-0">"{{quote}}"</p>
|
||||
<footer class="blockquote-footer mt-2">{{author}}</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Call to Action Block -->
|
||||
<section class="cta-section bg-primary text-white py-5">
|
||||
<div class="container text-center">
|
||||
<h2>{{cta_heading}}</h2>
|
||||
<p class="mb-4">{{cta_description}}</p>
|
||||
<a href="{{cta_button_link}}" class="btn btn-light">{{cta_button_text}}</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer Block -->
|
||||
<footer class="footer py-4 bg-dark text-white">
|
||||
<div class="container text-center">
|
||||
<p class="mb-1">© {{year}} {{brand_name}}. All rights reserved.</p>
|
||||
<small>{{footer_links}}</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<section class="py-5 bg-light">
|
||||
<div class="container">
|
||||
<h2 class="mb-4">{{title}}</h2>
|
||||
<form>
|
||||
{{#each fields}}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{{label}}</label>
|
||||
<input type="{{type}}" class="form-control" placeholder="{{placeholder}}">
|
||||
</div>
|
||||
{{/each}}
|
||||
<button type="submit" class="btn btn-primary">{{buttonText}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="py-5 text-center">
|
||||
<div class="container">
|
||||
<h2 class="mb-5">{{title}}</h2>
|
||||
<div class="row g-4">
|
||||
{{#each images}}
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<img src="{{url}}" alt="{{alt}}" class="img-fluid rounded shadow-sm" />
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="py-5 bg-light">
|
||||
<div class="container text-center">
|
||||
<h2 class="mb-5">{{title}}</h2>
|
||||
<div class="row">
|
||||
{{#each plans}}
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100 border-0 shadow">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{name}}</h5>
|
||||
<h6 class="card-price display-5 fw-bold">{{price}}</h6>
|
||||
<ul class="list-unstyled my-4">
|
||||
{{#each features}}
|
||||
<li>✔️ {{.}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<a href="{{buttonLink}}" class="btn btn-outline-primary">{{buttonText}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<article class="py-5">
|
||||
<div class="container">
|
||||
<h1 class="mb-3">{{title}}</h1>
|
||||
<p class="text-muted">{{date}}</p>
|
||||
{{#each paragraphs}}
|
||||
<p>{{.}}</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="py-5">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-6 mb-4 mb-lg-0">
|
||||
<img src="{{imageUrl}}" alt="{{imageAlt}}" class="img-fluid rounded shadow-sm" />
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<h1 class="mb-3">{{title}}</h1>
|
||||
<p class="text-muted">{{date}}</p>
|
||||
{{#each paragraphs}}
|
||||
<p>{{.}}</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -114,6 +114,10 @@
|
|||
background-color: rgba(255, 255, 255, 0.2)
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.contactform-overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
|
|
@ -208,3 +212,7 @@
|
|||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.rz-html-editor {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,8 @@
|
|||
link.id = "seemgen-css";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
};
|
||||
|
||||
window.getUserLanguage = () => {
|
||||
return navigator.language || navigator.userLanguage || "en";
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,100 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.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.986rem;
|
||||
}
|
||||
|
||||
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.488rem;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.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.986rem;
|
||||
}
|
||||
|
||||
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.488rem;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.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.986rem;
|
||||
}
|
||||
|
||||
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.488rem;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
|
@ -13,7 +13,8 @@ li {
|
|||
}
|
||||
|
||||
label {
|
||||
display: none;
|
||||
color: #000;
|
||||
/* display: none; */
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
@ -447,6 +448,9 @@ body {
|
|||
|
||||
.table {
|
||||
color: #fff !important;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
|
|
@ -474,7 +478,7 @@ body {
|
|||
}
|
||||
|
||||
.nav-link {
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
|
@ -0,0 +1,486 @@
|
|||
/*@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;
|
||||
}
|
||||
|
|
@ -0,0 +1,486 @@
|
|||
/*@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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,486 @@
|
|||
/*@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;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.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.986rem;
|
||||
}
|
||||
|
||||
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.488rem;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
|
@ -0,0 +1,486 @@
|
|||
/*@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;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 824 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
Loading…
Reference in New Issue