Compare commits
No commits in common. "9116876f7bde88f8f8c1c17af657207ece7c9c0f" and "68edb2c3a120619a37857803eecb78f192d2091c" have entirely different histories.
9116876f7b
...
68edb2c3a1
@ -3,7 +3,6 @@ version: '3'
|
|||||||
services:
|
services:
|
||||||
fbla_api:
|
fbla_api:
|
||||||
image: fbla-api
|
image: fbla-api
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@ -22,37 +22,47 @@ enum BusinessType {
|
|||||||
other,
|
other,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum JobType { cashier, server, mechanic, other }
|
|
||||||
|
|
||||||
class Business {
|
class Business {
|
||||||
int id;
|
int id;
|
||||||
String name;
|
String name;
|
||||||
String description;
|
String description;
|
||||||
String? website;
|
BusinessType type;
|
||||||
String? contactName;
|
String website;
|
||||||
String? contactEmail;
|
String contactName;
|
||||||
String? contactPhone;
|
String contactEmail;
|
||||||
String? notes;
|
String contactPhone;
|
||||||
String? locationName;
|
String notes;
|
||||||
String? locationAddress;
|
String locationName;
|
||||||
|
String locationAddress;
|
||||||
|
|
||||||
Business(
|
Business({
|
||||||
{required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.description,
|
required this.description,
|
||||||
this.website,
|
required this.type,
|
||||||
this.contactName,
|
required this.website,
|
||||||
this.contactEmail,
|
required this.contactName,
|
||||||
this.contactPhone,
|
required this.contactEmail,
|
||||||
this.notes,
|
required this.contactPhone,
|
||||||
this.locationName,
|
required this.notes,
|
||||||
this.locationAddress});
|
required this.locationName,
|
||||||
|
required this.locationAddress,
|
||||||
|
});
|
||||||
|
|
||||||
factory Business.fromJson(Map<String, dynamic> json) {
|
factory Business.fromJson(Map<String, dynamic> json) {
|
||||||
|
bool typeValid = true;
|
||||||
|
try {
|
||||||
|
BusinessType.values.byName(json['type']);
|
||||||
|
} catch (e) {
|
||||||
|
typeValid = false;
|
||||||
|
}
|
||||||
return Business(
|
return Business(
|
||||||
id: json['id'],
|
id: json['id'],
|
||||||
name: json['name'],
|
name: json['name'],
|
||||||
description: json['description'],
|
description: json['description'],
|
||||||
|
type: typeValid
|
||||||
|
? BusinessType.values.byName(json['type'])
|
||||||
|
: BusinessType.other,
|
||||||
website: json['website'],
|
website: json['website'],
|
||||||
contactName: json['contactName'],
|
contactName: json['contactName'],
|
||||||
contactEmail: json['contactEmail'],
|
contactEmail: json['contactEmail'],
|
||||||
@ -64,44 +74,6 @@ class Business {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JobListing {
|
|
||||||
String? id;
|
|
||||||
String? businessId;
|
|
||||||
String name;
|
|
||||||
String description;
|
|
||||||
JobType type;
|
|
||||||
String? wage;
|
|
||||||
String? link;
|
|
||||||
|
|
||||||
JobListing(
|
|
||||||
{this.id,
|
|
||||||
this.businessId,
|
|
||||||
required this.name,
|
|
||||||
required this.description,
|
|
||||||
required this.type,
|
|
||||||
this.wage,
|
|
||||||
this.link});
|
|
||||||
|
|
||||||
factory JobListing.fromJson(Map<String, dynamic> json) {
|
|
||||||
bool typeValid = true;
|
|
||||||
try {
|
|
||||||
JobType.values.byName(json['type']);
|
|
||||||
} catch (e) {
|
|
||||||
typeValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JobListing(
|
|
||||||
id: json['id'],
|
|
||||||
businessId: json['businessId'],
|
|
||||||
name: json['name'],
|
|
||||||
description: json['description'],
|
|
||||||
type: typeValid ? JobType.values.byName(json['type']) : JobType.other,
|
|
||||||
wage: json['wage'],
|
|
||||||
link: json['link'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> fetchBusinessData() async {
|
Future<String> fetchBusinessData() async {
|
||||||
final result = await postgres.query('''
|
final result = await postgres.query('''
|
||||||
SELECT json_agg(
|
SELECT json_agg(
|
||||||
@ -121,7 +93,9 @@ Future<String> fetchBusinessData() async {
|
|||||||
) FROM businesses
|
) FROM businesses
|
||||||
''');
|
''');
|
||||||
|
|
||||||
var encoded = json.encode(result[0][0]);
|
var encoded = json.encode(result);
|
||||||
|
var decoded = json.decode(encoded);
|
||||||
|
encoded = json.encode(decoded[0][0]);
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,95 +125,12 @@ void main() async {
|
|||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
app.get('/fbla-api/businessdata/overview', (Request request) async {
|
|
||||||
print('business overview request received');
|
|
||||||
|
|
||||||
var filters = request.url.queryParameters['filters']?.split(',') ??
|
|
||||||
JobType.values.asNameMap().keys;
|
|
||||||
|
|
||||||
// List<Map<String, List<Map<String, dynamic>>>> this is the real type lol
|
|
||||||
List<dynamic> output = [];
|
|
||||||
|
|
||||||
for (int i = 0; i < filters.length; i++) {
|
|
||||||
var postgresResult = (await postgres.query('''
|
|
||||||
SELECT json_agg(
|
|
||||||
json_build_object(
|
|
||||||
'id', id,
|
|
||||||
'name', name,
|
|
||||||
'description', description,
|
|
||||||
'website', website,
|
|
||||||
'contactEmail', "contactEmail",
|
|
||||||
'contactPhone', "contactPhone",
|
|
||||||
'locationName', "locationName"
|
|
||||||
)
|
|
||||||
) FROM public.businesses WHERE id IN (SELECT "businessId" FROM public.listings WHERE type='${filters.elementAt(i)}')
|
|
||||||
'''))[0][0];
|
|
||||||
|
|
||||||
if (postgresResult != null) {
|
|
||||||
output.add({filters.elementAt(i): postgresResult});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.ok(
|
|
||||||
json.encode(output),
|
|
||||||
headers: {
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
app.get('/fbla-api/businessdata/business/<business>',
|
|
||||||
(Request request, String business) async {
|
|
||||||
print('idividual business data request received');
|
|
||||||
|
|
||||||
var result = (await postgres.query('''
|
|
||||||
SELECT
|
|
||||||
json_build_object(
|
|
||||||
'id', b.id,
|
|
||||||
'name', b.name,
|
|
||||||
'description', b.description,
|
|
||||||
'website', b.website,
|
|
||||||
'contactName', b."contactName",
|
|
||||||
'contactEmail', b."contactEmail",
|
|
||||||
'contactPhone', b."contactPhone",
|
|
||||||
'notes', b.notes,
|
|
||||||
'locationName', b."locationName",
|
|
||||||
'locationAddress', b."locationAddress",
|
|
||||||
'listings',
|
|
||||||
json_agg(
|
|
||||||
json_build_object(
|
|
||||||
'id', l.id,
|
|
||||||
'name', l.name,
|
|
||||||
'description', l.description,
|
|
||||||
'type', l.type,
|
|
||||||
'wage', l.wage,
|
|
||||||
'link', l.link
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
FROM businesses b
|
|
||||||
LEFT JOIN listings l ON b.id = l.business_id
|
|
||||||
WHERE b.id = $business
|
|
||||||
GROUP BY b.id;
|
|
||||||
'''))[0][0];
|
|
||||||
|
|
||||||
return Response.ok(
|
|
||||||
json.encode(result),
|
|
||||||
headers: {
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
app.get('/fbla-api/businessdata', (Request request) async {
|
app.get('/fbla-api/businessdata', (Request request) async {
|
||||||
print('business data request received');
|
print('business data request received');
|
||||||
final output = await fetchBusinessData();
|
final output = await fetchBusinessData();
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
output.toString(),
|
output.toString(),
|
||||||
headers: {
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
app.get('/fbla-api/logos/<logo>', (Request request, String logoId) {
|
app.get('/fbla-api/logos/<logo>', (Request request, String logoId) {
|
||||||
@ -267,8 +158,8 @@ void main() async {
|
|||||||
Business business = Business.fromJson(json);
|
Business business = Business.fromJson(json);
|
||||||
|
|
||||||
await postgres.query('''
|
await postgres.query('''
|
||||||
INSERT INTO businesses (name, description, website, "contactName", "contactPhone", "contactEmail", notes, "locationName", "locationAddress")
|
INSERT INTO businesses (name, description, type, website, "contactName", "contactPhone", "contactEmail", notes, "locationName", "locationAddress")
|
||||||
VALUES ('${business.name.replaceAll("'", "''")}', '${business.description.replaceAll("'", "''")}', '${business.website ?? 'NULL'}', '${business.contactName?.replaceAll("'", "''") ?? 'NULL'}', '${business.contactPhone ?? 'NULL'}', '${business.contactEmail ?? 'NULL'}', '${business.notes?.replaceAll("'", "''") ?? 'NULL'}', '${business.locationName?.replaceAll("'", "''") ?? 'NULL'}', '${business.locationAddress?.replaceAll("'", "''") ?? 'NULL'}')
|
VALUES ('${business.name.replaceAll("'", "''")}', '${business.description.replaceAll("'", "''")}', '${business.type.name}', '${business.website}', '${business.contactName.replaceAll("'", "''")}', '${business.contactPhone}', '${business.contactEmail}', '${business.notes.replaceAll("'", "''")}', '${business.locationName.replaceAll("'", "''")}', '${business.locationAddress.replaceAll("'", "''")}')
|
||||||
''');
|
''');
|
||||||
|
|
||||||
final dbBusiness = await postgres.query('''SELECT * FROM public.businesses
|
final dbBusiness = await postgres.query('''SELECT * FROM public.businesses
|
||||||
@ -296,40 +187,6 @@ void main() async {
|
|||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
app.post('/fbla-api/createlisting', (Request request) async {
|
|
||||||
print('create business request received');
|
|
||||||
|
|
||||||
final payload = await request.readAsString();
|
|
||||||
var auth = request.headers['Authorization']?.replaceAll('Bearer ', '');
|
|
||||||
try {
|
|
||||||
JWT.verify(auth!, secretKey);
|
|
||||||
var json = jsonDecode(payload);
|
|
||||||
JobListing listing = JobListing.fromJson(json);
|
|
||||||
|
|
||||||
await postgres.query('''
|
|
||||||
INSERT INTO listings ("businessId", name, description, type, wage, link)
|
|
||||||
VALUES ('${listing.businessId}' '${listing.name.replaceAll("'", "''")}', '${listing.description.replaceAll("'", "''")}', '${listing.type.name}', '${listing.wage ?? 'NULL'}', '${listing.link?.replaceAll("'", "''") ?? 'NULL'}')
|
|
||||||
''');
|
|
||||||
|
|
||||||
final dbListing = await postgres.query('''SELECT id FROM public.listings
|
|
||||||
ORDER BY id DESC LIMIT 1''');
|
|
||||||
var id = dbListing[0][0];
|
|
||||||
|
|
||||||
return Response.ok(
|
|
||||||
id.toString(),
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
} on JWTExpiredException {
|
|
||||||
print('JWT Expired');
|
|
||||||
} on JWTException catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.unauthorized(
|
|
||||||
'unauthorized',
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
app.post('/fbla-api/deletebusiness', (Request request) async {
|
app.post('/fbla-api/deletebusiness', (Request request) async {
|
||||||
print('delete business request received');
|
print('delete business request received');
|
||||||
|
|
||||||
@ -340,7 +197,11 @@ void main() async {
|
|||||||
var json = jsonDecode(payload);
|
var json = jsonDecode(payload);
|
||||||
var id = json['id'];
|
var id = json['id'];
|
||||||
|
|
||||||
await postgres.query('DELETE FROM public.business WHERE id=$id;');
|
await postgres.query('''
|
||||||
|
DELETE FROM public.businesses
|
||||||
|
WHERE id IN
|
||||||
|
($id);
|
||||||
|
''');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await File('logos/$id.png').delete();
|
await File('logos/$id.png').delete();
|
||||||
@ -363,33 +224,6 @@ void main() async {
|
|||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
app.post('/fbla-api/deletelisting', (Request request) async {
|
|
||||||
print('delete listing request received');
|
|
||||||
|
|
||||||
final payload = await request.readAsString();
|
|
||||||
var auth = request.headers['Authorization']?.replaceAll('Bearer ', '');
|
|
||||||
try {
|
|
||||||
JWT.verify(auth!, secretKey);
|
|
||||||
var json = jsonDecode(payload);
|
|
||||||
var id = json['id'];
|
|
||||||
|
|
||||||
await postgres.query('DELETE FROM public.listings WHERE id=$id;');
|
|
||||||
|
|
||||||
return Response.ok(
|
|
||||||
id.toString(),
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
} on JWTExpiredException {
|
|
||||||
print('JWT Expired');
|
|
||||||
} on JWTException catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.unauthorized(
|
|
||||||
'unauthorized',
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
app.post('/fbla-api/editbusiness', (Request request) async {
|
app.post('/fbla-api/editbusiness', (Request request) async {
|
||||||
print('edit business request received');
|
print('edit business request received');
|
||||||
|
|
||||||
@ -403,7 +237,7 @@ void main() async {
|
|||||||
|
|
||||||
await postgres.query('''
|
await postgres.query('''
|
||||||
UPDATE businesses SET
|
UPDATE businesses SET
|
||||||
name = '${business.name.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, description = '${business.description.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, website = '${business.website!}'::text, "contactName" = '${business.contactName!.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "contactPhone" = '${business.contactPhone!}'::text, "contactEmail" = '${business.contactEmail!}'::text, notes = '${business.notes!.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationName" = '${business.locationName!.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationAddress" = '${business.locationAddress!.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text WHERE
|
name = '${business.name.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, description = '${business.description.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, website = '${business.website}'::text, type = '${business.type.name}'::text, "contactName" = '${business.contactName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "contactPhone" = '${business.contactPhone}'::text, "contactEmail" = '${business.contactEmail}'::text, notes = '${business.notes.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationName" = '${business.locationName.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text, "locationAddress" = '${business.locationAddress.replaceAll("'", "''").replaceAll("\"", "\"\"")}'::text WHERE
|
||||||
id = ${business.id};
|
id = ${business.id};
|
||||||
''');
|
''');
|
||||||
|
|
||||||
@ -436,38 +270,6 @@ void main() async {
|
|||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
app.post('/fbla-api/editlisting', (Request request) async {
|
|
||||||
print('edit listing request received');
|
|
||||||
|
|
||||||
final payload = await request.readAsString();
|
|
||||||
var auth = request.headers['Authorization']?.replaceAll('Bearer ', '');
|
|
||||||
try {
|
|
||||||
JWT.verify(auth!, secretKey);
|
|
||||||
|
|
||||||
var json = jsonDecode(payload);
|
|
||||||
JobListing listing = JobListing.fromJson(json);
|
|
||||||
|
|
||||||
await postgres.query('''
|
|
||||||
UPDATE listings SET
|
|
||||||
"businessId" = ${listing.businessId}, name = '${listing.name.replaceAll("'", "''")}'::text, description = '${listing.description.replaceAll("'", "''")}'::text, type = '${listing.type.name}'::text, wage = '${listing.wage ?? 'NULL'}'::text, link = '${listing.link?.replaceAll("'", "''") ?? 'NULL'}'::text WHERE
|
|
||||||
id = ${listing.id};
|
|
||||||
''');
|
|
||||||
|
|
||||||
return Response.ok(
|
|
||||||
listing.id.toString(),
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
} on JWTExpiredException {
|
|
||||||
print('JWT Expired');
|
|
||||||
} on JWTException catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.unauthorized(
|
|
||||||
'unauthorized',
|
|
||||||
headers: {'Access-Control-Allow-Origin': '*'},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
app.post('/fbla-api/signin', (Request request) async {
|
app.post('/fbla-api/signin', (Request request) async {
|
||||||
print('signin request received');
|
print('signin request received');
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,7 @@ void main() async {
|
|||||||
"id": 0,
|
"id": 0,
|
||||||
"name": "tmp",
|
"name": "tmp",
|
||||||
"description": "tmp",
|
"description": "tmp",
|
||||||
|
"type": "business",
|
||||||
"website": "tmp",
|
"website": "tmp",
|
||||||
"contactName": "tmp",
|
"contactName": "tmp",
|
||||||
"contactEmail": "tmp",
|
"contactEmail": "tmp",
|
||||||
|
|||||||
@ -26,7 +26,6 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
|||||||
),
|
),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
children: [
|
children: [
|
||||||
// Title, logo, desc, website
|
|
||||||
Card(
|
Card(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -42,7 +41,8 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
|||||||
),
|
),
|
||||||
leading: ClipRRect(
|
leading: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(6.0),
|
borderRadius: BorderRadius.circular(6.0),
|
||||||
child: Image.network('$apiAddress/logos/${business.id}',
|
child: Image.network(
|
||||||
|
'$apiAddress/logos/${business.id}',
|
||||||
width: 48,
|
width: 48,
|
||||||
height: 48, errorBuilder: (BuildContext context,
|
height: 48, errorBuilder: (BuildContext context,
|
||||||
Object exception, StackTrace? stackTrace) {
|
Object exception, StackTrace? stackTrace) {
|
||||||
@ -63,52 +63,6 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Available positions
|
|
||||||
Card(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 16.0, top: 8.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Available Postitions',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 20, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
// Container(
|
|
||||||
// height: 400,
|
|
||||||
// width: 300,
|
|
||||||
ListView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
shrinkWrap: true,
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
title: Text('Postition 1'),
|
|
||||||
leading: Icon(Icons.work),
|
|
||||||
onTap: () {
|
|
||||||
// launchUrl(Uri.parse(''));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('Postition 2'),
|
|
||||||
leading: Icon(Icons.work),
|
|
||||||
onTap: () {
|
|
||||||
// launchUrl(Uri.parse(''));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('Postition 3'),
|
|
||||||
leading: Icon(Icons.work),
|
|
||||||
onTap: () {
|
|
||||||
// launchUrl(Uri.parse(''));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Contact info
|
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: (business.contactEmail.isNotEmpty ||
|
visible: (business.contactEmail.isNotEmpty ||
|
||||||
business.contactPhone.isNotEmpty),
|
business.contactPhone.isNotEmpty),
|
||||||
@ -184,7 +138,6 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Location
|
|
||||||
Visibility(
|
Visibility(
|
||||||
child: Card(
|
child: Card(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
@ -199,7 +152,6 @@ class _CreateBusinessDetailState extends State<BusinessDetail> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Notes
|
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: business.notes.isNotEmpty,
|
visible: business.notes.isNotEmpty,
|
||||||
child: Card(
|
child: Card(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user