wip: info page and GET app login / settings

This commit is contained in:
2022-11-18 15:56:37 -05:00
parent 4a698e61d2
commit 67efdc0289
24 changed files with 1461 additions and 355 deletions

View File

@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.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';
@@ -11,98 +13,56 @@ class EventsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.grey[100],
child: SafeArea(
child: Stack(
fit: StackFit.loose,
children: [
SizedBox(
width: double.infinity,
height: double.infinity,
child: Align(
alignment: Alignment.topLeft,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 30),
width: double.infinity,
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Icon(Icons.calendar_month_outlined, size: 35, color: Colors.grey[700]),
const SizedBox(width: 12),
Text("Events", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
],
),
],
),
return AppPageLayout(
title: "Events",
icon: FlutterRemix.calendar_line,
content: Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const HeaderWidget(title: "Today"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList()
),
const HeaderWidget(title: "Tomorrow"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList(dateRange: constructDateRange(
DateTime.now().add(const Duration(days: 1)),
DateTime.now().add(const Duration(days: 1)),
)),
),
...[for(var i=2; i<7; i+=1) i].map((i) {
var date = DateTime.now().add(Duration(days: i));
var dayName = DateFormat('EEEE').format(date);
return Wrap(
children: [
HeaderWidget(title: dayName),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList(dateRange: constructDateRange(
date,
date,
)),
),
),
),
ScrollViewWithHeight(
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
),
padding: const EdgeInsets.symmetric(vertical: 20),
margin: const EdgeInsets.only(top: 100),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const HeaderWidget(title: "Today"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList()
),
const HeaderWidget(title: "Tomorrow"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList(dateRange: constructDateRange(
DateTime.now().add(const Duration(days: 1)),
DateTime.now().add(const Duration(days: 1)),
)),
),
...[for(var i=2; i<7; i+=1) i].map((i) {
var date = DateTime.now().add(Duration(days: i));
var dayName = DateFormat('EEEE').format(date);
return Wrap(
children: [
HeaderWidget(title: dayName),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: EventsList(dateRange: constructDateRange(
date,
date,
)),
),
],
);
}),
Center(child:
Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.center,
children: const [
Text("Need more events?"),
Text("Syncdin"),
Text("Athletics"),
Text("CLPs"),
],
),
),
],
),
),
),
],
),
],
);
}),
Center(child:
Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.center,
children: const [
Text("Need more events?"),
Text("Syncdin"),
Text("Athletics"),
Text("CLPs"),
],
),
),
],
),
),
);

View File

@@ -0,0 +1,63 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.dart';
import 'package:furman_now/src/services/info/contacts_service.dart';
import 'package:furman_now/src/widgets/info/info_card.dart';
class ContactsScreen extends StatelessWidget {
const ContactsScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return AppPageLayout(
title: "Contacts",
icon: FlutterRemix.arrow_left_line,
backgroundColor: Colors.deepPurple.shade50,
iconTapAction: () => context.router.pop(),
content: Padding(
padding: const EdgeInsets.all(20),
child: FutureBuilder<Iterable<ContactInfo>>(
future: ContactsService.fetchContactInfo(),
builder: (context, snapshot) {
if (snapshot.hasData) {
var items = snapshot.data!;
return Column(
children: items.map((item) {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: InfoCard(
title: item.name,
icon: item.buildingId != 0
? FlutterRemix.building_line
: FlutterRemix.contacts_line,
items: [
InfoCardItem(
name: item.phone,
icon: FlutterRemix.phone_line
),
],
onClick: () => item.launch(),
),
);
}).toList());
}
else if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: const TextStyle(color: Colors.red)
);
}
// By default, show a loading spinner.
return const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 25),
child: CircularProgressIndicator()
),
);
},
),
)
);
}
}

View File

@@ -0,0 +1,82 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.dart';
import 'package:furman_now/src/services/info/health_safety_service.dart';
import 'package:furman_now/src/widgets/info/info_card.dart';
class HealthSafetyScreen extends StatelessWidget {
const HealthSafetyScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return AppPageLayout(
title: "Health and Safety",
icon: FlutterRemix.arrow_left_line,
backgroundColor: Colors.red.shade50,
iconTapAction: () => context.router.pop(),
content: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Padding(
padding: const EdgeInsets.only(top: 15, bottom: 35),
child: Text(
"If you are in an emergency, dial 911",
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.red.shade800,
),
),
),
),
FutureBuilder<Iterable<HealthSafetyInfo>>(
future: HealthSafetyService.fetchHealthSafetyInfo(),
builder: (context, snapshot) {
if (snapshot.hasData) {
var items = snapshot.data!.where((item) =>
item.type != HealthSafetyInfoType.removed
);
var iconMap = {
HealthSafetyInfoType.phone: FlutterRemix.phone_line,
HealthSafetyInfoType.link: FlutterRemix.external_link_line,
HealthSafetyInfoType.app: FlutterRemix.apps_line,
};
return Column(
children: items.map((item) {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: InfoCard(
title: item.name,
icon: item.icon,
items: [
InfoCardItem(
name: item.linkText,
icon: iconMap[item.type] ?? FlutterRemix.link
),
],
onClick: () => item.launch(),
),
);
}).toList());
}
else if (snapshot.hasError) {
return Text(
'${snapshot.error}', style: const TextStyle(color: Colors.red),);
}
// By default, show a loading spinner.
return const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 25),
child: CircularProgressIndicator()
),
);
},
),
],
),
)
);
}
}

View File

@@ -0,0 +1,72 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.dart';
import 'package:furman_now/src/services/buildings/buildings_service.dart';
import 'package:furman_now/src/store/index.dart';
import 'package:furman_now/src/widgets/info/info_card.dart';
import 'package:provider/provider.dart';
class HoursScreen extends StatelessWidget {
const HoursScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return AppPageLayout(
title: "Hours",
icon: FlutterRemix.arrow_left_line,
backgroundColor: Colors.blue.shade50,
iconTapAction: () => context.router.pop(),
content: Padding(
padding: const EdgeInsets.all(20),
child: Consumer<AppState>(
builder: (context, state, _) {
return FutureBuilder<Iterable<Building>>(
future: state.buildings,
builder: (context, snapshot) {
if (snapshot.hasData) {
var items = snapshot.data!.where(
(building) => building.hoursList.isNotEmpty
);
return Column(
children: items.map((item) {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: InfoCard(
title: item.name,
icon: FlutterRemix.building_line,
items: item.hoursList.map((hours) =>
InfoCardItem(
name: ""
"${hours.daysOfWeek} from "
"${hours.startTime.format(context)} - "
"${hours.endTime.format(context)}",
icon: FlutterRemix.time_line,
),
).toList(),
),
);
}).toList(),
);
}
else if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: const TextStyle(color: Colors.red),
);
}
// By default, show a loading spinner.
return const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 25),
child: CircularProgressIndicator()
),
);
},
);
}
),
),
);
}
}

View File

@@ -1,84 +1,64 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:furman_now/src/utils/theme.dart';
import 'package:furman_now/src/widgets/info/info_card.dart';
import 'package:furman_now/src/widgets/scroll_view_height.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.dart';
import 'package:furman_now/src/routes/index.gr.dart';
import 'package:furman_now/src/widgets/info/info_category_card.dart';
class InfoScreen extends StatelessWidget {
const InfoScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.grey[100],
child: SafeArea(
child: Stack(
fit: StackFit.loose,
children: [
SizedBox(
width: double.infinity,
height: double.infinity,
child: Align(
alignment: Alignment.topLeft,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 30),
width: double.infinity,
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Icon(Icons.info_outline, size: 35, color: Colors.grey[700]),
const SizedBox(width: 12),
Text("Info", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
],
),
],
),
),
),
return AppPageLayout(
title: "Info",
icon: FlutterRemix.information_line,
content: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () => context.router.push(const HealthSafetyRoute()),
child: InfoCategoryCard(
color: Colors.red.shade50,
icon: Icons.local_hospital,
title: "Health and Safety",
description: "Important contact information and links regarding student health and safety.",
),
ScrollViewWithHeight(
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
),
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
margin: const EdgeInsets.only(top: 100),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InfoCard(
color: Colors.red.shade50,
icon: Icons.local_hospital,
title: "Health and Safety",
description: "Important contact information and links regarding student health and safety.",
),
const SizedBox(height: 10),
InfoCard(
color: Colors.deepPurple.shade50,
icon: Icons.phone,
title: "Contacts",
description: "Important contact information and links regarding student health and safety.",
),
const SizedBox(height: 10),
InfoCard(
color: Colors.blue.shade50,
icon: Icons.access_time,
title: "Hours",
description: "Important contact information and links regarding student health and safety.",
),
],
),
),
),
const SizedBox(height: 10),
GestureDetector(
onTap: () => context.router.push(const ContactsRoute()),
child: InfoCategoryCard(
color: Colors.deepPurple.shade50,
icon: Icons.phone,
title: "Contacts",
description: "Contact information for offices and resources on Furman's campus.",
),
],
),
),
const SizedBox(height: 10),
GestureDetector(
onTap: () => context.router.push(const HoursRoute()),
child: InfoCategoryCard(
color: Colors.blue.shade50,
icon: Icons.access_time,
title: "Hours",
description: "Check the hours for buildings and services on Furman's campus.",
),
),
const SizedBox(height: 10),
const Spacer(),
GestureDetector(
onTap: () => context.router.push(const SettingsRoute()),
child: InfoCategoryCard(
color: Colors.grey.shade100,
icon: Icons.settings,
title: "Settings",
description: "Account settings, GET login, dark mode",
),
),
],
),
),
);

View File

@@ -0,0 +1,42 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_remix/flutter_remix.dart';
import 'package:furman_now/src/layouts/app_page.dart';
import 'package:furman_now/src/services/get_app/user/user_service.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({Key? key}) : super(key: key);
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
final UserService _service = UserService();
@override
Widget build(BuildContext context) {
return AppPageLayout(
title: "Settings",
icon: FlutterRemix.arrow_left_line,
backgroundColor: Colors.grey.shade100,
iconTapAction: () => context.router.pop(),
content: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
GestureDetector(
onTap: () {
_service.login();
},
child: Container(
padding: EdgeInsets.all(20),
child: Text("Log in with GET app."),
),
)
],
),
),
);
}
}