Files
KCAPDemoServer/src/templates/tenant_selection.html
2025-06-19 16:08:18 -04:00

109 lines
5.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Select or Create Tenant - KCAP Demo Server</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1 class="text-center mb-4">KCAP Demo Server - Multi-Tenant</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'success' if category == 'success' else 'danger' }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3>Select an Existing Tenant</h3>
</div>
<div class="card-body">
{% if tenants %}
<div class="list-group">
{% for tenant in tenants %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<a href="/{{ tenant.id }}/" class="text-decoration-none flex-grow-1">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ tenant.name }}</h5>
<small>{{ tenant.created_at }}</small>
</div>
<p class="mb-1">Username: {{ tenant.username }}</p>
<p class="mb-1"><strong>Knox Capture AR Template URL:</strong> <code>{{ server_url }}/{{ tenant.id }}/</code></p>
<small>ID: {{ tenant.id }}</small>
</a>
<form method="POST" action="/tenant/{{ tenant.id }}/delete" class="ms-3" onsubmit="return confirmDelete('{{ tenant.name }}')">
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</form>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-muted">No tenants exist yet. Create one below!</p>
{% endif %}
</div>
</div>
<div class="card mt-4">
<div class="card-header">
<h3>Create a New Tenant</h3>
</div>
<div class="card-body">
<form id="newTenantForm">
<div class="mb-3">
<label for="tenantId" class="form-label">Tenant ID</label>
<input type="text" class="form-control" id="tenantId" placeholder="e.g., demo-company" required pattern="[a-zA-Z0-9_-]+">
<small class="form-text text-muted">Only letters, numbers, hyphens, and underscores allowed</small>
</div>
<button type="submit" class="btn btn-primary">Create & Enter Tenant</button>
</form>
</div>
</div>
<div class="mt-4 text-center">
<p class="text-muted">
<strong>Note:</strong> When you access a tenant URL directly (e.g., /my-tenant/),
it will be automatically created with default credentials (admin/admin).
</p>
<a href="/settings" class="btn btn-secondary mt-3">Server Settings</a>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
const reservedIds = ['admin', 'api', 'login', 'logout', 'arcontentfields', 'arinfo',
'images', 'barcodes', 'static', 'assets', 'js', 'css', 'tenant',
'auth', 'oauth', 'callback', 'webhook', 'health', 'status'];
document.getElementById('newTenantForm').addEventListener('submit', function(e) {
e.preventDefault();
const tenantId = document.getElementById('tenantId').value;
if (tenantId) {
// Convert to lowercase for consistency
const normalizedId = tenantId.toLowerCase();
if (reservedIds.includes(normalizedId)) {
alert(`"${tenantId}" is a reserved name and cannot be used as a tenant ID.`);
return;
}
// Use the normalized (lowercase) ID in the URL
window.location.href = '/' + normalizedId + '/';
}
});
function confirmDelete(tenantName) {
return confirm(`Are you sure you want to delete the tenant "${tenantName}"?\n\nThis will permanently delete all products and data associated with this tenant.`);
}
</script>
</body>
</html>