import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { toast } from "sonner"; import { BillingStatus, config } from "@turbostarter/billing"; import { isKey, useTranslation } from "@turbostarter/i18n"; import { Avatar, AvatarFallback, AvatarImage, } from "@turbostarter/ui-web/avatar"; import { Badge } from "@turbostarter/ui-web/badge"; import { Button } from "@turbostarter/ui-web/button"; import { DataTableColumnHeader } from "@turbostarter/ui-web/data-table/data-table-column-header"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, } from "@turbostarter/ui-web/dropdown-menu"; import { Icons } from "@turbostarter/ui-web/icons"; import { pathsConfig } from "~/config/paths"; import { authClient } from "~/lib/auth/client"; import { admin } from "~/modules/admin/lib/api"; import { TurboLink } from "~/modules/common/turbo-link"; import { CreditsDialog } from "../components/credits-dialog"; import { invalidateCustomers } from "../server/invalidate"; import { UpdateCustomerPlanModal } from "../update-customer-plan"; import type { ColumnDef } from "@tanstack/react-table"; import type { User } from "@turbostarter/auth"; import type { Customer } from "@turbostarter/billing"; export const CustomerActions = ({ customer, }: { customer: Customer & { user: Pick; credits: number }; }) => { const { t } = useTranslation(["common", "admin", "billing"]); const queryClient = useQueryClient(); const [creditsDialogOpen, setCreditsDialogOpen] = useState(false); const deleteCustomer = useMutation({ ...admin.mutations.customers.delete, onSuccess: async () => { await invalidateCustomers(); await queryClient.invalidateQueries( admin.queries.users.getPlans({ id: customer.userId, }), ); toast.success(t("customers.customer.delete.success")); }, }); return ( <> e.preventDefault()}> {t("updatePlan")} setCreditsDialogOpen(true)}> {t("manageCredits", { defaultValue: "Manage Credits" })} {(() => { const isPending = deleteCustomer.isPending && deleteCustomer.variables.id === customer.id; return ( deleteCustomer.mutate({ id: customer.id, }) } disabled={isPending} key={`remove-${customer.id}`} > {t("delete")} {isPending && ( )} ); })()} ); }; export const useColumns = (): ColumnDef< Customer & { user: Pick; credits: number } >[] => { const { t, i18n } = useTranslation(["common", "billing"]); const { data: session } = authClient.useSession(); return [ { id: "q", accessorKey: "q", meta: { placeholder: `${t("searchPlaceholder")}`, variant: "text", }, enableHiding: false, enableColumnFilter: true, }, { id: "user.name", accessorKey: "user.name", header: ({ column }) => ( ), cell: ({ row }) => { return (
{row.original.user.name} {row.original.userId === session?.user.id && ( {t("you")} )}
); }, enableHiding: false, }, { id: "customerId", accessorKey: "customerId", header: ({ column }) => ( ), meta: { label: t("id"), }, }, { id: "plan", accessorKey: "plan", header: ({ column }) => ( ), cell: ({ row }) => { const plan = config.plans.find((plan) => plan.id === row.original.plan); if (!plan) { return -; } return ( {isKey(plan.name, i18n, "billing") ? t(plan.name) : plan.name} ); }, meta: { label: t("common:plan"), variant: "multiSelect", options: Object.values(config.plans).map((plan) => ({ label: isKey(plan.name, i18n, "billing") ? t(plan.name) : plan.name, value: plan.id, })), }, enableColumnFilter: true, }, { id: "status", accessorKey: "status", header: ({ column }) => ( ), cell: ({ row }) => { const statusKey = `status.${row.original.status?.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase())}`; if (!row.original.status) { return -; } return ( {isKey(statusKey, i18n, "billing") ? t(statusKey) : statusKey} ); }, meta: { label: t("common:status"), variant: "multiSelect", options: Object.values(BillingStatus).map((status) => { const statusKey = `status.${status.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase())}`; return { label: isKey(statusKey, i18n, "billing") ? t(statusKey) : statusKey, value: status, }; }), }, enableColumnFilter: true, }, { id: "credits", accessorKey: "credits", header: ({ column }) => ( ), cell: ({ row }) => { return (
{row.original.credits.toLocaleString()}
); }, meta: { label: "Credits", }, }, { id: "createdAt", accessorKey: "createdAt", header: ({ column }) => (
), cell: ({ row }) => { return (
{row.original.createdAt.toLocaleDateString(i18n.language)}
); }, meta: { label: t("createdAt"), variant: "dateRange", }, enableColumnFilter: true, }, { id: "actions", cell: ({ row }) => (
), enableHiding: false, }, ]; };