FBLA24/fbla_ui/lib/pages/listing_detail.dart
2024-06-26 21:35:47 -05:00

210 lines
7.6 KiB
Dart

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';
import 'package:fbla_ui/shared/utils.dart';
import 'package:fbla_ui/shared/widgets.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
/// A page to view all specific details about a single job listing (with its businesses contact info)
class JobListingDetail extends StatefulWidget {
final JobListing listing;
final Business fromBusiness;
const JobListingDetail(
{super.key, required this.listing, required this.fromBusiness});
@override
State<JobListingDetail> createState() => _CreateBusinessDetailState();
}
class _CreateBusinessDetailState extends State<JobListingDetail> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.listing.name),
actions: _getActions(widget.listing, widget.fromBusiness),
),
body: _detailBody(widget.listing),
);
}
Widget _detailBody(JobListing listing) {
return ListView(
children: [
Center(
child: SizedBox(
width: 800,
child: Column(
children: [
// Top summary card
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: _summaryCard(listing)),
// Wage card
if (listing.wage != null && listing.wage != '')
Card(
child: ListTile(
leading: const Icon(Icons.attach_money),
subtitle: Text(listing.wage!),
title: const Text('Wage Information'),
),
),
// Contact information for the business contact
ContactInformationCard(business: widget.fromBusiness)
],
),
),
),
],
);
}
Widget _summaryCard(JobListing listing) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
children: [
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)),
),
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);
}),
),
),
),
),
if (listing.link != null && listing.link != '')
ListTile(
leading: const Icon(Icons.link),
title: const Text('More Information'),
subtitle: Text(
listing.link!
.replaceAll('https://', '')
.replaceAll('http://', '')
.replaceAll('www.', ''),
style: const TextStyle(color: Colors.blue)),
onTap: () {
launchUrl(Uri.parse(listing.link!));
},
),
],
),
);
}
List<Widget>? _getActions(JobListing listing, Business fromBusiness) {
if (loggedIn) {
return [
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CreateEditJobListing(
inputJobListing: listing,
inputBusiness: fromBusiness,
)));
},
),
IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Theme.of(context).colorScheme.surface,
title: const Text('Are You Sure?'),
content:
Text('This will permanently delete ${listing.name}.'),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
}),
TextButton(
child: const Text('Yes'),
onPressed: () async {
String? deleteResult =
await deleteListing(listing.id!);
if (deleteResult != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
width: 300,
behavior: SnackBarBehavior.floating,
content: Text(deleteResult)));
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const MainApp(
initialPage: 1,
)));
}
}),
],
);
});
},
),
];
}
return null;
}
}