Show event information in bottom modal
This commit is contained in:
parent
17350d798d
commit
7ca45d2f70
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:furman_now/src/utils/date_range.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/header.dart';
|
||||
import 'package:furman_now/src/widgets/home/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:furman_now/src/utils/greeting.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/header.dart';
|
||||
import 'package:furman_now/src/widgets/home/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/home/restaurants/restaurants_list.dart';
|
||||
import 'package:furman_now/src/widgets/home/transportation/transportation_card.dart';
|
||||
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
||||
|
|
|
@ -8,6 +8,16 @@ ThemeData _baseTheme = ThemeData(
|
|||
unselectedItemColor: Colors.grey[500],
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
headline1: TextStyle(
|
||||
color: Colors.grey[800],
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 22,
|
||||
),
|
||||
subtitle1: TextStyle(
|
||||
color: Colors.grey[500],
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
),
|
||||
subtitle2: TextStyle(
|
||||
color: Colors.grey[500],
|
||||
fontWeight: FontWeight.w500,
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/events/event_modal.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class EventCard extends StatelessWidget {
|
||||
const EventCard
|
||||
(
|
||||
this.event,
|
||||
{
|
||||
Key? key
|
||||
}
|
||||
) : super(key: key);
|
||||
|
||||
final Event event;
|
||||
|
||||
String get eventHour {
|
||||
var formatter = DateFormat('hh:mm');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
String get eventAmPm {
|
||||
var formatter = DateFormat('a');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
showEventsModal(
|
||||
context,
|
||||
event,
|
||||
);
|
||||
// showModalBottomSheet<void>(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) {
|
||||
// return EventModal(event: event);
|
||||
// }
|
||||
// );
|
||||
},
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xfff9f9fb),
|
||||
borderRadius: BorderRadius.all(Radius.circular(10))
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(eventHour, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w700))),
|
||||
Text(eventAmPm, style: Theme.of(context).textTheme.subtitle2),
|
||||
],
|
||||
),
|
||||
),
|
||||
VerticalDivider(
|
||||
width: 2,
|
||||
thickness: 2,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(event.title, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w600))),
|
||||
const SizedBox(height: 6),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: Icon(Icons.place_outlined, size: 20, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.location),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 2),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 1.0, right: 6.0),
|
||||
child: Icon(Icons.sell_outlined, size: 18, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.category),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:furman_now/src/services/events/events_service.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
void showEventsModal(BuildContext context, Event event) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return _EventModal(event: event);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class _EventModal extends StatefulWidget {
|
||||
final Event event;
|
||||
|
||||
const _EventModal({
|
||||
required this.event,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<_EventModal> createState() => _EventModalState();
|
||||
}
|
||||
|
||||
class _EventModalState extends State<_EventModal> {
|
||||
var childSize = Size.zero;
|
||||
BoxConstraints? _parentConstraints;
|
||||
final _key = GlobalKey();
|
||||
|
||||
double _maxChildHeight = 0.75;
|
||||
|
||||
void updateMaxHeight() {
|
||||
if (_parentConstraints != null) {
|
||||
print(_key.currentContext?.size?.height);
|
||||
var listHeight = _key.currentContext?.size?.height;
|
||||
var parentHeight = _parentConstraints?.maxHeight;
|
||||
if (listHeight != null && parentHeight != null) {
|
||||
setState(() {
|
||||
_maxChildHeight = (listHeight + 150) / parentHeight;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => updateMaxHeight());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
child: Container(
|
||||
color: const Color.fromRGBO(0, 0, 0, 0.001),
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
_parentConstraints = constraints;
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: DraggableScrollableSheet(
|
||||
initialChildSize: _maxChildHeight,
|
||||
minChildSize: 0.1,
|
||||
maxChildSize: _maxChildHeight,
|
||||
builder: (_, controller) {
|
||||
return Container(
|
||||
color: Colors.grey.shade100,
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: kBottomNavigationBarHeight),
|
||||
child: Column(
|
||||
children: [
|
||||
const Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: CloseButton(),
|
||||
),
|
||||
Flexible(
|
||||
child: NotificationListener<OverscrollIndicatorNotification>(
|
||||
onNotification: (OverscrollIndicatorNotification overscroll) {
|
||||
overscroll.disallowIndicator();
|
||||
return true;
|
||||
},
|
||||
child: _EventModalContent(
|
||||
key: _key,
|
||||
controller: controller,
|
||||
event: widget.event,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _EventModalContent extends StatelessWidget {
|
||||
final ScrollController controller;
|
||||
final Event event;
|
||||
|
||||
const _EventModalContent({
|
||||
required this.controller,
|
||||
required this.event,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||
controller: controller,
|
||||
children: <Widget>[
|
||||
// Title
|
||||
Text(
|
||||
event.title,
|
||||
style: Theme.of(context).textTheme.headline1,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// Location
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: Icon(
|
||||
Icons.place_outlined, size: 24,
|
||||
color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.location),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 5),
|
||||
if (event is ClpEvent) ...[
|
||||
// Organization
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: Icon(
|
||||
Icons.group_outlined,
|
||||
size: 24,
|
||||
color: Colors.grey[500]
|
||||
),
|
||||
),
|
||||
),
|
||||
TextSpan(text: (event as ClpEvent).organization),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 5),
|
||||
// Time
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 5.0),
|
||||
child: Icon(
|
||||
Icons.access_time_outlined,
|
||||
size: 24,
|
||||
color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.top,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat("EEEE, MMMM d")
|
||||
.format(
|
||||
(event as ClpEvent)
|
||||
.startTime),
|
||||
style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.subtitle1,
|
||||
),
|
||||
Text(
|
||||
"${DateFormat.jm().format(
|
||||
(event as ClpEvent)
|
||||
.startTime)} - ${DateFormat
|
||||
.jm().format(
|
||||
(event as ClpEvent)
|
||||
.endTime)}",
|
||||
style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.subtitle1,
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 5),
|
||||
// Description
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 5.0),
|
||||
child: Icon(Icons.notes, size: 24,
|
||||
color: Colors
|
||||
.grey[500])
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
(event as ClpEvent)
|
||||
.description,
|
||||
style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.subtitle1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class EventCard extends StatelessWidget {
|
||||
const EventCard
|
||||
(
|
||||
this.event,
|
||||
{
|
||||
Key? key
|
||||
}
|
||||
) : super(key: key);
|
||||
|
||||
final Event event;
|
||||
|
||||
String get eventHour {
|
||||
var formatter = DateFormat('hh:mm');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
String get eventAmPm {
|
||||
var formatter = DateFormat('a');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xfff9f9fb),
|
||||
borderRadius: BorderRadius.all(Radius.circular(10))
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(eventHour, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w700))),
|
||||
Text(eventAmPm, style: Theme.of(context).textTheme.subtitle2),
|
||||
],
|
||||
),
|
||||
),
|
||||
VerticalDivider(
|
||||
width: 2,
|
||||
thickness: 2,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(event.title, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w600))),
|
||||
const SizedBox(height: 6),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: Icon(Icons.place_outlined, size: 20, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.location),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 2),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 1.0, right: 6.0),
|
||||
child: Icon(Icons.sell_outlined, size: 18, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.category),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue