PunimTag Web Application - Major Feature Release #1

Open
tanyar09 wants to merge 106 commits from dev into master
Showing only changes of commit 7d415c56fe - Show all commits

View File

@ -1403,6 +1403,7 @@ function PhotoTagDialog({
getPhotoTags: (photoId: number) => Promise<any>
}) {
const [selectedTagName, setSelectedTagName] = useState('')
const [newTagName, setNewTagName] = useState('')
const [photoTags, setPhotoTags] = useState<any[]>([])
const [selectedTagIds, setSelectedTagIds] = useState<Set<number>>(new Set())
const [showConfirmDialog, setShowConfirmDialog] = useState(false)
@ -1421,10 +1422,36 @@ function PhotoTagDialog({
}
const handleAddTag = async () => {
if (!selectedTagName.trim()) return
await onAddTag(selectedTagName.trim())
setSelectedTagName('')
await loadPhotoTags()
// Collect both tags: selected existing tag and new tag name
const tagsToAdd: string[] = []
if (selectedTagName.trim()) {
tagsToAdd.push(selectedTagName.trim())
}
if (newTagName.trim()) {
tagsToAdd.push(newTagName.trim())
}
if (tagsToAdd.length === 0) {
alert('Please select a tag or enter a new tag name.')
return
}
try {
// Add all tags (onAddTag handles creating new tags if needed)
for (const tagName of tagsToAdd) {
await onAddTag(tagName)
}
// Clear inputs after successful tagging
setSelectedTagName('')
setNewTagName('')
await loadPhotoTags()
} catch (error) {
console.error('Failed to add tag:', error)
alert('Failed to add tag')
}
}
const handleRemoveTags = () => {
@ -1482,11 +1509,14 @@ function PhotoTagDialog({
{photo && <p className="text-sm text-gray-600">{photo.filename}</p>}
</div>
<div className="p-4 flex-1 overflow-auto">
<div className="mb-4 flex gap-2">
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Select Existing Tag:
</label>
<select
value={selectedTagName}
onChange={(e) => setSelectedTagName(e.target.value)}
className="flex-1 px-3 py-2 border border-gray-300 rounded"
className="w-full px-3 py-2 border border-gray-300 rounded"
>
<option value="">Select tag...</option>
{tags.map(tag => (
@ -1495,15 +1525,35 @@ function PhotoTagDialog({
</option>
))}
</select>
<button
onClick={handleAddTag}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
Add
</button>
<p className="text-xs text-gray-500 mt-1">
You can select an existing tag and enter a new tag name to add both at once.
</p>
</div>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Enter New Tag Name:
</label>
<input
type="text"
value={newTagName}
onChange={(e) => setNewTagName(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded"
placeholder="Type new tag name..."
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleAddTag()
}
}}
/>
<p className="text-xs text-gray-500 mt-1">
New tags will be created in the database automatically.
</p>
</div>
<div className="space-y-2">
<h3 className="font-semibold text-sm text-gray-700 mb-2">
Tags:
</h3>
{allTags.length === 0 ? (
<p className="text-gray-500 text-sm">No tags linked to this photo</p>
) : (
@ -1544,12 +1594,21 @@ function PhotoTagDialog({
>
Remove selected tags
</button>
<button
onClick={onClose}
className="px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200"
>
Close
</button>
<div className="flex gap-2">
<button
onClick={onClose}
className="px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200"
>
Close
</button>
<button
onClick={handleAddTag}
disabled={!selectedTagName.trim() && !newTagName.trim()}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed"
>
Add Tag
</button>
</div>
</div>
</div>
</div>