deckhearth/components/CollectionsCreateModal.js
Randall Stillwell f9a8ce695a Extract CollectionsCreateModal and tag helpers (Brief 1).
Moves create-list modal UI to components/CollectionsCreateModal.js and tag input helpers to lib/collection-tag-input.js (shared with edit modal).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 12:51:13 -05:00

181 lines
6.6 KiB
JavaScript
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.

import {
addCollectionTag,
handleCollectionTagKeyPress,
removeCollectionTag,
} from '../lib/collection-tag-input.js';
export default function CollectionsCreateModal({
isOpen,
newCollection,
setNewCollection,
tagInput,
setTagInput,
onClose,
onCreate,
}) {
if (!isOpen) {
return null;
}
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="card max-w-md w-full mx-4">
<h2 className="text-2xl font-bold mb-4" style={{ color: 'var(--text-primary)' }}>
Create New List
</h2>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
List Name
</label>
<input
type="text"
className="input-field w-full"
value={newCollection.name}
onChange={(e) => setNewCollection({ ...newCollection, name: e.target.value })}
placeholder="Enter list name"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Description
</label>
<textarea
className="input-field w-full"
rows="3"
value={newCollection.description}
onChange={(e) => setNewCollection({ ...newCollection, description: e.target.value })}
placeholder="Describe your list"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Hero Image (Optional)
</label>
<input
type="url"
className="input-field w-full"
value={newCollection.image}
onChange={(e) => setNewCollection({ ...newCollection, image: e.target.value })}
placeholder="Enter image URL or upload later"
/>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Add a custom thumbnail image, or we&apos;ll use your rarest cards
</p>
</div>
<div>
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
Tags (Optional)
</label>
<div className="space-y-2">
<div className="flex gap-2">
<input
type="text"
className="input-field flex-1"
value={tagInput}
onChange={(e) => setTagInput(e.target.value)}
onKeyPress={(e) =>
handleCollectionTagKeyPress(e, tagInput, setTagInput, newCollection, setNewCollection)
}
placeholder="Add tags (press Enter)"
/>
<button
type="button"
onClick={() => addCollectionTag(tagInput, setTagInput, newCollection, setNewCollection)}
className="px-3 py-2 rounded-lg text-sm font-medium transition-colors"
style={{
backgroundColor: 'var(--accent-ember)',
color: 'white',
}}
disabled={!tagInput.trim()}
>
Add
</button>
</div>
{newCollection.tags.length > 0 && (
<div className="flex flex-wrap gap-2">
{newCollection.tags.map((tag, index) => (
<span
key={index}
className="inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium"
style={{
backgroundColor: 'var(--bg-tertiary)',
color: 'var(--text-primary)',
border: '1px solid var(--border)',
}}
>
{tag}
<button
type="button"
onClick={() => removeCollectionTag(tag, newCollection, setNewCollection)}
className="ml-1 hover:text-red-500 transition-colors"
>
×
</button>
</span>
))}
</div>
)}
<p className="text-xs" style={{ color: 'var(--text-secondary)' }}>
Add tags to help organize and categorize your list
</p>
</div>
</div>
<div
className="flex items-center justify-between p-4 rounded-lg border"
style={{ borderColor: 'var(--border)' }}
>
<div>
<label className="text-sm font-medium" style={{ color: 'var(--text-primary)' }}>
Public List
</label>
<p className="text-xs mt-1" style={{ color: 'var(--text-secondary)' }}>
Make this list discoverable by other users
</p>
</div>
<button
type="button"
onClick={() => setNewCollection({ ...newCollection, isPublic: !newCollection.isPublic })}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
newCollection.isPublic ? 'bg-green-600' : 'bg-gray-300 dark:bg-gray-600'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
newCollection.isPublic ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
</div>
<div className="flex space-x-3 mt-6">
<button
type="button"
onClick={onClose}
className="flex-1 py-2 px-4 rounded-xl border transition-colors"
style={{
borderColor: 'var(--border)',
color: 'var(--text-secondary)',
}}
>
Cancel
</button>
<button
type="button"
onClick={onCreate}
disabled={!newCollection.name.trim()}
className="flex-1 py-2 px-4 rounded-xl font-medium transition-all duration-200 hover:shadow-md disabled:opacity-50"
style={{
backgroundColor: 'var(--accent-ember)',
color: 'white',
}}
>
Create List
</button>
</div>
</div>
</div>
);
}