TA_POLIJECARE_E31231389/frontend/src/components/Contact.jsx

296 lines
15 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { contactService } from '../services/contactService';
import { fadeIn, slideUp, staggerChildren } from '../utils/motionVariants';
const Contact = () => {
const [contactInfo, setContactInfo] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchContactInfo();
}, []);
const fetchContactInfo = async () => {
try {
setLoading(true);
const response = await contactService.get();
if (response.success) {
setContactInfo(response.data);
} else {
setError('Failed to load contact information');
}
} catch (err) {
setError('Failed to load contact information');
console.error('Error fetching contact info:', err);
} finally {
setLoading(false);
}
};
const defaultContact = {
address: 'Jl. Mastrip PO Box 164, Jember 68121, Jawa Timur, Indonesia',
phone: '+62 331-123456',
email: 'satgasppkpt@polije.ac.id',
instagram: '@satgasppkpt_polije',
whatsapp: '+62 812-3456-7890'
};
const contact = contactInfo || defaultContact;
const contactMethods = [
{
icon: (
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/>
</svg>
),
label: 'Telepon',
value: contact.phone,
href: `tel:${contact.phone}`,
color: 'text-primary'
},
{
icon: (
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
</svg>
),
label: 'Email',
value: contact.email,
href: `mailto:${contact.email}`,
color: 'text-primary'
},
{
icon: (
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.149-.67.149-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.095 3.2 5.076 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414-.074-.123-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413"/>
</svg>
),
label: 'WhatsApp',
value: contact.whatsapp,
href: `https://wa.me/${contact.whatsapp?.replace(/[^0-9]/g, '')}`,
color: 'text-accent'
}
];
const socialMedia = [
{
name: 'Instagram',
icon: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zM5.838 12a6.162 6.162 0 1112.324 0 6.162 6.162 0 01-12.324 0zM12 16a4 4 0 110-8 4 4 0 010 8zm4.965-10.405a1.44 1.44 0 112.881.001 1.44 1.44 0 01-2.881-.001z"/>
</svg>
),
href: `https://instagram.com/${contact.instagram?.replace('@', '')}`,
color: 'hover:text-pink-600'
}
];
return (
<section id="contact" className="py-20 bg-gray-50 relative overflow-hidden">
{/* Background Pattern */}
<div className="absolute inset-0 opacity-5">
<div className="absolute top-20 right-20 w-72 h-72 bg-primary rounded-full blur-3xl"></div>
<div className="absolute bottom-20 left-20 w-96 h-96 bg-accent rounded-full blur-3xl"></div>
</div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
{/* Section Header */}
<motion.div
className="text-center mb-20"
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<motion.h2
className="text-4xl md:text-5xl font-bold text-gray-900 mb-6"
variants={slideUp}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
Hubungi <span className="text-primary">Kami</span>
</motion.h2>
<motion.p
className="text-xl text-gray-600 max-w-3xl mx-auto leading-relaxed"
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.2 }}
>
Kami siap membantu Anda. Jangan ragu untuk menghubungi kami melalui berbagai metode komunikasi yang tersedia.
</motion.p>
</motion.div>
{/* Loading State */}
{loading && (
<motion.div
className="flex justify-center items-center py-20"
variants={fadeIn}
initial="hidden"
animate="visible"
>
<div className="flex flex-col items-center space-y-4">
<div className="w-12 h-12 border-4 border-primary/20 border-t-primary rounded-full animate-spin"></div>
<p className="text-gray-600 font-medium">Memuat informasi kontak...</p>
</div>
</motion.div>
)}
{/* Contact Content */}
{!loading && (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
{/* Contact Information */}
<motion.div
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<div className="bg-white rounded-3xl p-8 shadow-soft">
<h3 className="text-2xl font-bold text-gray-900 mb-8">Informasi Kontak</h3>
{/* Contact Methods */}
<div className="space-y-6 mb-8">
{contactMethods.map((method, index) => (
<motion.div
key={index}
className="flex items-start space-x-4 p-4 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.1 * index }}
>
<div className={`w-12 h-12 bg-gradient-to-br from-primary/10 to-accent/10 dark:from-primary/20 dark:to-accent/20 rounded-xl flex items-center justify-center ${method.color} flex-shrink-0`}>
<div className={method.color === 'text-primary' ? 'text-primary dark:text-primary-light' : method.color === 'text-accent' ? 'text-accent dark:text-accent-light' : 'text-gray-700 dark:text-gray-300'}>
{method.icon}
</div>
</div>
<div className="flex-1">
<h4 className="font-semibold text-gray-900 dark:text-white mb-1">{method.label}</h4>
<a
href={method.href}
className="text-gray-600 dark:text-gray-300 hover:text-primary dark:hover:text-primary-light transition-colors"
target={method.href.startsWith('http') ? '_blank' : '_self'}
rel={method.href.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{method.value}
</a>
</div>
</motion.div>
))}
</div>
{/* Address */}
<div className="p-4 bg-gray-50 rounded-xl">
<div className="flex items-start space-x-4">
<div className="w-12 h-12 bg-gradient-to-br from-primary/10 to-accent/10 rounded-xl flex items-center justify-center text-primary flex-shrink-0">
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
</svg>
</div>
<div>
<h4 className="font-semibold text-gray-900 mb-1">Alamat</h4>
<p className="text-gray-600 leading-relaxed">{contact.address}</p>
</div>
</div>
</div>
{/* Social Media */}
<div className="mt-8 pt-8 border-t border-gray-200">
<h4 className="font-semibold text-gray-900 mb-4">Ikuti Kami</h4>
<div className="flex space-x-4">
{socialMedia.map((social, index) => (
<motion.a
key={index}
href={social.href}
target="_blank"
rel="noopener noreferrer"
className={`w-12 h-12 bg-gray-100 rounded-xl flex items-center justify-center text-gray-600 ${social.color} transition-all duration-300`}
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.2 * index }}
whileHover={{ scale: 1.1 }}
>
{social.icon}
</motion.a>
))}
</div>
</div>
</div>
</motion.div>
{/* Emergency Contact */}
<motion.div
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.2 }}
>
<div className="bg-gradient-to-br from-danger/10 to-danger/5 border border-danger/20 rounded-3xl p-8">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-danger/20 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-danger" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-4">Butuh Bantuan Darurat?</h3>
<p className="text-gray-600 leading-relaxed">
Jika Anda atau orang lain berada dalam situasi darurat, segera hubungi kami untuk respons cepat 24/7.
</p>
</div>
<div className="space-y-4">
<motion.a
href={`https://wa.me/${contact.whatsapp?.replace(/[^0-9]/g, '')}`}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center w-full px-6 py-4 bg-danger text-white rounded-xl hover:bg-danger-dark transition-all duration-300 font-semibold shadow-soft hover:shadow-lg"
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.3 }}
whileHover={{ scale: 1.02 }}
>
<svg className="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.149-.67.149-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.095 3.2 5.076 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414-.074-.123-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413"/>
</svg>
Hubungi WhatsApp Darurat
</motion.a>
<motion.div
className="text-center p-4 bg-white/80 rounded-xl"
variants={fadeIn}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 0.4 }}
>
<div className="flex items-center justify-center space-x-2 text-gray-600">
<svg className="w-5 h-5 text-accent" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
</svg>
<span className="font-medium">Respons 24/7 - Privasi Terjamin</span>
</div>
</motion.div>
</div>
</div>
</motion.div>
</div>
)}
</div>
</section>
);
};
export default Contact;