feat: release contextual omnichannel customer platform

Add Telegram, WhatsApp and email account management, realtime messaging, contextual multilingual AI, customer intelligence, knowledge workflows, enterprise controls, a unified design system and complete repository documentation.
This commit is contained in:
wmq
2026-07-30 02:29:53 +08:00
parent 9804341463
commit af49d22ca7
66 changed files with 3181 additions and 554 deletions
+11 -13
View File
@@ -1,5 +1,5 @@
import { NavLink, useNavigate } from 'react-router-dom'
import { PanelLeftClose, PanelLeftOpen, Sparkles } from 'lucide-react'
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'
import { NAV_ITEMS } from '@/config/navigation'
import { useUiStore } from '@/app/store/ui'
import { useAuthStore } from '@/app/store/auth'
@@ -35,18 +35,16 @@ export function Sidebar() {
return (
<aside
className={cn(
'relative z-30 flex h-full flex-col border-e border-slate-300/80 bg-[#f8fafc] shadow-[4px_0_16px_-14px_rgba(15,23,42,.32)] transition-[width] duration-200',
sidebarCollapsed ? 'w-[68px]' : 'w-[228px]',
'relative z-30 flex h-full flex-col border-e border-slate-200 bg-white shadow-[6px_0_24px_-22px_rgba(15,23,42,.45)] transition-[width] duration-200',
sidebarCollapsed ? 'w-[68px]' : 'w-[236px]',
)}
>
{/* Logo */}
<div
className="flex h-16 cursor-pointer items-center gap-2.5 px-4"
className="flex h-16 cursor-pointer items-center gap-2.5 border-b border-slate-100 px-4"
onClick={() => navigate('/dashboard')}
>
<span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-primary-600 to-primary-800 text-primary-foreground shadow-sm shadow-primary-900/10">
<Sparkles className="h-4.5 w-4.5 h-[18px] w-[18px]" />
</span>
<img src="/brand-mark.svg" alt="" className="h-9 w-9 shrink-0 rounded-xl shadow-sm shadow-primary-900/10" />
{!sidebarCollapsed && (
<div className="min-w-0">
<p className="truncate text-[15px] font-semibold tracking-tight leading-tight">{t('app.name')}</p>
@@ -56,7 +54,7 @@ export function Sidebar() {
</div>
{/* 导航 */}
<nav className="flex-1 overflow-y-auto px-2.5 py-2 scrollbar-thin">
<nav className="flex-1 overflow-y-auto px-2.5 py-3 scrollbar-thin">
{groups.map((group) => {
const groupItems = items.filter((item) => item.group === group.key)
if (!groupItems.length) return null
@@ -76,10 +74,10 @@ export function Sidebar() {
title={sidebarCollapsed ? t(item.labelKey as never) : undefined}
className={({ isActive }) =>
cn(
'flex items-center gap-3 rounded-xl px-3 py-2.5 text-[13px] transition-all duration-150',
'group relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-[13px] transition-all duration-150',
isActive
? 'bg-primary-50/90 font-semibold text-primary-800 shadow-[inset_0_0_0_1px_rgba(37,99,235,.08)]'
: 'text-slate-600 hover:bg-slate-50 hover:text-slate-900',
? 'bg-primary-50 font-semibold text-primary-800 shadow-[inset_0_0_0_1px_rgba(37,99,235,.1)] before:absolute before:inset-y-2 before:left-0 before:w-[3px] before:rounded-r-full before:bg-primary-600'
: 'text-slate-600 hover:bg-slate-50 hover:text-slate-950',
sidebarCollapsed && 'justify-center px-0',
)
}
@@ -96,8 +94,8 @@ export function Sidebar() {
{/* 底部:套餐与企业信息 */}
{!sidebarCollapsed && (
<div className="border-t border-border p-3">
<div className="rounded-md bg-muted/60 p-3">
<div className="border-t border-slate-100 p-3">
<div className="rounded-[12px] border border-slate-200 bg-slate-50/80 p-3">
<div className="flex items-center justify-between">
<span className="text-xs text-muted-foreground">{t('sidebar.currentPlan')}</span>
<span className="text-xs font-medium text-primary-700">{plan.name}</span>