2025-06-19 14:25:42 -04:00
<!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 >
2025-06-19 14:35:13 -04:00
{% 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 %}
2025-06-19 14:25:42 -04:00
< 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 %}
2025-06-19 14:35:13 -04:00
< 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 >
2025-06-19 16:03:50 -04:00
< p class = "mb-1" > < strong > Knox Capture AR Template URL:< / strong > < code > {{ server_url }}/{{ tenant.id }}/< / code > < / p >
2025-06-19 14:35:13 -04:00
< 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 >
2025-06-19 14:25:42 -04:00
{% 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 >
2025-06-19 16:03:50 -04:00
< a href = "/settings" class = "btn btn-secondary mt-3" > Server Settings< / a >
2025-06-19 14:25:42 -04:00
< / div >
< / div >
< / div >
< / div >
2025-06-19 14:35:13 -04:00
< script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" > < / script >
2025-06-19 14:25:42 -04:00
< script >
2025-06-19 14:35:13 -04:00
const reservedIds = ['admin', 'api', 'login', 'logout', 'arcontentfields', 'arinfo',
'images', 'barcodes', 'static', 'assets', 'js', 'css', 'tenant',
'auth', 'oauth', 'callback', 'webhook', 'health', 'status'];
2025-06-19 14:25:42 -04:00
document.getElementById('newTenantForm').addEventListener('submit', function(e) {
e.preventDefault();
const tenantId = document.getElementById('tenantId').value;
if (tenantId) {
2025-06-19 14:35:13 -04:00
if (reservedIds.includes(tenantId.toLowerCase())) {
alert(`"${tenantId}" is a reserved name and cannot be used as a tenant ID.`);
return;
}
2025-06-19 14:25:42 -04:00
window.location.href = '/' + tenantId + '/';
}
});
2025-06-19 14:35:13 -04:00
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.`);
}
2025-06-19 14:25:42 -04:00
< / script >
< / body >
< / html >