refactor(card): extract deck modal (Brief 2) #83
2 changed files with 88 additions and 60 deletions
75
components/CardDetailDeckModal.js
Normal file
75
components/CardDetailDeckModal.js
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
export default function CardDetailDeckModal({
|
||||||
|
isOpen,
|
||||||
|
card,
|
||||||
|
decks,
|
||||||
|
selectedDeck,
|
||||||
|
onSelectedDeckChange,
|
||||||
|
onAdd,
|
||||||
|
onClose,
|
||||||
|
}) {
|
||||||
|
if (!isOpen || !card) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||||
|
<div
|
||||||
|
className="bg-white rounded-2xl p-6 max-w-md w-full mx-4"
|
||||||
|
style={{ backgroundColor: 'var(--bg-primary)' }}
|
||||||
|
>
|
||||||
|
<h3 className="text-xl font-bold mb-4" style={{ color: 'var(--text-primary)' }}>
|
||||||
|
Add to Deck
|
||||||
|
</h3>
|
||||||
|
<div className="mb-6">
|
||||||
|
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
|
||||||
|
Select Deck
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={selectedDeck}
|
||||||
|
onChange={(e) => onSelectedDeckChange(e.target.value)}
|
||||||
|
className="w-full p-3 rounded-xl border transition-all duration-200"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--bg-secondary)',
|
||||||
|
borderColor: 'var(--border)',
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="">Choose a deck...</option>
|
||||||
|
{decks
|
||||||
|
.filter((deck) => deck.game === card.game)
|
||||||
|
.map((deck) => (
|
||||||
|
<option key={deck.id} value={deck.id}>
|
||||||
|
{deck.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={onAdd}
|
||||||
|
disabled={!selectedDeck}
|
||||||
|
className={`flex-1 px-4 py-2 rounded-xl font-medium transition-all duration-200 ${
|
||||||
|
selectedDeck
|
||||||
|
? 'gradient-bg-purple text-white hover:shadow-lg'
|
||||||
|
: 'opacity-50 cursor-not-allowed'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
Add to Deck
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={onClose}
|
||||||
|
className="flex-1 px-4 py-2 rounded-xl font-medium border transition-all duration-200"
|
||||||
|
style={{
|
||||||
|
borderColor: 'var(--border)',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import Layout from '../../components/Layout';
|
||||||
import { useAuth } from '../../lib/use-auth';
|
import { useAuth } from '../../lib/use-auth';
|
||||||
import CollectionSelectionModal from '../../components/CollectionSelectionModal';
|
import CollectionSelectionModal from '../../components/CollectionSelectionModal';
|
||||||
import CardDetailQuantityModal from '../../components/CardDetailQuantityModal';
|
import CardDetailQuantityModal from '../../components/CardDetailQuantityModal';
|
||||||
|
import CardDetailDeckModal from '../../components/CardDetailDeckModal';
|
||||||
import { ManaCost, ColorIdentity, AdvancedManaCost } from '../../components/ManaSymbols';
|
import { ManaCost, ColorIdentity, AdvancedManaCost } from '../../components/ManaSymbols';
|
||||||
import ManaSymbolSettings from '../../components/ManaSymbolSettings';
|
import ManaSymbolSettings from '../../components/ManaSymbolSettings';
|
||||||
import { VOCAB, collectionDisplayName } from '../../lib/collection-vocabulary.js';
|
import { VOCAB, collectionDisplayName } from '../../lib/collection-vocabulary.js';
|
||||||
|
|
@ -801,66 +802,18 @@ export default function CardDetail() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Deck Modal */}
|
<CardDetailDeckModal
|
||||||
{showDeckModal && (
|
isOpen={showDeckModal}
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
card={card}
|
||||||
<div className="bg-white rounded-2xl p-6 max-w-md w-full mx-4" style={{ backgroundColor: 'var(--bg-primary)' }}>
|
decks={decks}
|
||||||
<h3 className="text-xl font-bold mb-4" style={{ color: 'var(--text-primary)' }}>
|
selectedDeck={selectedDeck}
|
||||||
Add to Deck
|
onSelectedDeckChange={setSelectedDeck}
|
||||||
</h3>
|
onAdd={handleAddToDeck}
|
||||||
<div className="mb-6">
|
onClose={() => {
|
||||||
<label className="block text-sm font-medium mb-2" style={{ color: 'var(--text-primary)' }}>
|
|
||||||
Select Deck
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
value={selectedDeck}
|
|
||||||
onChange={(e) => setSelectedDeck(e.target.value)}
|
|
||||||
className="w-full p-3 rounded-xl border transition-all duration-200"
|
|
||||||
style={{
|
|
||||||
backgroundColor: 'var(--bg-secondary)',
|
|
||||||
borderColor: 'var(--border)',
|
|
||||||
color: 'var(--text-primary)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="">Choose a deck...</option>
|
|
||||||
{decks
|
|
||||||
.filter(deck => deck.game === card.game)
|
|
||||||
.map(deck => (
|
|
||||||
<option key={deck.id} value={deck.id}>
|
|
||||||
{deck.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-3">
|
|
||||||
<button
|
|
||||||
onClick={handleAddToDeck}
|
|
||||||
disabled={!selectedDeck}
|
|
||||||
className={`flex-1 px-4 py-2 rounded-xl font-medium transition-all duration-200 ${
|
|
||||||
selectedDeck
|
|
||||||
? 'gradient-bg-purple text-white hover:shadow-lg'
|
|
||||||
: 'opacity-50 cursor-not-allowed'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Add to Deck
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setShowDeckModal(false);
|
setShowDeckModal(false);
|
||||||
setSelectedDeck('');
|
setSelectedDeck('');
|
||||||
}}
|
}}
|
||||||
className="flex-1 px-4 py-2 rounded-xl font-medium border transition-all duration-200"
|
/>
|
||||||
style={{
|
|
||||||
borderColor: 'var(--border)',
|
|
||||||
color: 'var(--text-secondary)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue