feat: Add Sonner toast notifications to all CRUD operations
- Install sonner package and create Toaster component - Add toast notifications to all admin dashboard operations: * AdminPlans: create, update, delete, reorder, toggle visibility * AdminPaymentMethods: create, update, delete, reorder, toggle active * AdminUsers: suspend, unsuspend, grant pro access * AdminPayments: verify, reject * AdminSettings: save settings - Add toast notifications to all member dashboard operations: * Wallets: create, update, delete * Transactions: create, update, delete * Profile: update name, avatar, phone, password, delete account * OTP: enable/disable email, WhatsApp, authenticator - Replace all alert() calls with toast.success/error/warning - Add proper success/error messages in Bahasa Indonesia - Implement smart plan deletion (permanent if no subscriptions, soft delete if has subscriptions) - Fix admin redirect after login (admin goes to /admin, users to /) - Exclude admin accounts from subscription distribution chart - Show inactive plans with visual indicators - Add real revenue data to admin dashboard charts - Use formatLargeNumber for consistent number formatting
This commit is contained in:
37
apps/api/dist/admin/admin-payments.service.js
vendored
37
apps/api/dist/admin/admin-payments.service.js
vendored
@@ -107,6 +107,43 @@ let AdminPaymentsService = class AdminPaymentsService {
|
||||
where: { status: 'pending' },
|
||||
});
|
||||
}
|
||||
async getMonthlyRevenue() {
|
||||
const sixMonthsAgo = new Date();
|
||||
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
|
||||
const payments = await this.prisma.payment.findMany({
|
||||
where: {
|
||||
status: 'paid',
|
||||
paidAt: {
|
||||
gte: sixMonthsAgo,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
amount: true,
|
||||
paidAt: true,
|
||||
},
|
||||
});
|
||||
const monthlyData = {};
|
||||
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
payments.forEach((payment) => {
|
||||
if (payment.paidAt) {
|
||||
const date = new Date(payment.paidAt);
|
||||
const monthKey = `${months[date.getMonth()]} ${date.getFullYear()}`;
|
||||
if (!monthlyData[monthKey]) {
|
||||
monthlyData[monthKey] = { revenue: 0, count: 0 };
|
||||
}
|
||||
monthlyData[monthKey].revenue += Number(payment.amount);
|
||||
monthlyData[monthKey].count += 1;
|
||||
}
|
||||
});
|
||||
const result = Object.entries(monthlyData)
|
||||
.map(([month, data]) => ({
|
||||
month: month.split(' ')[0],
|
||||
revenue: data.revenue,
|
||||
users: data.count,
|
||||
}))
|
||||
.slice(-6);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
exports.AdminPaymentsService = AdminPaymentsService;
|
||||
exports.AdminPaymentsService = AdminPaymentsService = __decorate([
|
||||
|
||||
Reference in New Issue
Block a user