erp-platform/ui/src/components/orders/TenantForm.tsx
2025-11-10 22:50:51 +03:00

497 lines
22 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getTenantByNameDetail } from '@/services/tenant.service'
import { CustomTenantDto } from '@/proxy/config/models'
import {
FaArrowLeft,
FaArrowRight,
FaDollarSign,
FaMoneyBillWave,
FaBuilding,
FaGlobe,
FaEnvelope,
FaMap,
FaMapPin,
FaPhone,
FaSearch,
FaUser,
FaUserPlus,
} from 'react-icons/fa'
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { ROUTES_ENUM } from '@/routes/route.constant'
interface TenantFormProps {
onSubmit: (tenant: CustomTenantDto) => void
onBack: () => void
}
export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
const [isExisting, setIsExisting] = useState<boolean>(true)
const [formData, setFormData] = useState<Partial<CustomTenantDto>>({})
const navigate = useNavigate()
const { translate } = useLocalization()
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
onSubmit({ ...formData, isExisting: isExisting! } as CustomTenantDto)
}
const handleInputChange = (field: keyof CustomTenantDto, value: string) => {
setFormData((prev) => ({ ...prev, [field]: value }))
}
const getTenantInfo = async () => {
if (!formData.name) return
try {
const tenant = await getTenantByNameDetail(formData.name)
setFormData((prev) => ({
...prev,
id: tenant.data.id,
name: tenant.data.name,
isActive: tenant.data.isActive,
organizationName: tenant.data.organizationName,
founder: tenant.data.founder,
vknTckn: tenant.data.vknTckn,
taxOffice: tenant.data.taxOffice,
address1: tenant.data.address1,
address2: tenant.data.address2,
district: tenant.data.district,
country: tenant.data.country,
city: tenant.data.city,
postalCode: tenant.data.postalCode,
phoneNumber: tenant.data.phoneNumber,
mobileNumber: tenant.data.mobileNumber,
faxNumber: tenant.data.faxNumber,
email: tenant.data.email,
website: tenant.data.website,
menuGroup: tenant.data.menuGroup,
}))
} catch (error) {
console.error('Kurum bilgisi alınırken hata:', error)
}
}
return (
<div className="flex flex-col lg:flex-row gap-6 mb-6">
<div className="w-full lg:w-1/3 bg-white rounded-xl shadow-lg border border-gray-200 p-6">
<div className="mb-6">
<h2 className="text-lg font-semibold mb-4 flex items-center">
<FaUser className="w-5 h-5 text-green-600 mr-2" />{' '}
{translate('::Public.payment.customerInfo')}
</h2>
</div>
<div className="space-y-4">
<div className="grid grid-cols-1 gap-4">
<button
onClick={() => setIsExisting(true)}
className={`p-4 border-2 rounded-xl transition-all text-left select-none ${
isExisting === true
? 'border-blue-500 bg-blue-50 shadow-md scale-[1.02]'
: 'border-gray-200 hover:border-blue-300'
}`}
>
<div className="font-semibold text-gray-900 mb-2">
{translate('::Public.products.tenantForm.existing.title')}
</div>
<div className="text-sm text-gray-600">
{translate('::Public.products.tenantForm.existing.desc')}
</div>
</button>
<button
onClick={() => setIsExisting(false)}
className={`p-4 border-2 rounded-xl transition-all text-left select-none ${
isExisting === false
? 'border-blue-500 bg-blue-50 shadow-md scale-[1.02]'
: 'border-gray-200 hover:border-blue-300'
}`}
>
<div className="font-semibold text-gray-900 mb-2">
{translate('::Public.products.tenantForm.new.title')}
</div>
<div className="text-sm text-gray-600">
{translate('::Public.products.tenantForm.new.desc')}
</div>
</button>
</div>
</div>
</div>
<div className="w-full lg:w-2/3 bg-white rounded-xl shadow-lg border border-gray-200 p-6">
{isExisting !== null && (
<form onSubmit={handleSubmit} className="space-y-6">
{isExisting ? (
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
{translate('::Public.payment.customer.code')}
</label>
<div className="relative flex flex-col sm:flex-row sm:items-stretch">
<div className="relative w-full">
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
autoFocus
placeholder="Enter your organization code"
value={formData.name || ''}
onChange={(e) => handleInputChange('name', e.target.value)}
onKeyDown={async (e) => {
if (e.key === 'Enter') {
e.preventDefault()
await getTenantInfo()
}
}}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg sm:rounded-l-lg sm:rounded-r-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"
/>
</div>
<button
type="button"
onClick={getTenantInfo}
className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-600 text-white rounded-lg sm:rounded-r-lg sm:rounded-l-none hover:bg-blue-700 transition-colors min-w-[180px]"
>
<FaSearch className="w-4 h-4" />
{translate('::Public.products.tenantForm.searchOrg')}
</button>
</div>
{formData.organizationName && (
<div className="grid grid-cols-1 gap-y-3 text-sm text-gray-700 p-3">
<div className="flex items-center gap-2">
<FaUser className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::LoginPanel.Profil')}
</span>
<span>{formData.founder}</span>
</div>
<div className="flex items-center gap-2">
<FaBuilding className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.payment.customer.company')}
</span>
<span>{formData.organizationName}</span>
</div>
<div className="flex items-center gap-2">
<FaEnvelope className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Abp.Account.EmailAddress')}:
</span>
<span>{formData.email}</span>
</div>
<div className="flex items-center gap-2">
<FaPhone className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::blog.categories.mobile')}:
</span>
<span>{formData.mobileNumber}</span>
</div>
<div className="flex items-start gap-2">
<FaMapPin className="w-4 h-4 text-gray-500 mt-0.5" />
<div>
<span className="font-medium">
{translate('::App.Address')}:
</span>
<div>{formData.address1}</div>
</div>
</div>
<div className="flex items-center gap-2">
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.payment.customer.country')}:
</span>
<span>{formData.country}</span>
</div>
<div className="flex items-center gap-2">
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.common.city')}:
</span>
<span>{formData.city}</span>
</div>
<div className="flex items-center gap-2">
<FaMap className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.payment.customer.district')}:
</span>
<span>{formData.district}</span>
</div>
<div className="flex items-center gap-2">
<FaMapPin className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.payment.customer.postalCode')}:
</span>
<span>{formData.postalCode}</span>
</div>
<div className="flex items-center gap-2">
<FaMoneyBillWave className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.contact.taxOffice')}:
</span>
<span>{formData.taxOffice}</span>
</div>
<div className="flex items-center gap-2">
<FaDollarSign className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.contact.taxNumber')}:
</span>
<span>{formData.vknTckn}</span>
</div>
{formData.reference && (
<div className="flex items-center gap-2">
<FaUserPlus className="w-4 h-4 text-gray-500" />
<span className="font-medium">
{translate('::Public.payment.customer.reference')}:
</span>
<span>{formData.reference}</span>
</div>
)}
</div>
)}
</div>
) : (
<div className="space-y-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
{translate('::Public.products.tenantForm.orgName')}
</label>
<div className="relative">
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
autoFocus
placeholder="Enter your organization name"
value={formData.organizationName || ''}
onChange={(e) => handleInputChange('organizationName', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"
/>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::LoginPanel.Profil')}
</label>
<div className="relative">
<FaUser className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="Enter founder's name"
value={formData.founder || ''}
onChange={(e) => handleInputChange('founder', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Abp.Identity.User.UserInformation.PhoneNumber')}
</label>
<div className="relative">
<FaPhone className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="tel"
required
placeholder="+90 (___) ___-____"
value={formData.phoneNumber || ''}
onChange={(e) => handleInputChange('phoneNumber', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Abp.Account.EmailAddress')}
</label>
<div className="relative">
<FaEnvelope className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="email"
required
placeholder="sample@email.com"
value={formData.email || ''}
onChange={(e) => handleInputChange('email', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::App.Address')}
</label>
<div className="relative">
<FaMapPin className="absolute left-3 top-3 text-gray-400 w-5 h-5" />
<textarea
required
placeholder="Enter your address"
value={formData.address1 || ''}
onChange={(e) => handleInputChange('address1', e.target.value)}
rows={3}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.payment.customer.country')}
</label>
<div className="relative">
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
placeholder="Türkiye"
value={formData.country || ''}
onChange={(e) => handleInputChange('country', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.common.city')}
</label>
<div className="relative">
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="İstanbul"
value={formData.city || ''}
onChange={(e) => handleInputChange('city', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.payment.customer.district')}
</label>
<div className="relative">
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="Çekmeköy"
value={formData.district || ''}
onChange={(e) => handleInputChange('district', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.payment.customer.postalCode')}
</label>
<div className="relative">
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="34782"
value={formData.postalCode || ''}
onChange={(e) => handleInputChange('postalCode', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.contact.taxOffice')}
</label>
<div className="relative">
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="Kozyatağı"
value={formData.taxOffice}
onChange={(e) => handleInputChange('taxOffice', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.contact.taxNumber')}
</label>
<div className="relative">
<FaDollarSign className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
placeholder="1234567890"
value={formData.vknTckn}
onChange={(e) => handleInputChange('vknTckn', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
<div>
<label className="text-sm font-medium text-gray-700">
{translate('::Public.payment.customer.reference')}
</label>
<div className="relative">
<FaUserPlus className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
placeholder={translate('::Public.payment.customer.reference')}
value={formData.reference || ''}
onChange={(e) => handleInputChange('reference', e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>
)}
<div className="flex justify-between items-center mt-6">
<button
type="button"
onClick={() => navigate(ROUTES_ENUM.public.products)}
className="flex items-center px-6 py-3 border border-gray-300 text-gray-700 rounded-lg"
>
<FaArrowLeft className="w-4 h-4 mr-2" />
{translate('::Public.payment.buttons.back')}
</button>
<button
type="submit"
className="flex items-center justify-center px-6 py-3 bg-green-600 text-white rounded-lg"
>
<FaArrowRight className="w-5 h-5 mr-2" />
{translate('::Abp.Account.ResetPassword.Continue')}
</button>
</div>
</form>
)}
</div>
</div>
)
}