diff --git a/client/kb-frontend/src/components/ArticleEdit.css b/client/kb-frontend/src/components/ArticleEdit.css index e1a3a05..dbcf88f 100644 --- a/client/kb-frontend/src/components/ArticleEdit.css +++ b/client/kb-frontend/src/components/ArticleEdit.css @@ -262,4 +262,65 @@ .badge-remove:hover { opacity: 1; +} + +.create-new-section { + padding: 0.75rem; + border-bottom: 1px solid #ddd; + background-color: #f9f9f9; +} + +.create-new-section input { + width: 100%; + padding: 0.5rem; + border: 1px solid #ddd; + border-radius: 4px; + margin-bottom: 0.5rem; +} + +.create-new-buttons { + display: flex; + gap: 0.5rem; +} + +.create-new-buttons button { + padding: 0.4rem 0.8rem; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 0.85rem; +} + +.create-new-buttons .create-btn { + background-color: #27ae60; + color: white; +} + +.create-new-buttons .create-btn:hover { + background-color: #229954; +} + +.create-new-buttons .cancel-btn { + background-color: #95a5a6; + color: white; +} + +.create-new-buttons .cancel-btn:hover { + background-color: #7f8c8d; +} + +.create-new-button-dropdown { + width: 100%; + padding: 0.75rem; + background-color: #27ae60; + color: white; + border: none; + border-bottom: 1px solid #ddd; + text-align: left; + cursor: pointer; + font-weight: bold; +} + +.create-new-button-dropdown:hover { + background-color: #229954; } \ No newline at end of file diff --git a/client/kb-frontend/src/components/ArticleEdit.jsx b/client/kb-frontend/src/components/ArticleEdit.jsx index 72bb3e1..044886a 100644 --- a/client/kb-frontend/src/components/ArticleEdit.jsx +++ b/client/kb-frontend/src/components/ArticleEdit.jsx @@ -65,7 +65,8 @@ function ArticleEditor({ article, onSave, onCancel, token }) { const [selectedTags, setSelectedTags] = useState([]); const [tagInput, setTagInput] = useState(''); const [showCategoryDropdown, setShowCategoryDropdown] = useState(false); - //const [showTagDropdown, setShowTagDropdown] = useState(false); + const [showCreateCategory, setShowCreateCategory] = useState(false); + const [newCategoryInput, setNewCategoryInput] = useState(''); const [showTagSuggestions, setShowTagSuggestions] = useState(false); const quillRef = useRef(null); @@ -95,7 +96,7 @@ function ArticleEditor({ article, onSave, onCancel, token }) { const data = await response.json(); setAvailableCategories(data.map(cat => cat.name)); } - } catch(err) { + } catch (err) { console.error('Error fetching categories:', err); } }; @@ -112,7 +113,7 @@ function ArticleEditor({ article, onSave, onCancel, token }) { const data = await response.json(); setAvailableTags(data.map(tag => tag.name)); } - } catch(err) { + } catch (err) { console.error('Error fetching tags:', err); } }; @@ -137,7 +138,7 @@ function ArticleEditor({ article, onSave, onCancel, token }) { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, - body: JSON.stringify({ categories: selectedCategories }) + body: JSON.stringify({ categories: selectedCategories }) }); await fetch(`http://localhost:9000/api/articles/${article.ka_number}/tags`, { @@ -149,7 +150,7 @@ function ArticleEditor({ article, onSave, onCancel, token }) { body: JSON.stringify({ tags: selectedTags }) }); - } catch(err) { + } catch (err) { console.error('Error saving categories/tags:', err); } }; @@ -187,6 +188,35 @@ function ArticleEditor({ article, onSave, onCancel, token }) { setIsGalleryOpen(!isGalleryOpen); }; + const handleCreateNewCategory = async () => { + if (!newCategoryInput.trim()) return; + + try { + const response = await fetch('http://localhost:9000/api/categories', { + method: 'POST', + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ name: newCategoryInput.trim() }) + }); + + if (response.ok) { + const data = await response.json(); + setAvailableCategories([...availableCategories, data.name]); + setSelectedCategories([...selectedCategories, data.name]); + setNewCategoryInput(''); + setShowCreateCategory(false); + } else { + const data = await response.json(); + alert(data.error || 'Failed to create cateogry'); + } + } catch (err) { + console.error('Failed to create new category:', err); + alert('Failed to create new category'); + } + }; + const modules = { toolbar: [ [{ 'header': [1, 2, 3, false] }], @@ -252,9 +282,9 @@ function ArticleEditor({ article, onSave, onCancel, token }) { } }; - const filteredTagSuggestions = availableTags.filter(tag => - tag.toLowerCase().includes(tagInput.toLowerCase()) - && !selectedTags.includes(tag) + const filteredTagSuggestions = availableTags.filter(tag => + tag.toLowerCase().includes(tagInput.toLowerCase()) + && !selectedTags.includes(tag) ); return ( @@ -282,19 +312,64 @@ function ArticleEditor({ article, onSave, onCancel, token }) {