import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:geolocator/geolocator.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:wheres_my_sign/models/property.dart'; import 'package:wheres_my_sign/widgets/custom_dialog_box.dart'; Future main() async { await dotenv.load(fileName: ".env"); runApp(SignLocatorApp()); } class SignLocatorApp extends StatelessWidget { const SignLocatorApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Sign Locator', theme: ThemeData(primarySwatch: Colors.blue), home: SignMapScreen(), ); } } class SignMapScreen extends StatefulWidget { const SignMapScreen({super.key}); @override SignMapScreenState createState() => SignMapScreenState(); } class SignMapScreenState extends State { GoogleMapController? mapController; Set markers = {}; LatLng _initialPosition = const LatLng(37.7749, -122.4194); // Default: SF BitmapDescriptor customIcon = BitmapDescriptor.defaultMarker; void customMarker() { BitmapDescriptor.asset( ImageConfiguration(), 'assets/icons/sign_marker.png', ).then((icon) { setState(() { customIcon = icon; }); }); } @override void initState() { super.initState(); _requestPermissions(); customMarker(); } Future _requestPermissions() async { await Permission.locationWhenInUse.request(); _goToUserLocation(); } Future _goToUserLocation() async { bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) return; LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) { permission = await Geolocator.requestPermission(); } Position position = await Geolocator.getCurrentPosition(); _initialPosition = LatLng(position.latitude, position.longitude); mapController?.animateCamera(CameraUpdate.newLatLng(_initialPosition)); } void _addMarker() async { Position position = await Geolocator.getCurrentPosition(); final markerId = MarkerId(DateTime.now().toString()); final newMarker = Marker( markerId: markerId, position: LatLng(position.latitude, position.longitude), infoWindow: InfoWindow(title: 'Sign Location'), icon: customIcon, ); setState(() { markers.add(newMarker); }); } // return something like this: // Property { // address: "1234 Smith St", // latitude: 37.7749, // longitude: -122.4194, // signLocations: [LatLng(37.77, -122.42), LatLng(37.775, -122.41)], // } void _addProperty() async { final Property? newProperty = await showDialog( context: context, builder: (BuildContext context) { return CustomDialogBox( title: "Show A Property", descriptions: "Let's show a new property!", text: "Yes", ); }, ); if (newProperty != null) { setState(() { // 🟢 Main property marker markers.add( Marker( markerId: MarkerId( 'property_${newProperty.latitude}_${newProperty.longitude}', ), position: LatLng(newProperty.latitude, newProperty.longitude), icon: BitmapDescriptor.defaultMarkerWithHue( BitmapDescriptor.hueGreen, ), infoWindow: InfoWindow(title: newProperty.address), ), ); // 🔴 Sign location markers for (int i = 0; i < newProperty.signLocations.length; i++) { final LatLng signLocation = newProperty.signLocations[i]; markers.add( Marker( markerId: MarkerId('sign_$i'), position: signLocation, icon: BitmapDescriptor.defaultMarkerWithHue( BitmapDescriptor.hueRed, ), infoWindow: InfoWindow(title: 'Sign ${i + 1}'), ), ); } }); // Optionally: Move camera to property location mapController?.animateCamera( CameraUpdate.newLatLngZoom( LatLng(newProperty.latitude, newProperty.longitude), 14.0, ), ); } } // void _addProperty() async { // showDialog( // context: context, // builder: (BuildContext context) { // return CustomDialogBox( // title: "Show A Property", // descriptions: "Let's show a new property!", // text: "Yes", // ); // }, // ); // } void _clearMarkers() { setState(() { markers.clear(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: SizedBox( width: MediaQuery.of(context).size.width, child: Image.asset( 'assets/app_title.png', // Replace with your image path fit: BoxFit.contain, // Adjust the height as needed ), ), ), body: GoogleMap( zoomGesturesEnabled: true, scrollGesturesEnabled: true, tiltGesturesEnabled: true, rotateGesturesEnabled: true, myLocationButtonEnabled: true, compassEnabled: true, mapType: MapType.normal, onMapCreated: (controller) { mapController = controller; }, initialCameraPosition: CameraPosition( target: _initialPosition, zoom: 14, ), myLocationEnabled: true, markers: markers, ), floatingActionButton: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ FloatingActionButton( onPressed: _addProperty, backgroundColor: Colors.green, tooltip: 'Add new property', child: Icon(Icons.add_home), ), SizedBox(height: 12), FloatingActionButton( onPressed: _addMarker, tooltip: 'Drop Pin', child: Icon(Icons.add_location), ), SizedBox(height: 12), FloatingActionButton( onPressed: _clearMarkers, backgroundColor: Colors.red, tooltip: 'Clear Pins', child: Icon(Icons.clear), ), ], ), ); } }