badar_madeena/app/views/incomes/report.html.erb

274 lines
7.2 KiB
Plaintext

<% content_for :title, "Income Report" %>
<style>
:root{
--card-bg: #ffffff;
--muted: #6b7280;
--accent: #2563eb;
--radius: 10px;
--shadow: 0 6px 20px rgba(16,24,40,0.06);
--gap: 18px;
font-family: "Inter", "Poppins", system-ui;
}
.er-container {
max-width: 920px;
margin: 28px auto;
padding: 18px;
color: #111827;
}
.er-header {
display:flex;
align-items:center;
justify-content:space-between;
gap:12px;
margin-bottom: var(--gap);
}
.er-title {
color: #fff;
font-size:1.4rem;
font-weight:600;
margin:0;
}
.er-actions { display:flex; gap:10px; align-items:center; }
.btn-simple {
background: var(--accent);
color:#fff;
padding:8px 12px;
border-radius:8px;
text-decoration:none;
font-weight:600;
font-size:0.95rem;
box-shadow: 0 6px 16px rgba(37,99,235,0.12);
transition: transform .12s ease, box-shadow .12s ease;
}
.btn-simple:hover { transform: translateY(-3px); box-shadow: 0 10px 26px rgba(37,99,235,0.16); }
.summary-row {
display: flex;
gap: 16px;
margin-bottom: 22px;
}
.card {
flex: 1;
padding: 16px;
border-radius: var(--radius);
background: #87ceeb;
border: 1px solid var(--border);
backdrop-filter: blur(12px);
box-shadow: var(--shadowG3);
transition: .25s;
}
.card:hover {
transform: translateY(-6px) scale(1.02);
box-shadow: 0 12px 36px rgba(168,85,247,0.75);
}
.card small {
color: var(--muted);
font-weight: 500;
}
.card .value {
font-size: 1.4rem;
font-weight: 700;
margin-top: 6px;
}
.chart-wrap {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding:12px;
margin-bottom: var(--gap);
border: 1px solid rgba(15,23,42,0.04);
}
.table {
width:100%;
border-collapse:collapse;
margin-bottom:20px;
background: transparent;
}
.table thead th {
text-align:left; font-size:0.9rem; color:var(--muted); padding:10px 12px;
border-bottom: 1px solid rgba(15,23,42,0.06);
}
.table tbody tr { background: #fff; border-radius:8px; }
.table td {
padding:11px 12px;
font-size:0.95rem;
vertical-align:middle;
border-bottom: 1px solid rgba(15,23,42,0.03);
}
.table tfoot th {
padding:10px 12px;
text-align:left;
font-weight:700;
border-top:1px solid rgba(15,23,42,0.06);
}
@media (max-width:720px){
.summary-row { flex-direction:column; }
.er-header { flex-direction:column; align-items:flex-start; gap:10px; }
}
</style>
<div class="er-container">
<div class="er-header">
<h1 class="er-title">INCOME REPORT</h1>
<div class="er-actions">
<%= link_to "New Income", new_income_path, class: "btn-simple" %>
</div>
</div>
<!-- Summary -->
<div class="summary-row">
<div class="card">
<small>Today's Income</small>
<div class="value"><%= number_to_currency(@daily_income || 0, unit: "₹") %></div>
</div>
<div class="card">
<small>This Week</small>
<div class="value"><%= number_to_currency(@weekly_income || 0, unit: "₹") %></div>
</div>
<div class="card">
<small>This Month</small>
<div class="value"><%= number_to_currency(@monthly_income || 0, unit: "₹") %></div>
</div>
</div>
<!-- Chart -->
<div class="chart-wrap">
<canvas id="incomeChart" height="120"></canvas>
</div>
<!-- Today's table -->
<section>
<h3 style="margin:0 0 8px 0; font-size:1rem; color:#fff;">Today's Income</h3>
<table class="table">
<thead>
<tr><th>Amount</th><th>Date</th></tr>
</thead>
<tbody>
<% (@daily_income_items || []).each do |income| %>
<tr>
<td><%= number_to_currency(income.amount, unit: "₹") %></td>
<td><%= income.created_at.strftime("%d %b %Y") %></td>
</tr>
<% end %>
<% if (@daily_income_items || []).empty? %>
<tr><td colspan="2" style="padding:12px;color:var(--muted)">No income for today.</td></tr>
<% end %>
</tbody>
<tfoot>
<tr><th>Total</th><th><%= number_to_currency(@daily_income || 0, unit: "₹") %></th></tr>
</tfoot>
</table>
</section>
<!-- Week table -->
<section>
<h3 style="margin:0 0 8px 0; font-size:1rem; color:#fff;">This Week's Income</h3>
<table class="table">
<thead>
<tr><th>Amount</th><th>Date</th></tr>
</thead>
<tbody>
<% (@weekly_income_items || []).each do |income| %>
<tr>
<td><%= number_to_currency(income.amount, unit: "₹") %></td>
<td><%= income.created_at.strftime("%d %b %Y") %></td>
</tr>
<% end %>
<% if (@weekly_income_items || []).empty? %>
<tr><td colspan="2" style="padding:12px;color:var(--muted)">No income for this week.</td></tr>
<% end %>
</tbody>
<tfoot>
<tr><th>Total</th><th><%= number_to_currency(@weekly_income || 0, unit: "₹") %></th></tr>
</tfoot>
</table>
</section>
<!-- Month table -->
<section>
<h3 style="margin:0 0 8px 0; font-size:1rem; color:#fff;">This Month's Income</h3>
<table class="table">
<thead>
<tr><th>Amount</th><th>Date</th></tr>
</thead>
<tbody>
<% (@monthly_income_items || []).each do |income| %>
<tr>
<td><%= number_to_currency(income.amount, unit: "₹") %></td>
<td><%= income.created_at.strftime("%d %b %Y") %></td>
</tr>
<% end %>
<% if (@monthly_income_items || []).empty? %>
<tr><td colspan="2" style="padding:12px;color:var(--muted)">No income for this month.</td></tr>
<% end %>
</tbody>
<tfoot>
<tr><th>Total</th><th><%= number_to_currency(@monthly_income || 0, unit: "₹") %></th></tr>
</tfoot>
</table>
</section>
</div>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
(function(){
const labels = <%= raw((@chart_labels || []).to_json) %>;
const data = <%= raw((@chart_data || []).to_json) %>;
const ctx = document.getElementById('incomeChart').getContext('2d');
const gradient = ctx.createLinearGradient(0,0,0,120);
gradient.addColorStop(0, 'rgba(37,99,235,0.18)');
gradient.addColorStop(1, 'rgba(37,99,235,0)');
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Income',
data: data,
fill: true,
backgroundColor: gradient,
borderColor: 'rgba(37,99,235,1)',
tension: 0.42,
borderWidth: 2,
pointRadius: 3,
pointBackgroundColor: 'rgba(37,99,235,1)'
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: { ticks: { color: '#374151' } },
y: {
beginAtZero: true,
ticks: { callback: v => '₹' + v, color: '#374151' },
grid: { color: 'rgba(15,23,42,0.04)' }
}
},
plugins: {
legend: { display: false },
tooltip: { callbacks: { label: ctx => '₹' + ctx.formattedValue } }
}
}
});
})();
</script>