211 lines
7.2 KiB
Dart
211 lines
7.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:real_estate_mobile/core/constants/app_colors.dart';
|
|
import 'package:real_estate_mobile/features/home/data/models/landing_page_content.dart';
|
|
import 'package:real_estate_mobile/features/home/presentation/providers/home_provider.dart';
|
|
|
|
/// Default testimonials — matches web's hardcoded defaultTestimonials fallback.
|
|
const _defaultTestimonials = [
|
|
TestimonialItem(
|
|
rating: 5,
|
|
title: 'I have been working with Lorem ..',
|
|
content:
|
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisl eget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc. Integer sed arcu vitae risus feugiat vehicula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.',
|
|
author: 'Conor Kenney',
|
|
role: 'Chief Operations Officer',
|
|
),
|
|
TestimonialItem(
|
|
rating: 5,
|
|
title: 'I have been working with Lorem ..',
|
|
content:
|
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisl eget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc. Integer sed arcu vitae risus feugiat vehicula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.',
|
|
author: 'Conor Kenney',
|
|
role: 'Chief Operations Officer',
|
|
),
|
|
TestimonialItem(
|
|
rating: 5,
|
|
title: 'I have been working with Lorem ..',
|
|
content:
|
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisl eget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc. Integer sed arcu vitae risus feugiat vehicula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.',
|
|
author: 'Conor Kenney',
|
|
role: 'Chief Operations Officer',
|
|
),
|
|
];
|
|
|
|
/// Default section content — matches web's hardcoded defaultContent fallback.
|
|
const _defaultContent = TestimonialsContent(
|
|
title: "Our Clients' Trust Is Our Foundation",
|
|
subtitle:
|
|
'We help buyers, sellers, and investors close successful real estate deals with confidence in every transaction.',
|
|
ratingInfo:
|
|
'Clients rate our real estate services 4.9 out of 5 on average, based on recent client reviews.',
|
|
stats: [
|
|
StatItem(
|
|
iconPath: 'cities',
|
|
boldText: '25+ Cities &',
|
|
normalText: 'neighborhoods served',
|
|
),
|
|
StatItem(
|
|
iconPath: 'properties',
|
|
boldText: '1,000+ Properties',
|
|
normalText: 'bought and sold for our clients.',
|
|
),
|
|
],
|
|
testimonials: _defaultTestimonials,
|
|
);
|
|
|
|
class TestimonialsSection extends ConsumerWidget {
|
|
const TestimonialsSection({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final homeState = ref.watch(homeProvider);
|
|
final cmsTestimonials = homeState.content?.testimonials;
|
|
|
|
// Use CMS data if available with non-empty testimonials, otherwise fallback
|
|
final data =
|
|
(cmsTestimonials != null && cmsTestimonials.testimonials.isNotEmpty)
|
|
? cmsTestimonials
|
|
: _defaultContent;
|
|
|
|
final title = data.title.isNotEmpty ? data.title : _defaultContent.title;
|
|
final subtitle =
|
|
data.subtitle.isNotEmpty ? data.subtitle : _defaultContent.subtitle;
|
|
final testimonials =
|
|
data.testimonials.isNotEmpty ? data.testimonials : _defaultTestimonials;
|
|
|
|
return Column(
|
|
children: [
|
|
// Section header
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
child: Column(
|
|
children: [
|
|
Text(
|
|
title,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(
|
|
fontFamily: 'Fractul',
|
|
fontSize: 25,
|
|
fontWeight: FontWeight.w700,
|
|
color: AppColors.primaryDark,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
subtitle,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(
|
|
fontFamily: 'SourceSerif4',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w400,
|
|
color: AppColors.primaryDark,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// Testimonial cards carousel
|
|
SizedBox(
|
|
height: 380,
|
|
child: ListView.builder(
|
|
scrollDirection: Axis.horizontal,
|
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
itemCount: testimonials.length,
|
|
itemBuilder: (context, index) => Padding(
|
|
padding: const EdgeInsets.only(right: 16),
|
|
child: _buildTestimonialCard(testimonials[index]),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildTestimonialCard(TestimonialItem testimonial) {
|
|
return Container(
|
|
width: 315,
|
|
padding: const EdgeInsets.all(24),
|
|
decoration: BoxDecoration(
|
|
color: AppColors.primaryDark,
|
|
borderRadius: BorderRadius.circular(15),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Quote icon
|
|
const Text(
|
|
'\u201C',
|
|
style: TextStyle(
|
|
fontFamily: 'SourceSerif4',
|
|
fontSize: 48,
|
|
fontWeight: FontWeight.w700,
|
|
color: AppColors.accentOrange,
|
|
height: 0.8,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
testimonial.title,
|
|
style: const TextStyle(
|
|
fontFamily: 'Fractul',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w700,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
Expanded(
|
|
child: Text(
|
|
testimonial.content,
|
|
style: const TextStyle(
|
|
fontFamily: 'SourceSerif4',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w400,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
// Stars
|
|
Row(
|
|
children: List.generate(
|
|
testimonial.rating,
|
|
(index) => const Padding(
|
|
padding: EdgeInsets.only(right: 4),
|
|
child: Icon(
|
|
Icons.star,
|
|
color: AppColors.accentOrange,
|
|
size: 18,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
// Author info
|
|
Text(
|
|
testimonial.author,
|
|
style: const TextStyle(
|
|
fontFamily: 'SourceSerif4',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
Text(
|
|
testimonial.role,
|
|
style: const TextStyle(
|
|
fontFamily: 'SourceSerif4',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|