EditNotebookDialog.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import React, { useEffect, useState } from 'react'
  2. import { X, Save } from 'lucide-react'
  3. import { KnowledgeGroup, UpdateGroupData } from '../types'
  4. interface EditNotebookDialogProps {
  5. isOpen: boolean
  6. onClose: () => void
  7. notebook: KnowledgeGroup
  8. onUpdate: (id: string, data: UpdateGroupData) => Promise<void>
  9. }
  10. export const EditNotebookDialog: React.FC<EditNotebookDialogProps> = ({
  11. isOpen,
  12. onClose,
  13. notebook,
  14. onUpdate,
  15. }) => {
  16. const [name, setName] = useState(notebook.name)
  17. const [description, setDescription] = useState(notebook.description || '')
  18. const [intro, setIntro] = useState(notebook.intro || '')
  19. const [isSubmitting, setIsSubmitting] = useState(false)
  20. // Reset form when notebook changes or dialog opens
  21. useEffect(() => {
  22. if (isOpen) {
  23. setName(notebook.name)
  24. setDescription(notebook.description || '')
  25. setIntro(notebook.intro || '')
  26. }
  27. }, [isOpen, notebook])
  28. if (!isOpen) return null
  29. const handleSubmit = async (e: React.FormEvent) => {
  30. e.preventDefault()
  31. if (!name.trim()) return
  32. try {
  33. setIsSubmitting(true)
  34. await onUpdate(notebook.id, {
  35. name: name.trim(),
  36. description: description.trim(),
  37. intro: intro.trim(),
  38. })
  39. onClose()
  40. } catch (error) {
  41. console.error('Failed to update notebook:', error)
  42. alert('更新失败,请重试')
  43. } finally {
  44. setIsSubmitting(false)
  45. }
  46. }
  47. return (
  48. <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
  49. <div className="bg-white rounded-xl shadow-xl w-full max-w-lg overflow-hidden animate-in fade-in zoom-in duration-200">
  50. <div className="flex justify-between items-center px-6 py-4 border-b">
  51. <h2 className="text-lg font-semibold text-slate-800">编辑知识组</h2>
  52. <button
  53. onClick={onClose}
  54. className="text-slate-400 hover:text-slate-600 transition-colors"
  55. >
  56. <X size={20} />
  57. </button>
  58. </div>
  59. <form onSubmit={handleSubmit} className="p-6 space-y-4">
  60. <div>
  61. <label className="block text-sm font-medium text-slate-700 mb-1">
  62. 名称
  63. </label>
  64. <input
  65. type="text"
  66. value={name}
  67. onChange={(e) => setName(e.target.value)}
  68. className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
  69. placeholder="知识组名称"
  70. required
  71. />
  72. </div>
  73. <div>
  74. <label className="block text-sm font-medium text-slate-700 mb-1">
  75. 简短描述
  76. </label>
  77. <input
  78. type="text"
  79. value={description}
  80. onChange={(e) => setDescription(e.target.value)}
  81. className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
  82. placeholder="一句话描述(可选)"
  83. />
  84. </div>
  85. <div>
  86. <label className="block text-sm font-medium text-slate-700 mb-1">
  87. 详细简介 (Intro)
  88. </label>
  89. <textarea
  90. value={intro}
  91. onChange={(e) => setIntro(e.target.value)}
  92. className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 h-32 resize-none"
  93. placeholder="用于生成播客或详细介绍背景知识(可选)"
  94. />
  95. </div>
  96. <div className="flex justify-end pt-2">
  97. <button
  98. type="button"
  99. onClick={onClose}
  100. className="px-4 py-2 text-slate-600 hover:bg-slate-100 rounded-lg mr-2 transition-colors"
  101. >
  102. 取消
  103. </button>
  104. <button
  105. type="submit"
  106. disabled={isSubmitting || !name.trim()}
  107. className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
  108. >
  109. <Save size={18} />
  110. {isSubmitting ? '保存中...' : '保存修改'}
  111. </button>
  112. </div>
  113. </form>
  114. </div>
  115. </div>
  116. )
  117. }