Rain/lib/app/widgets/create_card_weather.dart

245 lines
9.9 KiB
Dart
Raw Normal View History

2023-06-17 20:57:57 +03:00
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax/iconsax.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/widgets/text_form.dart';
2023-08-03 20:52:20 +03:00
import 'package:rain/main.dart';
2023-06-17 20:57:57 +03:00
class CreateWeatherCard extends StatefulWidget {
const CreateWeatherCard({super.key});
@override
State<CreateWeatherCard> createState() => _CreateWeatherCardState();
}
class _CreateWeatherCardState extends State<CreateWeatherCard> {
bool isLoading = false;
final formKey = GlobalKey<FormState>();
2023-08-03 20:52:20 +03:00
final _focusNode = FocusNode();
2023-06-17 20:57:57 +03:00
final locationController = Get.put(LocationController());
2023-08-03 20:52:20 +03:00
final _controller = TextEditingController();
final _controllerLat = TextEditingController();
final _controllerLon = TextEditingController();
final _controllerCity = TextEditingController();
final _controllerDistrict = TextEditingController();
2023-06-17 20:57:57 +03:00
textTrim(value) {
value.text = value.text.trim();
while (value.text.contains(" ")) {
value.text = value.text.replaceAll(" ", " ");
}
}
void fillController(selection) {
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
@override
Widget build(BuildContext context) {
2023-07-10 21:33:43 +03:00
return Form(
key: formKey,
child: SingleChildScrollView(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 10, left: 5, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Get.back();
},
2023-07-12 20:52:25 +03:00
icon: const Icon(
2023-07-10 21:33:43 +03:00
Iconsax.close_square,
2023-08-03 21:11:58 +03:00
size: 18,
2023-07-09 23:41:51 +03:00
),
2023-07-10 21:33:43 +03:00
),
Text(
'create'.tr,
2023-07-14 20:19:43 +03:00
style: context.textTheme.titleLarge?.copyWith(
fontSize: 20,
),
2023-07-10 21:33:43 +03:00
textAlign: TextAlign.center,
),
IconButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await locationController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
},
2023-07-12 20:52:25 +03:00
icon: const Icon(
2023-07-10 21:33:43 +03:00
Iconsax.tick_square,
2023-08-03 21:11:58 +03:00
size: 18,
2023-07-09 23:41:51 +03:00
),
2023-07-10 21:33:43 +03:00
),
],
2023-06-17 20:57:57 +03:00
),
2023-07-10 21:33:43 +03:00
),
2023-08-03 21:11:58 +03:00
RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return MyTextForm(
elevation: 4,
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(Iconsax.global_search),
controller: _controller,
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getSuggestions(textEditingValue.text, locale);
},
onSelected: (Result selection) => fillController(selection),
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Align(
2023-07-10 21:33:43 +03:00
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
2023-07-14 20:19:43 +03:00
style: context.textTheme.labelLarge,
2023-07-10 21:33:43 +03:00
),
),
);
},
),
),
2023-08-03 21:11:58 +03:00
),
);
},
2023-07-10 21:33:43 +03:00
),
MyTextForm(
2023-08-03 21:11:58 +03:00
elevation: 4,
2023-07-10 21:33:43 +03:00
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
2023-08-03 21:11:58 +03:00
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
2023-07-10 21:33:43 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 || numericValue > 90) {
return 'validate90'.tr;
}
return null;
},
),
MyTextForm(
2023-08-03 21:11:58 +03:00
elevation: 4,
2023-07-10 21:33:43 +03:00
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
2023-08-03 21:11:58 +03:00
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
2023-07-10 21:33:43 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 || numericValue > 180) {
return 'validate180'.tr;
}
return null;
},
),
MyTextForm(
2023-08-03 21:11:58 +03:00
elevation: 4,
2023-07-10 21:33:43 +03:00
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(Icons.location_city_rounded),
2023-08-03 21:11:58 +03:00
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
2023-07-10 21:33:43 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
2023-08-03 21:11:58 +03:00
elevation: 4,
2023-07-10 21:33:43 +03:00
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(Iconsax.global),
2023-08-03 21:11:58 +03:00
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
2023-07-10 21:33:43 +03:00
),
const SizedBox(height: 20),
],
),
),
if (isLoading)
const Center(
child: CircularProgressIndicator(),
2023-06-17 20:57:57 +03:00
),
2023-07-10 21:33:43 +03:00
],
2023-06-17 20:57:57 +03:00
),
),
);
}
}