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

@@ -1,4 +1,5 @@
import { useState, useEffect } from "react"
import { toast } from "sonner"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -167,18 +168,17 @@ export function TransactionDialog({ open, onOpenChange, transaction, onSuccess }
if (isEditing) {
await axios.put(`${API}/wallets/${walletId}/transactions/${transaction.id}`, data)
toast.success('Transaksi berhasil diupdate')
} else {
await axios.post(`${API}/wallets/${walletId}/transactions`, data)
toast.success('Transaksi berhasil ditambahkan')
}
onSuccess()
onOpenChange(false)
// Reset form
resetForm()
} catch (err: unknown) {
const message = err instanceof Error ? err.message : 'Failed to save transaction'
setError(message)
} catch (error) {
console.error("Failed to save transaction:", error)
toast.error('Gagal menyimpan transaksi')
} finally {
setLoading(false)
}