refactor: Consolidate testimonial display into a single sortable list with dynamic sorting, replacing separate latest and oldest sections.
This commit is contained in:
@@ -52,20 +52,16 @@ function TestimonialCard({ testimonial }: { testimonial: Testimonial }) {
|
|||||||
export function TestimonialsForm() {
|
export function TestimonialsForm() {
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
const [testimonialLink, setTestimonialLink] = useState('');
|
const [testimonialLink, setTestimonialLink] = useState('');
|
||||||
const [latestTestimonials, setLatestTestimonials] = useState<Testimonial[]>([]);
|
const [testimonials, setTestimonials] = useState<Testimonial[]>([]);
|
||||||
const [oldestTestimonials, setOldestTestimonials] = useState<Testimonial[]>([]);
|
const [sortOrder, setSortOrder] = useState<'latest' | 'oldest'>('latest');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [generating, setGenerating] = useState(false);
|
const [generating, setGenerating] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchTestimonials = async (sort: 'latest' | 'oldest') => {
|
||||||
const fetchTestimonials = async () => {
|
|
||||||
try {
|
try {
|
||||||
const [latest, oldest] = await Promise.all([
|
setLoading(true);
|
||||||
testimonialsService.getMyTestimonials('latest'),
|
const data = await testimonialsService.getMyTestimonials(sort);
|
||||||
testimonialsService.getMyTestimonials('oldest'),
|
setTestimonials(data);
|
||||||
]);
|
|
||||||
setLatestTestimonials(latest);
|
|
||||||
setOldestTestimonials(oldest);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch testimonials:', err);
|
console.error('Failed to fetch testimonials:', err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -73,8 +69,9 @@ export function TestimonialsForm() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchTestimonials();
|
useEffect(() => {
|
||||||
}, []);
|
fetchTestimonials(sortOrder);
|
||||||
|
}, [sortOrder]);
|
||||||
|
|
||||||
const handleGenerateLink = async () => {
|
const handleGenerateLink = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -156,12 +153,12 @@ export function TestimonialsForm() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Testimonials Columns */}
|
{/* Testimonials */}
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="flex items-center justify-center py-12">
|
<div className="flex items-center justify-center py-12">
|
||||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#E58625]"></div>
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#E58625]"></div>
|
||||||
</div>
|
</div>
|
||||||
) : latestTestimonials.length === 0 ? (
|
) : testimonials.length === 0 ? (
|
||||||
<div className="text-center py-12 bg-[#d9d9d9]/25 rounded-[7px]">
|
<div className="text-center py-12 bg-[#d9d9d9]/25 rounded-[7px]">
|
||||||
<p className="font-fractul font-medium text-[16px] text-[#00293D]/60">
|
<p className="font-fractul font-medium text-[16px] text-[#00293D]/60">
|
||||||
No testimonials yet
|
No testimonials yet
|
||||||
@@ -171,47 +168,28 @@ export function TestimonialsForm() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col lg:flex-row gap-4">
|
<div className="bg-[#d9d9d9]/25 rounded-[7px] p-5">
|
||||||
{/* Latest Column */}
|
<button
|
||||||
<div className="flex-1 bg-[#d9d9d9]/25 rounded-[7px] p-5">
|
onClick={() => setSortOrder(sortOrder === 'latest' ? 'oldest' : 'latest')}
|
||||||
<div className="flex items-center gap-1 mb-4">
|
className="flex items-center gap-1 mb-4 hover:opacity-70 transition-opacity"
|
||||||
|
>
|
||||||
<span className="font-fractul font-medium text-[14px] text-black">
|
<span className="font-fractul font-medium text-[14px] text-black">
|
||||||
Sort By : Latest
|
Sort By : {sortOrder === 'latest' ? 'Latest' : 'Oldest'}
|
||||||
</span>
|
</span>
|
||||||
<Image
|
<Image
|
||||||
src="/assets/icons/sort-arrow-down-icon.svg"
|
src="/assets/icons/sort-arrow-down-icon.svg"
|
||||||
alt=""
|
alt=""
|
||||||
width={14}
|
width={14}
|
||||||
height={14}
|
height={14}
|
||||||
|
className={sortOrder === 'oldest' ? 'rotate-180' : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</button>
|
||||||
<div className="space-y-4 max-h-[500px] overflow-y-auto pr-1 custom-scrollbar">
|
<div className="space-y-4 max-h-[600px] overflow-y-auto pr-1 custom-scrollbar">
|
||||||
{latestTestimonials.map((testimonial) => (
|
{testimonials.map((testimonial) => (
|
||||||
<TestimonialCard key={testimonial.id} testimonial={testimonial} />
|
<TestimonialCard key={testimonial.id} testimonial={testimonial} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Oldest Column */}
|
|
||||||
<div className="flex-1 bg-[#d9d9d9]/25 rounded-[7px] p-5">
|
|
||||||
<div className="flex items-center gap-1 mb-4">
|
|
||||||
<span className="font-fractul font-medium text-[14px] text-black">
|
|
||||||
Sort By : Oldest
|
|
||||||
</span>
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/sort-arrow-down-icon.svg"
|
|
||||||
alt=""
|
|
||||||
width={14}
|
|
||||||
height={14}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-4 max-h-[500px] overflow-y-auto pr-1 custom-scrollbar">
|
|
||||||
{oldestTestimonials.map((testimonial) => (
|
|
||||||
<TestimonialCard key={testimonial.id} testimonial={testimonial} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Custom scrollbar styles */}
|
{/* Custom scrollbar styles */}
|
||||||
|
|||||||
Reference in New Issue
Block a user