More fixes
This commit is contained in:
@@ -22,6 +22,7 @@ class BusinessDetail extends StatefulWidget {
|
||||
|
||||
class _CreateBusinessDetailState extends State<BusinessDetail> {
|
||||
late Future loadBusiness;
|
||||
bool _isRetrying = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -60,11 +61,17 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FilledButton(
|
||||
child: const Text('Retry'),
|
||||
onPressed: () {
|
||||
var refreshedData = fetchBusiness(widget.id);
|
||||
setState(() {
|
||||
loadBusiness = refreshedData;
|
||||
});
|
||||
onPressed: () async {
|
||||
if (!_isRetrying) {
|
||||
setState(() {
|
||||
_isRetrying = true;
|
||||
});
|
||||
var refreshedData =
|
||||
await fetchBusiness(widget.id);
|
||||
setState(() {
|
||||
loadBusiness = refreshedData;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -120,28 +127,32 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: Text(business.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 24, fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(
|
||||
business.description!,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${business.id}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder: (BuildContext context,
|
||||
Object exception, StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromBusinessType(
|
||||
business.type ?? BusinessType.other),
|
||||
size: 48);
|
||||
}),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ListTile(
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: Text(business.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 24, fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(
|
||||
business.description!,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${business.id}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context, Object exception,
|
||||
StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromBusinessType(
|
||||
business.type ?? BusinessType.other),
|
||||
size: 48);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (business.website != null)
|
||||
|
||||
@@ -40,6 +40,7 @@ class _BusinessesOverviewState extends State<BusinessesOverview> {
|
||||
ScrollController controller = ScrollController();
|
||||
bool _extended = true;
|
||||
double prevPixelPosition = 0;
|
||||
bool _isRetrying = false;
|
||||
|
||||
Map<BusinessType, List<Business>> _filterBySearch(
|
||||
Map<BusinessType, List<Business>> businesses, String query) {
|
||||
@@ -138,9 +139,14 @@ class _BusinessesOverviewState extends State<BusinessesOverview> {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FilledButton(
|
||||
child: const Text('Retry'),
|
||||
onPressed: () {
|
||||
widget.updateBusinessesCallback(
|
||||
businessTypeFilters);
|
||||
onPressed: () async {
|
||||
if (!_isRetrying) {
|
||||
setState(() {
|
||||
_isRetrying = true;
|
||||
});
|
||||
await widget.updateBusinessesCallback(
|
||||
businessTypeFilters);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -103,7 +103,17 @@ class _CreateEditBusinessState extends State<CreateEditBusiness> {
|
||||
)
|
||||
: const Icon(Icons.save),
|
||||
onPressed: () async {
|
||||
await _saveBusiness(context);
|
||||
if (!_isLoading) {
|
||||
await _saveBusiness(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
width: 400,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
content: Text('Please wait for it to save.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
)
|
||||
: null,
|
||||
@@ -114,28 +124,40 @@ class _CreateEditBusinessState extends State<CreateEditBusiness> {
|
||||
width: 800,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: Text(business.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 24, fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(
|
||||
business.description!,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'https://logo.clearbit.com/${business.website}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder: (BuildContext context,
|
||||
Object exception, StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromBusinessType(
|
||||
business.type ?? BusinessType.other),
|
||||
size: 48);
|
||||
}),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ListTile(
|
||||
titleAlignment:
|
||||
ListTileTitleAlignment.titleHeight,
|
||||
title: Text(business.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(
|
||||
business.description!,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'https://logo.clearbit.com/${business.website}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context,
|
||||
Object exception,
|
||||
StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromBusinessType(business.type ??
|
||||
BusinessType.other),
|
||||
size: 48);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
@@ -540,7 +562,18 @@ class _CreateEditBusinessState extends State<CreateEditBusiness> {
|
||||
],
|
||||
),
|
||||
onPressed: () async {
|
||||
await _saveBusiness(context);
|
||||
if (!_isLoading) {
|
||||
await _saveBusiness(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
width: 400,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
content:
|
||||
Text('Please wait for it to save.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -38,6 +38,8 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
link: null,
|
||||
offerType: null);
|
||||
bool _isLoading = false;
|
||||
late String businessName;
|
||||
bool _isRetrying = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -57,6 +59,7 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
.replaceAll('http://', '')
|
||||
.replaceAll('www.', ''));
|
||||
getBusinessNameMapping = fetchBusinessNames();
|
||||
businessName = widget.inputBusiness?.name ?? 'Offering business';
|
||||
}
|
||||
|
||||
final formKey = GlobalKey<FormState>();
|
||||
@@ -92,7 +95,17 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
)
|
||||
: const Icon(Icons.save),
|
||||
onPressed: () async {
|
||||
await _saveListing(context);
|
||||
if (!_isLoading) {
|
||||
await _saveListing(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
width: 400,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
content: Text('Please wait for it to save.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
})
|
||||
: null,
|
||||
body: FutureBuilder(
|
||||
@@ -112,11 +125,17 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
child: FilledButton(
|
||||
child: const Text('Retry'),
|
||||
onPressed: () async {
|
||||
var refreshedData = fetchBusinessNames();
|
||||
await refreshedData;
|
||||
setState(() {
|
||||
getBusinessNameMapping = refreshedData;
|
||||
});
|
||||
if (!_isRetrying) {
|
||||
setState(() {
|
||||
_isRetrying = true;
|
||||
});
|
||||
var refreshedData = fetchBusinessNames();
|
||||
await refreshedData;
|
||||
setState(() {
|
||||
getBusinessNameMapping = refreshedData;
|
||||
_isRetrying = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -135,43 +154,55 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
width: 800,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
titleAlignment:
|
||||
ListTileTitleAlignment.titleHeight,
|
||||
title: Text(listing.name,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
getNameFromJobType(
|
||||
listing.type ?? JobType.other),
|
||||
style: const TextStyle(fontSize: 18),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(right: 8.0),
|
||||
child: ListTile(
|
||||
titleAlignment: ListTileTitleAlignment
|
||||
.titleHeight,
|
||||
title: Text(listing.name,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
businessName,
|
||||
style: const TextStyle(
|
||||
fontSize: 18),
|
||||
),
|
||||
Text(
|
||||
listing.description,
|
||||
),
|
||||
],
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius:
|
||||
BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${listing.businessId}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context,
|
||||
Object exception,
|
||||
StackTrace?
|
||||
stackTrace) {
|
||||
return Icon(
|
||||
getIconFromJobType(
|
||||
listing.type ??
|
||||
JobType.other),
|
||||
size: 48);
|
||||
}),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
listing.description,
|
||||
),
|
||||
],
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 16),
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${listing.businessId}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context,
|
||||
Object exception,
|
||||
StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromJobType(
|
||||
listing.type ?? JobType.other),
|
||||
size: 48);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Business Type Dropdown
|
||||
@@ -286,6 +317,11 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
setState(() {
|
||||
listing.businessId =
|
||||
inputType!;
|
||||
businessName = nameMapping
|
||||
.where((element) =>
|
||||
element['id'] ==
|
||||
listing.businessId)
|
||||
.first['name'];
|
||||
businessDropdownErrorText =
|
||||
null;
|
||||
});
|
||||
@@ -435,7 +471,7 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FilledButton(
|
||||
child: const Row(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
@@ -443,13 +479,39 @@ class _CreateEditJobListingState extends State<CreateEditJobListing> {
|
||||
top: 8.0,
|
||||
right: 8.0,
|
||||
bottom: 8.0),
|
||||
child: Icon(Icons.save),
|
||||
child: _isLoading
|
||||
? SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
color:
|
||||
Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimary,
|
||||
strokeWidth: 3.0,
|
||||
),
|
||||
)
|
||||
: Icon(Icons.save),
|
||||
),
|
||||
Text('Save'),
|
||||
],
|
||||
),
|
||||
onPressed: () async {
|
||||
await _saveListing(context);
|
||||
if (!_isLoading) {
|
||||
await _saveListing(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
const SnackBar(
|
||||
width: 400,
|
||||
behavior:
|
||||
SnackBarBehavior.floating,
|
||||
content: Text(
|
||||
'Please wait for it to save.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:fbla_ui/main.dart';
|
||||
import 'package:fbla_ui/pages/business_detail.dart';
|
||||
import 'package:fbla_ui/pages/create_edit_listing.dart';
|
||||
import 'package:fbla_ui/shared/api_logic.dart';
|
||||
import 'package:fbla_ui/shared/global_vars.dart';
|
||||
@@ -44,53 +45,70 @@ class _CreateBusinessDetailState extends State<JobListingDetail> {
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
minVerticalPadding: 0,
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'${listing.name} (${getNameFromOfferType(listing.offerType!)})',
|
||||
style: const TextStyle(
|
||||
fontSize: 24, fontWeight: FontWeight.bold)),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
getNameFromJobType(listing.type!),
|
||||
style: const TextStyle(fontSize: 18),
|
||||
),
|
||||
Text(
|
||||
listing.description,
|
||||
),
|
||||
],
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: Badge(
|
||||
label: Text(
|
||||
getLetterFromOfferType(listing.offerType!),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ListTile(
|
||||
minVerticalPadding: 0,
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'${listing.name} (${getNameFromOfferType(listing.offerType!)})',
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold)),
|
||||
),
|
||||
largeSize: 26,
|
||||
offset: const Offset(15, -5),
|
||||
textColor: Colors.white,
|
||||
backgroundColor:
|
||||
getColorFromOfferType(listing.offerType!),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${listing.businessId}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context, Object exception,
|
||||
StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromJobType(
|
||||
listing.type ?? JobType.other),
|
||||
size: 48);
|
||||
}),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return BusinessDetail(
|
||||
id: widget.fromBusiness.id,
|
||||
name: widget.fromBusiness.name!);
|
||||
}));
|
||||
},
|
||||
child: Text(
|
||||
widget.fromBusiness.name!,
|
||||
style: const TextStyle(fontSize: 18),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
listing.description,
|
||||
),
|
||||
],
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(bottom: 8, left: 16),
|
||||
leading: Badge(
|
||||
label: Text(
|
||||
getLetterFromOfferType(listing.offerType!),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
largeSize: 24,
|
||||
offset: const Offset(12, -3),
|
||||
textColor: Colors.white,
|
||||
backgroundColor:
|
||||
getColorFromOfferType(listing.offerType!),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: Image.network(
|
||||
'$apiAddress/logos/${widget.fromBusiness.id}',
|
||||
width: 48,
|
||||
height: 48, errorBuilder:
|
||||
(BuildContext context, Object exception,
|
||||
StackTrace? stackTrace) {
|
||||
return Icon(
|
||||
getIconFromJobType(
|
||||
listing.type ?? JobType.other),
|
||||
size: 48);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -42,6 +42,7 @@ class _JobsOverviewState extends State<JobsOverview> {
|
||||
ScrollController controller = ScrollController();
|
||||
bool _extended = true;
|
||||
double prevPixelPosition = 0;
|
||||
bool _isRetrying = false;
|
||||
|
||||
Map<JobType, List<Business>> _filterBySearch(
|
||||
Map<JobType, List<Business>> businesses, String query) {
|
||||
@@ -145,8 +146,13 @@ class _JobsOverviewState extends State<JobsOverview> {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FilledButton(
|
||||
child: const Text('Retry'),
|
||||
onPressed: () {
|
||||
widget.updateBusinessesCallback(null, null);
|
||||
onPressed: () async {
|
||||
if (!_isRetrying) {
|
||||
setState(() {
|
||||
_isRetrying = true;
|
||||
});
|
||||
await widget.updateBusinessesCallback(null, null);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -534,12 +540,8 @@ class _JobHeaderState extends State<_JobHeader> {
|
||||
business.listings![0].offerType!),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
largeSize: 26,
|
||||
padding: business.listings![0].offerType! ==
|
||||
OfferType.internship
|
||||
? const EdgeInsets.symmetric(horizontal: 5)
|
||||
: null,
|
||||
offset: const Offset(13, -2),
|
||||
largeSize: 24,
|
||||
offset: const Offset(12, -3),
|
||||
textColor: Colors.white,
|
||||
backgroundColor: getColorFromOfferType(
|
||||
business.listings![0].offerType!),
|
||||
|
||||
Reference in New Issue
Block a user