diff --git a/Moonlight/App/Database/Entities/Domain.cs b/Moonlight/App/Database/Entities/Domain.cs
index 3b65089c..2f7645a6 100644
--- a/Moonlight/App/Database/Entities/Domain.cs
+++ b/Moonlight/App/Database/Entities/Domain.cs
@@ -1,8 +1,12 @@
-namespace Moonlight.App.Database.Entities;
+using System.ComponentModel.DataAnnotations;
+
+namespace Moonlight.App.Database.Entities;
public class Domain
{
public int Id { get; set; }
+
+ [Required]
public string Name { get; set; }
public SharedDomain SharedDomain { get; set; }
public User Owner { get; set; }
diff --git a/Moonlight/App/Helpers/FieldCssHelper.cs b/Moonlight/App/Helpers/FieldCssHelper.cs
new file mode 100644
index 00000000..557532a4
--- /dev/null
+++ b/Moonlight/App/Helpers/FieldCssHelper.cs
@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Components.Forms;
+
+namespace Moonlight.App.Helpers;
+
+public class FieldCssHelper : FieldCssClassProvider
+{
+ public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
+ {
+ return editContext.GetValidationMessages(fieldIdentifier).Any() ? "is-invalid" : "is-valid";
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Shared/Components/Forms/SmartForm.razor b/Moonlight/Shared/Components/Forms/SmartForm.razor
new file mode 100644
index 00000000..615ebef5
--- /dev/null
+++ b/Moonlight/Shared/Components/Forms/SmartForm.razor
@@ -0,0 +1,73 @@
+@using Moonlight.App.Helpers
+
+
+
+@code
+{
+ [Parameter]
+ public object Model { get; set; }
+
+ [Parameter]
+ public EventCallback OnValidSubmit { get; set; }
+
+ [Parameter]
+ public EventCallback OnInvalidSubmit { get; set; }
+
+ [Parameter]
+ public EventCallback OnSubmit { get; set; }
+
+ [Parameter]
+ public RenderFragment ChildContent { get; set; }
+
+ private EditForm EditForm;
+
+ private List ErrorMessages = new();
+
+ protected override void OnAfterRender(bool firstRender)
+ {
+ if (firstRender)
+ {
+ EditForm.EditContext!.SetFieldCssClassProvider(new FieldCssHelper());
+ }
+ }
+
+ private async Task ValidSubmit(EditContext context)
+ {
+ ErrorMessages.Clear();
+ await InvokeAsync(StateHasChanged);
+
+ await OnValidSubmit.InvokeAsync(context);
+ await OnSubmit.InvokeAsync(context);
+ }
+
+ private async Task InvalidSubmit(EditContext context)
+ {
+ ErrorMessages.Clear();
+ context.Validate();
+
+ foreach (var message in context.GetValidationMessages())
+ {
+ ErrorMessages.Add(message);
+ }
+
+ await InvokeAsync(StateHasChanged);
+
+ await OnInvalidSubmit.InvokeAsync(context);
+ await OnSubmit.InvokeAsync(context);
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Shared/Components/Forms/SmartSelect.razor b/Moonlight/Shared/Components/Forms/SmartSelect.razor
new file mode 100644
index 00000000..ea246825
--- /dev/null
+++ b/Moonlight/Shared/Components/Forms/SmartSelect.razor
@@ -0,0 +1,59 @@
+@typeparam TField
+@inherits InputBase
+
+
+
+@code
+{
+ [Parameter]
+ public TField[] Items { get; set; }
+
+ [Parameter]
+ public Func DisplayField { get; set; }
+
+ protected override void OnInitialized()
+ {
+
+ }
+
+ protected override string? FormatValueAsString(TField? value)
+ {
+ if (value == null)
+ return null;
+
+ return DisplayField.Invoke(value);
+ }
+
+ protected override bool TryParseValueFromString(string? value, out TField result, out string? validationErrorMessage)
+ {
+ validationErrorMessage = "";
+ result = default(TField)!;
+ return false;
+ }
+
+ private int Binding
+ {
+ get
+ {
+ if (Value == null)
+ return -1;
+
+ return Value.GetHashCode();
+ }
+ set
+ {
+ var i = Items.FirstOrDefault(x => x!.GetHashCode() == value);
+
+ if (i != null)
+ {
+ Value = i;
+ ValueChanged.InvokeAsync(i);
+ }
+ }
+ }
+}
diff --git a/Moonlight/Shared/Views/Test.razor b/Moonlight/Shared/Views/Test.razor
index 257b4518..948e8c30 100644
--- a/Moonlight/Shared/Views/Test.razor
+++ b/Moonlight/Shared/Views/Test.razor
@@ -1,2 +1,55 @@
@page "/test"
+@using Moonlight.App.Services.Interop
+@using Moonlight.App.Database.Entities
+@using Moonlight.App.Repositories.Domains
+@inject ToastService ToastService
+@inject SharedDomainRepository SharedDomainRepository
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@code
+{
+ private App.Database.Entities.Domain Domain = new();
+
+ private SharedDomain[] SharedDomains;
+
+ private async Task Callback(EditContext obj)
+ {
+ Console.WriteLine(Domain.Name);
+ Console.WriteLine(Domain.SharedDomain.Name);
+
+ await ToastService.Success("SUCCESS");
+ }
+
+ private Task Load(LazyLoader arg)
+ {
+ SharedDomains = SharedDomainRepository
+ .Get()
+ .ToArray();
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/resources/lang/de_de.lang b/Moonlight/resources/lang/de_de.lang
index 485272ea..038b7e81 100644
--- a/Moonlight/resources/lang/de_de.lang
+++ b/Moonlight/resources/lang/de_de.lang
@@ -393,3 +393,4 @@ Successfully updated user;Successfully updated user
Discord id;Discord id
Discord username;Discord username
Discord discriminator;Discord discriminator
+The Name field is required.;The Name field is required.