Enhance reports page UI with colorful gradient cards and improved filter layout

- Add gradient backgrounds to summary cards (Total Payin, Total Payout, Total Balance, CAP Redistribution)
- Include circular icon boxes with relevant icons for each metric
- Implement dynamic color for Total Balance (green for positive, red for negative)
- Reorganize filters into compact, collapsible layout with logical grouping
- Add collapsible header with animated chevron icon
- Enhance filter sections with icons and improved spacing
- Add comprehensive CSS styles for gradients, flexbox utilities, and visual effects
- Include JavaScript for smooth collapsible animation with icon rotation
parent 6a5e8b04
......@@ -169,6 +169,146 @@
.gap-1 {
gap: 1rem;
}
.gap-2 {
gap: 0.5rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-grow-1 {
flex-grow: 1;
}
.ms-3 {
margin-left: 1rem;
}
.me-1 {
margin-right: 0.25rem;
}
.me-2 {
margin-right: 0.5rem;
}
.mb-1 {
margin-bottom: 0.25rem;
}
.mb-3 {
margin-bottom: 1rem;
}
.mb-4 {
margin-bottom: 1.5rem;
}
.mb-0 {
margin-bottom: 0;
}
.fw-bold {
font-weight: bold;
}
.fw-semibold {
font-weight: 600;
}
.text-white-50 {
color: rgba(255, 255, 255, 0.75);
}
.text-muted {
color: #6c757d;
}
.text-success {
color: #28a745;
}
.text-danger {
color: #dc3545;
}
.text-end {
text-align: right;
}
.shadow-sm {
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}
.border-0 {
border: 0;
}
.rounded-circle {
border-radius: 50%;
}
.bg-opacity-25 {
background-color: rgba(255, 255, 255, 0.25);
}
.bg-gradient-primary {
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
}
.bg-gradient-info {
background: linear-gradient(135deg, #17a2b8 0%, #138496 100%);
}
.bg-gradient-success {
background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
}
.bg-gradient-danger {
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
}
.bg-gradient-warning {
background: linear-gradient(135deg, #ffc107 0%, #e0a800 100%);
}
.bg-white {
background-color: white;
}
.icon-box {
display: inline-flex;
align-items: center;
justify-content: center;
}
.input-group {
display: flex;
width: 100%;
}
.input-group input {
border-radius: 4px 0 0 4px;
}
.input-group input:last-child {
border-radius: 0 4px 4px 0;
border-left: 0;
}
.btn-outline-secondary {
background-color: transparent;
border: 1px solid #6c757d;
color: #6c757d;
}
.btn-outline-secondary:hover {
background-color: #6c757d;
color: white;
}
.btn-link {
background: none;
border: none;
color: #007bff;
text-decoration: none;
cursor: pointer;
}
.btn-link:hover {
text-decoration: underline;
}
.text-decoration-none {
text-decoration: none;
}
.w-100 {
width: 100%;
}
.text-start {
text-align: left;
}
.p-0 {
padding: 0;
}
.p-3 {
padding: 1rem;
}
.fa-2x {
font-size: 2em;
}
.fa-chevron-down {
transition: transform 0.3s ease;
}
.collapsed .fa-chevron-down {
transform: rotate(-90deg);
}
{% block extra_css %}{% endblock %}
</style>
</head>
......
......@@ -23,105 +23,174 @@
<!-- Summary Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white mb-3">
<div class="card bg-gradient-primary text-white mb-3 shadow-sm border-0">
<div class="card-body">
<h6 class="card-title">Total Payin</h6>
<h3 class="mb-0">{{ "{:,.2f}".format(totals.total_payin) }}</h3>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="icon-box bg-white bg-opacity-25 rounded-circle p-3">
<i class="fas fa-arrow-down fa-2x"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="card-title mb-1 text-white-50">Total Payin</h6>
<h3 class="mb-0 fw-bold">{{ "{:,.2f}".format(totals.total_payin) }}</h3>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white mb-3">
<div class="card bg-gradient-info text-white mb-3 shadow-sm border-0">
<div class="card-body">
<h6 class="card-title">Total Payout</h6>
<h3 class="mb-0">{{ "{:,.2f}".format(totals.total_payout) }}</h3>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="icon-box bg-white bg-opacity-25 rounded-circle p-3">
<i class="fas fa-arrow-up fa-2x"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="card-title mb-1 text-white-50">Total Payout</h6>
<h3 class="mb-0 fw-bold">{{ "{:,.2f}".format(totals.total_payout) }}</h3>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card {% if totals.total_balance >= 0 %}bg-success{% else %}bg-danger{% endif %} text-white mb-3">
<div class="card {% if totals.total_balance >= 0 %}bg-gradient-success{% else %}bg-gradient-danger{% endif %} text-white mb-3 shadow-sm border-0">
<div class="card-body">
<h6 class="card-title">Total Balance</h6>
<h3 class="mb-0">{{ "{:,.2f}".format(totals.total_balance) }}</h3>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="icon-box bg-white bg-opacity-25 rounded-circle p-3">
<i class="fas fa-balance-scale fa-2x"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="card-title mb-1 text-white-50">Total Balance</h6>
<h3 class="mb-0 fw-bold">{{ "{:,.2f}".format(totals.total_balance) }}</h3>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white mb-3">
<div class="card bg-gradient-warning text-white mb-3 shadow-sm border-0">
<div class="card-body">
<h6 class="card-title">CAP Redistribution Balance</h6>
<h3 class="mb-0">{{ "{:,.2f}".format(totals.cap_balance) }}</h3>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="icon-box bg-white bg-opacity-25 rounded-circle p-3">
<i class="fas fa-exchange-alt fa-2x"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="card-title mb-1 text-white-50">CAP Redistribution</h6>
<h3 class="mb-0 fw-bold">{{ "{:,.2f}".format(totals.cap_balance) }}</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-filter"></i> Filters</h5>
<div class="card mb-4 shadow-sm">
<div class="card-header bg-white">
<button class="btn btn-link text-decoration-none w-100 text-start p-0" type="button" data-bs-toggle="collapse" data-bs-target="#filterCollapse" aria-expanded="true" aria-controls="filterCollapse">
<h5 class="mb-0 d-flex align-items-center">
<i class="fas fa-filter me-2 text-primary"></i>
Filters
<i class="fas fa-chevron-down ms-auto" id="filterIcon"></i>
</h5>
</button>
</div>
<div class="card-body">
<form method="GET" action="{{ url_for('main.reports') }}" class="row g-3">
<div class="col-md-3">
<label for="client_id" class="form-label">Client</label>
<select class="form-select" id="client_id" name="client_id">
<option value="">All Clients</option>
{% for client in client_data %}
<option value="{{ client.client_id }}" {% if filters.client_id == client.client_id %}selected{% endif %}>{{ client.token_name }} ({{ client.client_id }})</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="date_range" class="form-label">Date Range</label>
<select class="form-select" id="date_range" name="date_range">
<option value="today" {% if filters.date_range == 'today' %}selected{% endif %}>Today</option>
<option value="yesterday" {% if filters.date_range == 'yesterday' %}selected{% endif %}>Yesterday</option>
<option value="this_week" {% if filters.date_range == 'this_week' %}selected{% endif %}>This Week</option>
<option value="last_week" {% if filters.date_range == 'last_week' %}selected{% endif %}>Last Week</option>
<option value="this_month" {% if filters.date_range == 'this_month' %}selected{% endif %}>This Month</option>
<option value="all" {% if filters.date_range == 'all' %}selected{% endif %}>All</option>
<option value="custom" {% if filters.date_range == 'custom' %}selected{% endif %}>Custom</option>
</select>
</div>
<div class="col-md-2">
<label for="start_date" class="form-label">Start Date</label>
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ filters.start_date }}">
</div>
<div class="col-md-1">
<label for="start_time" class="form-label">Start Time</label>
<input type="time" class="form-control" id="start_time" name="start_time" value="{{ filters.start_time }}">
</div>
<div class="col-md-2">
<label for="end_date" class="form-label">End Date</label>
<input type="date" class="form-control" id="end_date" name="end_date" value="{{ filters.end_date }}">
</div>
<div class="col-md-1">
<label for="end_time" class="form-label">End Time</label>
<input type="time" class="form-control" id="end_time" name="end_time" value="{{ filters.end_time }}">
</div>
<div class="col-md-1">
<label for="sort_by" class="form-label">Sort By</label>
<select class="form-select" id="sort_by" name="sort_by">
<option value="last_match_timestamp" {% if filters.sort_by == 'last_match_timestamp' %}selected{% endif %}>Last Match</option>
<option value="token_name" {% if filters.sort_by == 'token_name' %}selected{% endif %}>Client Name</option>
<option value="total_payin" {% if filters.sort_by == 'total_payin' %}selected{% endif %}>Total Payin</option>
<option value="total_payout" {% if filters.sort_by == 'total_payout' %}selected{% endif %}>Total Payout</option>
<option value="net_profit" {% if filters.sort_by == 'net_profit' %}selected{% endif %}>Net Profit</option>
<option value="total_bets" {% if filters.sort_by == 'total_bets' %}selected{% endif %}>Total Bets</option>
<option value="total_matches" {% if filters.sort_by == 'total_matches' %}selected{% endif %}>Total Matches</option>
<option value="cap_balance" {% if filters.sort_by == 'cap_balance' %}selected{% endif %}>CAP Balance</option>
</select>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">
<i class="fas fa-search"></i> Apply Filters
</button>
<a href="{{ url_for('main.reports') }}" class="btn btn-secondary">
<i class="fas fa-times"></i> Clear Filters
</a>
</div>
</form>
<div class="collapse show" id="filterCollapse">
<div class="card-body">
<form method="GET" action="{{ url_for('main.reports') }}">
<!-- Client Selection -->
<div class="row mb-3">
<div class="col-12">
<label for="client_id" class="form-label fw-semibold">
<i class="fas fa-user me-1"></i> Client
</label>
<select class="form-select" id="client_id" name="client_id">
<option value="">All Clients</option>
{% for client in client_data %}
<option value="{{ client.client_id }}" {% if filters.client_id == client.client_id %}selected{% endif %}>{{ client.token_name }} ({{ client.client_id }})</option>
{% endfor %}
</select>
</div>
</div>
<!-- Date Range Selection -->
<div class="row mb-3">
<div class="col-md-6">
<label for="date_range" class="form-label fw-semibold">
<i class="fas fa-calendar me-1"></i> Date Range
</label>
<select class="form-select" id="date_range" name="date_range">
<option value="today" {% if filters.date_range == 'today' %}selected{% endif %}>Today</option>
<option value="yesterday" {% if filters.date_range == 'yesterday' %}selected{% endif %}>Yesterday</option>
<option value="this_week" {% if filters.date_range == 'this_week' %}selected{% endif %}>This Week</option>
<option value="last_week" {% if filters.date_range == 'last_week' %}selected{% endif %}>Last Week</option>
<option value="this_month" {% if filters.date_range == 'this_month' %}selected{% endif %}>This Month</option>
<option value="all" {% if filters.date_range == 'all' %}selected{% endif %}>All</option>
<option value="custom" {% if filters.date_range == 'custom' %}selected{% endif %}>Custom</option>
</select>
</div>
<div class="col-md-6">
<label for="sort_by" class="form-label fw-semibold">
<i class="fas fa-sort me-1"></i> Sort By
</label>
<select class="form-select" id="sort_by" name="sort_by">
<option value="last_match_timestamp" {% if filters.sort_by == 'last_match_timestamp' %}selected{% endif %}>Last Match</option>
<option value="token_name" {% if filters.sort_by == 'token_name' %}selected{% endif %}>Client Name</option>
<option value="total_payin" {% if filters.sort_by == 'total_payin' %}selected{% endif %}>Total Payin</option>
<option value="total_payout" {% if filters.sort_by == 'total_payout' %}selected{% endif %}>Total Payout</option>
<option value="net_profit" {% if filters.sort_by == 'net_profit' %}selected{% endif %}>Net Profit</option>
<option value="total_bets" {% if filters.sort_by == 'total_bets' %}selected{% endif %}>Total Bets</option>
<option value="total_matches" {% if filters.sort_by == 'total_matches' %}selected{% endif %}>Total Matches</option>
<option value="cap_balance" {% if filters.sort_by == 'cap_balance' %}selected{% endif %}>CAP Balance</option>
</select>
</div>
</div>
<!-- Custom Date Range -->
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label fw-semibold">
<i class="fas fa-play me-1"></i> Start
</label>
<div class="input-group">
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ filters.start_date }}">
<input type="time" class="form-control" id="start_time" name="start_time" value="{{ filters.start_time }}">
</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold">
<i class="fas fa-stop me-1"></i> End
</label>
<div class="input-group">
<input type="date" class="form-control" id="end_date" name="end_date" value="{{ filters.end_date }}">
<input type="time" class="form-control" id="end_time" name="end_time" value="{{ filters.end_time }}">
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="row">
<div class="col-12">
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary flex-grow-1">
<i class="fas fa-search me-1"></i> Apply Filters
</button>
<a href="{{ url_for('main.reports') }}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i> Clear
</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
......@@ -217,4 +286,24 @@
</div>
</div>
</div>
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const filterCollapse = document.getElementById('filterCollapse');
const filterIcon = document.getElementById('filterIcon');
if (filterCollapse && filterIcon) {
filterCollapse.addEventListener('show.bs.collapse', function() {
filterIcon.classList.remove('fa-chevron-up');
filterIcon.classList.add('fa-chevron-down');
});
filterCollapse.addEventListener('hide.bs.collapse', function() {
filterIcon.classList.remove('fa-chevron-down');
filterIcon.classList.add('fa-chevron-up');
});
}
});
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment