first commit
This commit is contained in:
292
views/admin/settings/settings.templ
Normal file
292
views/admin/settings/settings.templ
Normal file
@@ -0,0 +1,292 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"gobeyhan/views/admin"
|
||||
"gobeyhan/database/models"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
templ Layout(title string) {
|
||||
@admin.Layout(title) {
|
||||
<div class="px-4 py-6 sm:px-0">
|
||||
<div class="mb-6 border-b border-gray-200">
|
||||
<nav class="-mb-px flex space-x-8" aria-label="Tabs">
|
||||
<a href="/admin/settings/whitelist" class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">CORS Whitelist</a>
|
||||
<a href="/admin/settings/blacklist" class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">CORS Blacklist</a>
|
||||
<a href="/admin/settings/rate-limits" class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Rate Limits</a>
|
||||
</nav>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
<script>
|
||||
function confirmDelete(formId) {
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: "You won't be able to revert this!",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
document.getElementById(formId).submit();
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
}
|
||||
}
|
||||
|
||||
templ WhitelistList(items []models.CorsWhitelist) {
|
||||
@Layout("CORS Whitelist") {
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">CORS Whitelist</h1>
|
||||
<a href="/admin/settings/whitelist/new" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Add Origin</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<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">Origin</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Description</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Active</th>
|
||||
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
for _, item := range items {
|
||||
<tr>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{ item.Origin }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{ item.Description }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
if item.IsActive {
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Active</span>
|
||||
} else {
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Inactive</span>
|
||||
}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<a href={ templ.SafeURL(fmt.Sprintf("/admin/settings/whitelist/%d/edit", item.ID)) } class="text-indigo-600 hover:text-indigo-900 mr-4">Edit</a>
|
||||
<form id={ fmt.Sprintf("delete-whitelist-%d", item.ID) } action={ templ.SafeURL(fmt.Sprintf("/admin/settings/whitelist/%d/delete", item.ID)) } method="POST" class="inline">
|
||||
<button type="button" class="text-red-600 hover:text-red-900" onclick={ templ.ComponentScript{ Call: fmt.Sprintf("confirmDelete('delete-whitelist-%d')", item.ID) } }>Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ WhitelistCreate(errors map[string]string) {
|
||||
@Layout("Add Whitelist Origin") {
|
||||
<div class="max-w-2xl mx-auto py-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-6">Add Allowed Origin</h1>
|
||||
<form action="/admin/settings/whitelist" method="POST" class="space-y-6 bg-white p-6 rounded-lg shadow">
|
||||
<div>
|
||||
<label for="origin" class="block text-sm font-medium text-gray-700">Origin (e.g. https://example.com)</label>
|
||||
<input type="text" name="origin" id="origin" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
if errors["origin"] != "" {
|
||||
<p class="mt-2 text-sm text-red-600">{ errors["origin"] }</p>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description</label>
|
||||
<input type="text" name="description" id="description" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="/admin/settings/whitelist" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">Cancel</a>
|
||||
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ WhitelistEdit(item *models.CorsWhitelist, errors map[string]string) {
|
||||
@Layout("Edit Whitelist Origin") {
|
||||
<div class="max-w-2xl mx-auto py-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-6">Edit Allowed Origin</h1>
|
||||
<form action={ templ.SafeURL(fmt.Sprintf("/admin/settings/whitelist/%d", item.ID)) } method="POST" class="space-y-6 bg-white p-6 rounded-lg shadow">
|
||||
<div>
|
||||
<label for="origin" class="block text-sm font-medium text-gray-700">Origin (e.g. https://example.com)</label>
|
||||
<input type="text" name="origin" id="origin" value={ item.Origin } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
if errors["origin"] != "" {
|
||||
<p class="mt-2 text-sm text-red-600">{ errors["origin"] }</p>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description</label>
|
||||
<input type="text" name="description" id="description" value={ item.Description } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="/admin/settings/whitelist" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">Cancel</a>
|
||||
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ BlacklistList(items []models.CorsBlacklist) {
|
||||
@Layout("CORS Blacklist") {
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">CORS Blacklist</h1>
|
||||
<a href="/admin/settings/blacklist/new" class="bg-red-600 text-white px-4 py-2 rounded-md hover:bg-red-700">Block Origin</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<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">Origin</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Reason</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Active</th>
|
||||
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
for _, item := range items {
|
||||
<tr>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{ item.Origin }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{ item.Reason }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
if item.IsActive {
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Active</span>
|
||||
} else {
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Inactive</span>
|
||||
}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<a href={ templ.SafeURL(fmt.Sprintf("/admin/settings/blacklist/%d/edit", item.ID)) } class="text-indigo-600 hover:text-indigo-900 mr-4">Edit</a>
|
||||
<form id={ fmt.Sprintf("delete-blacklist-%d", item.ID) } action={ templ.SafeURL(fmt.Sprintf("/admin/settings/blacklist/%d/delete", item.ID)) } method="POST" class="inline">
|
||||
<button type="button" class="text-red-600 hover:text-red-900" onclick={ templ.ComponentScript{ Call: fmt.Sprintf("confirmDelete('delete-blacklist-%d')", item.ID) } }>Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
templ BlacklistCreate(errors map[string]string) {
|
||||
@Layout("Block Origin") {
|
||||
<div class="max-w-2xl mx-auto py-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-6">Block Origin</h1>
|
||||
<form action="/admin/settings/blacklist" method="POST" class="space-y-6 bg-white p-6 rounded-lg shadow">
|
||||
<div>
|
||||
<label for="origin" class="block text-sm font-medium text-gray-700">Origin (e.g. 192.168.1.1)</label>
|
||||
<input type="text" name="origin" id="origin" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
if errors["origin"] != "" {
|
||||
<p class="mt-2 text-sm text-red-600">{ errors["origin"] }</p>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<label for="reason" class="block text-sm font-medium text-gray-700">Reason</label>
|
||||
<input type="text" name="reason" id="reason" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="/admin/settings/blacklist" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">Cancel</a>
|
||||
<button type="submit" class="bg-red-600 text-white px-4 py-2 rounded-md hover:bg-red-700">Block</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ BlacklistEdit(item *models.CorsBlacklist, errors map[string]string) {
|
||||
@Layout("Edit Blocked Origin") {
|
||||
<div class="max-w-2xl mx-auto py-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-6">Edit Blocked Origin</h1>
|
||||
<form action={ templ.SafeURL(fmt.Sprintf("/admin/settings/blacklist/%d", item.ID)) } method="POST" class="space-y-6 bg-white p-6 rounded-lg shadow">
|
||||
<div>
|
||||
<label for="origin" class="block text-sm font-medium text-gray-700">Origin (e.g. 192.168.1.1)</label>
|
||||
<input type="text" name="origin" id="origin" value={ item.Origin } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
if errors["origin"] != "" {
|
||||
<p class="mt-2 text-sm text-red-600">{ errors["origin"] }</p>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<label for="reason" class="block text-sm font-medium text-gray-700">Reason</label>
|
||||
<input type="text" name="reason" id="reason" value={ item.Reason } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="/admin/settings/blacklist" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">Cancel</a>
|
||||
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ RateLimitList(items []models.RateLimitSetting) {
|
||||
@Layout("Rate Limits") {
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Rate Limits</h1>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<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">Name</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Description</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Max Requests</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Window (s)</th>
|
||||
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
for _, item := range items {
|
||||
<tr>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{ item.Name }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{ item.Description }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{ fmt.Sprintf("%d", item.MaxRequests) }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{ fmt.Sprintf("%v", item.WindowSeconds) }</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<a href={ templ.SafeURL(fmt.Sprintf("/admin/settings/rate-limits/%d/edit", item.ID)) } class="text-indigo-600 hover:text-indigo-900 mr-4">Edit</a>
|
||||
if item.Name != "api" {
|
||||
<form id={ fmt.Sprintf("delete-ratelimit-%d", item.ID) } action={ templ.SafeURL(fmt.Sprintf("/admin/settings/rate-limits/%d/delete", item.ID)) } method="POST" class="inline">
|
||||
<button type="button" class="text-red-600 hover:text-red-900" onclick={ templ.ComponentScript{ Call: fmt.Sprintf("confirmDelete('delete-ratelimit-%d')", item.ID) } }>Delete</button>
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ RateLimitEdit(item *models.RateLimitSetting, errors map[string]string) {
|
||||
@Layout("Edit Rate Limit") {
|
||||
<div class="max-w-2xl mx-auto py-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-6">Edit Rate Limit: { item.Name }</h1>
|
||||
<form action={ templ.SafeURL(fmt.Sprintf("/admin/settings/rate-limits/%d", item.ID)) } method="POST" class="space-y-6 bg-white p-6 rounded-lg shadow">
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description</label>
|
||||
<input type="text" name="description" id="description" value={ item.Description } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="max_requests" class="block text-sm font-medium text-gray-700">Max Requests</label>
|
||||
<input type="number" name="max_requests" id="max_requests" value={ fmt.Sprintf("%d", item.MaxRequests) } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="window_seconds" class="block text-sm font-medium text-gray-700">Window (seconds)</label>
|
||||
<input type="number" name="window_seconds" id="window_seconds" value={ fmt.Sprintf("%d", item.WindowSeconds) } class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm p-2 border" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="/admin/settings/rate-limits" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">Cancel</a>
|
||||
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
1025
views/admin/settings/settings_templ.go
Normal file
1025
views/admin/settings/settings_templ.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user