first commit
This commit is contained in:
64
views/admin/partials/carts.html
Normal file
64
views/admin/partials/carts.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Sepet Yönetimi</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/carts" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2"
|
||||
placeholder="User ID ile Ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="ps-3 border-0 text-muted small text-uppercase">ID</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Kullanıcı (User ID)</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Ürün Sayısı (Çeşit)</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Oluşturulma Tarihi</th>
|
||||
<th class="border-0 text-muted small text-uppercase text-end pe-3">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Carts }}
|
||||
<tr>
|
||||
<td class="ps-3"><span class="text-secondary fw-medium">#{{ .ID }}</span></td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="ms-2">
|
||||
<div class="fw-semibold text-dark">Kullanıcı ID: {{ .UserID }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-info text-dark rounded-pill">{{ len .Items }} çeşit ürün
|
||||
eklendi</span>
|
||||
</td>
|
||||
<td class="text-secondary small">
|
||||
{{ .CreatedAt.Format "02.01.2006 15:04" }}
|
||||
</td>
|
||||
<td class="text-end pe-3">
|
||||
<form action="/admin/carts/{{ .ID }}/delete" method="POST" class="d-inline"
|
||||
onsubmit="return confirm('Bu sepeti silmek istediğinize emin misiniz?');">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Sil">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-cart-x fs-1 d-block mb-2"></i>
|
||||
Henüz kullanıcılar sepet oluşturmamış.
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
82
views/admin/partials/categories.html
Normal file
82
views/admin/partials/categories.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Kategoriler</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/categories" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="Ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<a href="/admin/categories/new" class="btn btn-sm btn-primary">Yeni Kategori</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/categories" class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/categories?deleted=true" class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Başlık</th>
|
||||
<th class="text-muted">Slug</th>
|
||||
<th class="text-muted">Parent</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Categories }}
|
||||
{{ range .Categories }}
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ .Title }}</td>
|
||||
<td class="text-secondary small text-nowrap">{{ .Slug }}</td>
|
||||
<td>
|
||||
{{ if .Parent }}
|
||||
<span class="badge bg-secondary">{{ .Parent.Title }}</span>
|
||||
{{ else }}
|
||||
<span class="text-muted">-</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/categories/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/categories/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary" title="Düzenle"><i class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/categories/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pagination -->
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link" href="/admin/content/categories?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link" href="/admin/content/categories?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
71
views/admin/partials/category_views.html
Normal file
71
views/admin/partials/category_views.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Category Views</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/category-views" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="IP ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/category-views" class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/category-views?deleted=true" class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-muted">IP Address</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Views }}
|
||||
{{ range .Views }}
|
||||
<tr>
|
||||
<td>{{ index $.CatMap .CategoryID }}</td>
|
||||
<td class="text-secondary small">{{ .IPAddress }}</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/category-views/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<form action="/admin/category-views/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link" href="/admin/content/category-views?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link" href="/admin/content/category-views?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
74
views/admin/partials/comments.html
Normal file
74
views/admin/partials/comments.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Yorumlar</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/comments" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="Ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/comments" class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/comments?deleted=true" class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Kullanıcı</th>
|
||||
<th>Post ID</th>
|
||||
<th class="text-muted">Yorum</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Comments }}
|
||||
{{ range .Comments }}
|
||||
<tr>
|
||||
<td>{{ .UserID }}</td>
|
||||
<td>{{ .PostID }}</td>
|
||||
<td class="text-truncate" style="max-width:400px;">{{ .Body }}</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/comments/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/comments/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary" title="Düzenle"><i class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/comments/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link" href="/admin/content/comments?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link" href="/admin/content/comments?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
75
views/admin/partials/dashboard.html
Normal file
75
views/admin/partials/dashboard.html
Normal file
@@ -0,0 +1,75 @@
|
||||
<div class="container-fluid">
|
||||
<h2 class="mb-4">Dashboard</h2>
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="card h-100 border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h6 class="card-subtitle mb-2 text-muted">Toplam Kullanıcı</h6>
|
||||
<h3 class="card-title">1,250</h3>
|
||||
<p class="card-text text-success"><i class="bi bi-arrow-up"></i> %5 artış</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card h-100 border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h6 class="card-subtitle mb-2 text-muted">Aktif Oturumlar</h6>
|
||||
<h3 class="card-title">45</h3>
|
||||
<p class="card-text text-primary">Anlık</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card h-100 border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h6 class="card-subtitle mb-2 text-muted">Sistem Yükü</h6>
|
||||
<h3 class="card-title">%12</h3>
|
||||
<p class="card-text text-success">Normal</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Activity Table -->
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-transparent border-0">
|
||||
<h5 class="mb-0">Son Aktiviteler</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Kullanıcı</th>
|
||||
<th>İşlem</th>
|
||||
<th>Tarih</th>
|
||||
<th>Durum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Ahmet Yılmaz</td>
|
||||
<td>Giriş Yaptı</td>
|
||||
<td>10 dk önce</td>
|
||||
<td><span class="badge bg-success">Başarılı</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ayşe Demir</td>
|
||||
<td>Profil Güncelledi</td>
|
||||
<td>1 saat önce</td>
|
||||
<td><span class="badge bg-primary">Kaydedildi</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mehmet Kara</td>
|
||||
<td>Hatalı Giriş</td>
|
||||
<td>2 saat önce</td>
|
||||
<td><span class="badge bg-danger">Hata</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
103
views/admin/partials/posts.html
Normal file
103
views/admin/partials/posts.html
Normal file
@@ -0,0 +1,103 @@
|
||||
<div class="container-fluid">
|
||||
{{ if .Error }}
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
{{ .Error }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .Success }}
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
{{ .Success }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Yazılar</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/posts" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="Ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<a href="/admin/posts/new" class="btn btn-sm btn-primary">Yeni Yazı</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/posts" class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/posts?deleted=true" class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Başlık</th>
|
||||
<th>Kategoriler</th>
|
||||
<th>Taglar</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Posts }}
|
||||
{{ range .Posts }}
|
||||
<tr>
|
||||
<td style="width:56px;">
|
||||
{{ with index $.ImageMap .ID }}
|
||||
<img src="{{ . }}" alt="thumb" class="rounded" style="width:48px;height:48px;object-fit:cover;">
|
||||
{{ else }}
|
||||
<div class="bg-secondary rounded" style="width:48px;height:48px;"></div>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>{{ .Title }}</td>
|
||||
<td>
|
||||
{{ range .Categories }}
|
||||
<span class="badge bg-secondary me-1">{{ .Title }}</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
{{ range .Tags }}
|
||||
<span class="badge bg-info text-dark me-1">{{ .Name }}</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/posts/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/posts/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary" title="Düzenle"><i class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/posts/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link" href="/admin/content/posts?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link" href="/admin/content/posts?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
73
views/admin/partials/product_categories.html
Normal file
73
views/admin/partials/product_categories.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Ürün Kategorileri</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a href="/admin/product-categories/new" class="btn btn-sm btn-primary">Yeni Kategori</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/product-categories"
|
||||
class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/product-categories?deleted=true"
|
||||
class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Başlık</th>
|
||||
<th class="text-muted">Slug</th>
|
||||
<th class="text-muted">Üst Kategori</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Categories }}
|
||||
{{ range .Categories }}
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ .Title }}</td>
|
||||
<td class="text-secondary small text-nowrap">{{ .Slug }}</td>
|
||||
<td>
|
||||
{{ if .Parent }}
|
||||
<span class="badge bg-secondary">{{ .Parent.Title }}</span>
|
||||
{{ else }}
|
||||
<span class="text-muted">-</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/product-categories/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i
|
||||
class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/product-categories/{{ .ID }}/edit"
|
||||
class="btn btn-sm btn-outline-secondary" title="Düzenle"><i
|
||||
class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/product-categories/{{ .ID }}/delete" method="POST"
|
||||
onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i
|
||||
class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
46
views/admin/partials/product_category_views.html
Normal file
46
views/admin/partials/product_category_views.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Kategori Görüntülenmeleri</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/product-category-views" method="GET">
|
||||
<input type="search" name="category_id" class="form-control form-control-sm me-2"
|
||||
placeholder="Category ID..." value="{{ .CategoryID }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="ps-3 border-0 text-muted small text-uppercase">ID</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Kategori ID</th>
|
||||
<th class="border-0 text-muted small text-uppercase">IP Adresi</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Ziyaret Tarihi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Views }}
|
||||
<tr>
|
||||
<td class="ps-3"><span class="text-secondary fw-medium">#{{ .ID }}</span></td>
|
||||
<td><span class="badge bg-primary">Kategori #{{ .CategoryID }}</span></td>
|
||||
<td><span class="text-dark font-monospace">{{ .IPAddress }}</span></td>
|
||||
<td class="text-secondary small">
|
||||
{{ .CreatedAt.Format "02.01.2006 15:04" }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-eye fs-1 d-block mb-2"></i>
|
||||
Kategorileriniz henüz görüntülenmemiş veya veri yok.
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
65
views/admin/partials/product_comments.html
Normal file
65
views/admin/partials/product_comments.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Ürün Yorumları</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/product-comments" method="GET">
|
||||
<input type="search" name="product_id" class="form-control form-control-sm me-2"
|
||||
placeholder="Ürün ID ile Ara..." value="{{ .ProductID }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="ps-3 border-0 text-muted small text-uppercase">ID</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Kullanıcı (User ID)</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Yorum (Body)</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Ürün ID</th>
|
||||
<th class="border-0 text-muted small text-uppercase">Tarih</th>
|
||||
<th class="border-0 text-muted small text-uppercase text-end pe-3">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .ProductComments }}
|
||||
<tr>
|
||||
<td class="ps-3"><span class="text-secondary fw-medium">#{{ .ID }}</span></td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="badge bg-secondary">User #{{ .UserID }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-dark">{{ .Body }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-primary">Product #{{ .ProductID }}</span>
|
||||
</td>
|
||||
<td class="text-secondary small">
|
||||
{{ .CreatedAt.Format "02.01.2006 15:04" }}
|
||||
</td>
|
||||
<td class="text-end pe-3">
|
||||
<form action="/admin/product-comments/{{ .ID }}/delete" method="POST" class="d-inline"
|
||||
onsubmit="return confirm('Bu yorumu silmek istediğinize emin misiniz?');">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Sil">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-chat-dots fs-1 d-block mb-2"></i>
|
||||
Henüz ürünlere yorum yapılmamış.
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
63
views/admin/partials/product_tags.html
Normal file
63
views/admin/partials/product_tags.html
Normal file
@@ -0,0 +1,63 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Ürün Etiketleri</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a href="/admin/product-tags/new" class="btn btn-sm btn-primary">Yeni Etiket</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/product-tags"
|
||||
class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/product-tags?deleted=true"
|
||||
class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>İsim</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Tags }}
|
||||
{{ range .Tags }}
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ .Name }}</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/product-tags/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i
|
||||
class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/product-tags/{{ .ID }}/edit"
|
||||
class="btn btn-sm btn-outline-secondary" title="Düzenle"><i
|
||||
class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/product-tags/{{ .ID }}/delete" method="POST"
|
||||
onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i
|
||||
class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
102
views/admin/partials/products.html
Normal file
102
views/admin/partials/products.html
Normal file
@@ -0,0 +1,102 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Ürünler</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/products" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="Ara..."
|
||||
value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<a href="/admin/products/new" class="btn btn-sm btn-primary">Yeni Ürün</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/products"
|
||||
class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/products?deleted=true"
|
||||
class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>Ürün</th>
|
||||
<th>Başlık</th>
|
||||
<th>Kategoriler</th>
|
||||
<th>Etiketler</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Products }}
|
||||
{{ range .Products }}
|
||||
<tr>
|
||||
<td style="width:56px;">
|
||||
{{ with index $.ImageMap .ID }}
|
||||
<img src="{{ . }}" alt="thumb" class="rounded"
|
||||
style="width:48px;height:48px;object-fit:cover;">
|
||||
{{ else }}
|
||||
<div class="bg-secondary rounded" style="width:48px;height:48px;"></div>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>{{ .Title }}</td>
|
||||
<td>
|
||||
{{ range .Categories }}
|
||||
<span class="badge bg-secondary me-1">{{ .Title }}</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
{{ range .Tags }}
|
||||
<span class="badge bg-info text-dark me-1">{{ .Name }}</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/products/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i
|
||||
class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/products/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary"
|
||||
title="Düzenle"><i class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/products/{{ .ID }}/delete" method="POST"
|
||||
onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i
|
||||
class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link"
|
||||
href="/admin/content/products?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages
|
||||
}}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link"
|
||||
href="/admin/content/products?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
538
views/admin/partials/settings.html
Normal file
538
views/admin/partials/settings.html
Normal file
@@ -0,0 +1,538 @@
|
||||
<div class="container-fluid" hx-trigger="heroListChanged from:body" hx-get="/admin/content/settings" hx-target="this"
|
||||
hx-swap="outerHTML">
|
||||
<h2 class="mb-4">Ayarlar & Banner Yönetimi</h2>
|
||||
|
||||
<ul class="nav nav-tabs mb-4" id="settingsTab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="general-tab" data-bs-toggle="tab" data-bs-target="#general"
|
||||
type="button" role="tab">Genel Ayarlar</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="security-tab" data-bs-toggle="tab" data-bs-target="#security" type="button" role="tab">Güvenlik</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="hero-tab" data-bs-toggle="tab" data-bs-target="#hero" type="button"
|
||||
role="tab">Banner (Hero) Yönetimi</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="settingsTabContent">
|
||||
<!-- General Settings Tab -->
|
||||
<div class="tab-pane fade show active" id="general" role="tabpanel">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<form action="/admin/settings" method="POST" enctype="multipart/form-data">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="title" class="form-label">Site Başlığı</label>
|
||||
<input type="text" class="form-control" id="title" name="title"
|
||||
value="{{ .Setting.Title }}">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="meta_title" class="form-label">Meta Başlık</label>
|
||||
<input type="text" class="form-control" id="meta_title" name="meta_title"
|
||||
value="{{ .Setting.MetaTitle }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="meta_description" class="form-label">Meta Açıklama</label>
|
||||
<textarea class="form-control" id="meta_description" name="meta_description"
|
||||
rows="2">{{ .Setting.MetaDescription }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="email" class="form-label">E-posta</label>
|
||||
<input type="email" class="form-control" id="email" name="email"
|
||||
value="{{ .Setting.Email }}">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="phone" class="form-label">Telefon</label>
|
||||
<input type="text" class="form-control" id="phone" name="phone"
|
||||
value="{{ .Setting.Phone }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="address" class="form-label">Adres</label>
|
||||
<textarea class="form-control" id="address" name="address"
|
||||
rows="2">{{ .Setting.Address }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="url" class="form-label">Site URL</label>
|
||||
<input type="text" class="form-control" id="url" name="url" value="{{ .Setting.URL }}">
|
||||
</div>
|
||||
|
||||
<h5 class="mt-4">Logo Ayarları</h5>
|
||||
<div class="row">
|
||||
<!-- White Logo (WLogo) -->
|
||||
<div class="col-md-6">
|
||||
<div class="card border p-3 mb-3">
|
||||
<h6 class="mb-3">Beyaz Logo (Genellikle Koyu Zemin İçin)</h6>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Logo Yükle</label>
|
||||
<input type="file" class="form-control" name="w_logo" accept="image/*">
|
||||
{{ if .Setting.WLogo }}
|
||||
<div class="mt-2 text-center p-2 logo-preview logo-preview-light border rounded">
|
||||
<img src="{{ .Setting.WLogo }}" alt="WLogo" style="max-height: 50px;">
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Genişlik</label>
|
||||
<input type="number" class="form-control form-control-sm" name="w_width"
|
||||
placeholder="Otomatik" value="{{ .Setting.WWidth }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Yükseklik</label>
|
||||
<input type="number" class="form-control form-control-sm" name="w_height"
|
||||
placeholder="Otomatik" value="{{ .Setting.WHeight }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Kalite (1-100)</label>
|
||||
<input type="number" class="form-control form-control-sm" name="w_quality"
|
||||
placeholder="80" value="{{ .Setting.WQuality }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Format</label>
|
||||
<select class="form-select form-select-sm" name="w_format">
|
||||
<option value="avif" {{ if eq .Setting.WFormat "avif" }}selected{{ end
|
||||
}}>AVIF (Önerilen)</option>
|
||||
<option value="webp" {{ if eq .Setting.WFormat "webp" }}selected{{ end
|
||||
}}>WebP</option>
|
||||
<option value="png" {{ if eq .Setting.WFormat "png" }}selected{{ end }}>
|
||||
PNG</option>
|
||||
<option value="jpg" {{ if eq .Setting.WFormat "jpg" }}selected{{ end }}>
|
||||
JPG</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Black Logo (BLogo) -->
|
||||
<div class="col-md-6">
|
||||
<div class="card border p-3 mb-3">
|
||||
<h6 class="mb-3">Siyah Logo (Genellikle Beyaz Zemin İçin)</h6>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Logo Yükle</label>
|
||||
<input type="file" class="form-control" name="b_logo" accept="image/*">
|
||||
{{ if .Setting.BLogo }}
|
||||
<div class="mt-2 text-center p-2 logo-preview logo-preview-light border rounded">
|
||||
<img src="{{ .Setting.BLogo }}" alt="BLogo" style="max-height: 50px;">
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Genişlik</label>
|
||||
<input type="number" class="form-control form-control-sm" name="b_width"
|
||||
placeholder="Otomatik" value="{{ .Setting.BWidth }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Yükseklik</label>
|
||||
<input type="number" class="form-control form-control-sm" name="b_height"
|
||||
placeholder="Otomatik" value="{{ .Setting.BHeight }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Kalite (1-100)</label>
|
||||
<input type="number" class="form-control form-control-sm" name="b_quality"
|
||||
placeholder="80" value="{{ .Setting.BQuality }}">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small text-muted mb-0">Format</label>
|
||||
<select class="form-select form-select-sm" name="b_format">
|
||||
<option value="avif" {{ if eq .Setting.BFormat "avif" }}selected{{ end
|
||||
}}>AVIF (Önerilen)</option>
|
||||
<option value="webp" {{ if eq .Setting.BFormat "webp" }}selected{{ end
|
||||
}}>WebP</option>
|
||||
<option value="png" {{ if eq .Setting.BFormat "png" }}selected{{ end }}>
|
||||
PNG</option>
|
||||
<option value="jpg" {{ if eq .Setting.BFormat "jpg" }}selected{{ end }}>
|
||||
JPG</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CORS and Rate Limit moved to Güvenlik tab -->
|
||||
|
||||
<h5 class="mt-4">Sosyal Medya</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Instagram</label>
|
||||
<input type="text" class="form-control" name="instagram"
|
||||
value="{{ .Setting.Instagram }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Twitter (X)</label>
|
||||
<input type="text" class="form-control" name="x" value="{{ .Setting.X }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Facebook</label>
|
||||
<input type="text" class="form-control" name="facebook" value="{{ .Setting.Facebook }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Whatsapp</label>
|
||||
<input type="text" class="form-control" name="whatsapp" value="{{ .Setting.Whatsapp }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Linkedin</label>
|
||||
<input type="text" class="form-control" name="linkedin" value="{{ .Setting.Linkedin }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Pinterest</label>
|
||||
<input type="text" class="form-control" name="pinterest"
|
||||
value="{{ .Setting.Pinterest }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="is_active" name="is_active" {{ if
|
||||
.Setting.IsActive }}checked{{ end }}>
|
||||
<label class="form-check-label" for="is_active">Site Aktif</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Kaydet</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Security Tab (CORS / Rate Limits) -->
|
||||
<div class="tab-pane fade" id="security" role="tabpanel">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5 class="mb-0">CORS Yönetimi</h5>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/settings" class="btn btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/settings?deleted=true" class="btn btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<div class="card border p-3 mb-3">
|
||||
<h6 class="mb-3">Whitelist (İzinli Origin'ler)</h6>
|
||||
{{ if .EditWhitelist.ID }}
|
||||
<form action="/admin/settings/cors/whitelist/{{ .EditWhitelist.ID }}/update" method="POST" class="mb-3">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="origin" class="form-control" placeholder="https://example.com" required value="{{ .EditWhitelist.Origin }}">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" name="description" class="form-control" placeholder="Açıklama (opsiyonel)" value="{{ .EditWhitelist.Description }}">
|
||||
</div>
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="wl_active" name="is_active" {{ if .EditWhitelist.IsActive }}checked{{ end }}>
|
||||
<label class="form-check-label" for="wl_active">Aktif</label>
|
||||
</div>
|
||||
<div class="d-flex gap-2 justify-content-end">
|
||||
<a href="/admin/content/settings" class="btn btn-sm btn-secondary">İptal</a>
|
||||
<button class="btn btn-sm btn-primary" type="submit">Güncelle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ else }}
|
||||
<form action="/admin/settings/cors/whitelist/create" method="POST" class="mb-3">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="origin" class="form-control" placeholder="https://example.com" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" name="description" class="form-control" placeholder="Açıklama (opsiyonel)">
|
||||
</div>
|
||||
<div class="d-flex gap-2 justify-content-end">
|
||||
<button class="btn btn-sm btn-primary" type="submit">Ekle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
<div>
|
||||
<ul class="list-group list-group-flush">
|
||||
{{ if .CorsWhitelist }}
|
||||
{{ range .CorsWhitelist }}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<strong>{{ .Origin }}</strong>
|
||||
<div class="small text-muted">{{ .Description }}</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/settings/cors/whitelist/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success">Geri Yükle</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/content/settings?edit_whitelist={{ .ID }}" class="btn btn-sm btn-outline-secondary">Düzenle</a>
|
||||
<form action="/admin/settings/cors/whitelist/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger">Sil</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<li class="list-group-item">Kayıt yok</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card border p-3 mb-3">
|
||||
<h6 class="mb-3">Blacklist (Yasaklı Origin'ler)</h6>
|
||||
{{ if .EditBlacklist.ID }}
|
||||
<form action="/admin/settings/cors/blacklist/{{ .EditBlacklist.ID }}/update" method="POST" class="mb-3">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="origin" class="form-control" placeholder="https://bad.com" required value="{{ .EditBlacklist.Origin }}">
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" name="reason" class="form-control" placeholder="Sebep (opsiyonel)" value="{{ .EditBlacklist.Reason }}">
|
||||
</div>
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="bl_active" name="is_active" {{ if .EditBlacklist.IsActive }}checked{{ end }}>
|
||||
<label class="form-check-label" for="bl_active">Aktif</label>
|
||||
</div>
|
||||
<div class="d-flex gap-2 justify-content-end">
|
||||
<a href="/admin/content/settings" class="btn btn-sm btn-secondary">İptal</a>
|
||||
<button class="btn btn-sm btn-primary" type="submit">Güncelle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ else }}
|
||||
<form action="/admin/settings/cors/blacklist/create" method="POST" class="mb-3">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="origin" class="form-control" placeholder="https://bad.com" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input type="text" name="reason" class="form-control" placeholder="Sebep (opsiyonel)">
|
||||
</div>
|
||||
<div class="d-flex gap-2 justify-content-end">
|
||||
<button class="btn btn-sm btn-primary" type="submit">Ekle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
<div>
|
||||
<ul class="list-group list-group-flush">
|
||||
{{ if .CorsBlacklist }}
|
||||
{{ range .CorsBlacklist }}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<strong>{{ .Origin }}</strong>
|
||||
<div class="small text-muted">{{ .Reason }}</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/settings/cors/blacklist/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success">Geri Yükle</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/content/settings?edit_blacklist={{ .ID }}" class="btn btn-sm btn-outline-secondary">Düzenle</a>
|
||||
<form action="/admin/settings/cors/blacklist/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger">Sil</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<li class="list-group-item">Kayıt yok</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="mb-3">Rate Limit Ayarları</h5>
|
||||
<div class="card border p-3 mb-3">
|
||||
{{ if .EditRateLimit.ID }}
|
||||
<form action="/admin/settings/rate-limit/{{ .EditRateLimit.ID }}/update" method="POST" class="row g-2 mb-3">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="name" class="form-control" placeholder="İsim (ör. login)" required value="{{ .EditRateLimit.Name }}">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="number" name="max_requests" class="form-control" placeholder="Max istek" required value="{{ .EditRateLimit.MaxRequests }}">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="number" name="window_seconds" class="form-control" placeholder="Pencere (s)" required value="{{ .EditRateLimit.WindowSeconds }}">
|
||||
</div>
|
||||
<div class="col-md-3 d-flex gap-2">
|
||||
<a href="/admin/content/settings" class="btn btn-secondary">İptal</a>
|
||||
<button class="btn btn-primary" type="submit">Güncelle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ else }}
|
||||
<form action="/admin/settings/rate-limit/create" method="POST" class="row g-2 mb-3">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="name" class="form-control" placeholder="İsim (ör. login)" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="number" name="max_requests" class="form-control" placeholder="Max istek" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="number" name="window_seconds" class="form-control" placeholder="Pencere (s)" required>
|
||||
</div>
|
||||
<div class="col-md-3 d-flex gap-2">
|
||||
<button class="btn btn-primary" type="submit">Ekle</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
<div>
|
||||
<ul class="list-group list-group-flush">
|
||||
{{ if .RateLimits }}
|
||||
{{ range .RateLimits }}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<strong>{{ .Name }}</strong>
|
||||
<div class="small text-muted">{{ .MaxRequests }} req / {{ .WindowSeconds }}s</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/settings/rate-limit/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success">Geri Yükle</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/content/settings?edit_ratelimit={{ .ID }}" class="btn btn-sm btn-outline-secondary">Düzenle</a>
|
||||
<form action="/admin/settings/rate-limit/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger">Sil</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<li class="list-group-item">Kayıt yok</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Management Tab -->
|
||||
<div class="tab-pane fade" id="hero" role="tabpanel">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="/admin/content/settings"
|
||||
class="btn btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/settings?deleted=true"
|
||||
class="btn btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
<a href="/admin/heroes/new" class="btn btn-primary">
|
||||
<i class="bi bi-plus-lg"></i> Yeni Banner Ekle
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Görsel/Renk</th>
|
||||
<th>Başlık</th>
|
||||
<th>Alt Başlık</th>
|
||||
<th>Durum</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Heroes }}
|
||||
<tr>
|
||||
<td>
|
||||
<div style="width: 50px; height: 30px; background-color: {{ .Color }}; border-radius: 4px; border: 1px solid #ddd;"
|
||||
title="{{ .Color }}"></div>
|
||||
</td>
|
||||
<td>{{ .Title }}</td>
|
||||
<td>{{ .Text1 }}</td>
|
||||
<td>
|
||||
{{ if .IsActive }}
|
||||
<span class="badge bg-success">Aktif</span>
|
||||
{{ else }}
|
||||
<span class="badge bg-secondary">Pasif</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex gap-2">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/heroes/{{ .ID }}/restore" method="POST"
|
||||
onsubmit="return confirmRestore(event, this);">
|
||||
<button type="submit" class="btn btn-sm btn-success" title="Geri Yükle">
|
||||
<i class="bi bi-arrow-counterclockwise"></i>
|
||||
</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/heroes/{{ .ID }}/edit"
|
||||
class="btn btn-sm btn-outline-secondary" title="Düzenle">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form action="/admin/heroes/{{ .ID }}/delete" method="POST"
|
||||
onsubmit="return confirmDelete(event, this);">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Sil">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Simple tab state preservation using URL hash or local storage is complex with HTMX
|
||||
// For now, let's just make sure tabs work via Bootstrap JS
|
||||
// The tabs might reset to first tab on HTMX swap/update if we are not careful.
|
||||
// Since we reload the whole #settings-container (this file) on update, tabs will reset.
|
||||
// We can add a small script to check URL param or sessionStorage to activate correct tab.
|
||||
(function(){
|
||||
const STORAGE_KEY = 'admin.settings.activeTab';
|
||||
|
||||
// Save active tab id when clicked
|
||||
document.querySelectorAll('#settingsTab button[data-bs-toggle="tab"]').forEach(btn => {
|
||||
btn.addEventListener('shown.bs.tab', (e) => {
|
||||
try { sessionStorage.setItem(STORAGE_KEY, e.target.id); } catch(e){}
|
||||
});
|
||||
});
|
||||
|
||||
// Restore on load
|
||||
function restoreTab(){
|
||||
try{
|
||||
const id = sessionStorage.getItem(STORAGE_KEY);
|
||||
if(id){
|
||||
const btn = document.getElementById(id);
|
||||
if(btn){
|
||||
const tab = new bootstrap.Tab(btn);
|
||||
tab.show();
|
||||
}
|
||||
}
|
||||
}catch(e){}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', restoreTab);
|
||||
|
||||
// HTMX: after swapping settings container, restore the tab
|
||||
document.addEventListener('htmx:afterSwap', function(evt){
|
||||
if(evt.detail.target && evt.detail.target.id === undefined){ return; }
|
||||
const tgt = evt.detail.target;
|
||||
if(tgt && (tgt.id === 'users-container' || tgt.id === 'main-content' || tgt.id === 'modal-area')){
|
||||
// not our container
|
||||
return;
|
||||
}
|
||||
// if settings container was swapped, restore
|
||||
if(tgt && tgt.closest && tgt.closest('.container-fluid') && tgt.closest('.container-fluid').querySelector('#settingsTab')){
|
||||
restoreTab();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
71
views/admin/partials/tags.html
Normal file
71
views/admin/partials/tags.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0">Taglar</h2>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<form class="d-flex" action="/admin/content/tags" method="GET">
|
||||
<input type="search" name="search" class="form-control form-control-sm me-2" placeholder="Ara..." value="{{ .Search }}">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
||||
</form>
|
||||
<a href="/admin/tags/new" class="btn btn-sm btn-primary">Yeni Tag</a>
|
||||
<div class="btn-group">
|
||||
<a href="/admin/content/tags" class="btn btn-sm btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/tags?deleted=true" class="btn btn-sm btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle">
|
||||
<thead class="bg-transparent text-muted small">
|
||||
<tr>
|
||||
<th>İsim</th>
|
||||
<th class="text-muted">Oluşturma</th>
|
||||
<th class="text-end text-muted">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ if .Tags }}
|
||||
{{ range .Tags }}
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ .Name }}</td>
|
||||
<td class="text-muted small">{{ .CreatedAt.Format "2006-01-02" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group" role="group">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/tags/{{ .ID }}/restore" method="POST">
|
||||
<button class="btn btn-sm btn-success" title="Geri Yükle"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/tags/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary" title="Düzenle"><i class="bi bi-pencil"></i></a>
|
||||
<form action="/admin/tags/{{ .ID }}/delete" method="POST" onsubmit="return confirmDelete(event, this);">
|
||||
<button class="btn btn-sm btn-outline-danger" title="Sil"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center text-muted py-4">Kayıt yok</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item {{ if eq .Page 1 }}disabled{{ end }}"><a class="page-link" href="/admin/content/tags?page={{ .PrevPage }}">« Önceki</a></li>
|
||||
<li class="page-item disabled"><span class="page-link">Sayfa {{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
<li class="page-item {{ if eq .Page .TotalPages }}disabled{{ end }}"><a class="page-link" href="/admin/content/tags?page={{ .NextPage }}">Sonraki »</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
118
views/admin/partials/users.html
Normal file
118
views/admin/partials/users.html
Normal file
@@ -0,0 +1,118 @@
|
||||
<div class="container-fluid" hx-trigger="userListChanged from:body"
|
||||
hx-get="/admin/content/users?page={{ .Page }}&search={{ .Search }}" hx-target="this" hx-swap="outerHTML">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>Kullanıcılar</h2>
|
||||
<div>
|
||||
<input type="text" class="form-control d-inline-block w-auto me-2" placeholder="Ara..." name="search"
|
||||
value="{{ .Search }}" hx-get="/admin/content/users" hx-trigger="keyup changed delay:500ms"
|
||||
hx-target="#users-container" hx-push-url="true">
|
||||
<div class="btn-group me-2" role="group">
|
||||
<a href="/admin/content/users"
|
||||
class="btn btn-outline-primary {{ if not .ShowDeleted }}active{{ end }}">Aktif</a>
|
||||
<a href="/admin/content/users?deleted=true"
|
||||
class="btn btn-outline-danger {{ if .ShowDeleted }}active{{ end }}">Silinenler</a>
|
||||
</div>
|
||||
<a href="/admin/users/new" class="btn btn-primary">
|
||||
<i class="bi bi-plus-lg"></i> Yeni Kullanıcı
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm" id="users-container">
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Ad Soyad</th>
|
||||
<th>Email</th>
|
||||
<th>Rol</th>
|
||||
<th>Durum</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Users }}
|
||||
<tr>
|
||||
<td>{{ .ID }}</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
{{ if .Profile }}
|
||||
{{ range .Profile }}
|
||||
{{ if .AvatarURL }}
|
||||
<img src="{{ .AvatarURL }}" class="rounded-circle me-2" width="32" height="32"
|
||||
alt="">
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ .UserName }}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ .Email }}</td>
|
||||
<td>
|
||||
{{ if isTrue .IsAdmin }}
|
||||
<span class="badge bg-danger">Admin</span>
|
||||
{{ else }}
|
||||
<span class="badge bg-info">User</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
{{ if isTrue .EmailVerified }}
|
||||
<span class="text-success"><i class="bi bi-check-circle-fill"></i> Onaylı</span>
|
||||
{{ else }}
|
||||
<span class="text-warning"><i class="bi bi-exclamation-circle-fill"></i> Bekliyor</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex gap-2">
|
||||
{{ if $.ShowDeleted }}
|
||||
<form action="/admin/users/{{ .ID }}/restore" method="POST"
|
||||
onsubmit="return confirmRestore(event, this);">
|
||||
<button type="submit" class="btn btn-sm btn-success" title="Geri Yükle">
|
||||
<i class="bi bi-arrow-counterclockwise"></i> Geri Yükle
|
||||
</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<a href="/admin/users/{{ .ID }}/edit" class="btn btn-sm btn-outline-secondary"
|
||||
title="Düzenle">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form action="/admin/users/{{ .ID }}/delete" method="POST"
|
||||
onsubmit="return confirmDelete(event, this);">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Sil">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{{ if gt .TotalPages 1 }}
|
||||
<nav class="mt-3">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item {{ if le .Page 1 }}disabled{{ end }}">
|
||||
<a class="page-link" href="#"
|
||||
hx-get="/admin/content/users?page={{ .PrevPage }}&search={{ .Search }}"
|
||||
hx-target="#users-container">Önceki</a>
|
||||
</li>
|
||||
|
||||
<li class="page-item disabled"><span class="page-link">{{ .Page }} / {{ .TotalPages }}</span></li>
|
||||
|
||||
<li class="page-item {{ if ge .Page .TotalPages }}disabled{{ end }}">
|
||||
<a class="page-link" href="#"
|
||||
hx-get="/admin/content/users?page={{ .NextPage }}&search={{ .Search }}"
|
||||
hx-target="#users-container">Sonraki</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user