Initial commit
This commit is contained in:
113
lib/src/screens/events/index.dart
Normal file
113
lib/src/screens/events/index.dart
Normal file
@@ -0,0 +1,113 @@
|
||||
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/scroll_view_height.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class EventsScreen extends StatelessWidget {
|
||||
const EventsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: Colors.grey[100],
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
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))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
96
lib/src/screens/home/index.dart
Normal file
96
lib/src/screens/home/index.dart
Normal file
@@ -0,0 +1,96 @@
|
||||
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/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';
|
||||
|
||||
class HomeScreen extends StatelessWidget {
|
||||
const HomeScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
color: Colors.grey[100],
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: <Color>[
|
||||
Color(0xffb7acc9),
|
||||
Color(0xffb7acc9),
|
||||
], // Gradient from https://learnui.design/tools/gradient-generator.html
|
||||
tileMode: TileMode.mirror,
|
||||
),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(40),
|
||||
width: double.infinity,
|
||||
height: 200,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("${greeting()},\nMichael", style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 36, fontWeight: FontWeight.w800))),
|
||||
const SizedBox(height: 5),
|
||||
Text("It's 76º and partly cloudy", style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 16, fontWeight: FontWeight.w500))),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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: 200),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const HeaderWidget(
|
||||
title: "Today's Events",
|
||||
link: HeaderLink(text: "View more", href: ""),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: EventsList(),
|
||||
),
|
||||
const HeaderWidget(title: "Food & Dining"),
|
||||
const RestaurantsList(),
|
||||
const HeaderWidget(title: "Transportation"),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: TransportationCard(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
89
lib/src/screens/info/index.dart
Normal file
89
lib/src/screens/info/index.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
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';
|
||||
|
||||
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: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
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))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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.",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
187
lib/src/screens/map/index.dart
Normal file
187
lib/src/screens/map/index.dart
Normal file
@@ -0,0 +1,187 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/map/filter_chip.dart';
|
||||
import 'package:furman_now/src/widgets/map/rotate_compass.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
class MapScreen extends StatefulWidget {
|
||||
const MapScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MapScreen> createState() => _MapScreenState();
|
||||
}
|
||||
|
||||
class _MapScreenState extends State<MapScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final MapController _mapController = MapController();
|
||||
|
||||
late final AnimationController _animationController = AnimationController(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
var _rotation = 0.0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_mapController.mapEventStream.listen((event) {
|
||||
if (event is MapEventRotate) {
|
||||
setState(() {
|
||||
_rotation = _mapController.rotation * (2 * pi) / 360;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_animationController.dispose();
|
||||
}
|
||||
|
||||
void resetRotation() async {
|
||||
// take the shortest rotation path
|
||||
var end = _mapController.rotation > 180 ? 360.0 : 0.0;
|
||||
var animation = Tween<double>(
|
||||
begin: _mapController.rotation,
|
||||
end: end,
|
||||
).animate(CurvedAnimation(
|
||||
parent: _animationController,
|
||||
curve: Curves.easeInOut,
|
||||
));
|
||||
|
||||
animationListener() {
|
||||
_mapController.rotate(animation.value);
|
||||
}
|
||||
|
||||
animation.addListener(animationListener);
|
||||
|
||||
await _animationController.forward();
|
||||
|
||||
animation.removeListener(animationListener);
|
||||
_animationController.reset();
|
||||
|
||||
_mapController.rotate(0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
children: [
|
||||
FlutterMap(
|
||||
mapController: _mapController,
|
||||
options: MapOptions(
|
||||
center: LatLng(34.925926, -82.439397),
|
||||
enableMultiFingerGestureRace: true,
|
||||
rotationWinGestures: MultiFingerGesture.all,
|
||||
pinchZoomThreshold: 0.2,
|
||||
rotationThreshold: 8,
|
||||
zoom: 15,
|
||||
minZoom: 12,
|
||||
maxZoom: 18,
|
||||
),
|
||||
layers: [
|
||||
TileLayerOptions(
|
||||
urlTemplate:
|
||||
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
userAgentPackageName: 'edu.furman.now',
|
||||
),
|
||||
],
|
||||
nonRotatedChildren: [
|
||||
AttributionWidget(
|
||||
attributionBuilder: (BuildContext context) {
|
||||
return const ColoredBox(
|
||||
color: Color(0xCCFFFFFF),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(3),
|
||||
child: Text("©️ OpenStreetMap contributors"),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: 12,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
padding: const EdgeInsets.only(left: 10, right: 20),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(60)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x33000000),
|
||||
blurRadius: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/bell-tower.svg", color: Theme.of(context).primaryColor, height: 32),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
"Search locations",
|
||||
style: furmanTextStyle(TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade500,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 12),
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
spacing: 6,
|
||||
children: const [
|
||||
MapFilterChip(icon: Icons.restaurant, text: "Restaurants"),
|
||||
MapFilterChip(icon: Icons.train, text: "Transportation"),
|
||||
MapFilterChip(icon: Icons.school, text: "Campus Buildings"),
|
||||
],
|
||||
),
|
||||
),
|
||||
MapRotateCompass(rotation: _rotation, resetRotation: resetRotation),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
72
lib/src/screens/student_id/index.dart
Normal file
72
lib/src/screens/student_id/index.dart
Normal file
@@ -0,0 +1,72 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:barcode_widget/barcode_widget.dart';
|
||||
import 'package:furman_now/src/services/get_app/barcode/barcode_service.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
class StudentIdScreen extends StatefulWidget {
|
||||
const StudentIdScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StudentIdScreen> createState() => _StudentIdScreenState();
|
||||
}
|
||||
|
||||
class _StudentIdScreenState extends State<StudentIdScreen> {
|
||||
String barcodeNumber = BarcodeService.generateGetBarcode();
|
||||
Timer? timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
timer = Timer.periodic(
|
||||
const Duration(seconds: 10),
|
||||
updateBarcode,
|
||||
);
|
||||
}
|
||||
|
||||
void updateBarcode(Timer timer) {
|
||||
setState(() {
|
||||
barcodeNumber = BarcodeService.generateGetBarcode();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(40),
|
||||
children: [
|
||||
Text(
|
||||
"Furman ID",
|
||||
style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 36, fontWeight: FontWeight.w800)),
|
||||
),
|
||||
const SizedBox(height: 200),
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
// hack since the barcode has a weird intrinsic size for some reason
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return BarcodeWidget(
|
||||
barcode: Barcode.pdf417(moduleHeight: 4),
|
||||
data: barcodeNumber,
|
||||
margin: const EdgeInsets.all(10),
|
||||
height: constraints.maxWidth / 3,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user