Просмотр исходного кода

Added support chat sync. Added admin support chat pages

Marcel Baumgartner 2 лет назад
Родитель
Сommit
8f3f9fa1fb

+ 1 - 0
.gitignore

@@ -443,3 +443,4 @@ Moonlight/obj/project.assets.json
 Moonlight/obj/project.nuget.cache
 Moonlight/obj/project.packagespec.json
 Moonlight/obj/Debug/net6.0/Moonlight.GeneratedMSBuildEditorConfig.editorconfig
+*.editorconfig

+ 1 - 5
Moonlight/App/Services/ServerService.cs

@@ -1,8 +1,4 @@
-using System.Security.Cryptography;
-using System.Text;
-using JWT.Algorithms;
-using JWT.Builder;
-using Logging.Net;
+using Logging.Net;
 using Microsoft.EntityFrameworkCore;
 using Moonlight.App.Database;
 using Moonlight.App.Database.Entities;

+ 7 - 2
Moonlight/App/Services/Support/SupportAdminServer.cs → Moonlight/App/Services/Support/SupportAdminService.cs

@@ -3,7 +3,7 @@ using Moonlight.App.Services.Sessions;
 
 namespace Moonlight.App.Services.Support;
 
-public class SupportAdminServer
+public class SupportAdminService
 {
     private readonly SupportServerService SupportServerService;
     private readonly IdentityService IdentityService;
@@ -14,7 +14,7 @@ public class SupportAdminServer
     private User Self;
     private User Recipient;
 
-    public SupportAdminServer(
+    public SupportAdminService(
         SupportServerService supportServerService,
         IdentityService identityService,
         MessageService messageService)
@@ -60,6 +60,11 @@ public class SupportAdminServer
         );
     }
 
+    public async Task Close()
+    {
+        await SupportServerService.Close(Recipient);
+    }
+
     public void Dispose()
     {
         MessageService.Unsubscribe($"support.{Recipient.Id}.message", this);

+ 56 - 22
Moonlight/App/Services/Support/SupportServerService.cs

@@ -27,36 +27,70 @@ public class SupportServerService : IDisposable
 
         Task.Run(async () =>
         {
-            message.CreatedAt = DateTime.UtcNow;
-            message.Sender = sender;
-            message.Recipient = recipient;
-            message.IsSupport = isSupport;
+            try
+            {
+                message.CreatedAt = DateTime.UtcNow;
+                message.Sender = sender;
+                message.Recipient = recipient;
+                message.IsSupport = isSupport;
 
-            SupportMessageRepository.Add(message);
+                SupportMessageRepository.Add(message);
 
-            await MessageService.Emit($"support.{recipient.Id}.message", message);
+                await MessageService.Emit($"support.{recipient.Id}.message", message);
 
-            if (!recipient.SupportPending)
+                if (!recipient.SupportPending)
+                {
+                    recipient.SupportPending = true;
+                    UserRepository.Update(recipient);
+
+                    if (!message.IsSupport)
+                    {
+                        var systemMessage = new SupportMessage()
+                        {
+                            Recipient = recipient,
+                            Sender = null,
+                            IsSystem = true,
+                            Message = "The support team has been notified. Please be patient"
+                        };
+
+                        SupportMessageRepository.Add(systemMessage);
+
+                        await MessageService.Emit($"support.{recipient.Id}.message", systemMessage);
+                    }
+                
+                    await MessageService.Emit($"support.new", recipient);
+
+                    Logger.Info("Support ticket created: " + recipient.Id);
+                    //TODO: Ping or so
+                }
+            }
+            catch (Exception e)
             {
-                recipient.SupportPending = true;
-                UserRepository.Update(recipient);
+                Logger.Error("Error sending message");
+                Logger.Error(e);
+            }
+        });
+    }
 
-                var systemMessage = new SupportMessage()
-                {
-                    Recipient = recipient,
-                    Sender = null,
-                    IsSystem = true,
-                    Message = "The support team has been notified. Please be patient"
-                };
+    public async Task Close(User user)
+    {
+        var recipient = UserRepository.Get().First(x => x.Id == user.Id);
+        
+        recipient.SupportPending = false;
+        UserRepository.Update(recipient);
 
-                SupportMessageRepository.Add(systemMessage);
+        var systemMessage = new SupportMessage()
+        {
+            Recipient = recipient,
+            Sender = null,
+            IsSystem = true,
+            Message = "The ticket is now closed. Type a message to open it again"
+        };
 
-                await MessageService.Emit($"support.{recipient.Id}.message", systemMessage);
+        SupportMessageRepository.Add(systemMessage);
 
-                Logger.Info("Support ticket created: " + recipient.Id);
-                //TODO: Ping or so
-            }
-        });
+        await MessageService.Emit($"support.{recipient.Id}.message", systemMessage);
+        await MessageService.Emit($"support.close", recipient);
     }
 
     public Task<SupportMessage[]> GetMessages(User r)

+ 0 - 1
Moonlight/Moonlight.csproj

@@ -60,7 +60,6 @@
     <Folder Include="App\Http\Middleware" />
     <Folder Include="App\Models\AuditLogData" />
     <Folder Include="resources\lang" />
-    <Folder Include="Shared\Views\Admin\Support" />
     <Folder Include="wwwroot\assets\media" />
   </ItemGroup>
 

+ 1 - 1
Moonlight/Program.cs

@@ -62,7 +62,7 @@ namespace Moonlight
 
             // Support
             builder.Services.AddSingleton<SupportServerService>();
-            builder.Services.AddScoped<SupportAdminServer>();
+            builder.Services.AddScoped<SupportAdminService>();
             builder.Services.AddScoped<SupportClientService>();
 
             // Helpers

+ 157 - 0
Moonlight/Shared/Views/Admin/Support/Index.razor

@@ -0,0 +1,157 @@
+@page "/admin/support"
+@using Moonlight.App.Repositories
+@using Moonlight.App.Database.Entities
+@using Microsoft.EntityFrameworkCore
+@using Moonlight.App.Database
+@using Moonlight.App.Services
+
+@inject SupportMessageRepository SupportMessageRepository
+@inject ConfigService ConfigService
+@inject MessageService MessageService
+@implements IDisposable
+
+<OnlyAdmin>
+    <LazyLoader @ref="LazyLoader" Load="Load">
+        <div class="card">
+            <div class="card-body">
+                <div class="d-flex flex-column flex-xl-row p-7">
+                    <div class="flex-lg-row-fluid me-xl-15 mb-20 mb-xl-0">
+                        <div class="mb-0">
+                            <h1 class="text-dark mb-10">
+                                <TL>Open tickets</TL>
+                            </h1>
+                            <div class="mb-10">
+                                @if (Users.Any())
+                                {
+                                    foreach (var user in Users)
+                                    {
+                                        <div class="d-flex mb-10">
+                                            <span class="svg-icon svg-icon-2x me-5 ms-n1 mt-2 svg-icon-success">
+                                                <i class="text-primary bx bx-md bx-message-dots"></i>
+                                            </span>
+    
+                                            <div class="d-flex flex-column">
+                                                <div class="d-flex align-items-center mb-2">
+                                                    <a href="/admin/support/view/@(user.Id)" class="text-dark text-hover-primary fs-4 me-3 fw-semibold">
+                                                        @(user.FirstName) @(user.LastName)
+                                                    </a>
+                                                </div>
+    
+                                                <span class="text-muted fw-semibold fs-6">
+                                                    @{
+                                                        var lastMessage = MessageCache.ContainsKey(user) ? MessageCache[user] : null;
+                                                    }
+    
+                                                    @if (lastMessage == null)
+                                                    {
+                                                        <TL>No message sent yet</TL>
+                                                    }
+                                                    else
+                                                    {
+                                                        @(lastMessage.Message)
+                                                    }
+                                                </span>
+                                            </div>
+                                        </div>
+                                    }
+                                }
+                                else
+                                {
+                                    <div class="alert alert-info">
+                                        <TL>No support ticket is currently open</TL>
+                                    </div>
+                                }
+                            </div>
+                        </div>
+                    </div>
+    
+                    <div class="flex-column flex-lg-row-auto w-100 mw-lg-300px mw-xxl-350px">
+    
+                        <div class="card-rounded bg-primary bg-opacity-5 p-10 mb-15">
+                            <h2 class="text-dark fw-bold mb-11">
+                                <TL>Actions</TL>
+                            </h2>
+    
+                            <div class="d-flex align-items-center mb-10">
+                                <!--begin::Icon-->
+                                <i class="bi bi-file-earmark-text text-primary fs-1 me-5"></i>
+                                <!--end::SymIconbol-->
+    
+                                <!--begin::Info-->
+                                <div class="d-flex flex-column">
+                                    <h5 class="text-gray-800 fw-bold">Project Briefing</h5>
+    
+                                    <!--begin::Section-->
+                                    <div class="fw-semibold">
+                                        <!--begin::Desc-->
+                                        <span class="text-muted">Check out our</span>
+                                        <!--end::Desc-->
+    
+                                        <!--begin::Link-->
+                                        <a href="#" class="link-primary">Support Policy</a>
+                                        <!--end::Link-->
+                                    </div>
+                                    <!--end::Section-->
+                                </div>
+                                <!--end::Info-->
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </LazyLoader>
+</OnlyAdmin>
+
+@code
+{
+    private User[] Users;
+    private Dictionary<User, SupportMessage?> MessageCache;
+
+    private LazyLoader? LazyLoader;
+
+    protected override void OnInitialized()
+    {
+        MessageCache = new();
+        
+        MessageService.Subscribe<Index, User>("support.new", this, async user =>
+        {
+            if (LazyLoader != null)
+                await LazyLoader.Reload();
+        });
+        
+        MessageService.Subscribe<Index, User>("support.close", this, async user =>
+        {
+            if (LazyLoader != null)
+                await LazyLoader.Reload();
+        });
+    }
+
+    private Task Load(LazyLoader arg)
+    {
+        // We dont want cache here
+        Users = (new UserRepository(new DataContext(ConfigService)))
+            .Get()
+            .Where(x => x.SupportPending)
+            .ToArray();
+
+        foreach (var user in Users)
+        {
+            var lastMessage = SupportMessageRepository
+                .Get()
+                .Include(x => x.Recipient)
+                .OrderByDescending(x => x.Id)
+                .FirstOrDefault(x => x.Recipient!.Id == user.Id);
+
+            MessageCache.Add(user, lastMessage);
+        }
+
+        return Task.CompletedTask;
+    }
+
+    public void Dispose()
+    {
+        MessageService.Unsubscribe("support.new", this);
+        MessageService.Unsubscribe("support.close", this);
+    }
+}

+ 194 - 0
Moonlight/Shared/Views/Admin/Support/View.razor

@@ -0,0 +1,194 @@
+@page "/admin/support/view/{Id:int}"
+@using Moonlight.App.Services.Support
+@using Moonlight.App.Database.Entities
+@using Moonlight.App.Helpers
+@using Moonlight.App.Repositories
+@using Moonlight.App.Services
+
+@inject SupportAdminService SupportAdminService
+@inject UserRepository UserRepository
+@inject SmartTranslateService SmartTranslateService
+@inject ResourceService ResourceService
+
+<OnlyAdmin>
+    <LazyLoader Load="Load">
+        @if (User == null)
+        {
+            <div class="alert alert-danger">
+                <TL>User not found</TL>
+            </div>
+        }
+        else
+        {
+            <div class="row">
+                <div class="d-flex flex-column flex-xl-row p-7">
+                    <div class="flex-lg-row-fluid me-xl-15 mb-20 mb-xl-0">
+                        <div class="card">
+                            <div class="card-body">
+                                <LazyLoader Load="LoadMessages">
+                                    <div class="scroll-y me-n5 pe-5" style="max-height: 65vh; display: flex; flex-direction: column-reverse;">
+                                        @foreach (var message in Messages)
+                                        {
+                                            if (message.IsSystem || message.IsSupport)
+                                            {
+                                                <div class="d-flex justify-content-end mb-10 ">
+                                                    <div class="d-flex flex-column align-items-end">
+                                                        <div class="d-flex align-items-center mb-2">
+                                                            <div class="me-3">
+                                                                <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
+                                                                <a class="fs-5 fw-bold text-gray-900 text-hover-primary ms-1">
+                                                                    @if (message.IsSupport && !message.IsSystem)
+                                                                    {
+                                                                        <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
+                                                                    }
+                                                                    else
+                                                                    {
+                                                                        <span>System</span>
+                                                                    }
+                                                                </a>
+                                                            </div>
+                                                            <div class="symbol  symbol-35px symbol-circle ">
+                                                                <img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
+                                                            </div>
+                                                        </div>
+    
+                                                        <div class="p-5 rounded bg-light-primary text-dark fw-semibold mw-lg-400px text-end">
+                                                            @if (message.IsSystem)
+                                                            {
+                                                                <TL>@(message.Message)</TL>
+                                                            }
+                                                            else
+                                                            {
+                                                                @(message.Message)
+                                                            }
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            }
+                                            else
+                                            {
+                                                <div class="d-flex justify-content-start mb-10 ">
+                                                    <div class="d-flex flex-column align-items-start">
+                                                        <div class="d-flex align-items-center mb-2">
+                                                            <div class="symbol  symbol-35px symbol-circle ">
+                                                                <img alt="Avatar" src="@(ResourceService.Avatar(message.Sender))">
+                                                            </div>
+                                                            <div class="ms-3">
+                                                                <a class="fs-5 fw-bold text-gray-900 text-hover-primary me-1">
+                                                                    <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
+                                                                </a>
+                                                                <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
+                                                            </div>
+                                                        </div>
+    
+                                                        <div class="p-5 rounded bg-light-info text-dark fw-semibold mw-lg-400px text-start">
+                                                            @(message.Message)
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            }
+                                        }
+                                    </div>
+                                </LazyLoader>
+                            </div>
+                            <div class="card-footer">
+                                <textarea @bind="Content" class="form-control form-control-flush mb-3" rows="1" placeholder="Type a message">            
+                    </textarea>
+                                <div class="d-flex flex-stack">
+                                    <div class="d-flex align-items-center me-2">
+                                        <button class="btn btn-sm btn-icon btn-active-light-primary me-1" type="button">
+                                            <i class="bx bx-upload fs-3"></i>
+                                        </button>
+                                    </div>
+                                    <WButton Text="@(SmartTranslateService.Translate("Send"))"
+                                             WorkingText="@(SmartTranslateService.Translate("Sending"))"
+                                             CssClasses="btn-primary"
+                                             OnClick="Send">
+                                    </WButton>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="flex-column flex-lg-row-auto w-100 mw-lg-300px mw-xxl-350px">
+                        <div class="card p-10 mb-15">
+                            <h2 class="text-dark fw-bold mb-11">
+                                <TL>User information</TL>
+                            </h2>
+    
+                            <div class="d-flex align-items-center mb-6">
+                                <spna class="fw-semibold text-gray-800 fs-5 m-0">
+                                    <TL>Firstname</TL>: @(User.FirstName)
+                                </spna>
+                            </div>
+                            <div class="d-flex align-items-center mb-6">
+                                <spna class="fw-semibold text-gray-800 fs-5 m-0">
+                                    <TL>Lastname</TL>: @(User.LastName)
+                                </spna>
+                            </div>
+                            <div class="d-flex align-items-center mb-6">
+                                <spna class="fw-semibold text-gray-800 fs-5 m-0">
+                                    <TL>Email</TL>: @(User.Email)
+                                </spna>
+                            </div>
+                            <div class="d-flex align-items-center mb-6">
+                                <spna class="fw-semibold text-gray-800 fs-5 m-0">
+                                    <WButton Text="@(SmartTranslateService.Translate("Close ticket"))"
+                                             WorkingText="@(SmartTranslateService.Translate("Closing"))"
+                                             CssClasses="btn-danger"
+                                             OnClick="CloseTicket">
+                                    </WButton>
+                                </spna>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        }
+    </LazyLoader>
+</OnlyAdmin>
+
+@code
+{
+    [Parameter]
+    public int Id { get; set; }
+
+    private User? User;
+    private SupportMessage[] Messages;
+    private string Content = "";
+
+    private async Task Load(LazyLoader arg)
+    {
+        User = UserRepository
+            .Get()
+            .FirstOrDefault(x => x.Id == Id);
+
+        if (User != null)
+        {
+            SupportAdminService.OnNewMessage += OnNewMessage;
+
+            await SupportAdminService.Start(User);
+        }
+    }
+
+    private async void OnNewMessage(object? sender, SupportMessage e)
+    {
+        Messages = (await SupportAdminService.GetMessages()).Reverse().ToArray();
+        await InvokeAsync(StateHasChanged);
+    }
+
+    private async Task LoadMessages(LazyLoader arg)
+    {
+        Messages = (await SupportAdminService.GetMessages()).Reverse().ToArray();
+    }
+
+    private async Task Send()
+    {
+        await SupportAdminService.SendMessage(Content);
+        Content = "";
+    }
+
+    private async Task CloseTicket()
+    {
+        await SupportAdminService.Close();
+    }
+}

+ 73 - 61
Moonlight/Shared/Views/Support.razor

@@ -14,80 +14,89 @@
     <div class="row">
         <div class="card">
             <div class="card-body">
-                <div class="scroll-y me-n5 pe-5" style="max-height: 65vh; display: flex; flex-direction: column-reverse;">
-                    @foreach (var message in Messages)
-                    {
-                        if (message.IsSystem || message.IsSupport)
+                <LazyLoader Load="LoadMessages">
+                    <div class="scroll-y me-n5 pe-5" style="max-height: 65vh; display: flex; flex-direction: column-reverse;">
+                        @foreach (var message in Messages)
                         {
-                            <div class="d-flex justify-content-start mb-10 ">
-                                <div class="d-flex flex-column align-items-start">
-                                    <div class="d-flex align-items-center mb-2">
-                                        <div class="symbol  symbol-35px symbol-circle ">
-                                            <img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
+                            if (message.IsSystem || message.IsSupport)
+                            {
+                                <div class="d-flex justify-content-start mb-10 ">
+                                    <div class="d-flex flex-column align-items-start">
+                                        <div class="d-flex align-items-center mb-2">
+                                            <div class="symbol  symbol-35px symbol-circle ">
+                                                <img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
+                                            </div>
+                                            <div class="ms-3">
+                                                <a class="fs-5 fw-bold text-gray-900 text-hover-primary me-1">
+                                                    @if (message.IsSupport && !message.IsSystem)
+                                                    {
+                                                        <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
+                                                    }
+                                                    else
+                                                    {
+                                                        <span>System</span>
+                                                    }
+                                                </a>
+                                                <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
+                                            </div>
                                         </div>
-                                        <div class="ms-3">
-                                            <a class="fs-5 fw-bold text-gray-900 text-hover-primary me-1">
-                                                @if (message.IsSupport && !message.IsSystem)
-                                                {
-                                                    <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
-                                                }
-                                                else
-                                                {
-                                                    <span>System</span>
-                                                }
-                                            </a>
-                                            <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
-                                        </div>
-                                    </div>
 
-                                    <div class="p-5 rounded bg-light-info text-dark fw-semibold mw-lg-400px text-start">
-                                        @(message.Message)
+                                        <div class="p-5 rounded bg-light-info text-dark fw-semibold mw-lg-400px text-start">
+                                            @if (message.IsSystem)
+                                            {
+                                                <TL>@(message.Message)</TL>
+                                            }
+                                            else
+                                            {
+                                                @(message.Message)
+                                            }
+                                        </div>
                                     </div>
                                 </div>
-                            </div>
-                        }
-                        else
-                        {
-                            <div class="d-flex justify-content-end mb-10 ">
-                                <div class="d-flex flex-column align-items-end">
-                                    <div class="d-flex align-items-center mb-2">
-                                        <div class="me-3">
-                                            <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
-                                            <a class="fs-5 fw-bold text-gray-900 text-hover-primary ms-1">
-                                                <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
-                                            </a>
-                                        </div>
-                                        <div class="symbol  symbol-35px symbol-circle ">
-                                            <img alt="Avatar" src="@(ResourceService.Avatar(message.Sender))">
+                            }
+                            else
+                            {
+                                <div class="d-flex justify-content-end mb-10 ">
+                                    <div class="d-flex flex-column align-items-end">
+                                        <div class="d-flex align-items-center mb-2">
+                                            <div class="me-3">
+                                                <span class="text-muted fs-7 mb-1">@(Formatter.FormatAgoFromDateTime(message.CreatedAt, SmartTranslateService))</span>
+                                                <a class="fs-5 fw-bold text-gray-900 text-hover-primary ms-1">
+                                                    <span>@(message.Sender!.FirstName) @(message.Sender!.LastName)</span>
+                                                </a>
+                                            </div>
+                                            <div class="symbol  symbol-35px symbol-circle ">
+                                                <img alt="Avatar" src="@(ResourceService.Avatar(message.Sender))">
+                                            </div>
                                         </div>
-                                    </div>
 
-                                    <div class="p-5 rounded bg-light-primary text-dark fw-semibold mw-lg-400px text-end">
-                                        @(message.Message)
+                                        <div class="p-5 rounded bg-light-primary text-dark fw-semibold mw-lg-400px text-end">
+                                            @(message.Message)
+                                        </div>
                                     </div>
                                 </div>
-                            </div>
+                            }
                         }
-                    }
-                    <div class="d-flex justify-content-start mb-10 ">
-                        <div class="d-flex flex-column align-items-start">
-                            <div class="d-flex align-items-center mb-2">
-                                <div class="symbol  symbol-35px symbol-circle ">
-                                    <img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
-                                </div>
-                                <div class="ms-3">
-                                    <a class="fs-5 fw-bold text-gray-900 text-hover-primary me-1">
-                                        <span>System</span>
-                                    </a>
+                        <div class="d-flex justify-content-start mb-10 ">
+                            <div class="d-flex flex-column align-items-start">
+                                <div class="d-flex align-items-center mb-2">
+                                    <div class="symbol  symbol-35px symbol-circle ">
+                                        <img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
+                                    </div>
+                                    <div class="ms-3">
+                                        <a class="fs-5 fw-bold text-gray-900 text-hover-primary me-1">
+                                            <span>System</span>
+                                        </a>
+                                    </div>
                                 </div>
-                            </div>
 
-                            <div class="p-5 rounded bg-light-info text-dark fw-semibold mw-lg-400px text-start">
-                                <TL>Welcome to the support chat. Ask your question here and we will help you</TL>
+                                <div class="p-5 rounded bg-light-info text-dark fw-semibold mw-lg-400px text-start">
+                                    <TL>Welcome to the support chat. Ask your question here and we will help you</TL>
+                                </div>
                             </div>
                         </div>
                     </div>
-                </div>
+                </LazyLoader>
             </div>
             <div class="card-footer">
                 <textarea @bind="Content" class="form-control form-control-flush mb-3" rows="1" placeholder="Type a message">            
@@ -125,8 +134,6 @@
         SupportClientService.OnNewMessage += OnNewMessage;
 
         await SupportClientService.Start();
-
-        Messages = (await SupportClientService.GetMessages()).Reverse().ToArray();
     }
 
     private async void OnNewMessage(object? sender, SupportMessage e)
@@ -141,4 +148,9 @@
         Content = "";
         await InvokeAsync(StateHasChanged);
     }
+
+    private async Task LoadMessages(LazyLoader arg)
+    {
+        Messages = (await SupportClientService.GetMessages()).Reverse().ToArray();
+    }
 }

+ 8 - 0
Moonlight/obj/Debug/net6.0/Moonlight.GeneratedMSBuildEditorConfig.editorconfig

@@ -199,6 +199,14 @@ build_metadata.AdditionalFiles.CssScope =
 build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFNlcnZlcnNcTmV3LnJhem9y
 build_metadata.AdditionalFiles.CssScope = 
 
+[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Views/Admin/Support/Index.razor]
+build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFN1cHBvcnRcSW5kZXgucmF6b3I=
+build_metadata.AdditionalFiles.CssScope = 
+
+[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Views/Admin/Support/View.razor]
+build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFN1cHBvcnRcVmlldy5yYXpvcg==
+build_metadata.AdditionalFiles.CssScope = 
+
 [C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Views/Index.razor]
 build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEluZGV4LnJhem9y
 build_metadata.AdditionalFiles.CssScope = 

+ 9 - 0
Moonlight/resources/lang/de_de.lang

@@ -215,3 +215,12 @@ less than a minute ago;less than a minute ago
 1 hour ago;1 hour ago
 1 minute ago;1 minute ago
 Failed;Failed
+ hours ago; hours ago
+Open tickets;Open tickets
+Actions;Actions
+No support ticket is currently open;No support ticket is currently open
+User information;User information
+Close ticket;Close ticket
+Closing;Closing
+The support team has been notified. Please be patient;The support team has been notified. Please be patient
+The ticket is now closed. Type a message to open it again;The ticket is now closed. Type a message to open it again