188 lines
7.1 KiB
TypeScript
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>
|
|
)
|
|
}
|