refactor(collection): extract edit + delete modals (Brief 2) #85

Merged
varutasu merged 1 commit from refactor/collection-identifier-split-brief-2 into main 2026-06-03 17:58:12 -04:00
3 changed files with 171 additions and 125 deletions
Showing only changes of commit f98f5b44c3 - Show all commits

View file

@ -0,0 +1,46 @@
import { collectionDisplayName } from '../lib/collection-vocabulary.js';
export default function CollectionDeleteModal({
isOpen,
collection,
onClose,
onConfirm,
}) {
if (!isOpen || !collection) {
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)' }}>
Delete List
</h2>
<p className="mb-6" style={{ color: 'var(--text-secondary)' }}>
Are you sure you want to delete &quot;{collectionDisplayName(collection)}&quot;? This action
cannot be undone and will permanently remove all cards and data associated with this list.
</p>
<div className="flex space-x-3">
<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={onConfirm}
className="flex-1 py-2 px-4 rounded-xl font-medium transition-all duration-200 hover:shadow-md bg-red-600 text-white hover:bg-red-700"
>
Delete List
</button>
</div>
</div>
</div>
);
}

View file

@ -0,0 +1,110 @@
export default function CollectionEditModal({
isOpen,
editForm,
setEditForm,
onClose,
onSave,
}) {
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)' }}>
Edit 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={editForm.name}
onChange={(e) => setEditForm({ ...editForm, 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={editForm.description}
onChange={(e) => setEditForm({ ...editForm, 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={editForm.image}
onChange={(e) => setEditForm({ ...editForm, image: e.target.value })}
placeholder="Enter image URL"
/>
</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 collection discoverable by other users
</p>
</div>
<button
type="button"
onClick={() => setEditForm({ ...editForm, isPublic: !editForm.isPublic })}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
editForm.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 ${
editForm.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={onSave}
disabled={!editForm.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',
}}
>
Save Changes
</button>
</div>
</div>
</div>
);
}

View file

@ -13,6 +13,8 @@ import ManaSymbolSettings from '../../components/ManaSymbolSettings';
import { useAuth } from '../../lib/use-auth';
import { VOCAB, collectionDisplayName } from '../../lib/collection-vocabulary.js';
import { downloadCollectionCardsCsv } from '../../lib/collection-cards-csv.js';
import CollectionEditModal from '../../components/CollectionEditModal';
import CollectionDeleteModal from '../../components/CollectionDeleteModal';
export default function CollectionView() {
const router = useRouter();
@ -832,132 +834,20 @@ export default function CollectionView() {
</div>
)}
{/* Edit Collection Modal */}
{showEditModal && (
<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)' }}>
Edit 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={editForm.name}
onChange={(e) => setEditForm({...editForm, 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={editForm.description}
onChange={(e) => setEditForm({...editForm, 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={editForm.image}
onChange={(e) => setEditForm({...editForm, image: e.target.value})}
placeholder="Enter image URL"
/>
</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 collection discoverable by other users
</p>
</div>
<button
type="button"
onClick={() => setEditForm({...editForm, isPublic: !editForm.isPublic})}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
editForm.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 ${
editForm.isPublic ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
</div>
<div className="flex space-x-3 mt-6">
<button
onClick={() => setShowEditModal(false)}
className="flex-1 py-2 px-4 rounded-xl border transition-colors"
style={{
borderColor: 'var(--border)',
color: 'var(--text-secondary)'
}}
>
Cancel
</button>
<button
onClick={handleEditCollection}
disabled={!editForm.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'
}}
>
Save Changes
</button>
</div>
</div>
</div>
)}
<CollectionEditModal
isOpen={showEditModal}
editForm={editForm}
setEditForm={setEditForm}
onClose={() => setShowEditModal(false)}
onSave={handleEditCollection}
/>
{/* Delete Confirmation Modal */}
{showDeleteModal && (
<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)' }}>
Delete List
</h2>
<p className="mb-6" style={{ color: 'var(--text-secondary)' }}>
Are you sure you want to delete &quot;{collectionDisplayName(collection)}&quot;? This action cannot be undone and will permanently remove all cards and data associated with this list.
</p>
<div className="flex space-x-3">
<button
onClick={() => setShowDeleteModal(false)}
className="flex-1 py-2 px-4 rounded-xl border transition-colors"
style={{
borderColor: 'var(--border)',
color: 'var(--text-secondary)'
}}
>
Cancel
</button>
<button
onClick={handleDeleteCollection}
className="flex-1 py-2 px-4 rounded-xl font-medium transition-all duration-200 hover:shadow-md bg-red-600 text-white hover:bg-red-700"
>
Delete List
</button>
</div>
</div>
</div>
)}
<CollectionDeleteModal
isOpen={showDeleteModal}
collection={collection}
onClose={() => setShowDeleteModal(false)}
onConfirm={handleDeleteCollection}
/>
{/* Upload Image Modal */}
<UploadImageModal