admin
Some checks are pending
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
b86e840cc6
commit
0cfd5f4524
3 changed files with 98 additions and 55 deletions
|
|
@ -52,8 +52,20 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
packsApi
|
||||
.getPacks({ page: 1, limit: 100, search: '' })
|
||||
.then((response) => {
|
||||
if (response && response.items) {
|
||||
setPacksData(response.items.map((pack) => ({ id: pack.id, title: pack.title })))
|
||||
try {
|
||||
if (response && response.items && Array.isArray(response.items)) {
|
||||
const packs = response.items.map((pack: any) => ({
|
||||
id: String(pack.id || ''),
|
||||
title: String(pack.title || pack.id || '')
|
||||
}))
|
||||
setPacksData(packs)
|
||||
} else {
|
||||
console.warn('Unexpected packs response format:', response)
|
||||
setPacksData([])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing packs response:', error)
|
||||
setPacksData([])
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
@ -66,6 +78,7 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
|
||||
// Initialize cards data
|
||||
useEffect(() => {
|
||||
if (images.length > 0) {
|
||||
const initialData = new Map<string, CardData>()
|
||||
images.forEach((image) => {
|
||||
initialData.set(image.id, {
|
||||
|
|
@ -82,15 +95,17 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
})
|
||||
})
|
||||
setCardsData(initialData)
|
||||
}
|
||||
}, [images])
|
||||
|
||||
const currentImage = images[currentIndex]
|
||||
const currentCard = cardsData.get(currentImage?.id || '')
|
||||
const currentCard = currentImage ? cardsData.get(currentImage.id) : undefined
|
||||
|
||||
const updateMutation = useMutation({
|
||||
mutationFn: (card: GameCardDto) => cardsApi.upsertCard(card),
|
||||
onSuccess: (response) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['cards'] })
|
||||
if (currentImage) {
|
||||
const imageId = currentImage.id
|
||||
setCardsData((prev) => {
|
||||
const newData = new Map(prev)
|
||||
|
|
@ -104,6 +119,7 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
}
|
||||
return newData
|
||||
})
|
||||
}
|
||||
toast.success('Card saved successfully')
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
|
|
@ -113,7 +129,7 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
})
|
||||
|
||||
const handleFieldChange = (field: keyof CardData, value: string) => {
|
||||
if (!currentCard) return
|
||||
if (!currentCard || !currentImage) return
|
||||
|
||||
setCardsData((prev) => {
|
||||
const newData = new Map(prev)
|
||||
|
|
@ -170,8 +186,21 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
const savedCount = Array.from(cardsData.values()).filter((card) => card.isSaved).length
|
||||
const totalCount = images.length
|
||||
|
||||
// Wait for images and cards data to be initialized
|
||||
if (images.length === 0) {
|
||||
return (
|
||||
<div className="p-4">
|
||||
<p className="text-muted-foreground">No images uploaded</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!currentImage || !currentCard) {
|
||||
return <div>Loading...</div>
|
||||
return (
|
||||
<div className="p-4">
|
||||
<p className="text-muted-foreground">Initializing card data...</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -199,15 +228,25 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Image Preview</CardTitle>
|
||||
<CardDescription>{currentImage.file.name}</CardDescription>
|
||||
<CardDescription>{currentImage.file?.name || 'Unknown'}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="relative aspect-square border rounded-lg overflow-hidden bg-muted">
|
||||
{currentImage.preview ? (
|
||||
<img
|
||||
src={currentImage.preview}
|
||||
alt={currentImage.file.name}
|
||||
alt={currentImage.file?.name || 'Card image'}
|
||||
className="w-full h-full object-contain"
|
||||
onError={(e) => {
|
||||
console.error('Failed to load image:', currentImage.preview)
|
||||
e.currentTarget.style.display = 'none'
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
|
||||
Image preview not available
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
@ -222,19 +261,21 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
|
|||
<div className="space-y-2">
|
||||
<Label htmlFor="packId">Pack ID (optional)</Label>
|
||||
<Select
|
||||
value={currentCard.packId}
|
||||
onValueChange={(value: string) => handleFieldChange('packId', value)}
|
||||
value={currentCard.packId || undefined}
|
||||
onValueChange={(value: string) => handleFieldChange('packId', value || '')}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a pack (optional)" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">None</SelectItem>
|
||||
{packsData.map((pack) => (
|
||||
{packsData && packsData.length > 0 ? (
|
||||
packsData.map((pack) => (
|
||||
<SelectItem key={pack.id} value={pack.id}>
|
||||
{pack.title}
|
||||
{pack.title || pack.id}
|
||||
</SelectItem>
|
||||
))}
|
||||
))
|
||||
) : null}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -366,19 +366,21 @@ export default function CardsPage() {
|
|||
<div className="space-y-2">
|
||||
<Label htmlFor="packId">Pack ID (optional)</Label>
|
||||
<Select
|
||||
value={formData.packId}
|
||||
onValueChange={(value: string) => setFormData(prev => ({ ...prev, packId: value }))}
|
||||
value={formData.packId || undefined}
|
||||
onValueChange={(value: string) => setFormData(prev => ({ ...prev, packId: value || '' }))}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a pack (optional)" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">None</SelectItem>
|
||||
{packsData?.items.map((pack) => (
|
||||
{packsData?.items && packsData.items.length > 0 ? (
|
||||
packsData.items.map((pack) => (
|
||||
<SelectItem key={pack.id} value={pack.id}>
|
||||
{pack.title}
|
||||
{pack.title || pack.id}
|
||||
</SelectItem>
|
||||
))}
|
||||
))
|
||||
) : null}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -387,10 +387,10 @@ export default function UsersPage() {
|
|||
<div className="space-y-2">
|
||||
<Label>Packs Owned</Label>
|
||||
<div className="border rounded-lg max-h-[200px] overflow-y-auto p-2">
|
||||
{packsData?.items.length === 0 ? (
|
||||
{!packsData?.items || packsData.items.length === 0 ? (
|
||||
<div className="text-sm text-muted-foreground">No packs available</div>
|
||||
) : (
|
||||
packsData?.items.map((pack) => (
|
||||
packsData.items.map((pack) => (
|
||||
<div key={pack.id} className="flex items-center space-x-2 py-1">
|
||||
<Checkbox
|
||||
id={`pack-${pack.id}`}
|
||||
|
|
|
|||
Loading…
Reference in a new issue