feat(agents, config, dashboard, i18n): add agent line provision wizard, site deletion, and site dashboard with multi-language support
Added agent line provision wizard page with permission gating, replacing redirect placeholder. Introduced site deletion API and UI with confirmation dialog in integration sites management. Added new site-scoped dashboard panel showing bet metrics, P/L trends, active players, and quick links. Enhanced chart tooltip to support custom formatters and fix indicator color
This commit is contained in:
26
src/components/admin/admin-no-integration-site-state.tsx
Normal file
26
src/components/admin/admin-no-integration-site-state.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import type { ReactElement } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { AdminNoResourceState } from "@/components/admin/admin-no-resource-state";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
export function AdminNoIntegrationSiteState({
|
||||
canCreate = false,
|
||||
}: {
|
||||
canCreate?: boolean;
|
||||
}): ReactElement {
|
||||
const { t } = useTranslation("common");
|
||||
|
||||
return (
|
||||
<AdminNoResourceState message={t("integrationSites.emptyPlatformHint")}>
|
||||
{canCreate ? (
|
||||
<Button nativeButton={false} size="sm" render={<Link href="/admin/config/integration-sites" />}>
|
||||
{t("integrationSites.createSite")}
|
||||
</Button>
|
||||
) : null}
|
||||
</AdminNoResourceState>
|
||||
);
|
||||
}
|
||||
@@ -202,7 +202,15 @@ function ChartTooltipContent({
|
||||
.map((item, index) => {
|
||||
const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`
|
||||
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
||||
const indicatorColor = color ?? item.payload?.fill ?? item.color
|
||||
const configColor =
|
||||
itemConfig && "color" in itemConfig ? itemConfig.color : undefined
|
||||
const indicatorColor =
|
||||
color ?? item.color ?? item.payload?.fill ?? configColor
|
||||
|
||||
const formattedValue =
|
||||
formatter && item?.value !== undefined && item.name
|
||||
? formatter(item.value, item.name, item, index, item.payload)
|
||||
: null
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -212,56 +220,50 @@ function ChartTooltipContent({
|
||||
indicator === "dot" && "items-center"
|
||||
)}
|
||||
>
|
||||
{formatter && item?.value !== undefined && item.name ? (
|
||||
formatter(item.value, item.name, item, index, item.payload)
|
||||
{itemConfig?.icon ? (
|
||||
<itemConfig.icon />
|
||||
) : (
|
||||
<>
|
||||
{itemConfig?.icon ? (
|
||||
<itemConfig.icon />
|
||||
) : (
|
||||
!hideIndicator && (
|
||||
<div
|
||||
className={cn(
|
||||
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
|
||||
{
|
||||
"h-2.5 w-2.5": indicator === "dot",
|
||||
"w-1": indicator === "line",
|
||||
"w-0 border-[1.5px] border-dashed bg-transparent":
|
||||
indicator === "dashed",
|
||||
"my-0.5": nestLabel && indicator === "dashed",
|
||||
}
|
||||
)}
|
||||
style={
|
||||
{
|
||||
"--color-bg": indicatorColor,
|
||||
"--color-border": indicatorColor,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
!hideIndicator && (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-1 justify-between leading-none",
|
||||
nestLabel ? "items-end" : "items-center"
|
||||
)}
|
||||
>
|
||||
<div className="grid gap-1.5">
|
||||
{nestLabel ? tooltipLabel : null}
|
||||
<span className="text-muted-foreground">
|
||||
{itemConfig?.label ?? item.name}
|
||||
</span>
|
||||
</div>
|
||||
{item.value != null && (
|
||||
<span className="font-mono font-medium text-foreground tabular-nums">
|
||||
{typeof item.value === "number"
|
||||
? item.value.toLocaleString()
|
||||
: String(item.value)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
className={cn("shrink-0 rounded-[2px]", {
|
||||
"h-2.5 w-2.5": indicator === "dot",
|
||||
"w-1": indicator === "line",
|
||||
"w-0 border-[1.5px] border-dashed bg-transparent":
|
||||
indicator === "dashed",
|
||||
"my-0.5": nestLabel && indicator === "dashed",
|
||||
})}
|
||||
style={
|
||||
indicator === "dashed"
|
||||
? { borderColor: indicatorColor }
|
||||
: {
|
||||
backgroundColor: indicatorColor,
|
||||
borderColor: indicatorColor,
|
||||
}
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-1 justify-between leading-none",
|
||||
nestLabel ? "items-end" : "items-center"
|
||||
)}
|
||||
>
|
||||
<div className="grid gap-1.5">
|
||||
{nestLabel ? tooltipLabel : null}
|
||||
<span className="text-muted-foreground">
|
||||
{itemConfig?.label ?? item.name}
|
||||
</span>
|
||||
</div>
|
||||
{item.value != null && (
|
||||
<span className="font-mono font-medium text-foreground tabular-nums">
|
||||
{formattedValue ??
|
||||
(typeof item.value === "number"
|
||||
? item.value.toLocaleString()
|
||||
: String(item.value))}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user