fix: 修复前端代码质量问题
- 创建 Toast 通知组件,替换所有 alert() 调用 - 修复 useReview hook 内存泄漏(setInterval 清理) - 移除所有 console.error 和 console.log 语句 - 为复制操作失败添加用户友好的 toast 提示 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
a5a005db0c
commit
37ac749071
@@ -5,6 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Modal } from '@/components/ui/Modal'
|
||||
import { SuccessTag, PendingTag, WarningTag } from '@/components/ui/Tag'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import {
|
||||
Search,
|
||||
Plus,
|
||||
@@ -110,6 +111,7 @@ function StatusTag({ status }: { status: string }) {
|
||||
}
|
||||
|
||||
export default function AgenciesManagePage() {
|
||||
const toast = useToast()
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [agencies, setAgencies] = useState<Agency[]>(initialAgencies)
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null)
|
||||
@@ -231,7 +233,7 @@ export default function AgenciesManagePage() {
|
||||
.filter(p => selectedProjects.includes(p.id))
|
||||
.map(p => p.name)
|
||||
.join('、')
|
||||
alert(`已将代理商「${assignModal.agency.name}」分配到项目「${projectNames}」`)
|
||||
toast.success(`已将代理商「${assignModal.agency.name}」分配到项目「${projectNames}」`)
|
||||
}
|
||||
setAssignModal({ open: false, agency: null })
|
||||
setSelectedProjects([])
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Button } from '@/components/ui/Button'
|
||||
import { Input } from '@/components/ui/Input'
|
||||
import { Select } from '@/components/ui/Select'
|
||||
import { SuccessTag, ErrorTag, PendingTag } from '@/components/ui/Tag'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import {
|
||||
Bot,
|
||||
Eye,
|
||||
@@ -68,6 +69,7 @@ type TestResult = {
|
||||
}
|
||||
|
||||
export default function AIConfigPage() {
|
||||
const toast = useToast()
|
||||
const [provider, setProvider] = useState('oneapi')
|
||||
const [baseUrl, setBaseUrl] = useState('https://oneapi.intelligrow.cn')
|
||||
const [apiKey, setApiKey] = useState('')
|
||||
@@ -133,7 +135,7 @@ export default function AIConfigPage() {
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
alert('配置已保存')
|
||||
toast.success('配置已保存')
|
||||
}
|
||||
|
||||
const getTestStatusIcon = (status: string) => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation'
|
||||
import { ArrowLeft, Check, X, CheckSquare, Video, Clock } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { getPlatformInfo } from '@/lib/platforms'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
|
||||
// 模拟待审核内容列表
|
||||
const mockReviewItems = [
|
||||
@@ -99,6 +100,7 @@ function ReviewProgressBar({ currentStep }: { currentStep: number }) {
|
||||
|
||||
export default function FinalReviewPage() {
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const [selectedItem, setSelectedItem] = useState(mockReviewItems[0])
|
||||
const [feedback, setFeedback] = useState('')
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
@@ -108,19 +110,19 @@ export default function FinalReviewPage() {
|
||||
setIsSubmitting(true)
|
||||
// 模拟提交
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
alert('已通过审核')
|
||||
toast.success('已通过审核')
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
|
||||
const handleReject = async () => {
|
||||
if (!feedback.trim()) {
|
||||
alert('请填写驳回原因')
|
||||
toast.error('请填写驳回原因')
|
||||
return
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
// 模拟提交
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
alert('已驳回')
|
||||
toast.success('已驳回')
|
||||
setIsSubmitting(false)
|
||||
setFeedback('')
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useRouter, useParams } from 'next/navigation'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Input } from '@/components/ui/Input'
|
||||
@@ -82,6 +83,7 @@ const strictnessOptions = [
|
||||
export default function ProjectConfigPage() {
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const toast = useToast()
|
||||
const projectId = params.id as string
|
||||
|
||||
const [brief, setBrief] = useState(mockData.brief)
|
||||
@@ -100,7 +102,7 @@ export default function ProjectConfigPage() {
|
||||
setIsSaving(true)
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
setIsSaving(false)
|
||||
alert('配置已保存')
|
||||
toast.success('配置已保存')
|
||||
}
|
||||
|
||||
const addRequirement = () => {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Input } from '@/components/ui/Input'
|
||||
@@ -40,6 +41,7 @@ const mockAgencies = [
|
||||
|
||||
export default function CreateProjectPage() {
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const [projectName, setProjectName] = useState('')
|
||||
const [deadline, setDeadline] = useState('')
|
||||
const [briefFile, setBriefFile] = useState<File | null>(null)
|
||||
@@ -73,14 +75,14 @@ export default function CreateProjectPage() {
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!projectName.trim() || !deadline || !briefFile || selectedAgencies.length === 0 || !selectedPlatform) {
|
||||
alert('请填写完整信息')
|
||||
toast.error('请填写完整信息')
|
||||
return
|
||||
}
|
||||
|
||||
setIsSubmitting(true)
|
||||
// 模拟提交
|
||||
await new Promise(resolve => setTimeout(resolve, 1500))
|
||||
alert('项目创建成功!')
|
||||
toast.success('项目创建成功!')
|
||||
router.push('/brand')
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import Link from 'next/link'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { SuccessTag, PendingTag, WarningTag, ErrorTag } from '@/components/ui/Tag'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import {
|
||||
FileText,
|
||||
Video,
|
||||
@@ -129,6 +130,7 @@ function TaskCard({
|
||||
type: 'script' | 'video'
|
||||
onPreview: (task: ScriptTask | VideoTask, type: 'script' | 'video') => void
|
||||
}) {
|
||||
const toast = useToast()
|
||||
const href = type === 'script' ? `/brand/review/script/${task.id}` : `/brand/review/video/${task.id}`
|
||||
const platform = getPlatformInfo(task.platform)
|
||||
|
||||
@@ -141,7 +143,7 @@ function TaskCard({
|
||||
const handleDownload = (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
alert(`下载文件: ${task.fileName}`)
|
||||
toast.info(`下载文件: ${task.fileName}`)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -243,6 +245,7 @@ function TaskCard({
|
||||
}
|
||||
|
||||
export default function BrandReviewListPage() {
|
||||
const toast = useToast()
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [activeTab, setActiveTab] = useState<'all' | 'script' | 'video'>('all')
|
||||
const [previewTask, setPreviewTask] = useState<{ task: ScriptTask | VideoTask; type: 'script' | 'video' } | null>(null)
|
||||
@@ -445,7 +448,7 @@ export default function BrandReviewListPage() {
|
||||
<Button variant="secondary" onClick={() => setPreviewTask(null)}>
|
||||
关闭
|
||||
</Button>
|
||||
<Button onClick={() => alert(`下载文件: ${previewTask?.task.fileName}`)}>
|
||||
<Button onClick={() => toast.info(`下载文件: ${previewTask?.task.fileName}`)}>
|
||||
<Download size={16} />
|
||||
下载
|
||||
</Button>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/Button'
|
||||
import { Modal, ConfirmModal } from '@/components/ui/Modal'
|
||||
import { SuccessTag, WarningTag, ErrorTag, PendingTag } from '@/components/ui/Tag'
|
||||
import { ReviewSteps, getBrandReviewSteps } from '@/components/ui/ReviewSteps'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import {
|
||||
ArrowLeft,
|
||||
FileText,
|
||||
@@ -99,6 +100,7 @@ function ReviewProgressBar({ taskStatus }: { taskStatus: string }) {
|
||||
export default function BrandScriptReviewPage() {
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const toast = useToast()
|
||||
const [showApproveModal, setShowApproveModal] = useState(false)
|
||||
const [showRejectModal, setShowRejectModal] = useState(false)
|
||||
const [rejectReason, setRejectReason] = useState('')
|
||||
@@ -109,17 +111,17 @@ export default function BrandScriptReviewPage() {
|
||||
|
||||
const handleApprove = () => {
|
||||
setShowApproveModal(false)
|
||||
alert('审核通过!')
|
||||
toast.success('审核通过')
|
||||
router.push('/brand/review')
|
||||
}
|
||||
|
||||
const handleReject = () => {
|
||||
if (!rejectReason.trim()) {
|
||||
alert('请填写驳回原因')
|
||||
toast.error('请填写驳回原因')
|
||||
return
|
||||
}
|
||||
setShowRejectModal(false)
|
||||
alert('已驳回')
|
||||
toast.success('已驳回')
|
||||
router.push('/brand/review')
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useRouter, useParams } from 'next/navigation'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Modal, ConfirmModal } from '@/components/ui/Modal'
|
||||
@@ -123,6 +124,7 @@ function RiskLevelTag({ level }: { level: string }) {
|
||||
export default function BrandVideoReviewPage() {
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const toast = useToast()
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
const [showApproveModal, setShowApproveModal] = useState(false)
|
||||
const [showRejectModal, setShowRejectModal] = useState(false)
|
||||
@@ -135,17 +137,17 @@ export default function BrandVideoReviewPage() {
|
||||
|
||||
const handleApprove = () => {
|
||||
setShowApproveModal(false)
|
||||
alert('审核通过!')
|
||||
toast.success('审核通过!')
|
||||
router.push('/brand/review')
|
||||
}
|
||||
|
||||
const handleReject = () => {
|
||||
if (!rejectReason.trim()) {
|
||||
alert('请填写驳回原因')
|
||||
toast.error('请填写驳回原因')
|
||||
return
|
||||
}
|
||||
setShowRejectModal(false)
|
||||
alert('已驳回')
|
||||
toast.success('已驳回')
|
||||
router.push('/brand/review')
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Modal } from '@/components/ui/Modal'
|
||||
import { useToast } from '@/components/ui/Toast'
|
||||
import {
|
||||
Bell,
|
||||
Shield,
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
|
||||
export default function BrandSettingsPage() {
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const [notifications, setNotifications] = useState({
|
||||
email: true,
|
||||
push: true,
|
||||
@@ -95,7 +97,7 @@ export default function BrandSettingsPage() {
|
||||
]
|
||||
|
||||
const handleSave = () => {
|
||||
alert('设置已保存')
|
||||
toast.success('设置已保存')
|
||||
}
|
||||
|
||||
const handleLogout = () => {
|
||||
@@ -105,10 +107,10 @@ export default function BrandSettingsPage() {
|
||||
|
||||
const handleChangePassword = () => {
|
||||
if (passwordForm.new !== passwordForm.confirm) {
|
||||
alert('两次输入的密码不一致')
|
||||
toast.error('两次输入的密码不一致')
|
||||
return
|
||||
}
|
||||
alert('密码修改成功')
|
||||
toast.success('密码修改成功')
|
||||
setShowPasswordModal(false)
|
||||
setPasswordForm({ current: '', new: '', confirm: '' })
|
||||
}
|
||||
@@ -116,18 +118,18 @@ export default function BrandSettingsPage() {
|
||||
const handleEnable2FA = () => {
|
||||
setTwoFAEnabled(true)
|
||||
setShow2FAModal(false)
|
||||
alert('双因素认证已启用')
|
||||
toast.success('双因素认证已启用')
|
||||
}
|
||||
|
||||
const handleChangeEmail = () => {
|
||||
alert(`邮箱已更新为 ${newEmail}`)
|
||||
toast.success(`邮箱已更新为 ${newEmail}`)
|
||||
setShowEmailModal(false)
|
||||
setNewEmail('')
|
||||
setEmailCode('')
|
||||
}
|
||||
|
||||
const handleChangePhone = () => {
|
||||
alert(`手机号已更新为 ${newPhone}`)
|
||||
toast.success(`手机号已更新为 ${newPhone}`)
|
||||
setShowPhoneModal(false)
|
||||
setNewPhone('')
|
||||
setPhoneCode('')
|
||||
@@ -139,11 +141,11 @@ export default function BrandSettingsPage() {
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
setIsExporting(false)
|
||||
setShowExportModal(false)
|
||||
alert('导出任务已创建,完成后将通知您下载')
|
||||
toast.info('导出任务已创建,完成后将通知您下载')
|
||||
}
|
||||
|
||||
const handleRemoveDevice = (deviceId: string) => {
|
||||
alert('已移除该设备的登录状态')
|
||||
toast.success('已移除该设备的登录状态')
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user