Files
Matthias Hinrichs 189e7a2329 first commit
2025-08-26 03:17:49 +02:00

1222 lines
94 KiB
Go

// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
package views
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"time"
"whereismymoney/internal/models"
)
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func Transactions(userName string, transactions []models.Transaction, bankAccounts []models.BankAccount, categories []models.Category, recurrenceRules []models.RecurrenceRule, currentPage int, totalPages int, totalCount int64) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = Navigation(userName).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <!-- Main Content --> <div class=\"min-h-screen bg-gray-50\"><div class=\"max-w-7xl mx-auto py-6 sm:px-6 lg:px-8\"><div class=\"px-4 py-6 sm:px-0\"><!-- Page Header --><div class=\"mb-8\"><h1 class=\"text-3xl font-bold text-gray-900\">Transaktionen</h1><p class=\"mt-2 text-gray-600\">Verwalte deine Einnahmen und Ausgaben</p></div><!-- Action Buttons --><div class=\"mb-6 flex gap-4\"><button onclick=\"showModal(&#39;transactionModal&#39;)\" class=\"bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg font-medium\">📝 Neue Transaktion</button> <button onclick=\"showModal(&#39;recurringModal&#39;)\" class=\"bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg font-medium\">🔄 Regelmäßige Transaktion</button></div><!-- Filter Section --><div class=\"bg-white shadow-sm rounded-lg mb-6\"><div class=\"px-6 py-4\"><h3 class=\"text-lg font-medium text-gray-900 mb-4\">Filter & Suche</h3><form id=\"filterForm\" class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\"><!-- Datumsbereich --><div><label for=\"date_from\" class=\"block text-sm font-medium text-gray-700\">Von Datum</label> <input type=\"date\" id=\"date_from\" name=\"date_from\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><div><label for=\"date_to\" class=\"block text-sm font-medium text-gray-700\">Bis Datum</label> <input type=\"date\" id=\"date_to\" name=\"date_to\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><!-- Beschreibung --><div><label for=\"search_description\" class=\"block text-sm font-medium text-gray-700\">Beschreibung</label> <input type=\"text\" id=\"search_description\" name=\"search_description\" placeholder=\"z.B. Supermarkt\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><!-- Kategorie --><div><label for=\"filter_category\" class=\"block text-sm font-medium text-gray-700\">Kategorie</label> <select id=\"filter_category\" name=\"filter_category\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Alle Kategorien</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, category := range categories {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", category.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 74, Col: 57}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 74, Col: 75}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 74, Col: 93}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><!-- Konto --><div><label for=\"filter_account\" class=\"block text-sm font-medium text-gray-700\">Konto</label> <select id=\"filter_account\" name=\"filter_account\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Alle Konten</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, account := range bankAccounts {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", account.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 85, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(account.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 85, Col: 73}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(account.Bank)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 85, Col: 91}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(")</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><!-- Transaktionstyp --><div><label for=\"filter_type\" class=\"block text-sm font-medium text-gray-700\">Typ</label> <select id=\"filter_type\" name=\"filter_type\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Alle Typen</option> <option value=\"income\">Einnahmen</option> <option value=\"expense\">Ausgaben</option></select></div><!-- Betrag --><div><label for=\"amount_min\" class=\"block text-sm font-medium text-gray-700\">Min. Betrag</label> <input type=\"number\" id=\"amount_min\" name=\"amount_min\" step=\"0.01\" placeholder=\"0.00\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><div><label for=\"amount_max\" class=\"block text-sm font-medium text-gray-700\">Max. Betrag</label> <input type=\"number\" id=\"amount_max\" name=\"amount_max\" step=\"0.01\" placeholder=\"9999.99\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div></form><!-- Filter Buttons --><div class=\"mt-4 flex flex-wrap gap-2\"><button type=\"button\" id=\"applyFilter\" onclick=\"applyFilters()\" class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500\">Filter anwenden</button> <button type=\"button\" id=\"clearFilter\" onclick=\"clearFilters()\" class=\"px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500\">Filter zurücksetzen</button><div id=\"filterStatus\" class=\"flex items-center text-sm text-gray-600\"><span id=\"filterCount\">Alle Transaktionen werden angezeigt</span></div></div></div></div><!-- Tabs --><div class=\"mb-6\"><div class=\"border-b border-gray-200\"><nav class=\"-mb-px flex space-x-8\"><button onclick=\"showTab(&#39;transactions&#39;)\" id=\"tab-transactions\" class=\"tab-button border-b-2 border-blue-500 text-blue-600 py-2 px-1 text-sm font-medium\">Alle Transaktionen</button> <button onclick=\"showTab(&#39;recurring&#39;)\" id=\"tab-recurring\" class=\"tab-button border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 py-2 px-1 text-sm font-medium\">Regelmäßige Transaktionen</button></nav></div></div><!-- Transactions Table --><div id=\"transactions-content\" class=\"tab-content\"><div class=\"bg-white shadow-sm rounded-lg overflow-hidden\"><div class=\"px-6 py-4 border-b border-gray-200 flex justify-between items-center\"><h2 class=\"text-lg font-medium text-gray-900\">Letzte Transaktionen</h2><div id=\"multiEditControls\" class=\"hidden flex space-x-2\"><button onclick=\"openMultiEditModal()\" class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500\"><span id=\"selectedCount\">0</span> ausgewählte bearbeiten</button> <button onclick=\"openMultiDeleteConfirm()\" class=\"px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500\"><span id=\"selectedCountDelete\">0</span> ausgewählte löschen</button></div></div><div class=\"overflow-x-auto\"><table class=\"min-w-full divide-y divide-gray-200\"><thead class=\"bg-gray-50\"><tr><th class=\"px-3 py-3 text-left\"><input type=\"checkbox\" id=\"selectAll\" class=\"rounded border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50\" onchange=\"toggleSelectAll()\"></th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Datum</th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Beschreibung</th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Kategorie</th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Konto</th><th class=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\">Betrag</th><th class=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\">Aktionen</th></tr></thead> <tbody class=\"bg-white divide-y divide-gray-200\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if len(transactions) == 0 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><td colspan=\"7\" class=\"px-6 py-4 text-center text-gray-500\">Noch keine Transaktionen vorhanden</td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
for _, transaction := range transactions {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr class=\"hover:bg-gray-50\"><td class=\"px-3 py-4 whitespace-nowrap\"><input type=\"checkbox\" class=\"transaction-checkbox rounded border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", transaction.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 182, Col: 58}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" onchange=\"updateMultiEditControls()\"></td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-900\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(transaction.Date.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 185, Col: 52}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 text-sm text-gray-900\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(transaction.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 188, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if transaction.IsRecurring {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800 ml-2\">🔄 Regelmäßig</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if transaction.Category != nil {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(transaction.Category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 198, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(transaction.Category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 198, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-gray-400\">Ohne Kategorie</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if transaction.BankAccount != nil {
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(transaction.BankAccount.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 206, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-gray-400\">Ohne Konto</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-right\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if transaction.Type == "income" {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-green-600 font-medium\">+")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.2f", transaction.Amount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 213, Col: 97}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" €</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-red-600 font-medium\">-")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.2f", transaction.Amount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 215, Col: 95}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" €</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\"><button data-transaction-id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", transaction.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 219, Col: 76}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"edit-transaction text-blue-600 hover:text-blue-900 mr-2\" title=\"Transaktion bearbeiten\">✏️</button> <button data-transaction-id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", transaction.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 222, Col: 76}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"delete-transaction text-red-600 hover:text-red-900\" title=\"Transaktion löschen\">🗑️</button></td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody></table></div><!-- Pagination -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if totalPages > 1 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-6 py-4 border-t border-gray-200 bg-gray-50\"><div class=\"flex items-center justify-between\"><div class=\"text-sm text-gray-700\">Zeige ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", (currentPage-1)*20+1))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 236, Col: 58}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" bis ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", min(currentPage*20, int(totalCount))))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 236, Col: 122}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" von ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", totalCount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 236, Col: 160}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" Transaktionen</div><div class=\"flex items-center space-x-2\"><!-- Previous Button -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if currentPage > 1 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 templ.SafeURL = templ.URL(fmt.Sprintf("/transactions?page=%d", currentPage-1))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var22)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:text-gray-700 hover:bg-gray-50\">Vorherige</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"px-3 py-2 text-sm font-medium text-gray-300 bg-gray-100 border border-gray-300 rounded-md cursor-not-allowed\">Vorherige</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!-- Page Numbers --><div class=\"flex items-center space-x-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if currentPage > 3 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 templ.SafeURL = templ.URL("/transactions?page=1")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var23)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:text-gray-700 hover:bg-gray-50\">1</a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if currentPage > 4 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"px-2 py-2 text-sm text-gray-500\">...</span> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
}
for i := max(1, currentPage-2); i <= min(totalPages, currentPage+2); i++ {
if i == currentPage {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"px-3 py-2 text-sm font-medium text-white bg-blue-600 border border-blue-600 rounded-md\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var24 string
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", i))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 264, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var25 templ.SafeURL = templ.URL(fmt.Sprintf("/transactions?page=%d", i))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var25)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:text-gray-700 hover:bg-gray-50\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", i))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 268, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
}
if currentPage < totalPages-2 {
if currentPage < totalPages-3 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"px-2 py-2 text-sm text-gray-500\">...</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var27 templ.SafeURL = templ.URL(fmt.Sprintf("/transactions?page=%d", totalPages))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var27)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:text-gray-700 hover:bg-gray-50\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", totalPages))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 278, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><!-- Next Button -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if currentPage < totalPages {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var29 templ.SafeURL = templ.URL(fmt.Sprintf("/transactions?page=%d", currentPage+1))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var29)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:text-gray-700 hover:bg-gray-50\">Nächste</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"px-3 py-2 text-sm font-medium text-gray-300 bg-gray-100 border border-gray-300 rounded-md cursor-not-allowed\">Nächste</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div><!-- Recurring Transactions Table --><div id=\"recurring-content\" class=\"tab-content hidden\"><div class=\"bg-white shadow-sm rounded-lg overflow-hidden\"><div class=\"px-6 py-4 border-b border-gray-200\"><h2 class=\"text-lg font-medium text-gray-900\">Regelmäßige Transaktionen</h2></div><div class=\"overflow-x-auto\"><table class=\"min-w-full divide-y divide-gray-200\"><thead class=\"bg-gray-50\"><tr><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Beschreibung</th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Intervall</th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Nächste Ausführung</th><th class=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\">Betrag</th><th class=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\">Status</th><th class=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\">Aktionen</th></tr></thead> <tbody class=\"bg-white divide-y divide-gray-200\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if len(recurrenceRules) == 0 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><td colspan=\"6\" class=\"px-6 py-4 text-center text-gray-500\">Noch keine regelmäßigen Transaktionen vorhanden</td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
for _, rule := range recurrenceRules {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr class=\"hover:bg-gray-50\"><td class=\"px-6 py-4 text-sm text-gray-900\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(rule.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 329, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if rule.Category != nil {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-xs text-gray-500 mt-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var31 string
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(rule.Category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 332, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var32 string
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(rule.Category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 332, Col: 58}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var33 string
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(getIntervalText(rule.Interval, rule.IntervalCount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 337, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var34 string
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(getNextExecutionDate(rule))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 340, Col: 41}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-right\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if rule.Type == "income" {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-green-600 font-medium\">+")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var35 string
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.2f", rule.Amount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 344, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" €</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-red-600 font-medium\">-")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var36 string
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.2f", rule.Amount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 346, Col: 88}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" €</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-right\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if rule.IsActive {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800\">Aktiv</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800\">Pausiert</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td class=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\"><button data-rule-id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var37 string
templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", rule.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 361, Col: 62}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"toggle-recurrence text-blue-600 hover:text-blue-900 mr-2\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if rule.IsActive {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("⏸️")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("▶️")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody></table></div></div></div></div></div></div><!-- Transaction Modal --> <div id=\"transactionModal\" class=\"fixed inset-0 bg-gray-600 bg-opacity-50 hidden z-50\"><div class=\"flex items-center justify-center min-h-screen px-4\"><div class=\"bg-white rounded-lg shadow-xl max-w-md w-full\"><form method=\"POST\" action=\"/transactions\"><div class=\"px-6 py-4 border-b border-gray-200\"><h3 class=\"text-lg font-medium text-gray-900\">Neue Transaktion</h3></div><div class=\"px-6 py-4 space-y-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Beschreibung</label> <input type=\"text\" name=\"description\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" placeholder=\"z.B. Supermarkt Einkauf\"></div><div class=\"grid grid-cols-2 gap-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Betrag</label> <input type=\"number\" name=\"amount\" step=\"0.01\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" placeholder=\"0.00\"></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Typ</label> <select name=\"type\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Wählen...</option> <option value=\"income\">💰 Einnahme</option> <option value=\"expense\">💸 Ausgabe</option></select></div></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Datum</label> <input type=\"date\" name=\"date\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var38 string
templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(time.Now().Format("2006-01-02"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 409, Col: 207}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Kategorie (optional)</label> <select name=\"category_id\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Ohne Kategorie</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, category := range categories {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var39 string
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", category.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 416, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var40 string
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 416, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var41 string
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 416, Col: 92}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Bankkonto (optional)</label> <select name=\"bank_account_id\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Ohne Konto</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, account := range bankAccounts {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var42 string
templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", account.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 425, Col: 55}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var43 string
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(account.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 425, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var44 string
templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(account.Bank)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 425, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(")</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div></div><div class=\"px-6 py-4 bg-gray-50 flex justify-end space-x-3\"><button type=\"button\" onclick=\"hideModal(&#39;transactionModal&#39;)\" class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50\">Abbrechen</button> <button type=\"submit\" class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700\">Erstellen</button></div></form></div></div></div><!-- Edit Transaction Modal --> <div id=\"editTransactionModal\" class=\"fixed inset-0 bg-gray-600 bg-opacity-50 hidden z-50\"><div class=\"flex items-center justify-center min-h-screen px-4\"><div class=\"bg-white rounded-lg shadow-xl max-w-md w-full\"><form id=\"editTransactionForm\" method=\"POST\"><div class=\"px-6 py-4 border-b border-gray-200\"><h3 class=\"text-lg font-medium text-gray-900\">Transaktion bearbeiten</h3></div><div class=\"px-6 py-4 space-y-4\"><div><label for=\"edit_description\" class=\"block text-sm font-medium text-gray-700\">Beschreibung</label> <input type=\"text\" id=\"edit_description\" name=\"description\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><div><label for=\"edit_amount\" class=\"block text-sm font-medium text-gray-700\">Betrag</label> <input type=\"number\" id=\"edit_amount\" name=\"amount\" step=\"0.01\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><div><label for=\"edit_type\" class=\"block text-sm font-medium text-gray-700\">Typ</label> <select id=\"edit_type\" name=\"type\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"expense\">Ausgabe</option> <option value=\"income\">Einnahme</option></select></div><div><label for=\"edit_date\" class=\"block text-sm font-medium text-gray-700\">Datum</label> <input type=\"date\" id=\"edit_date\" name=\"date\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div><div><label for=\"edit_category_id\" class=\"block text-sm font-medium text-gray-700\">Kategorie</label> <select id=\"edit_category_id\" name=\"category_id\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Keine Kategorie</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, category := range categories {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var45 string
templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", category.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 476, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var46 string
templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 476, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var47 string
templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 476, Col: 92}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><div><label for=\"edit_bank_account_id\" class=\"block text-sm font-medium text-gray-700\">Konto</label> <select id=\"edit_bank_account_id\" name=\"bank_account_id\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, account := range bankAccounts {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var48 string
templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", account.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 484, Col: 55}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var49 string
templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(account.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 484, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var50 string
templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(account.Bank)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 484, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(")</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div></div><div class=\"px-6 py-4 border-t border-gray-200 flex justify-end space-x-3\"><button type=\"button\" onclick=\"closeEditTransactionModal()\" class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200\">Abbrechen</button> <button type=\"submit\" class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700\">Speichern</button></div></form></div></div></div><!-- Recurring Transaction Modal --> <div id=\"recurringModal\" class=\"fixed inset-0 bg-gray-600 bg-opacity-50 hidden z-50\"><div class=\"flex items-center justify-center min-h-screen px-4\"><div class=\"bg-white rounded-lg shadow-xl max-w-lg w-full max-h-screen overflow-y-auto\"><form method=\"POST\" action=\"/transactions/recurring\"><div class=\"px-6 py-4 border-b border-gray-200\"><h3 class=\"text-lg font-medium text-gray-900\">Regelmäßige Transaktion</h3></div><div class=\"px-6 py-4 space-y-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Beschreibung</label> <input type=\"text\" name=\"description\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" placeholder=\"z.B. Miete\"></div><div class=\"grid grid-cols-2 gap-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Betrag</label> <input type=\"number\" name=\"amount\" step=\"0.01\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" placeholder=\"0.00\"></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Typ</label> <select name=\"type\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Wählen...</option> <option value=\"income\">💰 Einnahme</option> <option value=\"expense\">💸 Ausgabe</option></select></div></div><div class=\"grid grid-cols-2 gap-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Startdatum</label> <input type=\"date\" name=\"start_date\" required class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var51 string
templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(time.Now().Format("2006-01-02"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 532, Col: 214}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Enddatum (optional)</label> <input type=\"date\" name=\"end_date\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div></div><div class=\"grid grid-cols-2 gap-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Intervall</label> <select name=\"interval\" required onchange=\"toggleIntervalOptions()\" id=\"interval-select\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Wählen...</option> <option value=\"daily\">Täglich</option> <option value=\"weekly\">Wöchentlich</option> <option value=\"monthly\">Monatlich</option> <option value=\"yearly\">Jährlich</option></select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Alle X</label> <input type=\"number\" name=\"interval_count\" min=\"1\" value=\"1\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"></div></div><!-- Day of Month (for monthly) --><div id=\"day-of-month-group\" class=\"hidden\"><label class=\"block text-sm font-medium text-gray-700 mb-1\">Tag im Monat</label> <input type=\"number\" name=\"day_of_month\" min=\"1\" max=\"31\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\" placeholder=\"z.B. 1 für jeden ersten\"></div><!-- Day of Week (for weekly) --><div id=\"day-of-week-group\" class=\"hidden\"><label class=\"block text-sm font-medium text-gray-700 mb-1\">Wochentag</label> <select name=\"day_of_week\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Aktueller Wochentag</option> <option value=\"1\">Montag</option> <option value=\"2\">Dienstag</option> <option value=\"3\">Mittwoch</option> <option value=\"4\">Donnerstag</option> <option value=\"5\">Freitag</option> <option value=\"6\">Samstag</option> <option value=\"0\">Sonntag</option></select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Kategorie (optional)</label> <select name=\"category_id\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Ohne Kategorie</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, category := range categories {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var52 string
templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", category.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 582, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var53 string
templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 582, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var54 string
templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 582, Col: 92}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Bankkonto (optional)</label> <select name=\"bank_account_id\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Ohne Konto</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, account := range bankAccounts {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var55 string
templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", account.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 591, Col: 55}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var56 string
templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(account.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 591, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var57 string
templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(account.Bank)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 591, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(")</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div></div><div class=\"px-6 py-4 bg-gray-50 flex justify-end space-x-3\"><button type=\"button\" onclick=\"hideModal(&#39;recurringModal&#39;)\" class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50\">Abbrechen</button> <button type=\"submit\" class=\"px-4 py-2 text-sm font-medium text-white bg-green-600 border border-transparent rounded-md hover:bg-green-700\">Erstellen</button></div></form></div></div></div><!-- Multi-Edit Modal --> <div id=\"multiEditModal\" class=\"hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50\"><div class=\"relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 shadow-lg rounded-md bg-white\"><div class=\"mt-3\"><div class=\"flex items-center justify-between mb-4\"><h3 class=\"text-lg font-medium text-gray-900\">Mehrere Transaktionen bearbeiten</h3><button onclick=\"hideModal(&#39;multiEditModal&#39;)\" class=\"text-gray-400 hover:text-gray-600\"><span class=\"sr-only\">Schließen</span> <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></button></div><p class=\"text-sm text-gray-600 mb-4\">Nur die Felder ausfüllen, die für alle ausgewählten Transaktionen geändert werden sollen. Leere Felder bleiben unverändert.</p><form id=\"multiEditForm\" onsubmit=\"submitMultiEdit(event)\"><div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\"><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Beschreibung</label> <input type=\"text\" id=\"multiDescription\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><p class=\"text-xs text-gray-500 mt-1\">Leer lassen um unverändert zu lassen</p></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Betrag</label> <input type=\"number\" step=\"0.01\" id=\"multiAmount\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><p class=\"text-xs text-gray-500 mt-1\">Leer lassen um unverändert zu lassen</p></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Typ</label> <select id=\"multiType\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Unverändert lassen</option> <option value=\"income\">Einnahme</option> <option value=\"expense\">Ausgabe</option></select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Kategorie</label> <select id=\"multiCategory\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Unverändert lassen</option> <option value=\"null\">Ohne Kategorie</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, category := range categories {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var58 string
templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", category.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 651, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var59 string
templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(category.Icon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 651, Col: 74}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var60 string
templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(category.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 651, Col: 92}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Bankkonto</label> <select id=\"multiAccount\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><option value=\"\">Unverändert lassen</option> <option value=\"null\">Ohne Konto</option> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, account := range bankAccounts {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var61 string
templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", account.ID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 661, Col: 55}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var62 string
templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(account.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 661, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" (")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var63 string
templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(account.Bank)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/transactions.templ`, Line: 661, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(")</option>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select></div><div><label class=\"block text-sm font-medium text-gray-700 mb-1\">Datum</label> <input type=\"date\" id=\"multiDate\" class=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500\"><p class=\"text-xs text-gray-500 mt-1\">Leer lassen um unverändert zu lassen</p></div></div><div class=\"flex justify-end space-x-3\"><button type=\"button\" onclick=\"hideModal(&#39;multiEditModal&#39;)\" class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50\">Abbrechen</button> <button type=\"submit\" class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700\">Ausgewählte Transaktionen aktualisieren</button></div></form></div></div></div><!-- Multi-Delete Confirmation Modal --> <div id=\"multiDeleteModal\" class=\"hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50\"><div class=\"relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 shadow-lg rounded-md bg-white\"><div class=\"mt-3\"><div class=\"flex items-center justify-between mb-4\"><h3 class=\"text-lg font-medium text-gray-900\">Transaktionen löschen</h3><button onclick=\"hideModal(&#39;multiDeleteModal&#39;)\" class=\"text-gray-400 hover:text-gray-600\"><span class=\"sr-only\">Schließen</span> <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></button></div><div class=\"mb-4\"><div class=\"flex items-center mb-3\"><svg class=\"h-12 w-12 text-red-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\"></path></svg><div class=\"ml-4\"><h3 class=\"text-lg font-medium text-gray-900\">Sind Sie sicher?</h3><p class=\"text-sm text-gray-600\">Sie sind dabei, <span id=\"deleteCountText\" class=\"font-semibold text-red-600\">0</span> Transaktionen zu löschen. Diese Aktion kann nicht rückgängig gemacht werden.</p></div></div><div class=\"bg-red-50 border border-red-200 rounded-md p-3\"><p class=\"text-sm text-red-700\"><strong>Warnung:</strong> Alle ausgewählten Transaktionen werden permanent gelöscht. Stellen Sie sicher, dass Sie die richtigen Transaktionen ausgewählt haben.</p></div></div><div class=\"flex justify-end space-x-3\"><button type=\"button\" onclick=\"hideModal(&#39;multiDeleteModal&#39;)\" class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50\">Abbrechen</button> <button type=\"button\" onclick=\"confirmMultiDelete()\" class=\"px-4 py-2 text-sm font-medium text-white bg-red-600 border border-transparent rounded-md hover:bg-red-700\">Ja, löschen</button></div></div></div></div><script>\n\t\t\tfunction showModal(modalId) {\n\t\t\t\tdocument.getElementById(modalId).classList.remove('hidden');\n\t\t\t}\n\n\t\t\tfunction hideModal(modalId) {\n\t\t\t\tdocument.getElementById(modalId).classList.add('hidden');\n\t\t\t}\n\n\t\t\tfunction showTab(tabName) {\n\t\t\t\t// Hide all content\n\t\t\t\tdocument.querySelectorAll('.tab-content').forEach(content => {\n\t\t\t\t\tcontent.classList.add('hidden');\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// Remove active class from all tabs\n\t\t\t\tdocument.querySelectorAll('.tab-button').forEach(tab => {\n\t\t\t\t\ttab.classList.remove('border-blue-500', 'text-blue-600');\n\t\t\t\t\ttab.classList.add('border-transparent', 'text-gray-500');\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// Show selected content\n\t\t\t\tdocument.getElementById(tabName + '-content').classList.remove('hidden');\n\t\t\t\t\n\t\t\t\t// Activate selected tab\n\t\t\t\tconst activeTab = document.getElementById('tab-' + tabName);\n\t\t\t\tactiveTab.classList.add('border-blue-500', 'text-blue-600');\n\t\t\t\tactiveTab.classList.remove('border-transparent', 'text-gray-500');\n\t\t\t}\n\n\t\t\tfunction showEditTransactionModal(transaction) {\n\t\t\t\t// Populate form fields with transaction data\n\t\t\t\tdocument.getElementById('edit_description').value = transaction.description;\n\t\t\t\tdocument.getElementById('edit_amount').value = transaction.amount;\n\t\t\t\tdocument.getElementById('edit_type').value = transaction.type;\n\t\t\t\tdocument.getElementById('edit_date').value = transaction.date;\n\t\t\t\tdocument.getElementById('edit_category_id').value = transaction.category_id || '';\n\t\t\t\tdocument.getElementById('edit_bank_account_id').value = transaction.bank_account_id;\n\t\t\t\t\n\t\t\t\t// Set form action to update URL\n\t\t\t\tdocument.getElementById('editTransactionForm').action = '/transactions/' + transaction.id;\n\t\t\t\t\n\t\t\t\t// Show modal\n\t\t\t\tshowModal('editTransactionModal');\n\t\t\t}\n\n\t\t\tfunction closeEditTransactionModal() {\n\t\t\t\thideModal('editTransactionModal');\n\t\t\t}\n\n\t\t\tfunction toggleIntervalOptions() {\n\t\t\t\tconst interval = document.getElementById('interval-select').value;\n\t\t\t\tconst dayOfMonthGroup = document.getElementById('day-of-month-group');\n\t\t\t\tconst dayOfWeekGroup = document.getElementById('day-of-week-group');\n\t\t\t\t\n\t\t\t\t// Hide all\n\t\t\t\tdayOfMonthGroup.classList.add('hidden');\n\t\t\t\tdayOfWeekGroup.classList.add('hidden');\n\t\t\t\t\n\t\t\t\t// Show relevant option\n\t\t\t\tif (interval === 'monthly') {\n\t\t\t\t\tdayOfMonthGroup.classList.remove('hidden');\n\t\t\t\t} else if (interval === 'weekly') {\n\t\t\t\t\tdayOfWeekGroup.classList.remove('hidden');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Multi-Edit Funktionalität\n\t\t\tfunction toggleSelectAll() {\n\t\t\t\tconst selectAllCheckbox = document.getElementById('selectAll');\n\t\t\t\tconst transactionCheckboxes = document.querySelectorAll('.transaction-checkbox');\n\t\t\t\t\n\t\t\t\ttransactionCheckboxes.forEach(checkbox => {\n\t\t\t\t\tcheckbox.checked = selectAllCheckbox.checked;\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tupdateMultiEditControls();\n\t\t\t}\n\n\t\t\tfunction updateMultiEditControls() {\n\t\t\t\tconst transactionCheckboxes = document.querySelectorAll('.transaction-checkbox');\n\t\t\t\tconst checkedBoxes = document.querySelectorAll('.transaction-checkbox:checked');\n\t\t\t\tconst multiEditControls = document.getElementById('multiEditControls');\n\t\t\t\tconst selectedCount = document.getElementById('selectedCount');\n\t\t\t\tconst selectedCountDelete = document.getElementById('selectedCountDelete');\n\t\t\t\t\n\t\t\t\tif (checkedBoxes.length > 0) {\n\t\t\t\t\tmultiEditControls.classList.remove('hidden');\n\t\t\t\t\tselectedCount.textContent = checkedBoxes.length;\n\t\t\t\t\tselectedCountDelete.textContent = checkedBoxes.length;\n\t\t\t\t} else {\n\t\t\t\t\tmultiEditControls.classList.add('hidden');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Update \"Select All\" checkbox state\n\t\t\t\tconst selectAllCheckbox = document.getElementById('selectAll');\n\t\t\t\tif (checkedBoxes.length === 0) {\n\t\t\t\t\tselectAllCheckbox.indeterminate = false;\n\t\t\t\t\tselectAllCheckbox.checked = false;\n\t\t\t\t} else if (checkedBoxes.length === transactionCheckboxes.length) {\n\t\t\t\t\tselectAllCheckbox.indeterminate = false;\n\t\t\t\t\tselectAllCheckbox.checked = true;\n\t\t\t\t} else {\n\t\t\t\t\tselectAllCheckbox.indeterminate = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction openMultiEditModal() {\n\t\t\t\tconst checkedBoxes = document.querySelectorAll('.transaction-checkbox:checked');\n\t\t\t\tif (checkedBoxes.length === 0) {\n\t\t\t\t\talert('Bitte wählen Sie mindestens eine Transaktion aus.');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Reset form\n\t\t\t\tdocument.getElementById('multiEditForm').reset();\n\t\t\t\tshowModal('multiEditModal');\n\t\t\t}\n\n\t\t\tfunction submitMultiEdit(event) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\t\n\t\t\t\tconst checkedBoxes = document.querySelectorAll('.transaction-checkbox:checked');\n\t\t\t\tconst transactionIds = Array.from(checkedBoxes).map(cb => cb.value);\n\t\t\t\t\n\t\t\t\tif (transactionIds.length === 0) {\n\t\t\t\t\talert('Keine Transaktionen ausgewählt.');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tconst formData = {\n\t\t\t\t\ttransaction_ids: transactionIds,\n\t\t\t\t\tdescription: document.getElementById('multiDescription').value,\n\t\t\t\t\tamount: document.getElementById('multiAmount').value,\n\t\t\t\t\ttype: document.getElementById('multiType').value,\n\t\t\t\t\tcategory_id: document.getElementById('multiCategory').value,\n\t\t\t\t\tbank_account_id: document.getElementById('multiAccount').value,\n\t\t\t\t\tdate: document.getElementById('multiDate').value\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// Remove empty values\n\t\t\t\tObject.keys(formData).forEach(key => {\n\t\t\t\t\tif (formData[key] === '' || formData[key] === null) {\n\t\t\t\t\t\tdelete formData[key];\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// Special handling for null values\n\t\t\t\tif (document.getElementById('multiCategory').value === 'null') {\n\t\t\t\t\tformData.category_id = null;\n\t\t\t\t}\n\t\t\t\tif (document.getElementById('multiAccount').value === 'null') {\n\t\t\t\t\tformData.bank_account_id = null;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfetch('/transactions/multi-update', {\n\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(formData)\n\t\t\t\t})\n\t\t\t\t.then(response => {\n\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\thideModal('multiEditModal');\n\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresponse.text().then(text => {\n\t\t\t\t\t\t\talert('Fehler beim Aktualisieren: ' + text);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tconsole.error('Error:', error);\n\t\t\t\t\talert('Fehler beim Aktualisieren der Transaktionen');\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction openMultiDeleteConfirm() {\n\t\t\t\tconst checkedBoxes = document.querySelectorAll('.transaction-checkbox:checked');\n\t\t\t\tif (checkedBoxes.length === 0) {\n\t\t\t\t\talert('Bitte wählen Sie mindestens eine Transaktion aus.');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Update delete count in modal\n\t\t\t\tdocument.getElementById('deleteCountText').textContent = checkedBoxes.length;\n\t\t\t\tshowModal('multiDeleteModal');\n\t\t\t}\n\n\t\t\tfunction confirmMultiDelete() {\n\t\t\t\tconst checkedBoxes = document.querySelectorAll('.transaction-checkbox:checked');\n\t\t\t\tconst transactionIds = Array.from(checkedBoxes).map(cb => cb.value);\n\t\t\t\t\n\t\t\t\tif (transactionIds.length === 0) {\n\t\t\t\t\talert('Keine Transaktionen ausgewählt.');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Disable button to prevent double clicks\n\t\t\t\tconst deleteButton = event.target;\n\t\t\t\tdeleteButton.disabled = true;\n\t\t\t\tdeleteButton.textContent = 'Lösche...';\n\t\t\t\t\n\t\t\t\tfetch('/transactions/multi-delete', {\n\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\ttransaction_ids: transactionIds\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t\t.then(response => {\n\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\thideModal('multiDeleteModal');\n\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresponse.text().then(text => {\n\t\t\t\t\t\t\talert('Fehler beim Löschen: ' + text);\n\t\t\t\t\t\t\tdeleteButton.disabled = false;\n\t\t\t\t\t\t\tdeleteButton.textContent = 'Ja, löschen';\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tconsole.error('Error:', error);\n\t\t\t\t\talert('Fehler beim Löschen der Transaktionen');\n\t\t\t\t\tdeleteButton.disabled = false;\n\t\t\t\t\tdeleteButton.textContent = 'Ja, löschen';\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Filter-Funktionalität\n\t\t\tfunction applyFilters() {\n\t\t\t\tconst filterData = {\n\t\t\t\t\tdate_from: document.getElementById('date_from').value,\n\t\t\t\t\tdate_to: document.getElementById('date_to').value,\n\t\t\t\t\tsearch_description: document.getElementById('search_description').value,\n\t\t\t\t\tfilter_category: document.getElementById('filter_category').value,\n\t\t\t\t\tfilter_account: document.getElementById('filter_account').value,\n\t\t\t\t\tfilter_type: document.getElementById('filter_type').value,\n\t\t\t\t\tamount_min: document.getElementById('amount_min').value,\n\t\t\t\t\tamount_max: document.getElementById('amount_max').value\n\t\t\t\t};\n\n\t\t\t\t// Build URL with filter parameters\n\t\t\t\tconst params = new URLSearchParams();\n\t\t\t\tObject.entries(filterData).forEach(([key, value]) => {\n\t\t\t\t\tif (value && value.trim() !== '') {\n\t\t\t\t\t\tparams.append(key, value);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Redirect to filtered page\n\t\t\t\twindow.location.href = '/transactions?' + params.toString();\n\t\t\t}\n\n\t\t\tfunction clearFilters() {\n\t\t\t\tdocument.getElementById('filterForm').reset();\n\t\t\t\twindow.location.href = '/transactions';\n\t\t\t}\n\n\t\t\tfunction updateFilterStatus() {\n\t\t\t\tconst params = new URLSearchParams(window.location.search);\n\t\t\t\tconst activeFilters = [];\n\t\t\t\t\n\t\t\t\tif (params.get('date_from') || params.get('date_to')) {\n\t\t\t\t\tactiveFilters.push('Datum');\n\t\t\t\t}\n\t\t\t\tif (params.get('search_description')) {\n\t\t\t\t\tactiveFilters.push('Beschreibung');\n\t\t\t\t}\n\t\t\t\tif (params.get('filter_category')) {\n\t\t\t\t\tactiveFilters.push('Kategorie');\n\t\t\t\t}\n\t\t\t\tif (params.get('filter_account')) {\n\t\t\t\t\tactiveFilters.push('Konto');\n\t\t\t\t}\n\t\t\t\tif (params.get('filter_type')) {\n\t\t\t\t\tactiveFilters.push('Typ');\n\t\t\t\t}\n\t\t\t\tif (params.get('amount_min') || params.get('amount_max')) {\n\t\t\t\t\tactiveFilters.push('Betrag');\n\t\t\t\t}\n\n\t\t\t\tconst filterCountElement = document.getElementById('filterCount');\n\t\t\t\tif (activeFilters.length > 0) {\n\t\t\t\t\tfilterCountElement.textContent = `Gefiltert nach: ${activeFilters.join(', ')}`;\n\t\t\t\t} else {\n\t\t\t\t\tfilterCountElement.textContent = 'Alle Transaktionen werden angezeigt';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction buildPaginationURL(page) {\n\t\t\t\tconst params = new URLSearchParams(window.location.search);\n\t\t\t\tparams.set('page', page);\n\t\t\t\treturn '/transactions?' + params.toString();\n\t\t\t}\n\n\t\t\tfunction updatePaginationLinks() {\n\t\t\t\t// Update all pagination links to preserve filters\n\t\t\t\tconst paginationLinks = document.querySelectorAll('a[href*=\"/transactions?page=\"]');\n\t\t\t\tpaginationLinks.forEach(link => {\n\t\t\t\t\tconst href = link.getAttribute('href');\n\t\t\t\t\tconst pageMatch = href.match(/page=(\\d+)/);\n\t\t\t\t\tif (pageMatch) {\n\t\t\t\t\t\tconst page = pageMatch[1];\n\t\t\t\t\t\tlink.setAttribute('href', buildPaginationURL(page));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction loadFilterFromURL() {\n\t\t\t\tconst params = new URLSearchParams(window.location.search);\n\t\t\t\t\n\t\t\t\tdocument.getElementById('date_from').value = params.get('date_from') || '';\n\t\t\t\tdocument.getElementById('date_to').value = params.get('date_to') || '';\n\t\t\t\tdocument.getElementById('search_description').value = params.get('search_description') || '';\n\t\t\t\tdocument.getElementById('filter_category').value = params.get('filter_category') || '';\n\t\t\t\tdocument.getElementById('filter_account').value = params.get('filter_account') || '';\n\t\t\t\tdocument.getElementById('filter_type').value = params.get('filter_type') || '';\n\t\t\t\tdocument.getElementById('amount_min').value = params.get('amount_min') || '';\n\t\t\t\tdocument.getElementById('amount_max').value = params.get('amount_max') || '';\n\t\t\t}\n\n\t\t\t// Event Listeners\n\t\t\tdocument.addEventListener('DOMContentLoaded', function() {\n\t\t\t\tloadFilterFromURL();\n\t\t\t\tupdateFilterStatus();\n\t\t\t\tupdatePaginationLinks();\n\n\t\t\t\t// Enter key to apply filters\n\t\t\t\tconst form = document.getElementById('filterForm');\n\t\t\t\tif (form) {\n\t\t\t\t\tform.addEventListener('keypress', function(e) {\n\t\t\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tapplyFilters();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tdocument.addEventListener('DOMContentLoaded', function() {\n\t\t\t\t// Delete transaction buttons\n\t\t\t\tdocument.querySelectorAll('.delete-transaction').forEach(button => {\n\t\t\t\t\tbutton.addEventListener('click', async function() {\n\t\t\t\t\t\tconst id = this.getAttribute('data-transaction-id');\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (!confirm('Möchtest du diese Transaktion wirklich löschen?')) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst response = await fetch(`/transactions/${id}`, {\n\t\t\t\t\t\t\t\tmethod: 'DELETE'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\talert('Fehler beim Löschen der Transaktion');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\talert('Fehler beim Löschen der Transaktion');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\t// Edit transaction buttons\n\t\t\t\tdocument.querySelectorAll('.edit-transaction').forEach(button => {\n\t\t\t\t\tbutton.addEventListener('click', async function() {\n\t\t\t\t\t\tconst id = this.getAttribute('data-transaction-id');\n\t\t\t\t\t\t\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst response = await fetch(`/transactions/${id}/data`);\n\t\t\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\t\t\tconst transaction = await response.json();\n\t\t\t\t\t\t\t\tshowEditTransactionModal(transaction);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\talert('Fehler beim Laden der Transaktionsdaten');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\talert('Fehler beim Laden der Transaktionsdaten');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\t// Toggle recurrence rule buttons\n\t\t\t\tdocument.querySelectorAll('.toggle-recurrence').forEach(button => {\n\t\t\t\t\tbutton.addEventListener('click', async function() {\n\t\t\t\t\t\tconst id = this.getAttribute('data-rule-id');\n\t\t\t\t\t\t\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst response = await fetch(`/transactions/recurring/${id}/toggle`, {\n\t\t\t\t\t\t\t\tmethod: 'POST'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\talert('Fehler beim Umschalten der Regel');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\talert('Fehler beim Umschalten der Regel');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\t// Edit transaction form submit\n\t\t\t\tdocument.getElementById('editTransactionForm').addEventListener('submit', async function(e) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\n\t\t\t\t\tconst formData = new FormData(this);\n\t\t\t\t\tconst formObject = {};\n\t\t\t\t\tfor (let [key, value] of formData.entries()) {\n\t\t\t\t\t\tformObject[key] = value;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst response = await fetch(this.action, {\n\t\t\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: JSON.stringify(formObject)\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\t\tcloseEditTransactionModal();\n\t\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert('Fehler beim Speichern der Transaktion');\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\talert('Fehler beim Speichern der Transaktion');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Close modal when clicking outside\n\t\t\tdocument.addEventListener('click', function(event) {\n\t\t\t\tif (event.target.classList.contains('bg-opacity-50')) {\n\t\t\t\t\tevent.target.classList.add('hidden');\n\t\t\t\t}\n\t\t\t});\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = Layout("Transaktionen - WhereIsMyMoney").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func getIntervalText(interval string, count int) string {
var base string
switch interval {
case "daily":
base = "Tag"
if count > 1 {
base = "Tage"
}
case "weekly":
base = "Woche"
if count > 1 {
base = "Wochen"
}
case "monthly":
base = "Monat"
if count > 1 {
base = "Monate"
}
case "yearly":
base = "Jahr"
if count > 1 {
base = "Jahre"
}
default:
return interval
}
if count == 1 {
return fmt.Sprintf("Jeden %s", base)
}
return fmt.Sprintf("Alle %d %s", count, base)
}
func getNextExecutionDate(rule models.RecurrenceRule) string {
if !rule.IsActive {
return "Pausiert"
}
lastDate := rule.StartDate
if rule.LastGenerated != nil {
lastDate = *rule.LastGenerated
}
nextDate := rule.GetNextOccurrence(lastDate)
if nextDate == nil {
return "Beendet"
}
return nextDate.Format("02.01.2006")
}
var _ = templruntime.GeneratedTemplate