profit-planet-frontend/src/app/admin/pool-management/components/createNewPoolModal.tsx
DeathKaioken 646c293bc1 .
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 06:22:10 +02:00

188 lines
7.1 KiB
TypeScript

'use client'
import { useTranslation } from '../../../i18n/useTranslation';
import React from 'react'
interface Props {
isOpen: boolean
onClose: () => void
onCreate: (data: { pool_name: string; description: string; price: number; pool_type: 'coffee' | 'other'; subscription_coffee_id: number | null }) => void | Promise<void>
subscriptions: Array<{ id: number; title: string }>
creating: boolean
error?: string
success?: string
clearMessages: () => void
}
export default function CreateNewPoolModal({
isOpen,
onClose,
onCreate,
subscriptions,
creating,
error,
success,
clearMessages
}: Props) {
const { t } = useTranslation();
const [poolName, setPoolName] = React.useState('')
const [description, setDescription] = React.useState('')
const [price, setPrice] = React.useState('0.00')
const [poolType, setPoolType] = React.useState<'coffee' | 'other'>('other')
const [subscriptionCoffeeId, setSubscriptionCoffeeId] = React.useState<string>('')
const isDisabled = creating || !!success
React.useEffect(() => {
if (!isOpen) {
setPoolName('')
setDescription('')
setPrice('0.00')
setPoolType('other')
setSubscriptionCoffeeId('')
}
}, [isOpen])
if (!isOpen) return null
return (
<div className="fixed inset-0 z-50 flex items-center justify-center">
{/* Overlay */}
<div
className="absolute inset-0 bg-black/40 backdrop-blur-sm"
onClick={onClose}
/>
{/* Modal */}
<div className="relative w-full max-w-lg mx-4 rounded-2xl bg-white shadow-xl border border-blue-100 p-6">
<div className="flex items-center justify-between mb-4">
<h2 className="text-xl font-semibold text-blue-900">{t('autofix.k209ba561')}</h2>
<button
onClick={() => { clearMessages(); onClose(); }}
className="text-gray-500 hover:text-gray-700 transition text-sm"
aria-label={t('common.close')}
>
</button>
</div>
{success && (
<div className="mb-4 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">
{success}
</div>
)}
{error && (
<div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{error}
</div>
)}
<form
onSubmit={e => {
e.preventDefault()
clearMessages()
onCreate({
pool_name: poolName,
description,
price: parseFloat(price) || 0,
pool_type: poolType,
subscription_coffee_id: subscriptionCoffeeId ? Number(subscriptionCoffeeId) : null,
})
}}
className="space-y-4"
>
<div>
<label className="block text-sm font-medium text-blue-900 mb-1">{t('autofix.kd4a0fd1e')}</label>
<input
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm bg-gray-50 text-gray-900 focus:ring-2 focus:ring-blue-900 focus:border-transparent"
placeholder={t('autofix.k0925e287')}
value={poolName}
onChange={e => setPoolName(e.target.value)}
disabled={isDisabled}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-blue-900 mb-1">{t('autofix.k40b5c1d2')}</label>
<textarea
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm bg-gray-50 text-gray-900 focus:ring-2 focus:ring-blue-900 focus:border-transparent"
rows={3}
placeholder={t('autofix.kb573897d')}
value={description}
onChange={e => setDescription(e.target.value)}
disabled={isDisabled}
/>
</div>
<div>
<label className="block text-sm font-medium text-blue-900 mb-1">{t('autofix.k8ef02c19')}</label>
<input
type="number"
step="0.01"
min="0"
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm bg-gray-50 text-gray-900 focus:ring-2 focus:ring-blue-900 focus:border-transparent"
placeholder="0.00"
value={price}
onChange={e => setPrice(e.target.value)}
disabled={isDisabled}
required
/>
<p className="mt-1 text-xs text-gray-500">{t('autofix.k75cb45a7')}</p>
</div>
<div>
<label className="block text-sm font-medium text-blue-900 mb-1">{t('autofix.kd49dc1e1')}</label>
<select
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm bg-gray-50 text-gray-900 focus:ring-2 focus:ring-blue-900 focus:border-transparent"
value={poolType}
onChange={e => setPoolType(e.target.value as 'coffee' | 'other')}
disabled={isDisabled}
>
<option value="other">{t('autofix.ka320df81')}</option>
<option value="coffee">{t('autofix.k2f9cd1e0')}</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-blue-900 mb-1">{t('autofix.k59422f07')}</label>
<select
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm bg-gray-50 text-gray-900 focus:ring-2 focus:ring-blue-900 focus:border-transparent"
value={subscriptionCoffeeId}
onChange={e => setSubscriptionCoffeeId(e.target.value)}
disabled={isDisabled}
>
<option value="">{t('autofix.kb8d70f41')}</option>
{subscriptions.map((s) => (
<option key={s.id} value={String(s.id)}>{s.title}</option>
))}
</select>
</div>
<div className="flex gap-2">
<button
type="submit"
disabled={isDisabled}
className="px-5 py-3 text-sm font-semibold text-blue-50 rounded-lg bg-blue-900 hover:bg-blue-800 shadow inline-flex items-center gap-2 disabled:opacity-60"
>
{creating && <span className="h-4 w-4 rounded-full border-2 border-white/30 border-t-white animate-spin" />}
{creating ? t('autofix.k241a2d77') : t('autofix.kf9d2e4a0')}
</button>
<button
type="button"
className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-200 rounded-lg hover:bg-gray-300 transition"
onClick={() => { setPoolName(''); setDescription(''); setPrice('0.00'); setPoolType('other'); setSubscriptionCoffeeId(''); clearMessages(); }}
disabled={isDisabled}
>
{t('autofix.k612fc0a4')}
</button>
<button
type="button"
className="ml-auto px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800 transition"
onClick={() => { clearMessages(); onClose(); }}
disabled={isDisabled}
>
Close
</button>
</div>
</form>
</div>
</div>
)
}