Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.08 KB | None | 0 0
  1. // const route
  2. class Constant {
  3. static const String baseUrl = "http://192.168.6.106/latihan/api/";
  4. static const String apiAddProduct = baseUrl + "addproduct.php";
  5. static const String apiGetProduct = baseUrl + "getproduct.php";
  6. static const String apiLogin = baseUrl + "login.php";
  7. }
  8.  
  9. // entry dart
  10. import 'package:flutter/material.dart';
  11. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  12. import 'package:barcode_scan/barcode_scan.dart';
  13. import 'package:flutter/services.dart';
  14. import 'dart:async';
  15. import 'dart:convert';
  16. import 'package:http/http.dart' as http;
  17. import 'const.dart';
  18.  
  19. class Response {
  20. final String status;
  21. final String message;
  22.  
  23. Response({this.status, this.message});
  24.  
  25. factory Response.fromJson(Map<String, dynamic> json) {
  26. return Response(
  27. status: json['status'],
  28. message: json['message'],
  29. );
  30. }
  31. }
  32.  
  33. Future<Response> post(String url,var body)async{
  34. return await http
  35. .post(Uri.encodeFull(url), body: body, headers: {"Accept":"application/json"})
  36. .then((http.Response response) {
  37.  
  38. final int statusCode = response.statusCode;
  39.  
  40. if (statusCode < 200 || statusCode > 400 || json == null) {
  41. throw new Exception("Error while fetching data");
  42. }
  43. return Response.fromJson(json.decode(response.body));
  44. });
  45. }
  46.  
  47. class EntryData extends StatefulWidget {
  48. @override
  49. EntryDataState createState() => new EntryDataState();
  50. }
  51.  
  52. class EntryDataState extends State<EntryData> {
  53.  
  54. // text field
  55. final _nomerRakController = TextEditingController();
  56. final _namaProdukController = TextEditingController();
  57. // dropdown category
  58. List _category = ["Buah-buahan", "Snack", "Stationary", "Baju", "Ice Cream"];
  59. List<DropdownMenuItem<String>> _dropDownMenuItems;
  60. String _currentCategory;
  61. // datepicker
  62. String _datetime = '';
  63. int _year = 2018;
  64. int _month = 11;
  65. int _date = 11;
  66. // radio
  67. String _radioValue1;
  68. // scanner
  69. String _scanResult = '';
  70. // member simpan data
  71. String _response = '';
  72. bool apiCall = false;
  73.  
  74. @override
  75. void initState() {
  76. super.initState();
  77. // dropdown category
  78. _dropDownMenuItems = getDropDownMenuItems();
  79. _currentCategory = _dropDownMenuItems[0].value;
  80. // datepicker
  81. DateTime now = DateTime.now();
  82. _year = now.year;
  83. _month = now.month;
  84. _date = now.day;
  85. }
  86.  
  87. // widget simpan data
  88. Widget getProperWidget(){
  89. if(apiCall)
  90. return AlertDialog(
  91. content: new Column(
  92. children: <Widget>[
  93. CircularProgressIndicator(),
  94. Text("Please wait")
  95. ],
  96. )
  97. );
  98. else
  99. return Center(
  100. child: Text(
  101. _response,
  102. style: new TextStyle(fontSize: 15.0)
  103. )
  104. );
  105. }
  106.  
  107. void _callPostAPI() {
  108. post(
  109. Constant.apiAddProduct,
  110. {
  111. "nomor_rak": _nomerRakController.text,
  112. "nama_produk": _namaProdukController.text,
  113. "kategori": _currentCategory,
  114. "expired_date": _datetime,
  115. "scan_code": _scanResult,
  116. "discount": _radioValue1
  117. }).then((response) {
  118.  
  119. setState(() {
  120. apiCall = false;
  121. _response = response.message;
  122. });
  123.  
  124. // tambahkan baris ini
  125. Navigator.pop(context);
  126.  
  127. },
  128. onError: (error) {
  129. apiCall = false;
  130. _response = error.toString();
  131. }
  132. );
  133. }
  134.  
  135. // dropdown category
  136. List<DropdownMenuItem<String>> getDropDownMenuItems() {
  137. List<DropdownMenuItem<String>> items = new List();
  138. for (String kategori in _category) {
  139. items.add(new DropdownMenuItem(
  140. value: kategori,
  141. child: new Text(kategori)
  142. ));
  143. }
  144. return items;
  145. }
  146.  
  147. void changedDropDownItem(String selectedCategory) {
  148. setState(() {
  149. _currentCategory = selectedCategory;
  150. });
  151. }
  152.  
  153. // radio discount
  154. void _handleRadioValueChange1(String value) {
  155. setState(() {
  156. _radioValue1 = value;
  157. });
  158. }
  159.  
  160. /// Display date picker.
  161. void _showDatePicker() {
  162. final bool showTitleActions = false;
  163. DatePicker.showDatePicker(
  164. context,
  165. showTitleActions: true,
  166. minYear: 2019,
  167. maxYear: 2022,
  168. initialYear: _year,
  169. initialMonth: _month,
  170. initialDate: _date,
  171. confirm: Text(
  172. 'PILIH',
  173. style: TextStyle(color: Colors.red),
  174. ),
  175. cancel: Text(
  176. 'BATAL',
  177. style: TextStyle(color: Colors.cyan),
  178. ),
  179. locale: "en",
  180. dateFormat: "dd-mm-yyyy",
  181. onChanged: (year, month, date) {
  182. //debugPrint('onChanged date: $year-$month-$date');
  183.  
  184. if (!showTitleActions) {
  185. _changeDatetime(year, month, date);
  186. }
  187. },
  188. onConfirm: (year, month, date) {
  189. _changeDatetime(year, month, date);
  190. },
  191. );
  192. }
  193.  
  194. void _changeDatetime(int year, int month, int date) {
  195. setState(() {
  196. _year = year;
  197. _month = month;
  198. _date = date;
  199. _datetime = '$date-$month-$year';
  200. });
  201. }
  202.  
  203. // scan QR
  204. Future _scanQR() async {
  205. try {
  206. String qrResult = await BarcodeScanner.scan();
  207. setState(() {
  208. _scanResult = qrResult;
  209. });
  210. } on PlatformException catch (ex) {
  211. if (ex.code == BarcodeScanner.CameraAccessDenied) {
  212. setState(() {
  213. _scanResult = "Camera permission was denied";
  214. });
  215. } else {
  216. setState(() {
  217. _scanResult = "Unknown Error $ex";
  218. });
  219. }
  220. } on FormatException {
  221. setState(() {
  222. _scanResult = "You pressed the back button before scanning anything";
  223. });
  224. } catch (ex) {
  225. setState(() {
  226. _scanResult = "Unknown Error $ex";
  227. });
  228. }
  229. }
  230.  
  231.  
  232. @override
  233. Widget build(BuildContext context) {
  234. return Scaffold(
  235. appBar: AppBar(
  236. title: Text('Produk Entry'),
  237. ),
  238. body: SafeArea(
  239. child: ListView(
  240. padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  241. children: <Widget>[
  242. // text field
  243. TextField(
  244. controller: _nomerRakController,
  245. decoration: InputDecoration(
  246. filled: false,
  247. labelText: 'Nomer Rak',
  248. ),
  249. ),
  250. // spacer
  251. SizedBox(height: 5.0),
  252. // text field
  253. TextField(
  254. controller: _namaProdukController,
  255. decoration: InputDecoration(
  256. filled: false,
  257. labelText: 'Nama Produk',
  258. ),
  259. ),
  260.  
  261. // Dropdown
  262. new Container(
  263. padding: EdgeInsets.all(10.0),
  264. //color: Colors.blueGrey,
  265. child: new Row(
  266. children: <Widget>[
  267. new Text("Kategori: ", style: new TextStyle(fontSize: 15.0)),
  268. new DropdownButton(
  269. value: _currentCategory,
  270. items: _dropDownMenuItems,
  271. onChanged: changedDropDownItem,
  272. )
  273. ],
  274. ),
  275. ),
  276.  
  277. // datepicker
  278. new Container(
  279. //padding: EdgeInsets.all(10.0),
  280. //color: Colors.blueGrey,
  281. child: new Row(
  282. children: <Widget>[
  283. RaisedButton(
  284. child: Text('Expired Date', style: new TextStyle(fontSize: 15.0)),
  285. onPressed: () {
  286. _showDatePicker();
  287. },
  288. ),
  289. new Text(" $_datetime", style: new TextStyle(fontSize: 15.0)),
  290. ],
  291. ),
  292. ),
  293.  
  294. // QR scanner
  295. new Container(
  296. //padding: EdgeInsets.all(10.0),
  297. //color: Colors.blueGrey,
  298. child: new Row(
  299. children: <Widget>[
  300. RaisedButton(
  301. child: Text(' Scan Code ', style: new TextStyle(fontSize: 15.0)),
  302. onPressed: () {
  303. _scanQR();
  304. },
  305. ),
  306. new Text(" $_scanResult", style: new TextStyle(fontSize: 15.0)),
  307. ],
  308. ),
  309. ),
  310.  
  311. // Radio
  312. new Container(
  313. //padding: EdgeInsets.all(10.0),
  314. //color: Colors.blueGrey,
  315. child: new Row(
  316. children: <Widget>[
  317. new Radio(
  318. value: "Discount",
  319. groupValue: _radioValue1,
  320. onChanged: _handleRadioValueChange1,
  321. ),
  322. new Text(
  323. 'Discount',
  324. style: new TextStyle(fontSize: 15.0),
  325. ),
  326. new Radio(
  327. value: "Non Discount",
  328. groupValue: _radioValue1,
  329. onChanged: _handleRadioValueChange1,
  330. ),
  331. new Text(
  332. 'Non Discount',
  333. style: new TextStyle(fontSize: 15.0),
  334. ),
  335. ],
  336. ),
  337. ),
  338.  
  339. // button
  340. RaisedButton(
  341. child: Text('SIMPAN'),
  342. onPressed: () {
  343.  
  344. setState((){
  345. apiCall=true; // Set state like this
  346. });
  347.  
  348. _callPostAPI();
  349. },
  350.  
  351. ),
  352.  
  353. // POST Response
  354. getProperWidget(),
  355.  
  356. ],
  357. )
  358. ),
  359. );
  360. }
  361. }
  362.  
  363. // list.dart
  364. import 'package:flutter/material.dart';
  365. import 'package:flutter_app/login.dart';
  366. import 'dart:convert';
  367. import 'dart:async';
  368. import 'package:http/http.dart' as http;
  369. import 'package:flutter/foundation.dart';
  370. import 'package:shared_preferences/shared_preferences.dart';
  371. import 'const.dart';
  372.  
  373. // class untuk objek json
  374. class Product {
  375. final String id;
  376. final String nama_produk;
  377. final String kategori;
  378. final String expired_date;
  379. final String nomor_rak;
  380. final String scan_code;
  381. final String discount;
  382.  
  383. Product({this.id, this.nama_produk, this.kategori, this.expired_date,
  384. this.nomor_rak, this.scan_code, this.discount});
  385.  
  386. factory Product.fromJson(Map<String, dynamic> json) {
  387. return Product(
  388. id: json['id'] as String,
  389. nama_produk: json['nama_produk'] as String,
  390. kategori: json['kategori'] as String,
  391. expired_date: json['expired_date'] as String,
  392. nomor_rak: json['nomor_rak'] as String,
  393. scan_code: json['scan_code'] as String,
  394. discount: json['discount'] as String,
  395. );
  396. }
  397. }
  398.  
  399. // fungsi parse foto untuk mengubah dari string json ke array List<Photo>
  400. List<Product> parseProduct(String responseBody) {
  401. final parsed = json.decode(responseBody).cast<Map<String,dynamic>>();
  402. return parsed.map<Product>((json)=>Product.fromJson(json)).toList();
  403. }
  404.  
  405. // fungsi fetch untuk mengubah dari end point api ke array List<Photo>
  406. Future<List<Product>> fetchProduct(http.Client client) async {
  407. final response = await client.get(Constant.apiGetProduct);
  408. return compute(parseProduct, response.body);
  409. }
  410.  
  411. class ProductList extends StatelessWidget {
  412. @override
  413. Widget build(BuildContext context) {
  414. return FutureBuilder <List<Product>> (
  415. future: fetchProduct(http.Client()),
  416. builder: (context, snapshot) {
  417. if (snapshot.hasError) print(snapshot.error);
  418. return (snapshot.hasData) ? ProductListBuilder(photos: snapshot.data):
  419. Center(child: CircularProgressIndicator());
  420. }
  421. );
  422. }
  423. }
  424.  
  425. class ProductListBuilder extends StatelessWidget {
  426. final List<Product> photos;
  427. ProductListBuilder({Key key, this.photos}) : super(key : key);
  428.  
  429. @override
  430. Widget build(BuildContext context) {
  431. return ListView.builder(
  432. itemCount: photos.length,
  433. itemBuilder: (context, index) {
  434. return ListTile (
  435. // title: Text('Title '+photos[index].title),
  436. title : Column (
  437. children: <Widget>[
  438. ListTile(
  439. title: Text("Nama Produk : ${photos[index].nama_produk}"),
  440. subtitle: Text(
  441. "Kategori : ${photos[index].kategori} \n"+
  442. "Expired date : ${photos[index].expired_date} \n" +
  443. "Nomor Rak : ${photos[index].nomor_rak} \n" +
  444. "Scan code : ${photos[index].scan_code} \n" +
  445. "Diskon : ${photos[index].discount} \n"
  446. ),
  447. ),
  448. Divider(),
  449. ],
  450. ),
  451. );
  452. },
  453. );
  454. }
  455. }
  456.  
  457. Widget listProduct (BuildContext context) {
  458. return new Scaffold(
  459. appBar: new AppBar(
  460. title: const Text("W2 Flutter"),
  461. ),
  462. body: new ProductList(),
  463. floatingActionButton: FloatingActionButton(
  464. child: Icon(Icons.add),
  465. onPressed: () {
  466. Navigator.pushNamed(context, '/entry');
  467. }
  468. ),
  469. drawer: Drawer(
  470. child: ListView(
  471. children: <Widget>[
  472. UserAccountsDrawerHeader(
  473. accountName: Text("Wisnu Wijokangko"),
  474. accountEmail: Text("wisnuwijo3@gmail.com"),
  475. decoration: BoxDecoration(
  476. color: Colors.blueAccent,
  477. ),
  478. currentAccountPicture:
  479. CircleAvatar(
  480. backgroundImage: NetworkImage("https://i0.wp.com/www.winhelponline.com/blog/wp-content/uploads/2017/12/user.png?fit=256%2C256&quality=100&ssl=1"),
  481. ),
  482. ),
  483. ListTile(
  484. title: Text('Profile'),
  485. trailing: Icon(Icons.person),
  486. leading: Icon(Icons.arrow_right),
  487. onTap: () {
  488.  
  489. },
  490. ),
  491. ListTile(
  492. title: Text('Favorites'),
  493. trailing: Icon(Icons.favorite),
  494. leading: Icon(Icons.arrow_right),
  495. onTap: () {
  496.  
  497. },
  498. ),
  499. ListTile(
  500. title: Text('Settings'),
  501. trailing: Icon(Icons.settings),
  502. leading: Icon(Icons.arrow_right),
  503. onTap: () {
  504.  
  505. },
  506. ),
  507. ListTile(
  508. title: Text('Logout'),
  509. trailing: Icon(Icons.exit_to_app),
  510. leading: Icon(Icons.arrow_right),
  511. onTap: () async {
  512. // redirect ke login
  513. Navigator.pop(context);
  514. Navigator.push(
  515. context,
  516. MaterialPageRoute(builder: (context) => Login())
  517. );
  518.  
  519. Navigator.of(context).pushNamedAndRemoveUntil('/login',
  520. (Route<dynamic> route) => false);
  521.  
  522. final prefs = await SharedPreferences.getInstance();
  523. prefs.remove('login');
  524. },
  525. ),
  526. ],
  527. ),
  528. ),
  529. );
  530. }
  531.  
  532. // login
  533. import 'package:flutter/material.dart';
  534. import 'dart:async';
  535. import 'dart:convert';
  536. import 'package:http/http.dart' as http;
  537. import 'package:flutter_app/list.dart';
  538. import 'package:shared_preferences/shared_preferences.dart';
  539. import 'const.dart';
  540.  
  541. // class response json
  542. class Response {
  543. final String status;
  544. final String message;
  545.  
  546. Response({this.status, this.message});
  547.  
  548. factory Response.fromJson(Map<String, dynamic> json) {
  549. return Response(
  550. status: json['status'],
  551. message: json['message'],
  552. );
  553. }
  554. }
  555.  
  556.  
  557. class Login extends StatefulWidget {
  558. @override
  559. LoginState createState() => new LoginState();
  560. }
  561.  
  562. class LoginState extends State<Login> {
  563.  
  564. // variabel member class
  565. final _username = TextEditingController();
  566. final _password = TextEditingController();
  567.  
  568. // member response
  569. String _response = '';
  570. bool _apiCall = false;
  571.  
  572. // login shared prefs
  573. bool alreadyLogin = false;
  574.  
  575. // fungsi untuk kirim http post
  576. Future<Response> post(String url,var body)async{
  577. return await http
  578. .post(Uri.encodeFull(url), body: body, headers: {"Accept":"application/json"})
  579. .then((http.Response response) {
  580.  
  581. final int statusCode = response.statusCode;
  582.  
  583. if (statusCode < 200 || statusCode > 400 || json == null) {
  584. throw new Exception("Error while fetching data");
  585. }
  586. return Response.fromJson(json.decode(response.body));
  587. });
  588. }
  589.  
  590. // fungsi panggil API
  591. void _callPostAPI() {
  592. post(
  593. Constant.apiLogin,
  594. {
  595. 'username': _username.text,
  596. 'password': _password.text
  597. }).then((response) async {
  598. // jika respon normal
  599. setState(() {
  600. _apiCall = false;
  601. _response = response.message;
  602. });
  603.  
  604. if (response.status == "success") {
  605. // simpan shared prefs sudah login
  606. final prefs = await SharedPreferences.getInstance();
  607. setState(() {
  608. alreadyLogin = true;
  609. prefs.setBool('login', alreadyLogin);
  610. });
  611.  
  612. // menuju route list product
  613. // Navigator.push(
  614. // context,
  615. // MaterialPageRoute(builder: (context) => listProduct(context))
  616. // );
  617. Navigator.pushNamed(context,'/list');
  618. }
  619.  
  620. },
  621. // jika respon error
  622. onError: (error) {
  623. _apiCall = false;
  624. _response = error.toString();
  625. }
  626. );
  627. }
  628.  
  629. Widget progressWidget() {
  630. if (_apiCall)
  631. // jika masih proses kirim API
  632. return AlertDialog(
  633. content: new Column(
  634. children: <Widget>[
  635. CircularProgressIndicator(),
  636. Text("Please wait")
  637. ],
  638. ),
  639. );
  640. else
  641. // jika sudah selesai kirim API
  642. return Center(
  643. child: Text(
  644. _response,
  645. style: new TextStyle(fontSize: 15.0),
  646. ),
  647. );
  648. }
  649.  
  650. Future<bool> getLoginStatus() async{
  651. final prefs = await SharedPreferences.getInstance();
  652. bool loginStatus = prefs.getBool('login') ?? false;
  653. print('login status $loginStatus');
  654. return loginStatus;
  655. }
  656.  
  657. @override
  658. Widget build(BuildContext context) {
  659. return FutureBuilder<bool>(
  660. future: getLoginStatus(),
  661. builder: (context, snapshot) {
  662. return (snapshot.data) ?
  663. // jika alreadyLogin = true
  664. listProduct(context) :
  665. // jika alreadyLogin = false
  666. loginForm();
  667. },
  668. );
  669. }
  670.  
  671. Widget loginForm() {
  672. return Scaffold(
  673. appBar: new AppBar(
  674. title: const Text('W2 Flutter'),
  675. automaticallyImplyLeading: false,
  676. ),
  677. body: SafeArea(
  678. child: ListView(
  679. padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  680. children: <Widget>[
  681. // nama
  682. TextField(
  683. controller: _username,
  684. decoration: InputDecoration(
  685. filled: true,
  686. labelText: 'Username'
  687. ),
  688. ),
  689. // spasi
  690. SizedBox(height: 5.0),
  691. // alamat
  692. TextField(
  693. controller: _password,
  694. decoration: InputDecoration(
  695. filled: true,
  696. labelText: 'Password'
  697. ),
  698. obscureText: true,
  699. ),
  700. // spasi
  701. SizedBox(height: 10.0),
  702. // tombol
  703. RaisedButton(
  704. child: Text('LOGIN'),
  705. onPressed: () {
  706.  
  707. setState(() {
  708. _apiCall = true;
  709. });
  710. _callPostAPI();
  711. /*
  712. return showDialog(
  713. context: context,
  714. builder: (context) {
  715. return AlertDialog(
  716. content: Text('Username: ${_username.text}\nPassword: ${_password.text}'),
  717. );
  718. },
  719. );
  720. */
  721. },
  722. ),
  723.  
  724. // panggil loading widget
  725. progressWidget()
  726. ],
  727. )
  728. )
  729. );
  730.  
  731. }
  732. }
  733.  
  734. // main.dart
  735. import 'package:flutter/material.dart';
  736. import 'package:flutter_app/entry.dart';
  737. import 'package:flutter_app/list.dart';
  738. import 'sample_list.dart';
  739. //import 'tabs.dart';
  740. import 'login.dart';
  741.  
  742. void main() => runApp(MyApp());
  743.  
  744. class MyApp extends StatelessWidget {
  745. @override
  746. Widget build(BuildContext context) {
  747. return MaterialApp(
  748. title: 'Flutter Demo',
  749. theme: ThemeData(
  750. primarySwatch: Colors.green,
  751. ),
  752. home: new Login(),
  753. initialRoute: '/login',
  754. routes: {
  755. '/login' : (context) => Login(),
  756. '/list' : (context) => listProduct(context),
  757. '/entry' : (context) => EntryData(),
  758. },
  759. );
  760. }
  761. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement