Skip to content

Instantly share code, notes, and snippets.

@Daniel-Sogbey
Created April 26, 2023 21:43
Show Gist options
  • Save Daniel-Sogbey/77541760cda3b9a7ee0e292ea0158488 to your computer and use it in GitHub Desktop.
Save Daniel-Sogbey/77541760cda3b9a7ee0e292ea0158488 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import '../constants/store.dart';
import '../model/directions.dart';
class AppInfo extends ChangeNotifier {
Directions? userPickupLocation, userDropOffLocation;
updatePickupLocationAddress(Directions userPickupAddress) {
userPickupLocation = userPickupAddress;
notifyListeners();
return userPickupAddress;
}
void updateDropOffLocationAddress(Directions userDropOffAddress) {
userDropOffLocation = userDropOffAddress;
Store.setUserLocation(userDropOffLocation!.locationName!);
notifyListeners();
}
}
class Directions {
String? formattedAddress;
String? locationName;
String? locationId;
double? locationLatitude;
double? locationLongitude;
Directions({
this.formattedAddress,
this.locationName,
this.locationId,
this.locationLatitude,
this.locationLongitude,
});
}
import 'package:click_so/widgets/progress_dialog.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../constants/global.dart';
import '../constants/request_method.dart';
import '../constants/store.dart';
import '../constants/variable_constants.dart';
import '../model/directions.dart';
import '../model/predicted_places.dart';
import '../providers/app_info.dart';
class PlacePredictionTile extends StatefulWidget {
final PredictedPlaces? predictedPlaces;
const PlacePredictionTile({Key? key, required this.predictedPlaces})
: super(key: key);
@override
State<PlacePredictionTile> createState() => _PlacePredictionTileState();
}
class _PlacePredictionTileState extends State<PlacePredictionTile> {
getPlaceDirectionDetails(String? placeId, context) async {
showDialog(
context: context,
builder: (BuildContext context) {
return ProgressDialog(
message: "Processing new location..",
);
});
String placeDirectionsDetailsUrl =
"https://maps.googleapis.com/maps/api/place/details/json?place_id=$placeId&key=$mapKey";
var responseApi =
await RequestMethod.receiveRequest(placeDirectionsDetailsUrl);
Navigator.pop(context);
if (responseApi == "Something went wrong") {
return;
}
if (responseApi['status'] == 'OK') {
Directions directions = Directions();
directions.locationId = placeId;
directions.locationName = responseApi['result']['name'];
directions.locationLatitude =
responseApi['result']['geometry']['location']['lat'];
directions.locationLongitude =
responseApi['result']['geometry']['location']['lng'];
print("LOCATION NAME HERE : ${directions.locationName}");
print("LOCATION LATITUDE HERE : ${directions.locationLatitude}");
print("LOCATION LONGITUDE HERE : ${directions.locationLongitude}");
Provider.of<AppInfo>(context, listen: false)
.updateDropOffLocationAddress(directions);
setState(() {
userNewAddress = directions.locationName!;
});
Store.setUserLocation(userNewAddress);
Navigator.pop(context, userNewAddress);
userDropOffAddress = directions.locationName!;
Navigator.pop(context, 'obtainedDropOff');
}
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
child: ElevatedButton(
onPressed: () {
getPlaceDirectionDetails(widget.predictedPlaces!.place_id, context);
},
style: ElevatedButton.styleFrom(
primary: const Color(0xffffffff),
elevation: 1,
),
child: Row(
children: [
Icon(Icons.location_on_outlined, color: Theme.of(context).primaryColor),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
Text(
widget.predictedPlaces!.main_text!,
style: const TextStyle(color: Color(0xff3e3e3e)),
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 2),
Text(
widget.predictedPlaces!.secondary_text!,
style: const TextStyle(color: Color(0xff3e3e3e)),
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
],
),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
class PredictedPlaces {
String? place_id;
String? main_text;
String? secondary_text;
String? city;
PredictedPlaces(
{this.place_id, this.main_text, this.secondary_text, this.city});
PredictedPlaces.fromJson(Map<String, dynamic> jsonData) {
place_id = jsonData['place_id'];
main_text = jsonData["structured_formatting"]['main_text'];
secondary_text = jsonData["structured_formatting"]['secondary_text'];
city = (jsonData["structured_formatting"]['secondary_text'] as String)
.split(",")
.length >
1
? (jsonData["structured_formatting"]['secondary_text'] as String)
.split(",")[1]
: (jsonData["structured_formatting"]['secondary_text'] as String)
.split(",")[0];
debugPrint("USER SELECTED CITY $city");
}
}
// ignore_for_file: unnecessary_const
import 'package:flutter/material.dart';
import '../../constants/request_method.dart';
import '../../constants/variable_constants.dart';
import '../../model/predicted_places.dart';
import '../../widgets/place_prediction_tile.dart';
class SearchPlacesScreen extends StatefulWidget {
const SearchPlacesScreen({Key? key}) : super(key: key);
static const String routeName = '/search-places';
@override
State<SearchPlacesScreen> createState() => _SearchPlacesScreenState();
}
class _SearchPlacesScreenState extends State<SearchPlacesScreen> {
var _formController = TextEditingController();
var _toController = TextEditingController();
List<PredictedPlaces> placesPredictedList = [];
void findPlaceAutoCompleteSearch(String inputText) async {
if (inputText.isNotEmpty) {
String urlAutoCompleteSearch =
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$inputText&key=$mapKey&components=country:FRA";
var responseAutoCompleteSearch =
await RequestMethod.receiveRequest(urlAutoCompleteSearch);
print(responseAutoCompleteSearch);
if (responseAutoCompleteSearch == "Something went wrong") {
return;
}
print("Result from auto complete search: $responseAutoCompleteSearch");
if (responseAutoCompleteSearch["status"] == "OK") {
var placePredictions = responseAutoCompleteSearch["predictions"];
var placePredictionsList = (placePredictions as List).map((jsonData) {
// print("PREDICTION HERE IS: $jsonData");
return PredictedPlaces.fromJson(jsonData);
}).toList();
setState(() {
placesPredictedList = placePredictionsList;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xffffffff),
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
child: const Icon(
Icons.arrow_back,
color: Color(0xff3e3e3e),
size: 25.0,
),
),
);
},
),
title: const Text(
'Enter New Address',
style: TextStyle(
color: Color(0xff3e3e3e),
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
actions: <Widget>[
PopupMenuButton(
onSelected: (result) async {
if (result == 0) {
Navigator.of(context).pop();
}
},
offset: const Offset(0, kToolbarHeight),
itemBuilder: (BuildContext context) => <PopupMenuEntry>[],
),
],
),
backgroundColor: const Color(0xffffffff),
body: Column(
children: [
Container(
decoration: const BoxDecoration(
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
color: const Color(0xffededed),
height: 50,
child: TextFormField(
controller: _formController,
decoration: const InputDecoration(
fillColor: Color(0xff000000),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xffededed)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xffededed)),
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xffededed),
),
),
focusColor: Color(0xff3e3e3e),
hintStyle: TextStyle(
color: Color(0xff3e3e3e),
fontSize: 15,
fontWeight: FontWeight.w300,
),
hintText: ('Search address'),
prefixIcon: const Icon(
Icons.search_rounded,
color: Color(0xff3e3e3e),
),
),
onChanged: (value) {
findPlaceAutoCompleteSearch(value);
print(value);
},
),
),
const SizedBox(height: 10),
const Divider(
color: Color(0xffededed),
thickness: 2,
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 5, horizontal: 20),
child: Row(
children: [
// Container(
// width: 35,
// height: 35,
// child: const Icon(
// Icons.pin_drop_outlined,
// size: 20,
// color: Color(0xffffffff),
// ),
// decoration: const BoxDecoration(
// shape: BoxShape.circle,
// color: const Color(0xbf3e3e3e),
// ),
// ),
// const Padding(
// padding: EdgeInsets.all(8.0),
// child: Text(
// 'Previous Drop-off',
// style: TextStyle(
// color: Color(0xff3e3e3e),
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
],
),
),
],
),
),
),
// const Divider(
// color: Color(0xffededed),
// thickness: 2,
// ),
// Container(
// margin: EdgeInsets.symmetric(vertical: 5, horizontal: 20),
// child: Row(
// children: [
// Container(
// width: 35,
// height: 35,
// child: Icon(Icons.pin_drop_outlined,
// size: 20, color: Color(0xffffffff)),
// decoration: BoxDecoration(
// shape: BoxShape.circle, color: Color(0xbf3e3e3e)),
// ),
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: const Text(
// 'Previous Drop-off',
// style: TextStyle(
// color: Color(0xff3e3e3e),
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ],
// ),
// ),
//list view for predictions
(placesPredictedList.isNotEmpty)
? Expanded(
child: ListView.separated(
itemCount: placesPredictedList.length,
itemBuilder: (context, int index) {
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: PlacePredictionTile(
predictedPlaces: placesPredictedList[index],
),
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider(
height: 2,
thickness: 1,
color: Colors.white,
);
},
),
)
: Container(),
],
),
);
}
Widget _textField({
required TextEditingController controller,
FocusNode? focusNode,
required String label,
required String hint,
required double width,
required Icon prefixIcon,
required Function(String) locationCallback,
}) {
return Container(
width: width * 0.8,
child: TextField(
onChanged: (value) {
locationCallback(value);
},
controller: controller,
focusNode: focusNode,
decoration: InputDecoration(
prefixIcon: prefixIcon,
labelText: label,
filled: true,
fillColor: Colors.white,
enabledBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(
Radius.circular(10.0),
),
borderSide: BorderSide(
color: Colors.grey.shade400,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(
Radius.circular(10.0),
),
borderSide: BorderSide(
color: Colors.blue.shade300,
width: 2,
),
),
contentPadding: const EdgeInsets.all(15),
hintText: hint,
),
),
);
}
}
@Daniel-Sogbey
Copy link
Author

Daniel-Sogbey commented Apr 29, 2023

file_name : request_method.dart

`import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;

class RequestMethod {
static Future receiveRequest(String url) async {

Map<String, String> header = {
  'Access-Control-Allow-Origin': '*', // Required for CORS support to work
  "Access-Control-Allow-Headers":
  "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
  "Access-Control-Allow-Methods": "GET,POST, OPTIONS"
};
http.Response httpResponse = await http.get(Uri.parse(url), headers: header);

try {
  if (httpResponse.statusCode == 200) {
    String responseData = httpResponse.body; //in json format

    var decodeResponseData = json.decode(responseData);
    return decodeResponseData;
  } else {
    return "Something went wrong";
  }
} catch (e) {
  print(e);
  return "Something went wrong";
}

}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment