149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import { useState, useEffect } from 'react'
|
||
import { useNavigate } from 'react-router-dom'
|
||
import { X, ArrowRight, Home, Users, Calculator, CalendarCheck, ShieldAlert, Bot } from 'lucide-react'
|
||
|
||
const STORAGE_KEY = 'hr-onboarding-dismissed'
|
||
|
||
const modules = [
|
||
{
|
||
icon: Home,
|
||
color: 'text-blue-600',
|
||
bg: 'bg-blue-50',
|
||
title: '工作台',
|
||
desc: '风险总览、待办事项、日历事件',
|
||
path: '/',
|
||
},
|
||
{
|
||
icon: Users,
|
||
color: 'text-indigo-600',
|
||
bg: 'bg-indigo-50',
|
||
title: '团队管理',
|
||
desc: '花名册、用工办理、离职管理、特殊状态',
|
||
path: '/roster',
|
||
},
|
||
{
|
||
icon: Calculator,
|
||
color: 'text-amber-600',
|
||
bg: 'bg-amber-50',
|
||
title: '薪酬管理',
|
||
desc: '发薪批次、工资条、社保公积金、薪酬分析',
|
||
path: '/money',
|
||
},
|
||
{
|
||
icon: CalendarCheck,
|
||
color: 'text-green-600',
|
||
bg: 'bg-green-50',
|
||
title: '考勤时间',
|
||
desc: '考勤打卡、排班管理、休假审批',
|
||
path: '/attendance',
|
||
},
|
||
{
|
||
icon: ShieldAlert,
|
||
color: 'text-red-600',
|
||
bg: 'bg-red-50',
|
||
title: '合规风控',
|
||
desc: '风险中心、证据链、规章制度、用工体检',
|
||
path: '/risk-center',
|
||
},
|
||
{
|
||
icon: Bot,
|
||
color: 'text-purple-600',
|
||
bg: 'bg-purple-50',
|
||
title: 'AI 助手',
|
||
desc: '智能咨询、合同审查、判赔预测、人力分析',
|
||
path: '/ai-assistant',
|
||
},
|
||
]
|
||
|
||
export function isOnboardingDismissed() {
|
||
return localStorage.getItem(STORAGE_KEY) === '1'
|
||
}
|
||
|
||
export function dismissOnboarding() {
|
||
localStorage.setItem(STORAGE_KEY, '1')
|
||
}
|
||
|
||
export function resetOnboarding() {
|
||
localStorage.removeItem(STORAGE_KEY)
|
||
}
|
||
|
||
export default function OnboardingGuide() {
|
||
const [visible, setVisible] = useState(false)
|
||
const [dontShow, setDontShow] = useState(false)
|
||
const navigate = useNavigate()
|
||
|
||
useEffect(() => {
|
||
if (!isOnboardingDismissed()) {
|
||
setVisible(true)
|
||
}
|
||
}, [])
|
||
|
||
const close = () => {
|
||
if (dontShow) dismissOnboarding()
|
||
setVisible(false)
|
||
}
|
||
|
||
const goTo = (path: string) => {
|
||
if (dontShow) dismissOnboarding()
|
||
setVisible(false)
|
||
navigate(path)
|
||
}
|
||
|
||
if (!visible) return null
|
||
|
||
return (
|
||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
|
||
<div className="bg-white rounded-xl shadow-xl max-w-lg w-full mx-4 overflow-hidden">
|
||
<div className="flex items-center justify-between px-5 py-3 border-b border-gray-100">
|
||
<h2 className="text-base font-semibold">欢迎使用企业用工专家</h2>
|
||
<button onClick={close} className="text-gray-400 hover:text-gray-600">
|
||
<X className="w-5 h-5" />
|
||
</button>
|
||
</div>
|
||
<div className="px-5 py-4">
|
||
<p className="text-sm text-gray-500 mb-4">系统包含以下 6 大模块,点击任意模块可直接前往体验:</p>
|
||
<div className="grid grid-cols-2 gap-3">
|
||
{modules.map((m) => {
|
||
const Icon = m.icon
|
||
return (
|
||
<button
|
||
key={m.title}
|
||
onClick={() => goTo(m.path)}
|
||
className="flex items-start gap-3 p-3 rounded-lg border border-gray-100 hover:border-primary/30 hover:bg-primary/[0.02] transition-all text-left"
|
||
>
|
||
<div className={`flex items-center justify-center w-9 h-9 rounded-lg ${m.bg} ${m.color} shrink-0`}>
|
||
<Icon className="w-4.5 h-4.5" />
|
||
</div>
|
||
<div className="flex-1 min-w-0">
|
||
<div className="text-sm font-medium text-gray-800">{m.title}</div>
|
||
<div className="text-xs text-gray-500 mt-0.5 leading-relaxed">{m.desc}</div>
|
||
</div>
|
||
</button>
|
||
)
|
||
})}
|
||
</div>
|
||
|
||
<div className="mt-4 flex items-center justify-between">
|
||
<label className="flex items-center gap-2 text-sm text-gray-500 cursor-pointer">
|
||
<input
|
||
type="checkbox"
|
||
checked={dontShow}
|
||
onChange={(e) => setDontShow(e.target.checked)}
|
||
className="w-4 h-4 rounded border-gray-300 text-primary focus:ring-primary/10"
|
||
/>
|
||
不再自动显示
|
||
</label>
|
||
<button
|
||
onClick={close}
|
||
className="flex items-center gap-1 px-4 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary/90 transition-colors"
|
||
>
|
||
开始使用
|
||
<ArrowRight className="w-4 h-4" />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|