formatting changes for presentation
This commit is contained in:
@@ -4,12 +4,12 @@ import 'package:fbla_ui/pages/create_edit_listing.dart';
|
||||
import 'package:fbla_ui/pages/listing_detail.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:rive/rive.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../shared/utils.dart';
|
||||
|
||||
class BusinessDetail extends StatefulWidget {
|
||||
final int id;
|
||||
final String name;
|
||||
@@ -212,71 +212,7 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
||||
]),
|
||||
),
|
||||
// Contact info
|
||||
Card(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 16.0, top: 8.0),
|
||||
child: Text(
|
||||
business.contactName!,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (business.contactPhone != null)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.phone),
|
||||
title: Text(business.contactPhone!),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.surface,
|
||||
title:
|
||||
Text('Contact ${business.contactName}'),
|
||||
content: Text(
|
||||
'Would you like to call or text ${business.contactName}?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('Text'),
|
||||
onPressed: () {
|
||||
launchUrl(Uri.parse(
|
||||
'sms:${business.contactPhone}'));
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
TextButton(
|
||||
child: const Text('Call'),
|
||||
onPressed: () async {
|
||||
launchUrl(Uri.parse(
|
||||
'tel:${business.contactPhone}'));
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (business.contactEmail != null)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.email),
|
||||
title: Text(business.contactEmail!),
|
||||
onTap: () {
|
||||
launchUrl(
|
||||
Uri.parse('mailto:${business.contactEmail}'));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ContactInformationCard(business: business),
|
||||
// Location
|
||||
Card(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'package:fbla_ui/main.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:flutter/services.dart';
|
||||
|
||||
import '../shared/global_vars.dart';
|
||||
|
||||
class CreateEditBusiness extends StatefulWidget {
|
||||
final Business? inputBusiness;
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ 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 it's businesses contact info)
|
||||
class JobListingDetail extends StatefulWidget {
|
||||
final JobListing listing;
|
||||
final Business fromBusiness;
|
||||
@@ -33,104 +35,16 @@ class _CreateBusinessDetailState extends State<JobListingDetail> {
|
||||
Widget _detailBody(JobListing listing) {
|
||||
return ListView(
|
||||
children: [
|
||||
// Title, logo, desc, website
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 800,
|
||||
child: Column(
|
||||
children: [
|
||||
// Top summary card
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: 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!));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Wage
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: _summaryCard(listing)),
|
||||
// Wage card
|
||||
if (listing.wage != null && listing.wage != '')
|
||||
Card(
|
||||
child: ListTile(
|
||||
@@ -139,72 +53,8 @@ class _CreateBusinessDetailState extends State<JobListingDetail> {
|
||||
title: const Text('Wage Information'),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 16.0, top: 8.0),
|
||||
child: Text(
|
||||
widget.fromBusiness.contactName!,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (widget.fromBusiness.contactPhone != null)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.phone),
|
||||
title: Text(widget.fromBusiness.contactPhone!),
|
||||
// maybe replace ! with ?? ''. same is true for below
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.surface,
|
||||
title: Text(
|
||||
'Contact ${widget.fromBusiness.contactName}'),
|
||||
content: Text(
|
||||
'Would you like to call or text ${widget.fromBusiness.contactName}?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('Text'),
|
||||
onPressed: () {
|
||||
launchUrl(Uri.parse(
|
||||
'sms:${widget.fromBusiness.contactPhone}'));
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
TextButton(
|
||||
child: const Text('Call'),
|
||||
onPressed: () async {
|
||||
launchUrl(Uri.parse(
|
||||
'tel:${widget.fromBusiness.contactPhone}'));
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (widget.fromBusiness.contactEmail != null)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.email),
|
||||
title: Text(widget.fromBusiness.contactEmail!),
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse(
|
||||
'mailto:${widget.fromBusiness.contactEmail}'));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Contact information for the business contact
|
||||
ContactInformationCard(business: widget.fromBusiness)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -213,6 +63,90 @@ class _CreateBusinessDetailState extends State<JobListingDetail> {
|
||||
);
|
||||
}
|
||||
|
||||
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 [
|
||||
|
||||
Reference in New Issue
Block a user