AuthorBuddy/Components/Pages/Settings.razor
2026-05-14 12:31:35 +02:00

200 lines
7.2 KiB
Text

@page "/settings"
@inject IDbContextFactory<AppDbContext> ContextFactory
@inject IOllamaService OllamaService
@inject OllamaSettings OllamaConfig
@inject NavigationManager Navigation
@inject IJSRuntime JSRuntime
@inject IProjectService ProjectService
<PageTitle>Einstellungen - Author Buddy</PageTitle>
<div class="settings-page">
<div class="settings-section">
<h3 class="settings-section-title">Modelle</h3>
<div class="form-group">
<label for="ragModel">RAG-Modell (Faktenabfrage):</label>
<select id="ragModel" @bind="ragModel">
@if (availableModels.Count == 0)
{
<option value="">Keine Modelle gefunden</option>
}
@foreach (var m in availableModels)
{
<option value="@m.Model1">@m.Model1</option>
}
</select>
</div>
<div class="form-group">
<label for="styleModel">Stil-Modell (Lektorat):</label>
<select id="styleModel" @bind="styleModel">
@if (availableModels.Count == 0)
{
<option value="">Keine Modelle gefunden</option>
}
@foreach (var m in availableModels)
{
<option value="@m.Model1">@m.Model1</option>
}
</select>
</div>
<div class="form-group">
<label for="spellingModel">Rechtschreibprüfungs-Modell:</label>
<select id="spellingModel" @bind="spellingModel">
@if (availableModels.Count == 0)
{
<option value="">Keine Modelle gefunden</option>
}
@foreach (var m in availableModels)
{
<option value="@m.Model1">@m.Model1</option>
}
</select>
</div>
</div>
<div class="settings-section">
<h3 class="settings-section-title">Ollama Server</h3>
<div class="form-group">
<label for="ollamaUrl">Server-URL:</label>
<input id="ollamaUrl" @bind="ollamaUrl" placeholder="http://localhost:11434" />
<div class="form-hint">Adresse des Ollama-Servers (z. B. http://192.168.1.100:11434)</div>
</div>
</div>
<div class="settings-section">
<h3 class="settings-section-title">Design</h3>
<div class="form-group">
<label for="themeSelect">Theme:</label>
<select id="themeSelect" @bind="selectedTheme">
<option value="light">Hell</option>
<option value="dark">Dunkel</option>
<option value="w95">W95 (Retro)</option>
</select>
</div>
</div>
<div class="settings-section">
<h3 class="settings-section-title">Neues Projekt</h3>
<div class="form-group">
<label for="projectName">Projektname:</label>
<input id="projectName" @bind="newProjectName" placeholder="Projektname" />
<div class="form-hint">Der Projektordner wird in &quot;Dokumente\AuthorBuddy\&quot; erstellt.</div>
</div>
<button @onclick="CreateProject" disabled="@(string.IsNullOrWhiteSpace(newProjectName))">Projekt erstellen</button>
</div>
<div class="form-actions">
<button class="primary" @onclick="SaveSettings">Speichern</button>
<button @onclick='() => Navigation.NavigateTo("/")'>Abbrechen</button>
</div>
@if (!string.IsNullOrEmpty(statusMessage))
{
<div class="settings-status">@statusMessage</div>
}
</div>
@code {
private string ragModel = "llama3.2";
private string styleModel = "llama3.2";
private string spellingModel = "phi3:mini";
private string selectedTheme = "light";
private string ollamaUrl = "http://localhost:11434";
private string newProjectName = string.Empty;
private string statusMessage = string.Empty;
private List<Ollama.Model> availableModels = new();
protected override async Task OnInitializedAsync()
{
await using var context = await ContextFactory.CreateDbContextAsync();
ragModel = await GetSettingAsync(context, "ollama_rag_model") ?? "llama3.2";
styleModel = await GetSettingAsync(context, "ollama_style_model") ?? "llama3.2";
spellingModel = await GetSettingAsync(context, "ollama_spelling_model") ?? "phi3:mini";
selectedTheme = await GetSettingAsync(context, "theme") ?? "light";
ollamaUrl = await GetSettingAsync(context, "ollama_url") ?? "http://localhost:11434";
try
{
var models = await OllamaService.GetLocalModelsAsync();
availableModels = models.ToList();
}
catch
{
availableModels = new();
}
}
private static async Task<string?> GetSettingAsync(AppDbContext context, string key)
{
var setting = await context.Settings.FindAsync(key);
return setting?.Value;
}
private static async Task SaveSettingAsync(AppDbContext context, string key, string value)
{
var existing = await context.Settings.FindAsync(key);
if (existing != null)
{
existing.Value = value;
}
else
{
context.Settings.Add(new SettingEntity { Key = key, Value = value });
}
}
private async Task SaveSettings()
{
await using var context = await ContextFactory.CreateDbContextAsync();
await SaveSettingAsync(context, "ollama_rag_model", ragModel);
await SaveSettingAsync(context, "ollama_style_model", styleModel);
await SaveSettingAsync(context, "ollama_spelling_model", spellingModel);
await SaveSettingAsync(context, "theme", selectedTheme);
await SaveSettingAsync(context, "ollama_url", ollamaUrl);
await context.SaveChangesAsync();
OllamaConfig.OllamaUrl = ollamaUrl;
OllamaConfig.ChatModel = ragModel;
OllamaConfig.SpellingModel = spellingModel;
await OllamaService.ReconfigureAsync(ollamaUrl);
statusMessage = "Einstellungen gespeichert.";
await ApplyTheme(selectedTheme);
}
private async Task CreateProject()
{
if (string.IsNullOrWhiteSpace(newProjectName)) return;
try
{
string rootPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"AuthorBuddy",
newProjectName);
await ProjectService.CreateNewProjectAsync(newProjectName, rootPath);
statusMessage = $"Projekt '{newProjectName}' erstellt unter: {rootPath}";
newProjectName = string.Empty;
}
catch (Exception ex)
{
statusMessage = $"Fehler beim Erstellen: {ex.Message}";
}
}
private async Task ApplyTheme(string theme)
{
await JSRuntime.InvokeVoidAsync("eval",
$"document.getElementById('theme-css')?.remove(); " +
$"var link = document.createElement('link'); " +
$"link.id = 'theme-css'; " +
$"link.rel = 'stylesheet'; " +
$"link.href = 'css/themes/{theme}.css'; " +
$"document.head.appendChild(link);");
}
}