MIF7 移动信息架构整改收口
这个提交包含在:
@@ -0,0 +1,45 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
import { Button } from "../ui/button";
|
||||
|
||||
type MobileLocationState = {
|
||||
from?: string;
|
||||
};
|
||||
|
||||
type MobileDetailHeaderProps = {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
status?: ReactNode;
|
||||
fallbackTo: string;
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
function isSafeMobileSource(value: unknown, currentPath: string) {
|
||||
return typeof value === "string" && value.startsWith("/mobile") && value !== currentPath;
|
||||
}
|
||||
|
||||
export function MobileDetailHeader({ title, subtitle, status, fallbackTo, testId }: MobileDetailHeaderProps) {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const state = location.state as MobileLocationState | null;
|
||||
const currentPath = `${location.pathname}${location.search}`;
|
||||
const from = isSafeMobileSource(state?.from, currentPath) ? state?.from : null;
|
||||
|
||||
const handleBack = () => {
|
||||
navigate(from ?? fallbackTo, { replace: true });
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="mobile-detail-header flex min-h-12 items-center gap-3" data-testid={testId}>
|
||||
<Button className="shrink-0 px-3" size="sm" type="button" variant="secondary" onClick={handleBack}>
|
||||
返回
|
||||
</Button>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="truncate text-base font-semibold text-zinc-900">{title}</div>
|
||||
{subtitle ? <div className="mt-0.5 truncate text-xs text-zinc-500">{subtitle}</div> : null}
|
||||
</div>
|
||||
{status ? <div className="shrink-0">{status}</div> : null}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户