diff --git a/Moonlight/App/Models/Misc/MailTemplate.cs b/Moonlight/App/Models/Misc/MailTemplate.cs
new file mode 100644
index 00000000..1d67cdcf
--- /dev/null
+++ b/Moonlight/App/Models/Misc/MailTemplate.cs
@@ -0,0 +1,9 @@
+using Moonlight.App.Helpers.Files;
+
+namespace Moonlight.App.Models.Misc;
+
+public class MailTemplate // This is just for the blazor table at /admin/system/mail
+{
+ public string Name { get; set; } = "";
+ public FileData File { get; set; }
+}
\ No newline at end of file
diff --git a/Moonlight/Shared/Components/Navigations/AdminSystemNavigation.razor b/Moonlight/Shared/Components/Navigations/AdminSystemNavigation.razor
index e7f74242..1a92236d 100644
--- a/Moonlight/Shared/Components/Navigations/AdminSystemNavigation.razor
+++ b/Moonlight/Shared/Components/Navigations/AdminSystemNavigation.razor
@@ -44,6 +44,11 @@
Configuration
+
+
+ Mail
+
+
diff --git a/Moonlight/Shared/Views/Admin/Sys/Mail.razor b/Moonlight/Shared/Views/Admin/Sys/Mail.razor
new file mode 100644
index 00000000..92e2e07b
--- /dev/null
+++ b/Moonlight/Shared/Views/Admin/Sys/Mail.razor
@@ -0,0 +1,149 @@
+@page "/admin/system/mail"
+
+@using Moonlight.Shared.Components.Navigations
+@using Moonlight.Shared.Components.FileManagerPartials
+@using Moonlight.App.Helpers.Files
+@using Moonlight.App.Helpers
+@using BlazorTable
+@using Moonlight.App.Models.Misc
+@using Moonlight.App.Services
+@using Moonlight.App.Services.Interop
+
+@inject SmartTranslateService SmartTranslateService
+@inject ToastService ToastService
+@inject AlertService AlertService
+
+
+
+
+
+ @if (CurrentMailTemplate == null)
+ {
+
+
+
+
+
+
+
+ @{
+ var name = context.Name.Replace(Path.GetExtension(context.Name), "");
+ }
+
+ @(name)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ else
+ {
+
+ }
+
+
+
+@code
+{
+ private MailTemplate[] MailTemplateFiles;
+ private FileAccess FileAccess;
+ private LazyLoader LazyLoader;
+
+ private MailTemplate? CurrentMailTemplate;
+ private string CurrentMailTemplateContent;
+
+ private async Task Load(LazyLoader arg)
+ {
+ FileAccess = new HostFileAccess(PathBuilder.Dir("storage"));
+
+ await FileAccess.Cd("resources");
+ await FileAccess.Cd("mail");
+
+ MailTemplateFiles = (await FileAccess.Ls())
+ .Where(x => x.IsFile)
+ .Select(x => new MailTemplate()
+ {
+ Name = x.Name,
+ File = x
+ })
+ .ToArray();
+ }
+
+ private async Task EditTemplate(MailTemplate mailTemplate)
+ {
+ CurrentMailTemplate = mailTemplate;
+
+ CurrentMailTemplateContent = await FileAccess
+ .Read(CurrentMailTemplate.File);
+
+ await InvokeAsync(StateHasChanged);
+ }
+
+ private async Task DeleteTemplate(MailTemplate mailTemplate)
+ {
+ await FileAccess.Delete(mailTemplate.File);
+ await LazyLoader.Reload();
+ }
+
+ private async void OnCancelTemplateEdit()
+ {
+ CurrentMailTemplate = null;
+ await InvokeAsync(StateHasChanged);
+ }
+
+ private async void OnSubmitTemplateEdit(string text)
+ {
+ await FileAccess.Write(CurrentMailTemplate!.File, text);
+
+ await ToastService.Success(
+ SmartTranslateService.Translate("Successfully saved file"));
+ }
+
+ private async Task CreateNewMailTemplate()
+ {
+ var name = await AlertService.Text(
+ SmartTranslateService.Translate("New mail template"),
+ SmartTranslateService.Translate("Enter the name of the new template"),
+ ""
+ );
+
+ if(string.IsNullOrEmpty(name))
+ return;
+
+ await FileAccess.Write(new()
+ {
+ Name = name + ".html"
+ }, "");
+
+ await LazyLoader.Reload();
+ }
+}
\ No newline at end of file