erp-platform/company/src/pages/Demo.tsx
2025-07-28 23:20:06 +03:00

383 lines
14 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 React, { useEffect, useState } from "react";
import { useLanguage } from "../context/LanguageContext";
import { demoService } from "../services/demo.service";
import {
Building2,
User,
Mail,
Phone,
MapPin,
Users,
MessageSquare,
Send,
CheckCircle,
} from "lucide-react";
interface DemoModalProps {
isOpen: boolean;
onClose: () => void;
}
interface FormData {
organizationName: string;
fullName: string;
email: string;
phone: string;
address: string;
numberOfBranches: string;
numberOfUsers: string;
message: string;
}
const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
const { t } = useLanguage();
const [formData, setFormData] = useState<FormData>({
organizationName: "",
fullName: "",
email: "",
phone: "",
address: "",
numberOfBranches: "",
numberOfUsers: "",
message: "",
});
const [errors, setErrors] = useState<Partial<FormData>>({});
const [isSubmitted, setIsSubmitted] = useState(false);
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
if (errors[name as keyof FormData]) {
setErrors((prev) => ({
...prev,
[name]: "",
}));
}
};
const validateForm = (): boolean => {
const newErrors: Partial<FormData> = {};
if (!formData.organizationName.trim())
newErrors.organizationName = "Organization name is required";
if (!formData.fullName.trim()) newErrors.fullName = "Full name is required";
if (!formData.email.trim()) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
newErrors.email = "Please enter a valid email";
}
if (!formData.phone.trim()) newErrors.phone = "Phone number is required";
if (!formData.address.trim()) newErrors.address = "Address is required";
if (!formData.numberOfBranches.trim())
newErrors.numberOfBranches = "Number of branches is required";
if (!formData.numberOfUsers.trim())
newErrors.numberOfUsers = "Number of users is required";
if (!formData.message.trim()) newErrors.message = "Message is required";
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) return;
try {
await demoService.createDemoForm(formData);
setIsSubmitted(true);
onClose(); // modal'ı otomatik kapat
} catch (error) {
console.error("Gönderim hatası:", error);
alert("Sunucuya ulaşılamıyor.");
}
};
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
onClose();
}
};
if (isOpen) {
window.addEventListener("keydown", handleKeyDown);
}
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, [isOpen, onClose]);
// 🎉 Gönderim sonrası teşekkür ekranı
if (isSubmitted) {
return (
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto py-5 z-50">
<div className="mx-auto bg-white rounded-xl shadow-lg max-w-md w-full relative">
<div className="max-w-md w-full bg-gradient-to-br from-blue-50 to-indigo-100 rounded-3xl p-8 text-center border border-blue-200 shadow-xl">
{/* Kapat Butonu */}
<button
onClick={() => setIsSubmitted(false)}
className="absolute top-4 right-4 text-gray-500 hover:text-gray-800 text-2xl"
>
&times;
</button>
<div className="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-6">
<CheckCircle className="w-8 h-8 text-white" />
</div>
<h2 className="text-2xl font-bold text-gray-800 mb-4">
Teşekkürler!
</h2>
<p className="text-gray-600 mb-6">
Demo talebiniz başarıyla gönderildi. 24 saat içinde size geri
dönüş yapacağız.
</p>
<button
onClick={() => {
setIsSubmitted(false);
setFormData({
organizationName: "",
fullName: "",
email: "",
phone: "",
address: "",
numberOfBranches: "",
numberOfUsers: "",
message: "",
});
}}
className="px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-xl transition-all duration-300"
>
Yeni Talep Gönder
</button>
</div>
</div>
</div>
);
}
// Modal kapalıysa render etme
if (!isOpen) return null;
// 🎯 Normal form ekranı
return (
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto py-5 z-50">
<div className="mx-auto bg-white rounded-xl shadow-lg max-w-2xl w-full relative">
<button
onClick={onClose}
className="absolute top-4 right-4 text-gray-500 hover:text-gray-800 text-2xl"
>
&times;
</button>
<form
onSubmit={handleSubmit}
className="bg-white rounded-3xl p-6 lg:p-8 shadow-xl border border-gray-100"
>
<div className="space-y-3">
{/* Organization Name */}
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.company')} *
</label>
<div className="relative">
<Building2 className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
autoFocus
name="organizationName"
value={formData.organizationName}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.organizationName
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.organizationName')}
/>
</div>
</div>
{/* Full Name */}
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.fullName')} *
</label>
<div className="relative">
<User className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
name="fullName"
value={formData.fullName}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.fullName
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.fullName')}
/>
</div>
</div>
{/* Email & Phone Row */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.email')} *
</label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.email
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.email')}
/>
</div>
</div>
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.phone')} *
</label>
<div className="relative">
<Phone className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="tel"
name="phone"
value={formData.phone}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.phone
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.phone')}
/>
</div>
</div>
</div>
{/* Address */}
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.address')} *
</label>
<div className="relative">
<MapPin className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
name="address"
value={formData.address}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.address
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.address')}
/>
</div>
</div>
{/* Branches & Users Row */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.branchCount')} *
</label>
<div className="relative">
<Building2 className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="number"
name="numberOfBranches"
value={formData.numberOfBranches}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.numberOfBranches
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.branches')}
min="1"
/>
</div>
</div>
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.userCount')} *
</label>
<div className="relative">
<Users className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="number"
name="numberOfUsers"
value={formData.numberOfUsers}
onChange={handleInputChange}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.numberOfUsers
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300`}
placeholder={t('demo.users')}
min="1"
/>
</div>
</div>
</div>
{/* Message */}
<div>
<label className="block text-gray-700 text-sm font-medium mb-2">
{t('common.message')} *
</label>
<div className="relative">
<MessageSquare className="absolute left-3 top-3 w-5 h-5 text-gray-400" />
<textarea
name="message"
value={formData.message}
onChange={handleInputChange}
rows={4}
className={`w-full pl-11 pr-4 py-2.5 bg-gray-50 border ${
errors.message
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
: "border-gray-200 focus:border-blue-500 focus:ring-blue-500/20"
} rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none transition-all duration-300 resize-none`}
placeholder={t('demo.message')}
/>
</div>
</div>
{/* Submit Button */}
<button
type="submit"
className="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white font-semibold py-4 px-6 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-lg flex items-center justify-center gap-2"
>
<Send className="w-5 h-5" />
{t('demo.send')}
</button>
</div>
</form>
</div>
</div>
);
};
export default Demo;