| import { useState, useEffect, useCallback } from 'react'; |
| import { Tag } from '@/components/home/SortableTag'; |
| import { DragEndEvent } from '@dnd-kit/core'; |
| import { arrayMove } from '@dnd-kit/sortable'; |
| import { ADULT_STORAGE_KEY } from '@/lib/constants/adult-tags'; |
|
|
| export function useAdultTagManager() { |
| const [tags, setTags] = useState<Tag[]>([]); |
| const [selectedTag, setSelectedTag] = useState('recommend'); |
| const [showTagManager, setShowTagManager] = useState(false); |
| const [newTagInput, setNewTagInput] = useState(''); |
| const [justAddedTag, setJustAddedTag] = useState(false); |
| const [loading, setLoading] = useState(true); |
|
|
| |
| useEffect(() => { |
| const fetchTags = async () => { |
| try { |
| setLoading(true); |
| |
| |
| const { settingsStore } = await import('@/lib/store/settings-store'); |
| const settings = settingsStore.getSettings(); |
| const enabledSources = settings.adultSources.filter(s => s.enabled); |
|
|
| const response = await fetch('/api/adult/types', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| sources: enabledSources |
| }) |
| }); |
|
|
| const data = await response.json(); |
|
|
| if (data.tags && Array.isArray(data.tags)) { |
| |
| const savedTagsJson = localStorage.getItem(ADULT_STORAGE_KEY); |
| if (savedTagsJson) { |
| try { |
| const savedTags = JSON.parse(savedTagsJson); |
| |
| |
| |
| const apiTagMap = new Map<string, Tag>(); |
| if (Array.isArray(data.tags)) { |
| data.tags.forEach((t: Tag) => apiTagMap.set(t.id, t)); |
| } |
|
|
| const mergedTags: Tag[] = []; |
| const processedIds = new Set<string>(); |
|
|
| |
| if (Array.isArray(savedTags)) { |
| savedTags.forEach((savedTag: Tag) => { |
| if (apiTagMap.has(savedTag.id)) { |
| mergedTags.push(apiTagMap.get(savedTag.id)!); |
| processedIds.add(savedTag.id); |
| } |
| }); |
| } |
|
|
| |
| data.tags.forEach((tag: Tag) => { |
| if (!processedIds.has(tag.id)) { |
| mergedTags.push(tag); |
| } |
| }); |
|
|
| setTags(mergedTags); |
| } catch (e) { |
| console.error('Failed to parse saved tags', e); |
| setTags(data.tags); |
| } |
| } else { |
| setTags(data.tags); |
| } |
| } |
| } catch (error) { |
| console.error('Failed to fetch adult tags:', error); |
| } finally { |
| setLoading(false); |
| } |
| }; |
|
|
| fetchTags(); |
| }, []); |
|
|
| |
| useEffect(() => { |
| if (tags.length > 0 && !loading) { |
| localStorage.setItem(ADULT_STORAGE_KEY, JSON.stringify(tags)); |
| } |
| }, [tags, loading]); |
|
|
| const handleAddTag = () => { |
| |
| |
| }; |
|
|
| const handleDeleteTag = (tagId: string) => { |
| |
| |
| |
| const newTags = tags.filter((t) => t.id !== tagId); |
| setTags(newTags); |
|
|
| if (selectedTag === tagId) { |
| setSelectedTag(newTags[0]?.id || ''); |
| } |
| }; |
|
|
| const handleRestoreDefaults = async () => { |
| setLoading(true); |
| localStorage.removeItem(ADULT_STORAGE_KEY); |
| try { |
| const response = await fetch('/api/adult/types'); |
| const data = await response.json(); |
| if (data.tags) { |
| setTags(data.tags); |
| setSelectedTag('recommend'); |
| } |
| } catch (error) { |
| console.error('Failed to restore tags:', error); |
| } finally { |
| setLoading(false); |
| } |
| }; |
|
|
| const handleDragEnd = (event: DragEndEvent) => { |
| const { active, over } = event; |
|
|
| if (over && active.id !== over.id) { |
| setTags((items) => { |
| const oldIndex = items.findIndex((item) => item.id === active.id); |
| const newIndex = items.findIndex((item) => item.id === over.id); |
| return arrayMove(items, oldIndex, newIndex); |
| }); |
| } |
| }; |
|
|
| return { |
| tags, |
| selectedTag, |
| newTagInput, |
| showTagManager, |
| justAddedTag, |
| loading, |
| setSelectedTag, |
| setNewTagInput, |
| setShowTagManager, |
| setJustAddedTag, |
| handleAddTag, |
| handleDeleteTag, |
| handleRestoreDefaults, |
| handleDragEnd, |
| }; |
| } |
|
|