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:
dwindown
2025-10-12 08:43:50 +07:00
parent 258d326909
commit c0df4a7c2a
37 changed files with 2744 additions and 628 deletions

View File

@@ -16,10 +16,10 @@ export declare class AdminPaymentsController {
subscription: ({
plan: {
id: string;
currency: string;
createdAt: Date;
updatedAt: Date;
name: string;
currency: string;
slug: string;
description: string | null;
price: import("@prisma/client/runtime/library").Decimal;
@@ -42,10 +42,10 @@ export declare class AdminPaymentsController {
};
} & {
id: string;
userId: string;
status: string;
createdAt: Date;
updatedAt: Date;
status: string;
userId: string;
planId: string;
startDate: Date;
endDate: Date;
@@ -56,21 +56,19 @@ export declare class AdminPaymentsController {
}) | null;
} & {
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
method: string;
userId: string;
currency: string;
amount: import("@prisma/client/runtime/library").Decimal;
subscriptionId: string | null;
invoiceNumber: string;
amount: import("@prisma/client/runtime/library").Decimal;
currency: string;
method: string;
tripayReference: string | null;
tripayFee: import("@prisma/client/runtime/library").Decimal | null;
totalAmount: import("@prisma/client/runtime/library").Decimal;
paymentChannel: string | null;
paymentUrl: string | null;
qrUrl: string | null;
status: string;
proofImageUrl: string | null;
transferDate: Date | null;
verifiedBy: string | null;
@@ -81,8 +79,15 @@ export declare class AdminPaymentsController {
notes: string | null;
expiresAt: Date | null;
paidAt: Date | null;
createdAt: Date;
updatedAt: Date;
})[]>;
getPendingCount(): Promise<number>;
getMonthlyRevenue(): Promise<{
month: string;
revenue: number;
users: number;
}[]>;
findOne(id: string): Promise<({
user: {
id: string;
@@ -92,10 +97,10 @@ export declare class AdminPaymentsController {
subscription: ({
plan: {
id: string;
currency: string;
createdAt: Date;
updatedAt: Date;
name: string;
currency: string;
slug: string;
description: string | null;
price: import("@prisma/client/runtime/library").Decimal;
@@ -118,10 +123,10 @@ export declare class AdminPaymentsController {
};
} & {
id: string;
userId: string;
status: string;
createdAt: Date;
updatedAt: Date;
status: string;
userId: string;
planId: string;
startDate: Date;
endDate: Date;
@@ -132,21 +137,19 @@ export declare class AdminPaymentsController {
}) | null;
} & {
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
method: string;
userId: string;
currency: string;
amount: import("@prisma/client/runtime/library").Decimal;
subscriptionId: string | null;
invoiceNumber: string;
amount: import("@prisma/client/runtime/library").Decimal;
currency: string;
method: string;
tripayReference: string | null;
tripayFee: import("@prisma/client/runtime/library").Decimal | null;
totalAmount: import("@prisma/client/runtime/library").Decimal;
paymentChannel: string | null;
paymentUrl: string | null;
qrUrl: string | null;
status: string;
proofImageUrl: string | null;
transferDate: Date | null;
verifiedBy: string | null;
@@ -157,24 +160,24 @@ export declare class AdminPaymentsController {
notes: string | null;
expiresAt: Date | null;
paidAt: Date | null;
createdAt: Date;
updatedAt: Date;
}) | null>;
verify(id: string, req: RequestWithUser): Promise<{
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
method: string;
userId: string;
currency: string;
amount: import("@prisma/client/runtime/library").Decimal;
subscriptionId: string | null;
invoiceNumber: string;
amount: import("@prisma/client/runtime/library").Decimal;
currency: string;
method: string;
tripayReference: string | null;
tripayFee: import("@prisma/client/runtime/library").Decimal | null;
totalAmount: import("@prisma/client/runtime/library").Decimal;
paymentChannel: string | null;
paymentUrl: string | null;
qrUrl: string | null;
status: string;
proofImageUrl: string | null;
transferDate: Date | null;
verifiedBy: string | null;
@@ -185,26 +188,26 @@ export declare class AdminPaymentsController {
notes: string | null;
expiresAt: Date | null;
paidAt: Date | null;
createdAt: Date;
updatedAt: Date;
}>;
reject(id: string, req: RequestWithUser, body: {
reason: string;
}): Promise<{
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
method: string;
userId: string;
currency: string;
amount: import("@prisma/client/runtime/library").Decimal;
subscriptionId: string | null;
invoiceNumber: string;
amount: import("@prisma/client/runtime/library").Decimal;
currency: string;
method: string;
tripayReference: string | null;
tripayFee: import("@prisma/client/runtime/library").Decimal | null;
totalAmount: import("@prisma/client/runtime/library").Decimal;
paymentChannel: string | null;
paymentUrl: string | null;
qrUrl: string | null;
status: string;
proofImageUrl: string | null;
transferDate: Date | null;
verifiedBy: string | null;
@@ -215,6 +218,8 @@ export declare class AdminPaymentsController {
notes: string | null;
expiresAt: Date | null;
paidAt: Date | null;
createdAt: Date;
updatedAt: Date;
}>;
}
export {};