FBLA24/fbla_ui/lib/home.dart
2024-06-26 13:06:03 -05:00

312 lines
10 KiB
Dart

import 'package:fbla_ui/pages/businesses_overview.dart';
import 'package:fbla_ui/pages/create_edit_business.dart';
import 'package:fbla_ui/pages/create_edit_listing.dart';
import 'package:fbla_ui/pages/listings_overview.dart';
import 'package:fbla_ui/shared/api_logic.dart';
import 'package:fbla_ui/shared/global_vars.dart';
import 'package:fbla_ui/shared/utils.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Home extends StatefulWidget {
final void Function() themeCallback;
final int? initialPage;
const Home({super.key, required this.themeCallback, this.initialPage});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
Set<JobType> jobTypeFilters = <JobType>{};
Set<OfferType> offerTypeFilters = <OfferType>{};
Set<BusinessType> businessTypeFilters = <BusinessType>{};
String searchQuery = '';
late Future refreshBusinessDataOverviewJobFuture;
late Future refreshBusinessDataOverviewBusinessFuture;
int currentPageIndex = 0;
late dynamic previousJobData;
ScrollController scrollControllerBusinesses = ScrollController();
ScrollController scrollControllerJobs = ScrollController();
void _updateLoggedIn(bool updated) {
setState(() {
loggedIn = updated;
});
}
@override
void initState() {
super.initState();
currentPageIndex = widget.initialPage ?? 0;
initialLogin();
refreshBusinessDataOverviewJobFuture = fetchBusinessDataOverviewJobs();
refreshBusinessDataOverviewBusinessFuture =
fetchBusinessDataOverviewTypes();
}
Future<void> initialLogin() async {
final prefs = await SharedPreferences.getInstance();
bool? rememberMe = prefs.getBool('rememberMe');
if (rememberMe != null && rememberMe) {
String? username = prefs.getString('username');
String? password = prefs.getString('password');
jwt = await signIn(username!, password!);
if (!jwt.contains('Error:')) {
setState(() {
loggedIn = true;
});
}
}
}
Future<void> _updateOverviewBusinessesJobsCallback(
Set<JobType>? newJobTypeFilters,
Set<OfferType>? newOfferTypeFilters) async {
if (newJobTypeFilters != null) {
jobTypeFilters = Set.from(newJobTypeFilters);
}
if (newOfferTypeFilters != null) {
offerTypeFilters = Set.from(newOfferTypeFilters);
}
var refreshedData = fetchBusinessDataOverviewJobs(
typeFilters: jobTypeFilters, offerFilters: offerTypeFilters);
await refreshedData;
setState(() {
refreshBusinessDataOverviewJobFuture = refreshedData;
});
}
Future<void> _updateOverviewBusinessesBusinessCallback(
Set<BusinessType>? newFilters) async {
if (newFilters != null) {
businessTypeFilters = Set.from(newFilters);
}
var refreshedData = fetchBusinessDataOverviewTypes(
typeFilters: businessTypeFilters.toList());
await refreshedData;
setState(() {
refreshBusinessDataOverviewBusinessFuture = refreshedData;
});
}
@override
Widget build(BuildContext context) {
bool widescreen = MediaQuery.sizeOf(context).width >= widescreenWidth;
return Scaffold(
bottomNavigationBar: _getNavigationBar(widescreen),
body: RefreshIndicator(
edgeOffset: 145,
onRefresh: () async {
_updateOverviewBusinessesJobsCallback(null, null);
_updateOverviewBusinessesBusinessCallback(null);
},
child: widescreen
? Row(
children: [
_getNavigationRail(),
Expanded(
child: _ContentPane(
themeCallback: widget.themeCallback,
searchQuery: searchQuery,
currentPageIndex: currentPageIndex,
refreshBusinessDataOverviewBusinessFuture:
refreshBusinessDataOverviewBusinessFuture,
refreshBusinessDataOverviewJobFuture:
refreshBusinessDataOverviewJobFuture,
updateOverviewBusinessesBusinessCallback:
_updateOverviewBusinessesBusinessCallback,
updateOverviewBusinessesJobsCallback:
_updateOverviewBusinessesJobsCallback,
updateLoggedIn: _updateLoggedIn,
),
)
],
)
: _ContentPane(
themeCallback: widget.themeCallback,
searchQuery: searchQuery,
currentPageIndex: currentPageIndex,
refreshBusinessDataOverviewBusinessFuture:
refreshBusinessDataOverviewBusinessFuture,
refreshBusinessDataOverviewJobFuture:
refreshBusinessDataOverviewJobFuture,
updateOverviewBusinessesBusinessCallback:
_updateOverviewBusinessesBusinessCallback,
updateOverviewBusinessesJobsCallback:
_updateOverviewBusinessesJobsCallback,
updateLoggedIn: _updateLoggedIn,
),
),
);
}
Widget? _getNavigationBar(bool widescreen) {
if (!widescreen) {
return NavigationBar(
selectedIndex: currentPageIndex,
indicatorColor: Theme.of(context).colorScheme.primary.withOpacity(0.5),
onDestinationSelected: (int index) {
setState(() {
currentPageIndex = index;
});
},
destinations: <NavigationDestination>[
NavigationDestination(
icon: const Icon(Icons.business_outlined),
selectedIcon: Icon(
Icons.business,
color: Theme.of(context).colorScheme.onSurface,
),
label: 'Businesses'),
NavigationDestination(
icon: const Icon(Icons.work_outline),
selectedIcon: Icon(
Icons.work,
color: Theme.of(context).colorScheme.onSurface,
),
label: 'Job Listings'),
],
);
}
return null;
}
Widget _getNavigationRail() {
return Row(
children: [
NavigationRail(
selectedIndex: currentPageIndex,
indicatorColor:
Theme.of(context).colorScheme.primary.withOpacity(0.5),
trailing: Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(16),
child: IconButton(
iconSize: 30,
icon: Icon(
getIconFromThemeMode(themeMode),
),
onPressed: () {
setState(() {
widget.themeCallback();
});
},
),
),
),
),
leading: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 2.0, bottom: 8.0),
child: Image.asset(
'assets/Triangle256.png',
height: 50,
),
),
if (loggedIn)
FloatingActionButton(
heroTag: 'Homepage',
onPressed: () {
if (currentPageIndex == 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CreateEditBusiness()));
} else if (currentPageIndex == 1) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CreateEditJobListing()));
}
},
child: const Icon(Icons.add),
)
],
),
onDestinationSelected: (int index) {
setState(() {
currentPageIndex = index;
});
},
labelType: NavigationRailLabelType.all,
destinations: <NavigationRailDestination>[
NavigationRailDestination(
icon: const Icon(Icons.business_outlined),
selectedIcon: Icon(
Icons.business,
color: Theme.of(context).colorScheme.onSurface,
),
label: const Text('Businesses')),
NavigationRailDestination(
icon: const Icon(Icons.work_outline),
selectedIcon: Icon(
Icons.work,
color: Theme.of(context).colorScheme.onSurface,
),
label: const Text('Job Listings')),
],
),
],
);
}
}
class _ContentPane extends StatelessWidget {
final String searchQuery;
final Future refreshBusinessDataOverviewBusinessFuture;
final Future<void> Function(Set<BusinessType>)
updateOverviewBusinessesBusinessCallback;
final void Function() themeCallback;
final Future refreshBusinessDataOverviewJobFuture;
final Future<void> Function(Set<JobType>?, Set<OfferType>?)
updateOverviewBusinessesJobsCallback;
final int currentPageIndex;
final void Function(bool) updateLoggedIn;
const _ContentPane({
required this.searchQuery,
required this.refreshBusinessDataOverviewBusinessFuture,
required this.updateOverviewBusinessesBusinessCallback,
required this.themeCallback,
required this.refreshBusinessDataOverviewJobFuture,
required this.updateOverviewBusinessesJobsCallback,
required this.currentPageIndex,
required this.updateLoggedIn,
});
@override
Widget build(BuildContext context) {
return IndexedStack(
index: currentPageIndex,
children: [
BusinessesOverview(
searchQuery: searchQuery,
refreshBusinessDataOverviewFuture:
refreshBusinessDataOverviewBusinessFuture,
updateBusinessesCallback: updateOverviewBusinessesBusinessCallback,
themeCallback: themeCallback,
updateLoggedIn: updateLoggedIn,
),
JobsOverview(
searchQuery: searchQuery,
refreshJobDataOverviewFuture: refreshBusinessDataOverviewJobFuture,
updateBusinessesCallback: updateOverviewBusinessesJobsCallback,
themeCallback: themeCallback,
updateLoggedIn: updateLoggedIn,
),
],
);
}
}