260 lines
10 KiB
TypeScript
260 lines
10 KiB
TypeScript
"use client"
|
||
import { Button } from "@/components/ui/button"
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogDescription,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
DialogFooter,
|
||
} from "@/components/ui/dialog"
|
||
import { Input } from "@/components/ui/input"
|
||
import { Label } from "@/components/ui/label"
|
||
import { useState, useEffect } from "react"
|
||
import { useDashboard } from "../_lib/contexts/DashboardContext"
|
||
import type React from "react" // Added import for React
|
||
|
||
// 修改 ConfigButton 组件,添加一个隐藏的条件
|
||
// 将按钮设置为隐藏,但保留组件以便将来可能需要重新启用
|
||
export function ConfigButton() {
|
||
const { config, updateConfig } = useDashboard()
|
||
const stallCount = config.stallCount ?? 2011
|
||
const ownerRate = config.ownerRate ?? 82
|
||
const dailyRevenueBase = config.dailyRevenueBase ?? 28
|
||
const privateUserCount = config.privateUserCount ?? config.totalFans ?? 308000
|
||
const activeUserRate = config.activeUserRate ?? 13.5
|
||
const [localConfig, setLocalConfig] = useState({
|
||
...config,
|
||
stallCount,
|
||
ownerRate,
|
||
dailyRevenueBase,
|
||
privateUserCount,
|
||
activeUserRate,
|
||
averageOrderValue: config.averageOrderValue ?? 28,
|
||
accessPassword: config.accessPassword ?? "",
|
||
calculatedOwnerCount: Math.floor((stallCount * ownerRate) / 100),
|
||
calculatedDailyRevenue: Math.floor(((stallCount * ownerRate) / 100) * dailyRevenueBase),
|
||
calculatedActiveUsers: Math.floor((privateUserCount * activeUserRate) / 100),
|
||
calculatedDataAssetValue: privateUserCount * config.userValue,
|
||
})
|
||
|
||
const [open, setOpen] = useState(false)
|
||
|
||
// 设置按钮为隐藏
|
||
const isButtonVisible = false
|
||
|
||
// 计算关联数据
|
||
useEffect(() => {
|
||
const ownerCount = Math.floor((localConfig.stallCount * localConfig.ownerRate) / 100)
|
||
const dailyRevenue = ownerCount * localConfig.dailyRevenueBase
|
||
const activeUsers = Math.floor((localConfig.privateUserCount * localConfig.activeUserRate) / 100)
|
||
const dataAssetValue = localConfig.privateUserCount * localConfig.userValue
|
||
|
||
setLocalConfig((prev) => ({
|
||
...prev,
|
||
calculatedOwnerCount: ownerCount,
|
||
calculatedDailyRevenue: dailyRevenue,
|
||
calculatedActiveUsers: activeUsers,
|
||
calculatedDataAssetValue: dataAssetValue,
|
||
}))
|
||
}, [
|
||
localConfig.stallCount,
|
||
localConfig.ownerRate,
|
||
localConfig.dailyRevenueBase,
|
||
localConfig.privateUserCount,
|
||
localConfig.activeUserRate,
|
||
localConfig.userValue,
|
||
])
|
||
|
||
const handleChange = (key: string) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
const val = key === "accessPassword" ? e.target.value : Number(e.target.value)
|
||
setLocalConfig((prev) => ({ ...prev, [key]: val }))
|
||
}
|
||
|
||
const handleSave = () => {
|
||
updateConfig(localConfig)
|
||
setOpen(false)
|
||
}
|
||
|
||
// 如果按钮不可见,则不渲染任何内容
|
||
if (!isButtonVisible) {
|
||
return null
|
||
}
|
||
|
||
return (
|
||
<Dialog open={open} onOpenChange={setOpen}>
|
||
<DialogContent className="sm:max-w-[625px] bg-slate-800 text-slate-100 z-50">
|
||
<DialogHeader>
|
||
<DialogTitle>数据配置</DialogTitle>
|
||
<DialogDescription className="text-slate-400">调整显示数据的相关配置参数</DialogDescription>
|
||
</DialogHeader>
|
||
<div className="grid gap-4 py-4">
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="stall-count" className="text-right">
|
||
摊位总数
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<Input
|
||
id="stall-count"
|
||
value={localConfig.stallCount}
|
||
onChange={handleChange("stallCount")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<p className="text-xs text-slate-400">基础数据</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="owner-rate" className="text-right">
|
||
摊主占比
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<div className="flex items-center gap-2">
|
||
<Input
|
||
id="owner-rate"
|
||
type="number"
|
||
value={localConfig.ownerRate}
|
||
onChange={handleChange("ownerRate")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<span className="text-slate-400">%</span>
|
||
</div>
|
||
<p className="text-xs text-slate-400">
|
||
摊主数 = 摊位总数 × 摊主占比 = {localConfig.calculatedOwnerCount?.toLocaleString() ?? 0}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="average-order" className="text-right">
|
||
平均客单价
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<div className="flex items-center gap-2">
|
||
<Input
|
||
id="average-order"
|
||
type="number"
|
||
value={localConfig.averageOrderValue ?? 28}
|
||
onChange={handleChange("averageOrderValue")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<span className="text-slate-400">¥</span>
|
||
</div>
|
||
<p className="text-xs text-slate-400">基础数据</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="daily-revenue" className="text-right">
|
||
日营收基数
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<Input
|
||
id="daily-revenue"
|
||
type="number"
|
||
value={localConfig.dailyRevenueBase}
|
||
onChange={handleChange("dailyRevenueBase")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<p className="text-xs text-slate-400">
|
||
日总营收 = 摊主数 × 日营收基数 = ¥{localConfig.calculatedDailyRevenue?.toLocaleString() ?? 0}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="private-users" className="text-right">
|
||
私域用户数
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<Input
|
||
id="private-users"
|
||
value={localConfig.privateUserCount}
|
||
onChange={handleChange("privateUserCount")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<p className="text-xs text-slate-400">基础数据</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="active-rate" className="text-right">
|
||
活跃度
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<div className="flex items-center gap-2">
|
||
<Input
|
||
id="active-rate"
|
||
type="number"
|
||
value={localConfig.activeUserRate}
|
||
onChange={handleChange("activeUserRate")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<span className="text-slate-400">%</span>
|
||
</div>
|
||
<p className="text-xs text-slate-400">
|
||
活跃用户数 = 私域用户数 × 活跃度 = {localConfig.calculatedActiveUsers?.toLocaleString() ?? 0}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="user-value" className="text-right">
|
||
单用户价值
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<Input
|
||
id="user-value"
|
||
type="number"
|
||
value={localConfig.userValue}
|
||
onChange={handleChange("userValue")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<p className="text-xs text-slate-400">
|
||
数据资产估值 = 私域用户数 × 单用户价值 = ¥
|
||
{localConfig.calculatedDataAssetValue?.toLocaleString() ?? 0}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="update-interval" className="text-right">
|
||
更新间隔
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<div className="flex items-center gap-2">
|
||
<Input
|
||
id="update-interval"
|
||
type="number"
|
||
value={localConfig.updateInterval}
|
||
onChange={handleChange("updateInterval")}
|
||
className="bg-slate-900 border-slate-700"
|
||
/>
|
||
<span className="text-slate-400">ms</span>
|
||
</div>
|
||
<p className="text-xs text-slate-400">数据刷新间隔时间</p>
|
||
</div>
|
||
</div>
|
||
{/* 添加密码配置字段 */}
|
||
<div className="grid grid-cols-4 items-center gap-4">
|
||
<Label htmlFor="access-password" className="text-right">
|
||
访问密码
|
||
</Label>
|
||
<div className="col-span-3 space-y-2">
|
||
<Input
|
||
id="access-password"
|
||
type="password"
|
||
value={localConfig.accessPassword ?? ""}
|
||
onChange={handleChange("accessPassword")}
|
||
className="bg-slate-900 border-slate-700"
|
||
placeholder="设置访问密码"
|
||
/>
|
||
<p className="text-xs text-slate-400">设置访问大屏时需要验证的密码</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<DialogFooter>
|
||
<Button onClick={handleSave} className="bg-blue-600 hover:bg-blue-700 text-white">
|
||
保存配置
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
)
|
||
}
|