import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group.tsx";
import { Label } from "@/components/ui/label.tsx";
import {
ChargeProps,
chargeTypes,
defaultChargeType,
nonBilling,
timesBilling,
tokenBilling,
} from "@/admin/charge.ts";
import { useTranslation } from "react-i18next";
import { Input } from "@/components/ui/input.tsx";
import { useMemo, useReducer, useState } from "react";
import { Button } from "@/components/ui/button.tsx";
import {
AlertCircle,
Cloud,
DownloadCloud,
Eraser,
EyeOff,
Minus,
PencilLine,
Plus,
RotateCw,
Search,
Settings2,
Trash,
UploadCloud,
} from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu.tsx";
import {
Command,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command.tsx";
import { channelModels } from "@/admin/channel.ts";
import { toastState } from "@/admin/utils.ts";
import { Switch } from "@/components/ui/switch.tsx";
import { NumberInput } from "@/components/ui/number-input.tsx";
import {
Table,
TableBody,
TableCell,
TableHeader,
TableRow,
} from "@/components/ui/table.tsx";
import OperationAction from "@/components/OperationAction.tsx";
import { Badge } from "@/components/ui/badge.tsx";
import { useToast } from "@/components/ui/use-toast";
import { deleteCharge, listCharge, setCharge } from "@/admin/api/charge.ts";
import { useEffectAsync } from "@/utils/hook.ts";
import { cn } from "@/components/ui/lib/utils.ts";
import { allModels } from "@/conf.ts";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert.tsx";
import Tips from "@/components/Tips.tsx";
const initialState: ChargeProps = {
id: -1,
type: defaultChargeType,
models: [],
anonymous: false,
input: 0,
output: 0,
};
function reducer(state: ChargeProps, action: any): ChargeProps {
switch (action.type) {
case "set":
return { ...action.payload };
case "set-models":
return { ...state, models: action.payload };
case "add-model":
const model = action.payload.trim();
if (model.length === 0 || state.models.includes(model)) return state;
return { ...state, models: [...state.models, model] };
case "remove-model":
return {
...state,
models: state.models.filter((model) => model !== action.payload),
};
case "set-type":
return { ...state, type: action.payload };
case "set-anonymous":
return { ...state, anonymous: action.payload };
case "set-input":
return { ...state, input: action.payload };
case "set-output":
return { ...state, output: action.payload };
case "clear":
return initialState;
case "clear-param":
return { ...initialState, id: state.id };
default:
return state;
}
}
function preflight(state: ChargeProps): ChargeProps {
state.models = state.models
.map((model) => model.trim())
.filter((model) => model.length > 0);
switch (state.type) {
case nonBilling:
state.input = 0;
state.output = 0;
break;
case timesBilling:
state.input = 0;
state.anonymous = false;
break;
case tokenBilling:
state.anonymous = false;
break;
}
if (state.input < 0) state.input = 0;
if (state.output < 0) state.output = 0;
return state;
}
type ChargeAlertProps = {
models: string[];
};
function ChargeAlert({ models }: ChargeAlertProps) {
const { t } = useTranslation();
return (
models.length > 0 && (
{t("admin.charge.unused-model")}