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

This commit is contained in:
Dmitry 2025-12-14 22:34:43 +03:00
parent 889784e11f
commit 8053fda0ec
6 changed files with 165 additions and 11 deletions

View file

@ -218,7 +218,7 @@ export function BulkCardEditor({ images, onComplete, onCancel }: BulkCardEditorP
<Label htmlFor="packId">Pack ID (optional)</Label> <Label htmlFor="packId">Pack ID (optional)</Label>
<Select <Select
value={currentCard.packId} value={currentCard.packId}
onValueChange={(value) => handleFieldChange('packId', value)} onValueChange={(value: string) => handleFieldChange('packId', value)}
> >
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Select a pack (optional)" /> <SelectValue placeholder="Select a pack (optional)" />

View file

@ -1,9 +1,7 @@
import { useState, useRef } from 'react' import { useState, useRef } from 'react'
import { Button } from './ui/button' import { Button } from './ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card'
import { Label } from './ui/label' import { Upload, X, Check } from 'lucide-react'
import { Upload, X, Image as ImageIcon, Check } from 'lucide-react'
import { Badge } from './ui/badge'
interface UploadedImage { interface UploadedImage {
id: string id: string

View file

@ -1,8 +1,6 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { cardsApi } from '@/api/cards' import { cardsApi } from '@/api/cards'
import type { GameCardDto } from '@/types/models'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label' import { Label } from '@/components/ui/label'
import { import {
@ -14,7 +12,7 @@ import {
TableRow, TableRow,
} from '@/components/ui/table' } from '@/components/ui/table'
import { Badge } from '@/components/ui/badge' import { Badge } from '@/components/ui/badge'
import { Search, Plus, X, Check } from 'lucide-react' import { Search, Check } from 'lucide-react'
interface PackCardsManagerProps { interface PackCardsManagerProps {
currentCardIds: string[] currentCardIds: string[]

View file

@ -2,7 +2,7 @@ import { useRef, useState } from 'react'
import { Button } from './button' import { Button } from './button'
import { Label } from './label' import { Label } from './label'
import { Input } from './input' import { Input } from './input'
import { X, Upload, Music, Play, Pause } from 'lucide-react' import { X, Music, Play, Pause } from 'lucide-react'
interface AudioUploadProps { interface AudioUploadProps {
label?: string label?: string
@ -136,8 +136,6 @@ export function AudioUpload({
} }
} }
const audioUrl = value ? `data:audio/mpeg;base64,${value}` : null
return ( return (
<div className="space-y-2"> <div className="space-y-2">
{label && <Label>{label}</Label>} {label && <Label>{label}</Label>}

View file

@ -0,0 +1,160 @@
"use client"
import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { Check, ChevronDown, ChevronUp } from "lucide-react"
import { cn } from "@/lib/utils"
const Select = SelectPrimitive.Root
const SelectGroup = SelectPrimitive.Group
const SelectValue = SelectPrimitive.Value
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName
const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props}
/>
))
SelectLabel.displayName = SelectPrimitive.Label.displayName
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName
const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
}

View file

@ -367,7 +367,7 @@ export default function CardsPage() {
<Label htmlFor="packId">Pack ID (optional)</Label> <Label htmlFor="packId">Pack ID (optional)</Label>
<Select <Select
value={formData.packId} value={formData.packId}
onValueChange={(value) => setFormData(prev => ({ ...prev, packId: value }))} onValueChange={(value: string) => setFormData(prev => ({ ...prev, packId: value }))}
> >
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Select a pack (optional)" /> <SelectValue placeholder="Select a pack (optional)" />