mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-04-30 15:30:51 -05:00
add: daily + monthly donations charts
This commit is contained in:
@@ -34,7 +34,28 @@ class DonationController extends Controller
|
||||
{
|
||||
abort_unless($request->user()->group->is_owner, 403);
|
||||
|
||||
return view('Staff.donation.index', ['donations' => Donation::with('package')->latest()->paginate(25)]);
|
||||
$donations = Donation::with('package')->latest()->paginate(25);
|
||||
|
||||
$dailyDonations = Donation::selectRaw('DATE(donations.created_at) as date, SUM(donation_packages.cost) as total')
|
||||
->join('donation_packages', 'donations.package_id', '=', 'donation_packages.id')
|
||||
->where('donations.status', Donation::APPROVED)
|
||||
->groupBy('date')
|
||||
->orderBy('date') // Ensure the data is ordered by date
|
||||
->get();
|
||||
|
||||
$monthlyDonations = Donation::selectRaw('YEAR(donations.created_at) as year, MONTH(donations.created_at) as month, SUM(donation_packages.cost) as total')
|
||||
->join('donation_packages', 'donations.package_id', '=', 'donation_packages.id')
|
||||
->where('donations.status', Donation::APPROVED)
|
||||
->groupBy('year', 'month')
|
||||
->orderBy('year')
|
||||
->orderBy('month') // Ensure the data is ordered by year and month
|
||||
->get();
|
||||
|
||||
return view('Staff.donation.index', [
|
||||
'donations' => $donations,
|
||||
'dailyDonations' => $dailyDonations,
|
||||
'monthlyDonations' => $monthlyDonations,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"ajv": "^8.10.0",
|
||||
"alpinejs": "^3.9.1",
|
||||
"axios": "^1.7.2",
|
||||
"chart.js": "^4.4.4",
|
||||
"chartjs-adapter-date-fns": "^3.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dayjs": "^1.11.0",
|
||||
"laravel-echo": "^1.11.4",
|
||||
|
||||
@@ -32,6 +32,12 @@ if (token) {
|
||||
import Swal from 'sweetalert2';
|
||||
window.Swal = Swal;
|
||||
|
||||
// ChartJS
|
||||
import { Chart, registerables } from 'chart.js';
|
||||
import 'chartjs-adapter-date-fns';
|
||||
Chart.register(...registerables);
|
||||
window.Chart = Chart;
|
||||
|
||||
// Vite Import
|
||||
import.meta.glob(['/public/img/pipes/**', '/resources/sass/vendor/webfonts/font-awesome/**']);
|
||||
|
||||
|
||||
@@ -46,3 +46,15 @@
|
||||
height: 40px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
/* Donation Charts */
|
||||
|
||||
.chart-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
gap: 20px;
|
||||
|
||||
& > div {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,20 @@
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h2 class="panel__heading">Donation Statistics</h2>
|
||||
</header>
|
||||
<div class="chart-wrapper">
|
||||
<div>
|
||||
<canvas id="dailyDonationsChart"></canvas>
|
||||
</div>
|
||||
<div>
|
||||
<canvas id="monthlyDonationsChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h2 class="panel__heading">Donations</h2>
|
||||
@@ -40,10 +54,10 @@
|
||||
<td>{{ $donation->transaction }}</td>
|
||||
<td>$ {{ $donation->package->cost }}</td>
|
||||
<td>
|
||||
{{ App\Helpers\StringHelper::formatBytes($donation->package->upload_value) }}
|
||||
{{ App\Helpers\StringHelper::formatBytes($donation->package->upload_value ?? 0) }}
|
||||
</td>
|
||||
<td>{{ $donation->package->invite_value }}</td>
|
||||
<td>{{ $donation->package->bonus_value }}</td>
|
||||
<td>{{ $donation->package->invite_value ?? 0 }}</td>
|
||||
<td>{{ $donation->package->bonus_value ?? 0 }}</td>
|
||||
<td>
|
||||
@if ($donation->package->donor_value === null)
|
||||
Lifetime
|
||||
@@ -108,3 +122,62 @@
|
||||
{{ $donations->links('partials.pagination') }}
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script nonce="{{ HDVinnie\SecureHeaders\SecureHeaders::nonce('script') }}">
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const dailyDonations = @json($dailyDonations);
|
||||
const monthlyDonations = @json($monthlyDonations);
|
||||
|
||||
// Daily Donations Chart
|
||||
const dailyCtx = document.getElementById('dailyDonationsChart').getContext('2d');
|
||||
new Chart(dailyCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: dailyDonations.map((d) => d.date),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Daily Donations',
|
||||
data: dailyDonations.map((d) => d.total),
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
borderWidth: 1,
|
||||
fill: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
x: { type: 'time', time: { unit: 'day' } },
|
||||
y: { beginAtZero: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Monthly Donations Chart
|
||||
const monthlyCtx = document.getElementById('monthlyDonationsChart').getContext('2d');
|
||||
new Chart(monthlyCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: monthlyDonations.map((d) => `${d.year}-${d.month}`),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Monthly Donations',
|
||||
data: monthlyDonations.map((d) => d.total),
|
||||
backgroundColor: 'rgba(153, 102, 255, 0.2)',
|
||||
borderColor: 'rgba(153, 102, 255, 1)',
|
||||
borderWidth: 1,
|
||||
fill: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
x: { type: 'category' },
|
||||
y: { beginAtZero: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
Reference in New Issue
Block a user