2025-08-12 13:33:25 +03:00

432 lines
19 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{{ tenant.display_name }} - Tenant Details - {{ block.super }}{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- Page Header -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-1">{{ tenant.display_name }}</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'core:tenant_list' %}">Tenants</a></li>
<li class="breadcrumb-item active">{{ tenant.name }}</li>
</ol>
</nav>
</div>
<div class="btn-group">
<a href="{% url 'core:tenant_update' tenant.pk %}" class="btn btn-primary">
<i class="fas fa-edit me-2"></i>Edit Tenant
</a>
<div class="dropdown">
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
<i class="fas fa-cog me-2"></i>Actions
</button>
<ul class="dropdown-menu">
{% if tenant.is_active %}
<li><a class="dropdown-item text-warning" href="#" onclick="deactivateTenant()">
<i class="fas fa-pause me-2"></i>Deactivate Tenant
</a></li>
{% else %}
<li><a class="dropdown-item text-success" href="#" onclick="activateTenant()">
<i class="fas fa-play me-2"></i>Activate Tenant
</a></li>
{% endif %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" onclick="exportTenantData()">
<i class="fas fa-download me-2"></i>Export Data
</a></li>
<li><a class="dropdown-item text-danger" href="{% url 'core:tenant_delete' tenant.pk %}">
<i class="fas fa-trash me-2"></i>Delete Tenant
</a></li>
</ul>
</div>
</div>
</div>
<!-- Status Alert -->
{% if not tenant.is_active %}
<div class="alert alert-warning" role="alert">
<i class="fas fa-exclamation-triangle me-2"></i>
This tenant is currently <strong>inactive</strong>. Users will not be able to access the system.
</div>
{% endif %}
<div class="row">
<!-- Basic Information -->
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-info-circle me-2"></i>Basic Information
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Organization Name</label>
<p class="fw-bold">{{ tenant.name }}</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Display Name</label>
<p class="fw-bold">{{ tenant.display_name }}</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Organization Type</label>
<p>
<span class="badge bg-info">{{ tenant.get_organization_type_display }}</span>
</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Domain</label>
<p>
{% if tenant.domain %}
<code>{{ tenant.domain }}</code>
{% else %}
<span class="text-muted">Not configured</span>
{% endif %}
</p>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Status</label>
<p>
{% if tenant.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-danger">Inactive</span>
{% endif %}
</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Tenant ID</label>
<p>
<code>{{ tenant.tenant_id }}</code>
<button class="btn btn-sm btn-outline-secondary ms-2" onclick="copyToClipboard('{{ tenant.tenant_id }}')">
<i class="fas fa-copy"></i>
</button>
</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Created</label>
<p>{{ tenant.created_at|date:"F d, Y \a\t H:i" }}</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Last Updated</label>
<p>{{ tenant.updated_at|date:"F d, Y \a\t H:i" }}</p>
</div>
</div>
</div>
{% if tenant.description %}
<div class="mt-3">
<label class="form-label text-muted">Description</label>
<p>{{ tenant.description|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
<!-- Contact Information -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-address-book me-2"></i>Contact Information
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Primary Email</label>
<p>
{% if tenant.contact_email %}
<a href="mailto:{{ tenant.contact_email }}">{{ tenant.contact_email }}</a>
{% else %}
<span class="text-muted">Not provided</span>
{% endif %}
</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Phone Number</label>
<p>
{% if tenant.contact_phone %}
<a href="tel:{{ tenant.contact_phone }}">{{ tenant.contact_phone }}</a>
{% else %}
<span class="text-muted">Not provided</span>
{% endif %}
</p>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Website</label>
<p>
{% if tenant.website %}
<a href="{{ tenant.website }}" target="_blank">{{ tenant.website }}</a>
{% else %}
<span class="text-muted">Not provided</span>
{% endif %}
</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Timezone</label>
<p>{{ tenant.timezone|default:"Not configured" }}</p>
</div>
</div>
</div>
{% if tenant.address %}
<div class="mt-3">
<label class="form-label text-muted">Address</label>
<p>{{ tenant.address|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
<!-- Configuration Settings -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-cogs me-2"></i>Configuration Settings
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Max Users</label>
<p>{{ tenant.max_users|default:"Unlimited" }}</p>
</div>
<div class="mb-3">
<label class="form-label text-muted">Storage Limit</label>
<p>{{ tenant.storage_limit_gb|default:"Unlimited" }}{% if tenant.storage_limit_gb %} GB{% endif %}</p>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label text-muted">Features Enabled</label>
<div>
{% if tenant.features_enabled %}
{% for feature in tenant.features_enabled %}
<span class="badge bg-primary me-1">{{ feature }}</span>
{% endfor %}
{% else %}
<span class="text-muted">Default features</span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Quick Stats -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-chart-bar me-2"></i>Quick Stats
</h5>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-6 mb-3">
<div class="border-end">
<h4 class="text-primary mb-1">{{ tenant.total_users|default:0 }}</h4>
<small class="text-muted">Total Users</small>
</div>
</div>
<div class="col-6 mb-3">
<h4 class="text-success mb-1">{{ tenant.active_users|default:0 }}</h4>
<small class="text-muted">Active Users</small>
</div>
<div class="col-6">
<div class="border-end">
<h4 class="text-info mb-1">{{ tenant.total_departments|default:0 }}</h4>
<small class="text-muted">Departments</small>
</div>
</div>
<div class="col-6">
<h4 class="text-warning mb-1">{{ tenant.storage_used_gb|default:0 }}</h4>
<small class="text-muted">GB Used</small>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-history me-2"></i>Recent Activity
</h5>
</div>
<div class="card-body">
{% if recent_activities %}
{% for activity in recent_activities %}
<div class="d-flex align-items-start mb-3">
<div class="avatar-sm bg-primary text-white rounded-circle d-flex align-items-center justify-content-center me-3">
<i class="fas fa-{{ activity.icon|default:'circle' }}"></i>
</div>
<div class="flex-grow-1">
<p class="mb-1">{{ activity.description }}</p>
<small class="text-muted">{{ activity.timestamp|timesince }} ago</small>
</div>
</div>
{% endfor %}
{% else %}
<p class="text-muted text-center">No recent activity</p>
{% endif %}
</div>
</div>
<!-- System Health -->
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-heartbeat me-2"></i>System Health
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-muted">Database</span>
<span class="badge bg-success">Healthy</span>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-success" style="width: 95%"></div>
</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-muted">Storage</span>
<span class="badge bg-warning">75%</span>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-warning" style="width: 75%"></div>
</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-muted">API Response</span>
<span class="badge bg-success">Good</span>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-success" style="width: 88%"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(function() {
// Show success feedback
const button = event.target.closest('button');
const originalIcon = button.innerHTML;
button.innerHTML = '<i class="fas fa-check"></i>';
button.classList.add('btn-success');
button.classList.remove('btn-outline-secondary');
setTimeout(() => {
button.innerHTML = originalIcon;
button.classList.remove('btn-success');
button.classList.add('btn-outline-secondary');
}, 2000);
});
}
function activateTenant() {
if (confirm('Activate this tenant? Users will be able to access the system.')) {
fetch(`{% url 'core:activate_tenant' tenant.pk %}`, {
method: 'POST',
headers: {
'X-CSRFToken': getCsrfToken()
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Error activating tenant: ' + data.error);
}
})
.catch(error => {
console.error('Error:', error);
alert('Error activating tenant');
});
}
}
function deactivateTenant() {
if (confirm('Deactivate this tenant? This will prevent users from accessing the system.')) {
fetch(`{% url 'core:deactivate_tenant' tenant.pk %}`, {
method: 'POST',
headers: {
'X-CSRFToken': getCsrfToken()
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Error deactivating tenant: ' + data.error);
}
})
.catch(error => {
console.error('Error:', error);
alert('Error deactivating tenant');
});
}
}
{#function exportTenantData() {#}
{# window.open(`{% url 'core:' tenant.pk %}`, '_blank');#}
{# }#}
function getCsrfToken() {
return document.querySelector('[name=csrfmiddlewaretoken]').value;
}
</script>
<style>
.avatar-sm {
width: 32px;
height: 32px;
font-size: 14px;
}
.progress {
background-color: #e9ecef;
}
.card-body .row.text-center .border-end {
border-right: 1px solid #dee2e6 !important;
}
@media (max-width: 576px) {
.card-body .row.text-center .border-end {
border-right: none !important;
border-bottom: 1px solid #dee2e6 !important;
padding-bottom: 1rem;
margin-bottom: 1rem;
}
}
</style>
{% endblock %}