medora-provider/lib/screens/patient_screens/appoinment_bookings/speciality_screen.dart
Jipson George b1ae31c7dd feature/medora-116 (#7)
fixed bugs from qa test

Co-authored-by: Jipson George <152465898+Jipson-cosq@users.noreply.github.com>
Co-authored-by: DhanshCOSQ <dhanshas@cosq.net>
Reviewed-on: cosqnet/telemednet#7
Co-authored-by: Jipson George <jipsongeorge@cosq.net>
Co-committed-by: Jipson George <jipsongeorge@cosq.net>
2024-11-05 09:25:52 +00:00

427 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:animate_do/animate_do.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:medora/route/route_names.dart';
class Specialty {
final String name;
final IconData icon;
final Color color;
final String description;
Specialty({
required this.name,
required this.icon,
required this.color,
required this.description,
});
}
class SpecialtyScreen extends StatefulWidget {
const SpecialtyScreen({super.key});
@override
State<SpecialtyScreen> createState() => _SpecialtyScreenState();
}
class _SpecialtyScreenState extends State<SpecialtyScreen> {
final List<Specialty> _allSpecialties = [
Specialty(
name: 'Pediatric',
icon: Icons.child_care,
color: Colors.blue,
description: 'Medical care for infants, children, and adolescents',
),
Specialty(
name: 'General Medicine',
icon: Icons.medical_services,
color: Colors.green,
description:
'Primary healthcare for adults and general medical conditions',
),
Specialty(
name: 'Family Medicine',
icon: Icons.family_restroom,
color: Colors.teal,
description: 'Comprehensive healthcare for families and individuals',
),
Specialty(
name: 'Cardiologist',
icon: Icons.favorite,
color: Colors.red,
description: 'Diagnosis and treatment of heart conditions',
),
Specialty(
name: 'Neurology',
icon: Icons.psychology,
color: Colors.purple,
description: 'Treatment of nervous system disorders',
),
Specialty(
name: 'Gastroenterology',
icon: Icons.local_hospital,
color: Colors.orange,
description: 'Digestive system disorders and treatment',
),
Specialty(
name: 'Dermatologist',
icon: Icons.face,
color: Colors.pink,
description: 'Skin, hair, and nail conditions',
),
Specialty(
name: 'Orthopedic',
icon: Icons.wheelchair_pickup,
color: Colors.indigo,
description: 'Musculoskeletal system and injury treatment',
),
Specialty(
name: 'Ophthalmology',
icon: Icons.remove_red_eye,
color: Colors.brown,
description: 'Eye care and vision treatment',
),
Specialty(
name: 'ENT',
icon: Icons.hearing,
color: Colors.cyan,
description: 'Ear, nose, and throat specialist',
),
Specialty(
name: 'Psychiatry',
icon: Icons.psychology_outlined,
color: Colors.deepPurple,
description: 'Mental health and behavioral disorders',
),
Specialty(
name: 'Gynecology',
icon: Icons.pregnant_woman,
color: Colors.pinkAccent,
description: "Women's health and reproductive care",
),
Specialty(
name: 'Urology',
icon: Icons.water_drop,
color: Colors.lightBlue,
description: 'Urinary tract and male reproductive health',
),
Specialty(
name: 'Endocrinology',
icon: Icons.biotech,
color: Colors.amber,
description: 'Hormone and metabolic disorders',
),
Specialty(
name: 'Oncology',
icon: Icons.bloodtype,
color: Colors.redAccent,
description: 'Cancer diagnosis and treatment',
),
Specialty(
name: 'Rheumatology',
icon: Icons.accessibility,
color: Colors.deepOrange,
description: 'Arthritis and autoimmune conditions',
),
Specialty(
name: 'Pulmonology',
icon: Icons.air,
color: Colors.lightGreen,
description: 'Respiratory system disorders',
),
Specialty(
name: 'Nephrology',
icon: Icons.water,
color: Colors.blueGrey,
description: 'Kidney diseases and disorders',
),
Specialty(
name: 'Dentistry',
icon: Icons.cleaning_services,
color: Colors.cyan,
description: 'Oral health and dental care',
),
Specialty(
name: 'Physical Therapy',
icon: Icons.accessibility_new,
color: Colors.deepPurple,
description: 'Rehabilitation and physical medicine',
),
Specialty(
name: 'Sports Medicine',
icon: Icons.sports,
color: Colors.green,
description: 'Athletic injuries and performance',
),
Specialty(
name: 'Allergy & Immunology',
icon: Icons.sick,
color: Colors.orange,
description: 'Allergies and immune system disorders',
),
Specialty(
name: 'Pain Management',
icon: Icons.healing,
color: Colors.red,
description: 'Chronic pain treatment',
),
Specialty(
name: 'Sleep Medicine',
icon: Icons.bedtime,
color: Colors.indigo,
description: 'Sleep disorders and treatment',
),
Specialty(
name: 'Geriatrics',
icon: Icons.elderly,
color: Colors.brown,
description: 'Healthcare for elderly patients',
),
];
late List<Specialty> _filteredSpecialties;
final TextEditingController _searchController = TextEditingController();
bool _isSearching = false;
@override
void initState() {
super.initState();
_filteredSpecialties = _allSpecialties;
_searchController.addListener(_onSearchChanged);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
void _onSearchChanged() {
final searchQuery = _searchController.text.toLowerCase();
setState(() {
_isSearching = searchQuery.isNotEmpty;
_filteredSpecialties = _allSpecialties
.where((specialty) =>
specialty.name.toLowerCase().contains(searchQuery) ||
specialty.description.toLowerCase().contains(searchQuery))
.toList();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF5F7FF),
body: CustomScrollView(
slivers: [
_buildSliverAppBar(),
SliverToBoxAdapter(
child: _buildSearchBar(),
),
SliverPadding(
padding: const EdgeInsets.all(16),
sliver: _buildSpecialtiesGrid(),
),
],
),
);
}
Widget _buildSliverAppBar() {
return SliverAppBar(
expandedHeight: 55,
floating: true,
pinned: true,
stretch: true,
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black87),
onPressed: () => Navigator.pop(context),
),
flexibleSpace: FlexibleSpaceBar(
title: Text(
'Find a Specialist',
style: GoogleFonts.poppins(
color: Colors.black87,
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
centerTitle: true,
),
);
}
Widget _buildSearchBar() {
return FadeIn(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: 'Search specialties...',
hintStyle: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 14,
),
prefixIcon: const Icon(Icons.search, color: Colors.grey),
suffixIcon: _isSearching
? IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_searchController.clear();
FocusScope.of(context).unfocus();
},
)
: null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.white,
),
),
),
),
);
}
Widget _buildSpecialtiesGrid() {
return SliverAnimationBuilder(
child: MasonryGridView.count(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _filteredSpecialties.length,
itemBuilder: (context, index) {
final specialty = _filteredSpecialties[index];
return FadeInUp(
delay: Duration(milliseconds: 100 * index),
child: _buildSpecialtyCard(specialty),
);
},
),
);
}
Widget _buildSpecialtyCard(Specialty specialty) {
return GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
RouteNames.doctorListScreen,
arguments: {
'specialty': specialty.name,
},
);
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: specialty.color.withOpacity(0.1),
blurRadius: 20,
offset: const Offset(0, 5),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
Positioned(
right: -20,
top: -20,
child: CircleAvatar(
radius: 40,
backgroundColor: specialty.color.withOpacity(0.1),
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: specialty.color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
specialty.icon,
color: specialty.color,
size: 28,
),
),
const SizedBox(height: 16),
Text(
specialty.name,
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
const SizedBox(height: 8),
Text(
specialty.description,
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.grey[600],
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
),
),
);
}
}
class SliverAnimationBuilder extends StatelessWidget {
final Widget child;
const SliverAnimationBuilder({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
return SliverAnimatedList(
initialItemCount: 1,
itemBuilder: (context, index, animation) {
return SlideInUp(
from: 50,
child: child,
);
},
);
}
}