Using Flutter GetX and an API, how do I display the API data into a Text widget? - flutter

I have been watching YouTube videos and reading how to use GetX to display API data but I cannot get it to work with my API. I cannot figure out what I am missing to be able to display the price of a stock from my StockQuoteModel. I am attempting to put the price into the trailing section of my ListView but do not know how to access the data.
Picture of the App
main.dart
void main() async {
await GetStorage.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
homepage.dart
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final StockController sC = Get.put(StockController());
final StockQuoteController sQC = Get.put(StockQuoteController());
TextEditingController tEC = TextEditingController();
return Scaffold(
appBar: AppBar(
title: Text('Add to List Practice'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Get.bottomSheet(
Container(
height: 150,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(100, 0, 100, 10),
child: TextField(
controller: tEC,
autofocus: true,
maxLines: 1,
autocorrect: false,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.characters,
decoration: InputDecoration(
labelText: 'Add Stock',
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black87,
),
borderRadius: BorderRadius.circular(10),
),
),
onSubmitted: (text) {
sC.stocks.add(Stock(symbol: tEC.text));
tEC.clear();
Get.back();
},
),
),
// SizedBox(height: 15),
ElevatedButton(
onPressed: () {
sC.stocks.add(Stock(symbol: tEC.text));
tEC.clear();
Get.back();
},
child: Text('Enter'),
style: ElevatedButton.styleFrom(
primary: Colors.blue,
),
),
],
),
),
enableDrag: false,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0)),
),
backgroundColor: Colors.white,
);
},
child: Icon(Icons.add),
),
body: Container(
child: Padding(
padding: EdgeInsets.all(5),
child: Obx(
() => ListView.separated(
itemCount: sC.stocks.length,
separatorBuilder: (context, index) {
return Divider(
color: Colors.black,
thickness: 0.1,
height: 0.0,
);
},
itemBuilder: (context, index) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.endToStart,
onDismissed: (direction) {
sC.stocks.removeAt(index);
},
background: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20.0),
color: Colors.red,
child: Icon(
Icons.delete,
color: Colors.white,
),
),
child: ListTile(
leading: Text(
sC.stocks[index].symbol,
),
trailing: Obx(() {
if (sQC.isLoading.value)
return Text('loading');
else
return Text(
sQC.stockQuote.price); // stuck here!
}),
),
);
},
),
),
),
),
);
}
}
services.dart
class StockQuoteServices {
static Future<StockQuote?> getStockQuote() async {
String url =
'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=sq&apikey=***********';
http.Response response;
response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
StockQuote stockQuote = StockQuote.fromJson(json.decode(response.body));
return stockQuote;
} else {
return null;
}
}
}
This is the api json
{
"Global Quote": {
"01. symbol": "SQ",
"02. open": "261.8500",
"03. high": "267.7700",
"04. low": "261.2800",
"05. price": "264.0000",
"06. volume": "6374083",
"07. latest trading day": "2021-07-23",
"08. previous close": "260.5900",
"09. change": "3.4100",
"10. change percent": "1.3086%"
}
}
controller.dart
class StockController extends GetxController {
var stocks = [].obs;
void add(Stock s) {
stocks.add(s);
}
#override
void onInit() {
List? storedStocks = GetStorage().read<List>('stocks');
if (storedStocks != null) {
stocks = storedStocks.map((e) => Stock.fromJson(e)).toList().obs;
}
ever(stocks, (_) {
GetStorage().write('stocks', stocks.toList());
});
super.onInit();
}
}
class StockQuoteController extends GetxController {
var isLoading = true.obs;
var stockQuote = StockQuote().obs;
#override
void onInit() {
getStockQuote();
super.onInit();
}
void getStockQuote() async {
try {
isLoading(true);
var quotes = await StockQuoteServices.getStockQuote();
if (quotes != null) {
stockQuote.value = quotes;
}
} finally {
isLoading(false);
}
}
}
stockmodel.dart
class Stock {
String symbol;
Stock({required this.symbol});
factory Stock.fromJson(Map<String, dynamic> json) =>
Stock(symbol: json['symbol']);
Map<String, dynamic> toJson() => {'symbol': symbol};
}
stockquotemodel.dart
class StockQuote {
GlobalQuote? globalQuote;
StockQuote({this.globalQuote});
StockQuote.fromJson(Map<String, dynamic> json) {
globalQuote = json['Global Quote'] != null
? new GlobalQuote.fromJson(json['Global Quote'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.globalQuote != null) {
data['Global Quote'] = this.globalQuote?.toJson();
}
return data;
}
}
class GlobalQuote {
String? symbol;
String? open;
String? high;
String? low;
String? price;
String? volume;
String? latestTradingDay;
String? previousClose;
String? change;
String? changePercent;
GlobalQuote(
{this.symbol,
this.open,
this.high,
this.low,
this.price,
this.volume,
this.latestTradingDay,
this.previousClose,
this.change,
this.changePercent});
GlobalQuote.fromJson(Map<String, dynamic> json) {
symbol = json['01. symbol'];
open = json['02. open'];
high = json['03. high'];
low = json['04. low'];
price = json['05. price'];
volume = json['06. volume'];
latestTradingDay = json['07. latest trading day'];
previousClose = json['08. previous close'];
change = json['09. change'];
changePercent = json['10. change percent'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['01. symbol'] = this.symbol;
data['02. open'] = this.open;
data['03. high'] = this.high;
data['04. low'] = this.low;
data['05. price'] = this.price;
data['06. volume'] = this.volume;
data['07. latest trading day'] = this.latestTradingDay;
data['08. previous close'] = this.previousClose;
data['09. change'] = this.change;
data['10. change percent'] = this.changePercent;
return data;
}
}

Krish Bhanushali answered it.
I was missing value.
sQC.stockQuote.value.globalQuote!.price as String worked for me.
Had to add the null check and as String for null safety. Not sure if this was the best way but it works.

Related

Getting the total amount of the checkboxes

I am a beginer to flutter
I am trying to get the total amount of checkboxes after checking it.
First Partof the code is working alright but the second part of the code is where I am having issues.
I want to be able to check the boxes, get the total amount in total checked
Please Help me.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:liquid_pull_to_refresh/liquid_pull_to_refresh.dart';
import 'dart:convert';
import 'dart:ffi';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stachup/models/TeamModel.dart';
import 'package:stachup/models/newStaches.dart';
import 'package:stachup/models/TeamModel.dart';
class Stash extends StatefulWidget {
String first_name;
String token;
String referalcode;
String last_name;
Stash(
{Key? key,
required this.first_name,
required this.token,
required this.last_name,
required this.referalcode})
: super(key: key);
#override
State<Stash> createState() => _StashState();
}
class _StashState extends State<Stash> {
bool isChecked = false;
String? first_name;
String? token;
String? last_name;
String? referalcode;
bool setup = false;
String? setupError;
bool _isChecked = false;
late SharedPreferences logindata;
userData() async {
logindata = await SharedPreferences.getInstance();
first_name = logindata.getString('first_name')!;
last_name = logindata.getString('last_name')!;
referalcode = logindata.getString('referalcode')!;
token = logindata.getString('token')!;
setState(() {});
}
List<Team> teams = [];
Future getData() async {
var response = await http.get(Uri.https(
'incoming.isplitpay.com', 'api/durationlist', {'token': token}));
var jsonData = jsonDecode(response.body);
print(token);
for (var eachTeam in jsonData) {
var datetime = DateTime.parse(eachTeam["paid_date"]);
final team = Team(
id_pes: eachTeam['id_pes'],
amount: eachTeam['amount'],
paid_date: datetime,
);
teams.add(team);
}
// print(teams.length);
}
#override
void initState() {
super.initState();
userData();
}
#override
Widget build(BuildContext context) {
//getData();
return Scaffold(
backgroundColor: Colors.blue.shade50,
body: FutureBuilder(
future: getData(),
builder: ((context, snapshot) {
//if done loading show data
if (snapshot.connectionState == ConnectionState.done) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
),
child: ListView.builder(
itemCount: teams.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
height: 80,
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
),
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Checkbox(
checkColor: Colors.white,
value: teams[index].isChecked ?? false,
onChanged: (bool? value) {
setState(() {
teams[index].isChecked = value;
});
print(value);
},
),
Text(
'GHS ' + teams[index].amount,
),
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Text(
'Savings for',
style: GoogleFonts.lato(
fontSize: 16,
),
),
),
Text(
"${teams[index].paid_date.day.toString().padLeft(2, '0')}-${teams[index].paid_date.month.toString().padLeft(2, '0')}-${teams[index].paid_date.year}",
style: GoogleFonts.lato(
fontSize: 16,
),
),
],
)
],
),
),
);
}),
);
//else show circule progress bar
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}),
),
);
}
}
second part of the code
#override
Widget build(BuildContext context) {
var checkedList = dataList.where((data) => data.isChecked ?? false);
var totalAmount = checkedList.isNotEmpty
? 'TotalAmount:${checkedList.reduce((before, after) => Team(amount: '${double.parse(before.amount) + double.parse(after.amount)}', id_pes: '_', paid_date: DateTime.now())).amount} '
: '';
return Scaffold(
body: ListView.builder(
shrinkWrap: true,
itemCount: dataList.length,
itemBuilder: (context, index) {
return Tooltip(message: totalAmount, child: _buildListItem(index));
}));
}

Flutter: Bad state Error: cannot get a field on a DocumentSnapshotPlatform which does not exist

I'm new to Flutter and getting this issue.
Trying to develop a social media app which includes a chat feature. However, it says DocumentSnapshot is not exist.
Of course I understood that one thing is missing, it is clear. But I couldn't understand what is that missing thing and how to solve it.
I examined a lot of posts about this but I couldn't solve my issue. There is no misspelling between Cloud Firestore and my code. I couldn't understand am I missing key or something like this?
It looks like this
Sometimes it also can not upload the profile picture of person.
Here are my codes,
Thanks for helping.
I got this error when I try to type a message:
class Conversation extends StatefulWidget {
final String userId;
final String chatId;
const Conversation({required this.userId, required this.chatId});
#override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State<Conversation> {
FocusNode focusNode = FocusNode();
ScrollController scrollController = ScrollController();
TextEditingController messageController = TextEditingController();
bool isFirst = false;
String? chatId;
#override
void initState() {
super.initState();
scrollController.addListener(() {
focusNode.unfocus();
});
print(widget.chatId);
if (widget.chatId == 'newChat') {
isFirst = true;
}
chatId = widget.chatId;
messageController.addListener(() {
if (focusNode.hasFocus && messageController.text.isNotEmpty) {
setTyping(true);
} else if (!focusNode.hasFocus ||
(focusNode.hasFocus && messageController.text.isEmpty)) {
setTyping(false);
}
});
}
setTyping(typing) {
//here
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
//here
var user = Provider.of<UserViewModel>(context, listen: false).user;
Provider.of<ConversationViewModel>(context, listen: false)
.setUserTyping(widget.chatId, user, typing);
}
#override
Widget build(BuildContext context) {
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
var user = Provider.of<UserViewModel>(context, listen: true).user;
return Consumer<ConversationViewModel>(
builder: (BuildContext context, viewModel, Widget? child) {
return Scaffold(
key: viewModel.scaffoldKey,
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.keyboard_backspace,
),
),
elevation: 0.0,
titleSpacing: 0,
title: buildUserName(),
),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
Flexible(
child: StreamBuilder<QuerySnapshot>(
stream: messageListStream(widget.chatId),
builder: (context, snapshot) {
if (snapshot.hasData) {
//snapshot.hasData
//print(snapshot.data);
print(viewModel);
List messages = snapshot.data!.docs;
viewModel.setReadCount(
widget.chatId, user, messages.length);
return ListView.builder(
controller: scrollController,
padding: EdgeInsets.symmetric(horizontal: 10.0),
itemCount: messages.length,
reverse: true,
itemBuilder: (BuildContext context, int index) {
Message message = Message.fromJson(
messages.reversed.toList()[index].data(),
);
print(message.content);
print(message.senderUid);
print(message.time);
print(message.type);
return ChatBubble(
message: '${message.content}',
time: message.time!,
isMe: message.senderUid == user!.uid,
type: message.type!,
);
},
);
} else {
return Center(child: circularProgress(context));
}
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
elevation: 10.0,
child: Container(
constraints: BoxConstraints(maxHeight: 100.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
IconButton(
icon: Icon(
CupertinoIcons.photo_on_rectangle,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () => showPhotoOptions(viewModel, user),
),
Flexible(
child: TextField(
controller: messageController,
focusNode: focusNode,
style: TextStyle(
fontSize: 15.0,
color:
Theme.of(context).textTheme.headline6!.color,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: InputBorder.none,
border: InputBorder.none,
hintText: "Type your message",
hintStyle: TextStyle(
color: Theme.of(context)
.textTheme
.headline6!
.color,
),
),
maxLines: null,
),
),
IconButton(
icon: Icon(
Ionicons.send,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () {
if (messageController.text.isNotEmpty) {
sendMessage(viewModel, user);
}
},
),
],
),
),
),
)
],
),
),
);
});
}
_buildOnlineText(
var user,
bool typing,
) {
if (user.isOnline) {
if (typing) {
return "typing...";
} else {
return "online";
}
} else {
return 'last seen ${timeago.format(user.lastSeen.toDate())}';
}
}
buildUserName() {
return StreamBuilder(
stream: usersRef.doc('${widget.userId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot documentSnapshot =
snapshot.data as DocumentSnapshot<Object?>;
UserModel user = UserModel.fromJson(
documentSnapshot.data() as Map<String, dynamic>,
);
return InkWell(
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: Hero(
tag: user.email!,
child: CircleAvatar(
radius: 25.0,
backgroundImage: CachedNetworkImageProvider(
'${user.photoUrl}',
),
),
),
),
SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'${user.username}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
SizedBox(height: 5.0),
StreamBuilder(
stream: chatRef.doc('${widget.chatId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot? snap =
snapshot.data as DocumentSnapshot<Object?>;
Map? data = snap.data() as Map<dynamic, dynamic>?;
Map? usersTyping = data?['typing'] ?? {};
return Text(
_buildOnlineText(
user,
usersTyping![widget.userId] ?? false,
),
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 11,
),
);
} else {
return SizedBox();
}
},
),
],
),
),
],
),
onTap: () {},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
showPhotoOptions(ConversationViewModel viewModel, var user) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
builder: (context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Camera"),
onTap: () {
sendMessage(viewModel, user, imageType: 0, isImage: true);
},
),
ListTile(
title: Text("Gallery"),
onTap: () {
sendMessage(viewModel, user, imageType: 1, isImage: true);
},
),
],
);
},
);
}
sendMessage(ConversationViewModel viewModel, var user,
{bool isImage = false, int? imageType}) async {
String msg;
if (isImage) {
msg = await viewModel.pickImage(
source: imageType!,
context: context,
chatId: widget.chatId,
);
} else {
msg = messageController.text.trim();
messageController.clear();
}
Message message = Message(
content: '$msg',
senderUid: user?.uid,
type: isImage ? MessageType.IMAGE : MessageType.TEXT,
time: Timestamp.now(),
);
if (msg.isNotEmpty) {
if (isFirst) {
print("FIRST");
String id = await viewModel.sendFirstMessage(widget.userId, message);
setState(() {
isFirst = false;
chatId = id;
});
} else {
viewModel.sendMessage(
widget.chatId,
message,
);
}
}
}
Stream<QuerySnapshot> messageListStream(String documentId) {
return chatRef
.doc(documentId)
.collection('messages')
.orderBy('time')
.snapshots();
}
}
Also here is the ViewModel codes if I did something wrong here:
class ConversationViewModel extends ChangeNotifier {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
ChatService chatService = ChatService();
bool uploadingImage = false;
final picker = ImagePicker();
File? image;
sendMessage(String chatId, Message message) {
chatService.sendMessage(
message,
chatId,
);
}
Future<String> sendFirstMessage(String recipient, Message message) async {
String newChatId = await chatService.sendFirstMessage(
message,
recipient,
);
return newChatId;
}
setReadCount(String chatId, var user, int count) {
chatService.setUserRead(chatId, user, count);
}
setUserTyping(String chatId, var user, bool typing) {
chatService.setUserTyping(chatId, user, typing);
}
pickImage({int? source, BuildContext? context, String? chatId}) async {
PickedFile? pickedFile = source == 0
? await picker.getImage(
source: ImageSource.camera,
)
: await picker.getImage(
source: ImageSource.gallery,
);
if (pickedFile != null) {
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedFile.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Crop image',
toolbarColor: Theme.of(context!).appBarTheme.backgroundColor,
toolbarWidgetColor: Theme.of(context).iconTheme.color,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
minimumAspectRatio: 1.0,
),
],
);
Navigator.of(context).pop();
if (croppedFile != null) {
uploadingImage = true;
image = File(croppedFile.path);
notifyListeners();
showInSnackBar("Uploading image...", context);
String imageUrl = await chatService.uploadImage(image!, chatId!);
return imageUrl;
}
}
}
void showInSnackBar(String value, context) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
),
);
}
}
Here is the ChatService code:
class ChatService {
FirebaseStorage storage = FirebaseStorage.instance;
sendMessage(Message message, String chatId) async {
//will send message to chats collection with the usersId
await chatRef.doc("$chatId").collection("messages").add(message.toJson());
//will update "lastTextTime" to the last time a text was sent
await chatRef.doc("$chatId").update({"lastTextTime": Timestamp.now()});
}
Future<String> sendFirstMessage(Message message, String recipient) async {
User user = firebaseAuth.currentUser!;
DocumentReference ref = await chatRef.add({
'users': [recipient, user.uid],
});
await sendMessage(message, ref.id);
return ref.id;
}
Future<String> uploadImage(File image, String chatId) async {
Reference storageReference =
storage.ref().child("chats").child(chatId).child(uuid.v4());
UploadTask uploadTask = storageReference.putFile(image);
await uploadTask.whenComplete(() => null);
String imageUrl = await storageReference.getDownloadURL();
return imageUrl;
}
//determine if a user has read a chat and updates how many messages are unread
setUserRead(String chatId, User user, int count) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map reads = snap.get('reads') ?? {};
reads[user.uid] = count;
await chatRef.doc(chatId).update({'reads': reads});
}
//determine when a user has start typing a message
setUserTyping(String chatId, User user, bool userTyping) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map typing = snap.get('typing');
typing[user.uid] = userTyping;
await chatRef.doc(chatId).update({
'typing': typing,
});
}
}

How to configure the eventloader with data from sqlite?

Hi I'm beginner of flutter
I want to make marker on my calendar with eventloader
I try to take the data from SQLite and deliver it to the eventloader, but I saw the log that it failed because it was a Future type.
Sqlite has data List of "Challenge"
event loader need Map<DateTime, List> selectedEvents
When I exit and run the application again, the events stored in the currently selected event disappear.
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_auth/firebase_auth.dart';
import ...
// //
main(){
WidgetsFlutterBinding.ensureInitialized();
runApp(HomePage());
}
// //
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late Map<DateTime, List<Event>> selectedEvents;
CalendarFormat format = CalendarFormat.month;
DateTime selectedDay = DateTime.now();
DateTime focusedDay = DateTime.now();
DatabaseReference ref = FirebaseDatabase.instance.ref("performance");
List<Challenge> makeList = [];
Map<DateTime, List<dynamic>> _events = {};
TextEditingController _eventController = TextEditingController(); // 텍스트 필드에서 text 가져오기
String name = "";
#override
void initState() {
selectedEvents = {};
super.initState();
}
List<Event> _getEventsfromDay(DateTime date) {
return selectedEvents[date] ?? [];
}
#override
void dispose() {
_eventController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xfff2a900),
title: Text("Challenge"),
centerTitle: true,
),
body: Column(
children: [
TableCalendar(
focusedDay: selectedDay,
firstDay: DateTime(1990),
lastDay: DateTime(2050),
calendarFormat: format,
onFormatChanged: (CalendarFormat _format) {
setState(() {
format = _format;
});
},
startingDayOfWeek: StartingDayOfWeek.sunday,
daysOfWeekVisible: true,
//Day Changed
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
selectedDay = selectDay;
focusedDay = focusDay;
});
// print(focusedDay);
},
selectedDayPredicate: (DateTime date) {
return isSameDay(selectedDay, date);
},
eventLoader: _getEventsfromDay,
//To style the Calendar
calendarStyle: CalendarStyle(
isTodayHighlighted: true,
selectedDecoration: BoxDecoration(
color: Color(0xff60584C),
// color: (255, 188, 80),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
),
selectedTextStyle: TextStyle(color: Colors.white),
todayDecoration: BoxDecoration(
color: const Color(0xfff2a900),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
),
defaultDecoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
),
weekendDecoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
),
),
headerStyle: HeaderStyle(
formatButtonVisible: true,
titleCentered: true,
formatButtonShowsNext: false,
formatButtonDecoration: BoxDecoration(
color: Color(0xff60584C),
borderRadius: BorderRadius.circular(10.0),
),
formatButtonTextStyle: TextStyle(
color: Colors.white,
),
),
),
/// 새로추가
Expanded(
child:FutureBuilder<List<Challenge>>(
future: DatabaseHelper.instance.getChallenge(),
builder: (BuildContext context,
AsyncSnapshot<List<Challenge>> snapshot){
if(!snapshot.hasData){
return Center(child:Text('Loading'));
}
return snapshot.data!.isEmpty
? Center(child:Text('챌린지에 참여해보세요!'))
: ListView( // 챌린지 리스트
children: snapshot.data!.map((challenge){
DateTime sqlDate = DateTime.parse(challenge.date);
return Card(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Row(
children: [
SizedBox(
width: 200,
height: 50,
child: Center(
child: Text(challenge.challenge,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: const Color(0xff60584C),
),
),
)
),
],
)
),
Container(
// width: MediaQuery.of(context).size.width * 0.7,
child: Align(
alignment: Alignment.bottomRight,
child: Text(
challenge.date,
style: TextStyle(
fontSize: 15,
color: Colors.grey),
),
),
)
],
)
);
return Center(
child:ListTile(
title:Text(challenge.challenge),
),
);
}).toList(),
);
}),
),
],
),
floatingActionButton: FloatingActionButton.extended(
backgroundColor: Color(0xfff2a900),
onPressed: () => showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("Today's Challenge"),
content: TextFormField(
controller: _eventController,
),
actions: [
TextButton(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text("Ok"),
onPressed: () async {
// 텍스트 필드가 비었을 때
if (_eventController.text.isEmpty) {
} else { // challenge 입력
/// 마커만들 때 쓰일 Map<DateTime, List<Event>> 원소 추가 코드
if (selectedEvents[selectedDay] != null) {
selectedEvents[selectedDay]?.add(
Event(title: _eventController.text),
);
} else {
selectedEvents[selectedDay] = [
Event(title: _eventController.text)
];
}
///
// 로그인한 사용자정보
User? user = FirebaseAuth.instance.currentUser;
for(final providerProfile in user!.providerData){
final emailAddress = providerProfile.email;
List<String>? currentUser = emailAddress?.split('#');
name = currentUser![0];
}
// 현재 날짜
final dateStr = DateFormat('yyyy-MM-dd').format(selectedDay);
// realtime firebase
await ref
.child(name)
.set(_eventController.text)
.asStream();
// sqlite
await DatabaseHelper.instance.add(
Challenge(date:dateStr, challenge: _eventController.text),
);
// _fetchEvents();
}
Navigator.pop(context);
_eventController.clear();
setState((){
///
///
});
return;
},
),
],
),
),
label: Text("🌱"),
icon: Icon(Icons.add),
),
);
}
}
class Challenge{
final int? id;
final String date;
final String challenge;
Challenge({this.id, required this.date, required this.challenge});
factory Challenge.fromMap(Map<String, dynamic> json) => new Challenge(
id : json['id'],
date : json['date'],
challenge: json['challenge']);
Map<String, dynamic> toMap(){
return {
'id' : id,
'date' : date,
'challenge' : challenge,
};
}
}
class DatabaseHelper{
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database> get database async => _database ??=await _initDatabase();
Future<Database> _initDatabase() async{
String path = join(await getDatabasesPath(), 'my_challenge.db');
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
);
}
Future _onCreate(Database db, int version) async{
await db.execute('''
CREATE TABLE my_challenge(
id INTEGER PRIMARY_KEY,
date TEXT,
challenge TEXT
)
''');
}
Future<List<Challenge>> getChallenge() async {
Database db = await instance.database;
var challenges = await db.query('my_challenge', orderBy: 'date');
List<Challenge> challengeList = challenges.isNotEmpty
? challenges.map((c)=>Challenge.fromMap(c)).toList()
:[];
/// selectedEvents : Map<Datetime, List<Event>>
///
return challengeList;
}
Future<int> add(Challenge challenge) async{
Database db = await instance.database;
return await db.insert('my_challenge', challenge.toMap());
}
}
class Event
class Event {
final String title;
Event({required this.title});
String toString() => this.title;
}

how to build sorted listview in flutter (sort as per dates)

I want to display a listview from database. The notes stored in 'note' table are displayed successully. I want to display it as per the dates. i.e recent ones at the top and later ones(future ones) below them. if the date is of tomorrow then it should be at the top and day after tomorrow one below it. If the dates are same I want to sort them as per priority. Can anyone please help me.
(If u use any other date and time picker which can accept date and time together would also be helpful). In my case the table calendar only accepts the date. I am storing the date as TEXT(i dont know if its right)
new_note.dart// this is where I add a new note to the database.
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:intl/intl.dart';
import 'package:vers2cts/models/color_dropdown.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/form_helper.dart';
class NewNote extends StatefulWidget{
final NoteModel note;
final CustomerModel customer;
NewNote(this.customer,this. note);
#override
State<StatefulWidget> createState() {
return New_NoteState(this.customer,this.note);
}
}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
New_NoteState(this.customer,this.note);
NoteModel note=new NoteModel();
CustomerModel customer=new CustomerModel();
TextEditingController NoteController=TextEditingController();
TextEditingController custfNameController = TextEditingController();
DateTime _reminderDate = DateTime.now();
DateTime _selectedDay = DateTime.now();
DBService dbService=new DBService();
double _height;
double _width;
dynamic currentTime = DateFormat.jm().format(DateTime.now());
String _setTime, _setDate;
String _hour, _minute, _time;
String dateTime;
DateTime selectedDate = DateTime.now();
TimeOfDay selectedTime = TimeOfDay(hour: 00, minute: 00);
TextEditingController _dateController = TextEditingController();
TextEditingController _timeController = TextEditingController();
SpeedDial _speedDial(){
return SpeedDial(
animatedIcon: AnimatedIcons.add_event,
animatedIconTheme: IconThemeData(size: 24.0),
backgroundColor: Colors.yellow,
curve: Curves.easeInCirc,
children: [
SpeedDialChild(
child: Icon(Icons.location_on,color: Colors.yellow,),
label: 'Add Location',
),
SpeedDialChild(
child: Icon(Icons.keyboard_voice),
label: 'Add voice',
),
SpeedDialChild(
child: Icon(Icons.attachment_outlined,color :Colors.redAccent),
label: 'Add File',
),
SpeedDialChild(
child: Icon(Icons.image,color: Colors.lightBlue,),
label: 'Add Image',
),
],
);
}
//for Switch
bool isSwitched = false;
var textValue = 'Switch is OFF';
void toggleSwitch(bool value) {
if(isSwitched == false)
{
setState(() {
isSwitched = true;
note.rmnd_ind=1;
});
}
else
{
setState(() {
isSwitched = false;
note.rmnd_ind=0;
});
}
}
Future<Null> _selectTime(BuildContext context) async {
final TimeOfDay picked = await showTimePicker(
context: context,
initialTime: selectedTime,
);
if (picked != null)
setState(() {
selectedTime = picked;
_hour = selectedTime.hour.toString();
_minute = selectedTime.minute.toString();
_time = _hour + ' : ' + _minute;
_timeController.text = _time;
});
}
#override
void initState() {
_timeController.text=currentTime;
super.initState();
}
#override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
var name=customer.first_name+" "+customer.last_name;
custfNameController.text = name;
String _chosenValue;
return WillPopScope(
onWillPop: () {navigationBar
moveToLastScreen();
},
child: Scaffold(
appBar:AppBar(),
body:ListView(
children: <Widget>[
SizedBox(
height: 2.0,
),
TextField(controller: custfNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Align(
alignment: Alignment.centerLeft,
child: Text("Add New",textAlign: TextAlign.left,
style: TextStyle(fontSize: 22,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 2.0,
),
Divider(),
SizedBox(
height: 2.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: NoteController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: const BorderSide(width: 2.0),)),
keyboardType: TextInputType.multiline,
minLines: 5,//Normal textInputField will be displayed
maxLines: 5, // when user presses enter it will adapt to it
onChanged: (value) {
this.note.note = value;
},
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: TableCalendar(
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay=selectedDay;
String _reminderDate = DateFormat('dd-MM-yyyy').format(_selectedDay);
note.actn_on=_reminderDate.toString();
});
},// Set initial date
focusedDay: DateTime.now(),
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),),
),
Row(
children: <Widget>[
Expanded(child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text("Set time",style: TextStyle(fontSize: 20),),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: InkWell(
onTap: () {
_selectTime(context);
},
child: TextFormField(
style: TextStyle(fontSize: 30),
textAlign: TextAlign.center,
onSaved: (String val) {
_setTime = val;
},
enabled: false,
keyboardType: TextInputType.text,
controller: _timeController,
),
),
),
),
]
),
SizedBox(
height: height*0.03,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
Text("Remind me",style: TextStyle(fontSize: 20),),
Padding(
padding: const EdgeInsets.only(left:80.0),
child: Container(
child: Switch(
onChanged: toggleSwitch,
value: isSwitched,
),
),
),
],),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.start,
children:<Widget>[
Text("Priority",style: TextStyle(fontSize: 20.0),),
Padding(
padding: const EdgeInsets.only(left:20.0),
child: Container(
child: SmoothStarRating(
size: height=50.0,
allowHalfRating: false,
onRated: (value) {
this.note.prty=value;
print("rating value -> $value");
},
),
),
)]),
),
SizedBox(
height: height*0.08,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme.of(context).primaryColorDark,
textColor: Colors.white,
child: Text('Save',textScaleFactor: 1.5,),
onPressed: (){
setState(() {
_save();
});
},
),
),
),
],
),
floatingActionButton:_speedDial(),
));
}
void moveToLastScreen() {
Navigator.pop(context, true);
}
void _save() async {
moveToLastScreen();
note.cust_id=customer.cust_id;
print(customer.cust_id);
print(note.cust_id);
int result;
if (note.note_id != null) { // Case 1: Update operation
result = await dbService.updateNote(note);
} else {
result = await dbService.insertNote(note);
}
if (result != 0) {
FormHelper.showAlertDialog(context,'Status', 'Note Saved Successfully');
} else {
FormHelper.showAlertDialog(context,'Status', 'Problem Saving Note');
}
}
}
note_info.dart // This is the screen which displays the listview
import 'dart:io';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/db_helper.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:vers2cts/utils/form_helper.dart';
import 'new_note.dart';
class Note_Info extends StatefulWidget{
final String appBarTitle;
final CustomerModel customer;
Note_Info(this. customer, this.appBarTitle);
#override
State<StatefulWidget> createState() {
return Note_InfoState(this. customer,this.appBarTitle);
}
}
class Note_InfoState extends State<Note_Info> {
DBService dbService = DBService();
List<NoteModel> noteList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
NoteModel note=NoteModel();
String appBarTitle;
CustomerModel customer=new CustomerModel();
Note_InfoState(this.customer, this.appBarTitle);
bool rememberMe = false;
DateTime _date = DateTime.now();
TextEditingController custfNameController = TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
updateListView();
if (noteList == null) {
noteList = List<NoteModel>();
updateListView();
}
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
var height = MediaQuery.of(context).size.height;
var name=customer.first_name+" "+customer.last_name;
custfNameController.text = name;
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.add,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => NewNote(customer,note)));
},
)
],
),
body: Container(
child: Column(
children: <Widget>[
TextField(controller: custfNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(children: [
ImageProfile(customer.cust_photo),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: IconButton(
icon: Icon(
Icons.call,
color: Colors.green,
size: 45,
),
onPressed: () {
},
),
),
],),
),
SizedBox(
height: 50,
child: AppBar(
bottom: TabBar(
tabs: [
Tab(
text: "All",
),
Tab(
text: "Pending",
),
Tab(
text: "Cancelled",
),
Tab(
text: "Completed",
),
],
),
),
),
// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
child: getNotecheckList()
),
// second tab bar viiew widget
Container(
),
Container(
child: Center(
child: Text(
'Cancelled',
),
),
),
Container(
child: Center(
child: Text(
'Completed',
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme
.of(context)
.primaryColorDark,
textColor: Colors.white,
child: Text('Save', textScaleFactor: 1.5,),
onPressed: () {
setState(() {
//_reset();
});
},
),
),
),
]
),
)
));
}
Widget ImageProfile(String fileName) {
return Center(
child: CircleAvatar(
radius: 80.0,
backgroundImage: fileName == null
?AssetImage('images/person_icon.jpg')
:FileImage(File(customer.cust_photo))),
);
}
ListView getNoteListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(this.noteList[position].note, style: titleStyle,),
//subtitle: Text(this.customerList[position].date),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.grey,),
onTap: () {
// _delete(context, customerList[position]);
},
),
onTap: () {
//navigateToDetail(this.customerList[position],'Edit ');
},
),
);
},
);
}
Future<void> updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
int cid=customer.cust_id;
Future<List<NoteModel>> noteListFuture = dbService.getCustomerNotes(cid);
noteListFuture.then((noteList) {
setState(() {
this.noteList = noteList;
this.count = noteList.length;
});
});
});
}
int _isChecked=-1;
var selectedIndices = [];
ListView getNotecheckList() {
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: CheckboxListTile(
title: Text(this.noteList[position].note),
subtitle: Text(this.noteList[position].actn_on),
value: selectedIndices.contains(position),
onChanged: (_) {
if (selectedIndices.contains(position)) {
selectedIndices.remove(position);// unselect
} else {
selectedIndices.add(position); // select
}
},
controlAffinity: ListTileControlAffinity.leading,
),
);
},
);
}
}
}
note_model.dart
import 'model.dart';
class NoteModel extends Model {
static String table = 'note';
bool isSelected=false;
int note_id;
int cust_id;
String note;
String actn_on;
int rmnd_ind;
double prty;
String colr;
String sts;
int id;
String cre_date;
String cre_by;
String mod_date;
String mod_by;
int txn_id;
int delete_ind;
NoteModel({
this.note_id,
this.cust_id,
this.note,
this.actn_on,
this.rmnd_ind,
this.prty,
this.colr,
this.sts,
this.id,
this.cre_date,
this.cre_by,
this.mod_date,
this.mod_by,
this.txn_id,
this.delete_ind
});
static NoteModel fromMap(Map<String, dynamic> map) {
return NoteModel(
note_id: map["note_id"],
cust_id: map['cust_id'],
note: map['note'].toString(),
actn_on: map['actn_on'].toString(),
rmnd_ind: map['rmnd_ind'],
prty: map['prty'],
colr: map['colr'].toString(),
sts: map['sts'].toString(),
id: map['id'],
cre_date: map['cre_date'].toString(),
cre_by: map['cre_by'].toString(),
mod_date: map['mod_date'].toString(),
mod_by: map['mod_by'].toString(),
txn_id: map['txn_id'],
delete_ind: map['delete_ind'],
);
}
Map<String, dynamic> toMap() {
Map<String, dynamic> map = {
'note_id': note_id,
'cust_id': cust_id,
'note':note,
'actn_on': actn_on,
'rmnd_ind': rmnd_ind,
'prty': prty,
'colr': colr,
'sts':sts,
'id': id,
'cre_date': cre_date,
'cre_by': cre_by,
'mod_date':mod_date,
'mod_by':mod_by,
'txn_id':txn_id,
'delete_ind': delete_ind
};
if (note_id != null) {
map['note_id'] = note_id;
}
return map;
}
}
db_service.dart
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/utils/db_helper.dart';
class DBService {
Future<int> insertNote(NoteModel note) async {
await DB.init();
var result = await DB.insert(NoteModel.table, note);
return result;
}
Future<List<Map<String, dynamic>>> getNoteMapList() async {
await DB.init();
var result = await DB.query(NoteModel.table);
return result;
}
Future<List<NoteModel>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("note WHERE cust_id = '$customer'");
int count = res.length;
List<NoteModel> notelist = List<NoteModel>();
for (int i = 0; i < count; i++) {
notelist.add(NoteModel.fromMap(res[i]));
}
return notelist;
}
}
db_helper.dart actn_on saves the date and prty saves the priority
import 'dart:async';
import 'package:vers2cts/models/model.dart';
import 'package:path/path.dart' as p;
import 'package:sqflite/sqflite.dart';
abstract class DB {
static Database _db;
static int get _version => 1;
static Future<Database> init() async {
if (_db != null) {
return _db;
}
try {
var databasesPath = await getDatabasesPath();
String _path = p.join(databasesPath, 'CTS.db');
_db = await openDatabase(_path, version: _version, onCreate: onCreate);
print('db location:'+_path);
} catch (ex) {
print(ex);
}
}
static void onCreate(Database db, int version) async {
await db.execute(
'CREATE TABLE note (note_id INTEGER PRIMARY KEY,cust_id INTEGER, '
'note TEXT, '
'actn_on TEXT, rmnd_ind INTEGER, prty REAL, colr TEXT,'
'sts TEXT,'
'id INTEGER, cre_date TEXT,cre_by TEXT, mod_date TEXT,mod_by TEXT, txn_id INTEGER, delete_ind INTEGER)');
}
static Future<List<Map<String, dynamic>>> query(String table) async =>
_db.query(table);
static Future<int> insert(String table, Model model) async =>
await _db.insert(table, model.toMap());
static Future<List<Map<String, dynamic>>> rawQuery(String table) async =>
_db.query(table);
}
Thankyou DarShan I got my answer I just had to use ORDER BY in my query
Future<List<NoteModel>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("note WHERE cust_id = '$customer' ORDER BY actn_on ASC,prty DESC;");
int count = res.length;
List<NoteModel> notelist = List<NoteModel>();
// For loop to create a 'Note List' from a 'Map List'
for (int i = 0; i < count; i++) {
notelist.add(NoteModel.fromMap(res[i]));
}
return notelist;
}

Is it possible to POST Data using localhost woocommerce rest api in flutter

Is it possible to POST data from flutter app to woocommerce localhost using woocommerce localhost server rest api.
i have GET & POST data with private domain but i want to POST & GET data with localhost woocommerce rest api. i have setup my wordpress and woocommerce on localhost I am trying to make flutter ecommerce app and trying to GET & POST data from woocommerce localhost. but its not working and i dont want to send from private domain rest api, i can get data on postman if i select OAuth 1.0 but if i dont use OAuth 1.0 i cant get data.
Config.dart
class Config {
static String key =
'ck_00000000000000000000000000';
static String sceret =
'cs_00000000000000000000000000';
static String url = 'http://10.0.2.2:80/wordpress_new/wp-json/wc/v3/';
static String customerURL = 'customers';
}
customer.dart
class CustomerModel {
String email;
String firstName;
String lastName;
String password;
CustomerModel({
this.email,
this.firstName,
this.lastName,
this.password,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {};
map.addAll({
'email': email,
'first_name': firstName,
'last_name': lastName,
'password': password,
'username': email,
});
return map;
}
}
apiservice.dart
class APIService {
Future<bool> createCustomer(CustomerModel model) async {
var authToken = base64.encode(
utf8.encode(Config.key + ':' + Config.sceret),
);
bool ret = false;
try {
var response = await Dio().post(
Config.url +
Config.customerURL,
data: model.toJson(),
options: new Options(headers: {
HttpHeaders.authorizationHeader: 'Basic $authToken',
HttpHeaders.contentTypeHeader: 'application/json',
}));
if (response.statusCode == 201) {
ret = true;
}
} on DioError catch (e) {
if (e.response.statusCode == 404) {
print(e.response.statusCode);
ret = false;
} else {
print(e.message);
print(e.request);
ret = false;
}
}
return ret;
}
Future<LoginResponseModel> loginCustomer(
String username,
String password,
) async {
LoginResponseModel model;
try {
var response = await Dio().post(Config.tokenURL,
data: {
'username': username,
'password': password,
},
options: new Options(headers: {
HttpHeaders.contentTypeHeader: 'application/x-www-form-urlencoded',
}));
if (response.statusCode == 200) {
model = LoginResponseModel.fromJson(response.data);
}
} on DioError catch (e) {
print(e.message);
}
return model;
}
}
signuppage.dart
class SignupPage extends StatefulWidget {
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
APIService apiService;
CustomerModel model;
GlobalKey<FormState> globalKey = GlobalKey<FormState>();
bool hidePassword = true;
bool isApiCallProcess = false;
#override
void initState() {
apiService = new APIService();
model = new CustomerModel();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
automaticallyImplyLeading: true,
title: Text('Sign Up'),
),
body: ProgressHUD(
child: Form(
key: globalKey,
child: _formUI(),
),
inAsyncCall: isApiCallProcess,
opacity: 0.3),
);
}
Widget _formUI() {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(10.00),
child: Container(
child: Align(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FormHelper.fieldLabel('First Name'),
FormHelper.textInput(
context,
model.firstName,
(value) => {
this.model.firstName = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter First Name.';
}
return null;
},
),
FormHelper.fieldLabel('Last Name'),
FormHelper.textInput(
context,
model.lastName,
(value) => {
this.model.lastName = value,
},
onValidate: (value) {
return null;
},
),
FormHelper.fieldLabel('Email Id'),
FormHelper.textInput(
context,
model.email,
(value) => {
this.model.email = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter Email id.';
}
if (value.isNotEmpty && !value.toString().isValidEmail()) {
return 'Please enter valid email id';
}
},
),
FormHelper.fieldLabel('Password'),
FormHelper.textInput(
context,
model.password,
(value) => {
this.model.password = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter Password.';
}
return null;
},
obscureText: hidePassword,
suffixIcon: IconButton(
onPressed: () {
setState(() {
hidePassword = !hidePassword;
});
},
color: Theme.of(context).accentColor.withOpacity(0.4),
icon: Icon(
hidePassword ? Icons.visibility_off : Icons.visibility,
),
),
),
SizedBox(
height: 20,
),
Center(
child: FormHelper.saveButton(
'Register',
() {
if (validateAndSave()) {
print(model.toJson());
setState(() {
isApiCallProcess = true;
});
apiService.createCustomer(model).then(
(ret) {
setState(() {
isApiCallProcess = false;
});
if (ret) {
FormHelper.showMessage(
context,
'WooCommerce App',
'Registration Successfull',
'Ok',
() {
Navigator.of(context).pop();
},
);
} else {
FormHelper.showMessage(
context,
'WooCommerce App',
'Email Id already registered.',
'Ok',
() {
Navigator.of(context).pop();
},
);
}
},
);
}
},
),
)
],
),
),
),
),
);
}
bool validateAndSave() {
final form = globalKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
}
form_helper.dart
class FormHelper {
static Widget textInput(
BuildContext context,
Object initialValue,
Function onChanged, {
bool isTextArea = false,
bool isNumberInput = false,
obscureText: false,
Function onValidate,
Widget prefixIcon,
Widget suffixIcon,
}) {
return TextFormField(
initialValue: initialValue != null ? initialValue.toString() : "",
decoration: fieldDecoration(
context,
"",
"",
suffixIcon: suffixIcon,
),
obscureText: obscureText,
maxLines: !isTextArea ? 1 : 3,
keyboardType: isNumberInput ? TextInputType.number : TextInputType.text,
onChanged: (String value) {
return onChanged(value);
},
validator: (value) {
return onValidate(value);
},
);
}
static InputDecoration fieldDecoration(
BuildContext context,
String hintText,
String helperText, {
Widget prefixIcon,
Widget suffixIcon,
}) {
return InputDecoration(
contentPadding: EdgeInsets.all(6),
hintText: hintText,
helperText: helperText,
prefixIcon: prefixIcon,
suffixIcon: suffixIcon,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 1,
),
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 1,
),
),
);
}
static Widget fieldLabel(String labelName) {
return new Padding(
padding: EdgeInsets.fromLTRB(0, 5, 0, 10),
child: Text(
labelName,
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
);
}
static Widget saveButton(String buttonText, Function onTap,
{String color, String textColor, bool fullWidth}) {
return Container(
height: 50.0,
width: 150,
child: GestureDetector(
onTap: () {
onTap();
},
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.redAccent,
style: BorderStyle.solid,
width: 1.0,
),
color: Colors.redAccent,
borderRadius: BorderRadius.circular(30.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Text(
buttonText,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
letterSpacing: 1,
),
),
),
],
),
),
),
);
}
static void showMessage(
BuildContext context,
String title,
String message,
String buttonText,
Function onPressed,
) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(title),
content: new Text(message),
actions: [
new FlatButton(
onPressed: () {
return onPressed();
},
child: new Text(buttonText),
)
],
);
},
);
}
}
progressHUD.dart
class ProgressHUD extends StatelessWidget {
final Widget child;
final bool inAsyncCall;
final double opacity;
final Color color;
final Animation<Color> valueColor;
ProgressHUD({
Key key,
#required this.child,
#required this.inAsyncCall,
this.opacity = 0.3,
this.color = Colors.grey,
this.valueColor,
}) : super(key: key);
#override
Widget build(BuildContext context) {
List<Widget> widgetList = new List<Widget>();
widgetList.add(child);
if (inAsyncCall) {
final modal = new Stack(
children: [
new Opacity(
opacity: opacity,
child: ModalBarrier(dismissible: false, color: color),
),
new Center(child: new CircularProgressIndicator()),
],
);
widgetList.add(modal);
}
return Stack(
children: widgetList,
);
}
}