feat: initialize TJWater WebGIS frontend
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
"use client";
|
||||
|
||||
import { Target, TriangleAlert, X } from "lucide-react";
|
||||
import { useMemo } from "react";
|
||||
import type { DetailFeature } from "../types";
|
||||
import {
|
||||
getFeatureInsightMetrics,
|
||||
getLocalizedFeatureProperties
|
||||
} from "../utils/feature-properties";
|
||||
import { FeaturePropertyList } from "./feature-property-list";
|
||||
|
||||
type FeatureInsightPanelProps = {
|
||||
feature: DetailFeature | null;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
export function FeatureInsightPanel({ feature, onClose }: FeatureInsightPanelProps) {
|
||||
const metrics = useMemo(() => {
|
||||
if (!feature) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return getFeatureInsightMetrics(feature.layer, feature.properties);
|
||||
}, [feature]);
|
||||
|
||||
const propertyEntries = useMemo(() => {
|
||||
if (!feature) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return getLocalizedFeatureProperties(feature.properties);
|
||||
}, [feature]);
|
||||
|
||||
return (
|
||||
<aside className="acrylic-panel pointer-events-auto flex h-full min-h-0 flex-col rounded border">
|
||||
<div className="border-b border-slate-200/80 p-4">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-xs font-medium tracking-[0.14em] text-slate-500">要素详情</p>
|
||||
<h2 className="mt-1 text-lg font-semibold text-slate-950">
|
||||
{feature ? feature.title : "选择一个管网对象"}
|
||||
</h2>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="关闭详情"
|
||||
title="关闭详情"
|
||||
onClick={onClose}
|
||||
className="surface-control grid h-9 w-9 place-items-center rounded border text-slate-500 hover:text-slate-900"
|
||||
>
|
||||
<X size={16} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<p className="mt-2 text-sm text-slate-600">
|
||||
{feature ? feature.subtitle : "点击地图上的管线或节点后,这里会展示属性和 Agent 解释。"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="min-h-0 flex-1 overflow-auto p-4">
|
||||
{feature ? (
|
||||
<>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{metrics.map(({ label, value }) => (
|
||||
<div key={label} className="surface-reading rounded border p-3">
|
||||
<p className="text-xs text-slate-500">{label}</p>
|
||||
<p className="mt-1 truncate text-sm font-semibold text-slate-900 tabular-nums">{value}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<section className="material-tone-warning mt-4 rounded border border-orange-100 p-3">
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-orange-900">
|
||||
<TriangleAlert size={16} aria-hidden="true" />
|
||||
Agent 解释
|
||||
</div>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-700">
|
||||
该对象来自 GeoServer MVT。当前仅执行前端预览,不会写入样式、模型参数或调度工单。
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mt-4">
|
||||
<h3 className="text-sm font-semibold text-slate-900">属性</h3>
|
||||
<div className="mt-2">
|
||||
<FeaturePropertyList entries={propertyEntries} />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex h-full flex-col items-center justify-center text-center">
|
||||
<div className="surface-reading grid h-12 w-12 place-items-center rounded border text-slate-500">
|
||||
<Target size={22} aria-hidden="true" />
|
||||
</div>
|
||||
<p className="mt-3 text-sm font-medium text-slate-800">等待地图选择</p>
|
||||
<p className="mt-1 max-w-[260px] text-sm leading-6 text-slate-500">
|
||||
选择要素后,可查看基础属性、模拟入口与 Agent 会话联动结果。
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user