301 lines
14 KiB
TypeScript
301 lines
14 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from '@/components/ui/dialog';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation';
|
|
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
|
|
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
|
|
import 'filepond/dist/filepond.min.css';
|
|
import { Star } from 'lucide-react';
|
|
import { FilePond, registerPlugin } from 'react-filepond';
|
|
|
|
import 'swiper/css';
|
|
import 'swiper/css/navigation';
|
|
import 'swiper/css/pagination';
|
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
|
|
|
import { useTranslations } from '@/utils/i18n';
|
|
import { useForm } from '@inertiajs/react';
|
|
import { useEffect, useState } from 'react';
|
|
import { toast } from 'sonner';
|
|
import { Pagination } from 'swiper/modules';
|
|
|
|
// const testimonial = [
|
|
// {
|
|
// name: 'Priya Sharada',
|
|
// company: 'Sharada Group',
|
|
// review: 'What impressed me the most was the attention to detail and the evident care put into making the rug, It has become a center piece in my living room, gathering compliments from everyone who sees it. If you are considering handmade rugs, I highly recommend Kaleen.',
|
|
// img: testimonial1,
|
|
// },
|
|
// {
|
|
// name: 'Kedar Bhakta Mathema',
|
|
// company:
|
|
// 'Former VC of Tribhuwan University, Nepal, Former Nepalese Ambassador to Japan',
|
|
// review: 'I am delighted to recommend Kaleen Carpet in Kathmandu to anyone seeking skilled carpet weavers. What impressed me most about Kaleen was their willingness to make several changes to the design at my request without any hesitation. I find Kaleen to be highly professional and trustworthy in all their dealings.',
|
|
// img: testimonial3,
|
|
// },
|
|
// {
|
|
// name: 'Ani Rudra Silwal and Srijana Silwal',
|
|
// company: 'USA',
|
|
// review: "Thank you for making these carpets for us! We couldn't be more pleased with them. The entire process - from the custom design to shipping - was seamless and very professional. We look forward to having these beautiful Nepali handmade carpets in our home for many years to come!",
|
|
// img: testimonial1,
|
|
// },
|
|
// {
|
|
// name: 'Manila Pradhan and Bhaskar Joshi',
|
|
// company: 'USA',
|
|
// review: 'We absolutely love the carpet. Thank you so much for the excellent design and execution.',
|
|
// img: testimonial2,
|
|
// },
|
|
// ];
|
|
export default function Testimonial({
|
|
testimonial,
|
|
}: {
|
|
testimonial: [
|
|
{
|
|
name: string;
|
|
location: string;
|
|
image: string;
|
|
description: string;
|
|
},
|
|
];
|
|
}) {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const [file, setFile] = useState<any | null>(null);
|
|
const [open, setOpen] = useState(false);
|
|
const { data, setData, post, processing, errors } = useForm({
|
|
name: '',
|
|
location: '',
|
|
description: '',
|
|
image: null as File | null,
|
|
});
|
|
registerPlugin(
|
|
FilePondPluginImageExifOrientation,
|
|
FilePondPluginImagePreview,
|
|
);
|
|
useEffect(() => {
|
|
if (file) {
|
|
setData('image', file.file);
|
|
}
|
|
}, [file, setData]);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
post('/testimonial', {
|
|
// forceFormData: true,
|
|
onSuccess: () => {
|
|
toast.success('Testimonial successfully uploaded!');
|
|
setOpen(false);
|
|
setFile(null);
|
|
setData({
|
|
name: '',
|
|
location: '',
|
|
description: '',
|
|
image: null,
|
|
});
|
|
},
|
|
});
|
|
};
|
|
|
|
const { t } = useTranslations();
|
|
return (
|
|
<>
|
|
<section className="mx-auto flex max-w-screen-2xl flex-col items-center gap-12 px-16 py-12 max-sm:px-8">
|
|
<h4 className="text-center font-serif text-4xl font-medium">
|
|
{t('pages.home.sections.testimonial.title')}
|
|
</h4>
|
|
{/* <div className="grid grid-cols-4 gap-8 max-lg:grid-cols-2 max-md:grid-cols-2 max-sm:grid-cols-1">
|
|
{testimonial.map((review) => (
|
|
<div className="flex flex-col items-center gap-4 rounded-lg border border-gray-300 px-6 py-6 text-center">
|
|
<div className="flex flex-col gap-1">
|
|
<img
|
|
src={review.image}
|
|
alt={review.name}
|
|
className="mb-4 aspect-video rounded-md object-cover object-center"
|
|
/>
|
|
<p className="text-lg font-bold">
|
|
{review.name}
|
|
</p>
|
|
<p className="text-sm text-gray-500">
|
|
{review.location}
|
|
</p>
|
|
</div>
|
|
<p className="text-sm text-gray-800">
|
|
{review.description}
|
|
</p>
|
|
|
|
<div className="flex items-center">
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div> */}
|
|
<div
|
|
className="relative max-w-7xl overflow-clip max-sm:max-w-sm"
|
|
id="testimonial"
|
|
>
|
|
<Swiper
|
|
spaceBetween={16}
|
|
slidesPerView={4}
|
|
breakpoints={{
|
|
432: {
|
|
slidesPerView: 2,
|
|
spaceBetween: 8,
|
|
},
|
|
768: {
|
|
slidesPerView: 3,
|
|
spaceBetween: 8,
|
|
},
|
|
1024: {
|
|
slidesPerView: 4,
|
|
spaceBetween: 16,
|
|
},
|
|
}}
|
|
loop={true}
|
|
autoplay={{
|
|
delay: 1500,
|
|
}}
|
|
className="w-full"
|
|
pagination={true}
|
|
// navigation={true}
|
|
modules={[Pagination]}
|
|
>
|
|
{testimonial.map((review) => (
|
|
<SwiperSlide className="relative overflow-clip">
|
|
<div className="flex flex-col items-center gap-4 rounded-lg border border-gray-300 px-6 py-6 text-center">
|
|
<div className="flex flex-col gap-1">
|
|
<img
|
|
src={review.image}
|
|
alt={review.name}
|
|
className="mb-4 aspect-video rounded-md object-cover object-center"
|
|
/>
|
|
<p className="text-lg font-bold">
|
|
{review.name}
|
|
</p>
|
|
<p className="text-sm text-gray-500">
|
|
{review.location}
|
|
</p>
|
|
</div>
|
|
<p className="text-sm text-gray-800">
|
|
{review.description}
|
|
</p>
|
|
|
|
<div className="flex items-center">
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
<Star size={16} color="#EDC001" />
|
|
</div>
|
|
</div>
|
|
</SwiperSlide>
|
|
))}
|
|
</Swiper>
|
|
</div>
|
|
<Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogTrigger asChild>
|
|
<Button className="cursor-pointer">
|
|
{t('pages.home.sections.testimonial.button')}
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent className="!max-w-3xl">
|
|
<DialogHeader>
|
|
<DialogTitle>Give your testimonial</DialogTitle>
|
|
<DialogDescription></DialogDescription>
|
|
<form
|
|
className="grid gap-4"
|
|
onSubmit={handleSubmit}
|
|
method="POST"
|
|
>
|
|
<div className="grid gap-3">
|
|
<Label htmlFor="name">Name</Label>
|
|
<Input
|
|
id="name"
|
|
name="name"
|
|
placeholder="Enter your name"
|
|
value={data.name}
|
|
onChange={(e) =>
|
|
setData('name', e.target.value)
|
|
}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-3">
|
|
<Label htmlFor="company">Location</Label>
|
|
<Input
|
|
id="company"
|
|
name="location"
|
|
placeholder="Enter you location (e.g. Private Company / Country Name)"
|
|
value={data.location}
|
|
onChange={(e) =>
|
|
setData('location', e.target.value)
|
|
}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-3">
|
|
<Label htmlFor="review">Description</Label>
|
|
<Textarea
|
|
id="review"
|
|
name="review"
|
|
cols={20}
|
|
placeholder="Write your review..."
|
|
value={data.description}
|
|
onChange={(e) =>
|
|
setData(
|
|
'description',
|
|
e.target.value,
|
|
)
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid gap-3">
|
|
<Label>Image</Label>
|
|
<FilePond
|
|
files={file ? [file] : []}
|
|
onupdatefiles={(fileItems) => {
|
|
setFile(fileItems[0] || null);
|
|
}}
|
|
allowMultiple={false}
|
|
maxFiles={1}
|
|
name="image"
|
|
instantUpload={false}
|
|
storeAsFile={true}
|
|
labelIdle='Drag & Drop your image or <span class="filepond--label-action">Browse</span>'
|
|
/>
|
|
{errors.image && (
|
|
<span className="text-red-600">
|
|
{errors.image}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
disabled={processing}
|
|
className="cursor-pointer"
|
|
>
|
|
{processing
|
|
? 'Submitting...'
|
|
: 'Submit Now'}
|
|
</Button>
|
|
</form>
|
|
</DialogHeader>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|