import 'package:carousel_slider/carousel_slider.dart';
import 'package:chipin_blogpost/features/authentication/services/auth_service.dart';
import 'package:chipin_blogpost/features/authentication/views/auth_main_view.dart';
import 'package:chipin_blogpost/features/events/models/event_model.dart';
import 'package:chipin_blogpost/features/events/services/event_service.dart';
import 'package:chipin_blogpost/features/events/views/create_events.dart';
import 'package:chipin_blogpost/features/events/views/created_events.dart';
import 'package:chipin_blogpost/features/events/views/join_events.dart';
import 'package:chipin_blogpost/features/events/views/joined_events.dart';
import 'package:chipin_blogpost/features/events/widgets/event_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class HomePageLayout extends StatelessWidget {
const HomePageLayout({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 15.0),
Expanded(
child: FutureBuilder<List<MyEventModel>>(
future: EventService.getAllEvents(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final events = snapshot.data!;
if (events.isEmpty) {
return const Center(
child: Text('No events to display'),
);
}
return CarouselSlider.builder(
itemCount: events.length,
itemBuilder: (context, index, _) {
return EventCard(event: events[index]);
},
options: CarouselOptions(
height: 685,
viewportFraction: 0.8,
enlargeCenterPage: true,
enableInfiniteScroll: true,
autoPlay: true,
autoPlayInterval: const Duration(seconds: 2),
autoPlayCurve: Curves.fastOutSlowIn,
),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return const CircularProgressIndicator();
}
},
),
),
],
);
}
}
class _HomePageState extends State<HomePage> {
int _selectedIndex = 0;
final List<Widget> _widgetOptions = <Widget>[
const HomePageLayout(),
MyJoinedEventsScreen(eventService: EventService()),
MyCreatedEventsScreen(eventService: EventService()),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: FutureBuilder<String>(
future: AuthService.getUserName(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final userName = snapshot.data!;
return Text('Welcome, $userName!');
} else {
return const Text('Home Page');
}
},
),
actions: [
PopupMenuButton(
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem(
value: 'logout',
child: Text('Logout'),
),
];
},
onSelected: (value) async {
if (value == 'logout') {
await AuthService.logout();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => const AuthMainView(),
),
(route) => false,
);
}
},
),
],
),
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: 'Joined Events',
),
BottomNavigationBarItem(
icon: Icon(Icons.event),
label: 'My Events',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
floatingActionButton: SpeedDial(
animatedIcon: AnimatedIcons.menu_close,
visible: true,
curve: Curves.bounceIn,
children: [
SpeedDialChild(
child: const Icon(Icons.add),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EventCreationScreen(
eventService: EventService(),
),
),
);
},
label: 'Create Event',
),
SpeedDialChild(
child: const Icon(Icons.arrow_upward),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => JoinEventsScreen(
eventService: EventService(),
),
),
);
},
label: 'Join Events',
),
],
),
);
}
}
Importing Packages:
The code starts by importing necessary packages required for the code to work correctly. These packages include:
chipin_blogpost/features/events/models/event_model.dart
: Contains the event model definition.chipin_blogpost/features/events/views/event_details.dart
: Contains the screen for displaying event details.flutter/material.dart
: Provides widgets and classes for building user interfaces.intl/intl.dart
: Provides date and time formatting capabilities.Defining the EventCard Widget:
The EventCard
class is declared as a stateless widget using the class
keyword. It represents a card that displays event information. It takes several parameters including event
, showJoinButton
, and onJoinPressed
.
build() Method:
The build
method is responsible for building the widget tree that represents the UI of the card. It takes a BuildContext
object as a parameter, representing the context in which the widget is being built. The method returns a GestureDetector
widget, which detects gestures on its child and triggers the specified actions.
Formatting Date and Time:
Two DateFormat
instances are created: formattedDate
and formattedTime
. They are used to format the event's date and time, respectively, according to specified patterns.
GestureDetector:
The onTap
property of the GestureDetector
widget is set to a function that navigates to the event details screen when the card is tapped. It uses the Navigator.push
method to navigate to the EventDetailsScreen
, passing the current event as a parameter.
Container:
A Container
widget is used as the outermost widget of the card. It provides margin, decoration, and constraints to the card.
Image.network:
An Image.network
widget is used to display the event image. It loads the image from the specified URL and uses BoxFit.cover
to fit the image within its container.
Padding and Column:
A Padding
widget is used to add padding around the content within the card. Inside the Padding
, a Column
widget is used to arrange the various components vertically.
Displaying Event Information:
Text
widget with specific styling properties. The overflow
and maxLines
properties are used to handle text overflow and limit the number of lines to two.Row
widget, with an icon and the formatted date and time text.Row
widget, showing an icon and the creator's ID.Row
widget, showing an icon and the description text. The Expanded
widget is used to allow the description text to take up the available horizontal space.Join Button (optional):
If the showJoinButton
parameter is set to true, an ElevatedButton
widget is displayed. The button's label is set to "Join" and its onPressed
property is set to the onJoinPressed
callback. When the button is pressed, the onJoinPressed
function, provided as a parameter, will be executed.