| 1 | /** |
| 2 | * PluginNoPermission - 插件未授权状态组件 |
| 3 | * 显示授权引导和检查权限按钮 |
| 4 | */ |
| 5 | |
| 6 | 'use client' |
| 7 | |
| 8 | import { AlertTriangle, BookOpen, Loader2 } from 'lucide-react' |
| 9 | import Link from 'next/link' |
| 10 | import { useState } from 'react' |
| 11 | import { useTranslation } from 'react-i18next' |
| 12 | import { useChannelManagerStore } from '@/components/ChannelManager' |
| 13 | import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' |
| 14 | import { Button } from '@/components/ui/button' |
| 15 | import { usePluginStore } from '@/store/plugin' |
| 16 | |
| 17 | /** |
| 18 | * 插件未授权状态组件 |
| 19 | */ |
| 20 | export function PluginNoPermission() { |
| 21 | const { t } = useTranslation('plugin') |
| 22 | const init = usePluginStore(state => state.init) |
| 23 | const hostAccessGranted = usePluginStore(state => state.hostAccessGranted) |
| 24 | const closePluginModal = usePluginStore(state => state.closePluginModal) |
| 25 | const closeChannelManager = useChannelManagerStore(state => state.closeModal) |
| 26 | const [checking, setChecking] = useState(false) |
| 27 | |
| 28 | // 检查权限 |
| 29 | const handleCheckPermission = async () => { |
| 30 | setChecking(true) |
| 31 | try { |
| 32 | await init() |
| 33 | } |
| 34 | finally { |
| 35 | setChecking(false) |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | const handleViewGuide = () => { |
| 40 | closePluginModal() |
| 41 | closeChannelManager() |
| 42 | } |
| 43 | |
| 44 | return ( |
| 45 | <div className="flex flex-col items-center py-8 px-4"> |
| 46 | {/* 图标 */} |
| 47 | <div className="mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-warning/10"> |
| 48 | <AlertTriangle className="h-10 w-10 text-warning" /> |
| 49 | </div> |
| 50 | |
| 51 | {/* 标题 */} |
| 52 | <h3 className="mb-2 text-lg font-semibold text-foreground"> |
| 53 | {t('header.permissionRequired')} |
| 54 | </h3> |
| 55 | |
| 56 | {/* 描述 */} |
| 57 | <p className="mb-8 max-w-sm text-center text-sm text-muted-foreground"> |
| 58 | {t('header.permissionDescription')} |
| 59 | </p> |
| 60 | |
| 61 | {hostAccessGranted === false && ( |
| 62 | <Alert className="mb-6 max-w-sm border-warning/30 bg-warning/10 text-foreground [&>svg]:text-warning"> |
| 63 | <AlertTriangle className="h-4 w-4" /> |
| 64 | <div> |
| 65 | <AlertTitle>{t('header.siteAccessRequiredTitle')}</AlertTitle> |
| 66 | <AlertDescription> |
| 67 | <p>{t('header.siteAccessRequiredDescription')}</p> |
| 68 | <ol className="mt-3 list-decimal space-y-2 pl-5"> |
| 69 | <li>{t('header.siteAccessStepReauthorize')}</li> |
| 70 | <li>{t('header.siteAccessStepExtensionSettings')}</li> |
| 71 | </ol> |
| 72 | </AlertDescription> |
| 73 | </div> |
| 74 | </Alert> |
| 75 | )} |
| 76 | |
| 77 | {/* 检查权限按钮 */} |
| 78 | <Button onClick={handleCheckPermission} disabled={checking} className="cursor-pointer gap-2"> |
| 79 | {checking && <Loader2 className="h-4 w-4 animate-spin" />} |
| 80 | {t('header.checkPermission')} |
| 81 | </Button> |
| 82 | |
| 83 | {/* 查看安装教程链接 */} |
| 84 | <Link |
| 85 | href="/websit/plugin-guide#authorize" |
| 86 | onClick={handleViewGuide} |
| 87 | className="mt-6 flex w-full max-w-xs cursor-pointer items-center justify-center gap-2 rounded-lg border border-warning/30 bg-warning/10 px-4 py-3 text-warning transition-colors hover:bg-warning/15" |
| 88 | > |
| 89 | <BookOpen className="h-5 w-5" /> |
| 90 | <span className="font-medium">{t('header.viewGuide')}</span> |
| 91 | </Link> |
| 92 | </div> |
| 93 | ) |
| 94 | } |
| 95 |