Your Name 964797d2e9 feat: 完善品牌方和代理商前端功能
品牌方功能:
- 项目看板: 添加截止日期编辑功能
- 项目详情: 添加代理商管理、截止日期编辑、最近任务显示代理商
- 项目创建: 代理商选择支持搜索(名称/ID/公司名)
- 代理商管理: 通过ID邀请、添加备注/分配项目/移除操作
- Brief配置: 新增项目级Brief和规则配置页面
- 系统设置: 完善账户安全(密码/2FA/邮箱/手机/设备管理)、数据导出、退出登录

代理商功能:
- 个人中心: 新增代理商ID展示、公司信息(企业验证)、个人信息编辑
- 账户设置: 密码修改、手机/邮箱绑定、两步验证
- 通知设置: 分类型和渠道的通知开关
- 审核历史: 搜索筛选和统计展示
- 帮助反馈: FAQ分类搜索和客服联系

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:40:11 +08:00

195 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import {
ArrowLeft,
CircleUser,
Camera,
Copy,
Check
} from 'lucide-react'
// 模拟用户数据
const mockUserData = {
avatar: '星',
name: '张经理',
agencyId: 'AG789012',
phone: '138****8888',
email: 'zhang@starmedia.com',
position: '运营总监',
department: '内容审核部',
}
export default function AgencyProfileEditPage() {
const router = useRouter()
const [formData, setFormData] = useState(mockUserData)
const [isSaving, setIsSaving] = useState(false)
const [copied, setCopied] = useState(false)
const handleCopyId = async () => {
try {
await navigator.clipboard.writeText(formData.agencyId)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error('复制失败:', err)
}
}
const handleSave = async () => {
setIsSaving(true)
await new Promise(resolve => setTimeout(resolve, 1000))
setIsSaving(false)
alert('个人信息已保存')
router.back()
}
return (
<div className="space-y-6">
{/* 顶部导航 */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<button
type="button"
onClick={() => router.back()}
className="p-2 rounded-lg hover:bg-bg-elevated transition-colors"
>
<ArrowLeft size={20} className="text-text-secondary" />
</button>
<div>
<h1 className="text-2xl font-bold text-text-primary"></h1>
<p className="text-sm text-text-secondary mt-0.5"></p>
</div>
</div>
<Button variant="primary" onClick={handleSave} disabled={isSaving}>
{isSaving ? '保存中...' : '保存'}
</Button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* 左侧:头像 */}
<Card>
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
<CardContent className="flex flex-col items-center">
<div className="relative">
<div
className="w-32 h-32 rounded-full flex items-center justify-center"
style={{
background: 'linear-gradient(135deg, #6366F1 0%, #4F46E5 100%)',
}}
>
<span className="text-5xl font-bold text-white">{formData.avatar}</span>
</div>
<button
type="button"
className="absolute bottom-0 right-0 w-10 h-10 rounded-full bg-accent-indigo flex items-center justify-center text-white shadow-lg hover:bg-accent-indigo/80 transition-colors"
>
<Camera size={18} />
</button>
</div>
<p className="text-sm text-text-tertiary mt-4"></p>
<p className="text-xs text-text-tertiary mt-1"> JPGPNG 2MB</p>
</CardContent>
</Card>
{/* 右侧:基本信息 */}
<div className="lg:col-span-2">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<CircleUser size={18} className="text-accent-indigo" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-5">
{/* 代理商ID只读 */}
<div>
<label className="text-sm text-text-secondary mb-1.5 block">ID</label>
<div className="flex items-center gap-2">
<div className="flex-1 px-4 py-2.5 rounded-xl bg-bg-elevated border border-border-subtle">
<span className="font-mono font-medium text-accent-indigo">{formData.agencyId}</span>
</div>
<button
type="button"
onClick={handleCopyId}
className="px-4 py-2.5 rounded-xl bg-bg-elevated border border-border-subtle hover:bg-bg-page transition-colors flex items-center gap-2"
>
{copied ? (
<>
<Check size={16} className="text-accent-green" />
<span className="text-accent-green text-sm"></span>
</>
) : (
<>
<Copy size={16} className="text-text-secondary" />
<span className="text-text-secondary text-sm"></span>
</>
)}
</button>
</div>
<p className="text-xs text-text-tertiary mt-1">ID不可修改使</p>
</div>
{/* 姓名 */}
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<Input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="请输入姓名"
/>
</div>
{/* 职位和部门 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<Input
value={formData.position}
onChange={(e) => setFormData({ ...formData, position: e.target.value })}
placeholder="请输入职位"
/>
</div>
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<Input
value={formData.department}
onChange={(e) => setFormData({ ...formData, department: e.target.value })}
placeholder="请输入部门"
/>
</div>
</div>
{/* 联系方式 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<Input
value={formData.phone}
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
placeholder="请输入手机号"
/>
</div>
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<Input
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder="请输入邮箱"
/>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
)
}