고원빈

[frontend]2021-05-24

...@@ -69,3 +69,8 @@ appbar 관련 디자인은 추후 구현 예정 ...@@ -69,3 +69,8 @@ appbar 관련 디자인은 추후 구현 예정
69 69
70 ### 2021-05-22 70 ### 2021-05-22
71 + 약병 검색 기능 구현 중 71 + 약병 검색 기능 구현 중
72 +
73 +### 2021-0523
74 ++ 로그인 하여 메인페이지 과정 구현 완료
75 ++ 폴더 정리
76 +
......
1 -SERVER_URL=http://192.168.0.3:4000/api/
...\ No newline at end of file ...\ No newline at end of file
1 +SERVER_URL=
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; ...@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
2 import 'package:flutter/services.dart'; 2 import 'package:flutter/services.dart';
3 import '../shared/colors.dart'; 3 import '../shared/colors.dart';
4 import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 import 'package:flutter_screenutil/flutter_screenutil.dart';
5 -import './SignInPage.dart'; 5 +import './Register/SignInPage.dart';
6 -import './SignUpLocal.dart'; 6 +import 'Register/SignUpLocal.dart';
7 7
8 class HomePage extends StatefulWidget { 8 class HomePage extends StatefulWidget {
9 final String pageTitle; 9 final String pageTitle;
...@@ -106,7 +106,8 @@ class _HomePageState extends State<HomePage> { ...@@ -106,7 +106,8 @@ class _HomePageState extends State<HomePage> {
106 color: Color(0xff1674f6), 106 color: Color(0xff1674f6),
107 shape: RoundedRectangleBorder( 107 shape: RoundedRectangleBorder(
108 borderRadius: BorderRadius.circular(50)), 108 borderRadius: BorderRadius.circular(50)),
109 - )), 109 + ),
110 + ),
110 ), 111 ),
111 GestureDetector( 112 GestureDetector(
112 child: Container( 113 child: Container(
......
...@@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; ...@@ -3,8 +3,8 @@ import 'package:flutter/material.dart';
3 import 'package:flutter/services.dart'; 3 import 'package:flutter/services.dart';
4 import 'package:http/http.dart' as http; 4 import 'package:http/http.dart' as http;
5 import 'package:flutter_dotenv/flutter_dotenv.dart'; 5 import 'package:flutter_dotenv/flutter_dotenv.dart';
6 -import 'models/Bottle.dart'; 6 +import '../models/Bottle.dart';
7 -import 'DashBoard.dart'; 7 +import '../DashBoard.dart';
8 8
9 class BottleList extends StatefulWidget { 9 class BottleList extends StatefulWidget {
10 List<Bottle> bottlelist; 10 List<Bottle> bottlelist;
...@@ -44,7 +44,9 @@ class _BottleListState extends State<BottleList> { ...@@ -44,7 +44,9 @@ class _BottleListState extends State<BottleList> {
44 Expanded( 44 Expanded(
45 child: ListView.separated( 45 child: ListView.separated(
46 padding: const EdgeInsets.all(30), 46 padding: const EdgeInsets.all(30),
47 - itemCount: widget.bottlelist.length, 47 + itemCount: widget.bottlelist.length == null
48 + ? 0
49 + : widget.bottlelist.length,
48 itemBuilder: (BuildContext context, int index) { 50 itemBuilder: (BuildContext context, int index) {
49 return Container( 51 return Container(
50 padding: EdgeInsets.all(8.0), 52 padding: EdgeInsets.all(8.0),
......
1 +import 'package:Smart_Medicine_Box/src/screens/DashBoard.dart';
2 +import 'package:flutter/material.dart';
3 +import 'package:flutter/cupertino.dart';
4 +import 'dart:convert';
5 +import 'package:http/http.dart' as http;
6 +import 'package:flutter_dotenv/flutter_dotenv.dart';
7 +import '../models/Medicine.dart';
8 +
9 +class DetailMedicine extends StatefulWidget {
10 + Medicine searchMedicine;
11 + String bottleId;
12 + DetailMedicine({Key key, this.searchMedicine, this.bottleId})
13 + : super(key: key);
14 + @override
15 + _DetailMedicineState createState() => _DetailMedicineState();
16 +}
17 +
18 +class _DetailMedicineState extends State<DetailMedicine> {
19 + final medicineDosageController = TextEditingController();
20 + //약 등록
21 + Future<String> patchMedcine() async {
22 + http.Response response = await http.patch(
23 + Uri.encodeFull(
24 + DotEnv().env['SERVER_URL'] + 'bottle/' + widget.bottleId),
25 + headers: {"Content-Type": "application/json"},
26 + body: jsonEncode({
27 + 'medicineId': widget.searchMedicine.medicineId,
28 + 'dosage': medicineDosageController.text
29 + }));
30 +
31 + print(response.statusCode);
32 + if (response.statusCode == 200) {
33 + return "Complete";
34 + } else if (response.statusCode == 404) {
35 + return "약병이 존재하지 않습니다.";
36 + } else if (response.statusCode == 403) {
37 + return "약병에 접근할 권한이 없습니다.";
38 + } else {
39 + return "알 수 없는 오류";
40 + }
41 + }
42 +
43 + Widget build(BuildContext context) {
44 + final Size size = MediaQuery.of(context).size;
45 + return MaterialApp(
46 + home: Scaffold(
47 + appBar: AppBar(
48 + backgroundColor: Colors.white,
49 + leading: new Icon(Icons.medical_services_rounded,
50 + color: Colors.black, size: 45.0),
51 + title: Text(
52 + 'Smart Medicine Box',
53 + style: TextStyle(
54 + color: Colors.black,
55 + fontSize: 23,
56 + fontFamily: 'Noto',
57 + fontWeight: FontWeight.bold),
58 + ),
59 + ),
60 + body: SingleChildScrollView(
61 + scrollDirection: Axis.vertical,
62 + child: Column(
63 + crossAxisAlignment: CrossAxisAlignment.center,
64 + children: <Widget>[
65 + SizedBox(height: 30),
66 + Container(
67 + padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
68 + height: size.height * 0.08,
69 + width: size.width,
70 + child: Center(
71 + child: Text(
72 + '세부 약 정보',
73 + textAlign: TextAlign.center,
74 + textScaleFactor: 1.0,
75 + style: TextStyle(
76 + color: Colors.black,
77 + fontSize: 36,
78 + fontFamily: 'NotoSansKR',
79 + fontWeight: FontWeight.w700),
80 + ),
81 + ),
82 + ),
83 + SizedBox(height: 5),
84 + Container(
85 + width: size.width,
86 + padding: EdgeInsets.fromLTRB(5, 0, 5, 5),
87 + margin: EdgeInsets.all(15),
88 + decoration: BoxDecoration(
89 + border: Border.all(),
90 + borderRadius: BorderRadius.all(
91 + Radius.circular(25.0) // <--- border radius here
92 + ),
93 + ),
94 + child: Column(
95 + children: [
96 + SizedBox(height: 40),
97 + Container(
98 + child: Center(
99 + child: Text(widget.searchMedicine.name,
100 + style: TextStyle(
101 + color: Colors.black,
102 + fontSize: 24,
103 + fontFamily: 'NotoSansKR',
104 + fontWeight: FontWeight.w700)),
105 + ),
106 + ),
107 + SizedBox(height: 15),
108 + Container(
109 + width: size.width,
110 + alignment: Alignment(0.9, 0),
111 + child: Text(
112 + '제조사: ' + widget.searchMedicine.company,
113 + style: TextStyle(
114 + color: Colors.grey,
115 + fontSize: 20,
116 + ),
117 + ),
118 + ),
119 + SizedBox(height: 30),
120 + Container(
121 + width: size.width,
122 + padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
123 + alignment: Alignment(-1, 0),
124 + child: Text(
125 + '타겟 층 : ' + widget.searchMedicine.target,
126 + style: TextStyle(color: Colors.black, fontSize: 16),
127 + ),
128 + ),
129 + SizedBox(height: 15),
130 + Container(
131 + width: size.width,
132 + padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
133 + alignment: Alignment(-1, 0),
134 + child: Text(
135 + '복약 정보 : ' + widget.searchMedicine.dosage,
136 + style: TextStyle(color: Colors.black, fontSize: 16),
137 + ),
138 + ),
139 + SizedBox(height: 10),
140 + Container(
141 + width: size.width,
142 + padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
143 + alignment: Alignment(-1, 0),
144 + child: Column(
145 + children: [
146 + SizedBox(
147 + height: 12,
148 + ),
149 + Container(
150 + width: size.width,
151 + child: Text(
152 + '경고',
153 + style: TextStyle(
154 + color: Colors.redAccent, fontSize: 14),
155 + ),
156 + ),
157 + SizedBox(height: 12),
158 + Container(
159 + width: size.width,
160 + child: Text(
161 + widget.searchMedicine.warn,
162 + style: TextStyle(
163 + color: Colors.redAccent, fontSize: 14),
164 + ),
165 + ),
166 + ],
167 + ),
168 + ),
169 + ],
170 + ),
171 + ),
172 + SizedBox(height: 12),
173 + Container(
174 + height: size.height * 0.1,
175 + padding: const EdgeInsets.fromLTRB(20, 10, 20, 5),
176 + child: TextFormField(
177 + keyboardType: TextInputType.text,
178 + controller: medicineDosageController,
179 + decoration: InputDecoration(
180 + border: OutlineInputBorder(),
181 + errorBorder: InputBorder.none,
182 + disabledBorder: InputBorder.none,
183 + hintText: '하루에 섭취할 적정 복용량을 숫자만 입력하세요',
184 + ),
185 + style: TextStyle(
186 + fontSize: 16,
187 + fontFamily: 'NotoSansKR',
188 + fontWeight: FontWeight.w600)),
189 + ),
190 + SizedBox(height: 12),
191 + Container(
192 + height: size.height * 0.07,
193 + width: size.width * 0.8,
194 + child: FlatButton(
195 + padding: EdgeInsets.fromLTRB(0, 5, 0, 5),
196 + onPressed: () async {
197 + String saveMessage = await patchMedcine();
198 + if (saveMessage == "Complete") {
199 + showDialog(
200 + context: context,
201 + builder: (BuildContext context) {
202 + return AlertDialog(
203 + title: new Text('약 등록'),
204 + content: new Text('약 등록이 완료 되었습니다.'),
205 + actions: <Widget>[
206 + new FlatButton(
207 + child: new Text('Close'),
208 + onPressed: () {
209 + Navigator.push(
210 + context,
211 + MaterialPageRoute(
212 + builder: (BuildContext context) =>
213 + DashBoard(
214 + pageNumber: 1,
215 + bottleID: int.parse(
216 + widget.bottleId),
217 + )));
218 + })
219 + ],
220 + );
221 + });
222 + }
223 + },
224 + child: Text(
225 + '약 등록',
226 + textScaleFactor: 1.0,
227 + style: TextStyle(
228 + color: Colors.white,
229 + fontSize: 20,
230 + fontFamily: 'Noto',
231 + fontWeight: FontWeight.bold),
232 + ),
233 + color: Color(0xff1674f6),
234 + shape: RoundedRectangleBorder(
235 + borderRadius: BorderRadius.circular(50)),
236 + ),
237 + ),
238 + SizedBox(height: 30)
239 + ],
240 + ),
241 + ),
242 + ),
243 + );
244 + }
245 +}
...@@ -5,7 +5,7 @@ import 'package:http/http.dart' as http; ...@@ -5,7 +5,7 @@ import 'package:http/http.dart' as http;
5 import 'package:flutter_dotenv/flutter_dotenv.dart'; 5 import 'package:flutter_dotenv/flutter_dotenv.dart';
6 // Screen import 6 // Screen import
7 import 'RegisterBottle.dart'; 7 import 'RegisterBottle.dart';
8 -import 'models/Bottle.dart'; 8 +import '../models/Bottle.dart';
9 import 'BottleList.dart'; 9 import 'BottleList.dart';
10 10
11 class HubList extends StatefulWidget { 11 class HubList extends StatefulWidget {
...@@ -89,8 +89,6 @@ class _HubListState extends State<HubList> { ...@@ -89,8 +89,6 @@ class _HubListState extends State<HubList> {
89 var result = 89 var result =
90 await getBottleList(widget.hublist[index]); 90 await getBottleList(widget.hublist[index]);
91 if (result == "GET") { 91 if (result == "GET") {
92 - print(0);
93 - print(_bottleList);
94 Navigator.push( 92 Navigator.push(
95 context, 93 context,
96 MaterialPageRoute( 94 MaterialPageRoute(
......
...@@ -16,9 +16,6 @@ class RegisterBottle extends StatefulWidget { ...@@ -16,9 +16,6 @@ class RegisterBottle extends StatefulWidget {
16 16
17 class _RegisterBottleState extends State<RegisterBottle> { 17 class _RegisterBottleState extends State<RegisterBottle> {
18 final medicineBottleIDController = TextEditingController(); 18 final medicineBottleIDController = TextEditingController();
19 - final medicineHubIDController = TextEditingController();
20 - final medicineHubPortController = TextEditingController();
21 - final medicineHubHostController = TextEditingController();
22 19
23 Future<String> registerhub_Validate() async { 20 Future<String> registerhub_Validate() async {
24 http.Response bottleresponse = await http.post( 21 http.Response bottleresponse = await http.post(
...@@ -119,7 +116,11 @@ class _RegisterBottleState extends State<RegisterBottle> { ...@@ -119,7 +116,11 @@ class _RegisterBottleState extends State<RegisterBottle> {
119 context, 116 context,
120 MaterialPageRoute( 117 MaterialPageRoute(
121 builder: (BuildContext context) => 118 builder: (BuildContext context) =>
122 - SearchMedicine())); 119 + SearchMedicine(
120 + bottleId:
121 + medicineBottleIDController
122 + .text,
123 + )));
123 }) 124 })
124 ], 125 ],
125 ); 126 );
......
...@@ -3,17 +3,46 @@ import 'package:flutter/material.dart'; ...@@ -3,17 +3,46 @@ import 'package:flutter/material.dart';
3 import 'package:flutter/services.dart'; 3 import 'package:flutter/services.dart';
4 import 'package:http/http.dart' as http; 4 import 'package:http/http.dart' as http;
5 import 'package:flutter_dotenv/flutter_dotenv.dart'; 5 import 'package:flutter_dotenv/flutter_dotenv.dart';
6 -import 'models/Bottle.dart'; 6 +import '../models/Medicine.dart';
7 -import 'DashBoard.dart'; 7 +import 'DetailMedicine.dart';
8 8
9 class SearchMedicine extends StatefulWidget { 9 class SearchMedicine extends StatefulWidget {
10 + String bottleId;
11 +
12 + SearchMedicine({Key key, this.bottleId}) : super(key: key);
10 @override 13 @override
11 _SearchMedicineState createState() => _SearchMedicineState(); 14 _SearchMedicineState createState() => _SearchMedicineState();
12 } 15 }
13 16
14 class _SearchMedicineState extends State<SearchMedicine> { 17 class _SearchMedicineState extends State<SearchMedicine> {
18 + List<Medicine> _medicineList = new List<Medicine>();
15 final medicineNameController = TextEditingController(); 19 final medicineNameController = TextEditingController();
16 - final medicineFactureController = TextEditingController(); 20 + final medicineCompanyController = TextEditingController();
21 +
22 + Future<String> postMeicineList() async {
23 + http.Response response =
24 + await http.post(Uri.encodeFull(DotEnv().env['SERVER_URL'] + 'medicine'),
25 + headers: {"Content-Type": "application/json"},
26 + body: jsonEncode({
27 + 'name': medicineNameController.text,
28 + 'company': medicineCompanyController.text,
29 + }));
30 +
31 + if (_medicineList.length != 0) {
32 + _medicineList.clear();
33 + }
34 + if (response.statusCode == 200) {
35 + List<dynamic> values = new List<dynamic>();
36 + values = json.decode(response.body);
37 + for (int i = 0; i < values.length; i++) {
38 + Map<String, dynamic> map = values[i];
39 + _medicineList.add(Medicine.fromJson(map));
40 + }
41 + return "GET";
42 + } else {
43 + return "Not Found";
44 + }
45 + }
17 46
18 Widget build(BuildContext context) { 47 Widget build(BuildContext context) {
19 bool isForward = false; 48 bool isForward = false;
...@@ -125,7 +154,7 @@ class _SearchMedicineState extends State<SearchMedicine> { ...@@ -125,7 +154,7 @@ class _SearchMedicineState extends State<SearchMedicine> {
125 width: size.width * 0.50, 154 width: size.width * 0.50,
126 child: TextFormField( 155 child: TextFormField(
127 keyboardType: TextInputType.text, 156 keyboardType: TextInputType.text,
128 - controller: medicineFactureController, 157 + controller: medicineCompanyController,
129 decoration: InputDecoration( 158 decoration: InputDecoration(
130 border: InputBorder.none, 159 border: InputBorder.none,
131 focusedBorder: InputBorder.none, 160 focusedBorder: InputBorder.none,
...@@ -158,7 +187,11 @@ class _SearchMedicineState extends State<SearchMedicine> { ...@@ -158,7 +187,11 @@ class _SearchMedicineState extends State<SearchMedicine> {
158 padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), 187 padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
159 child: IconButton( 188 child: IconButton(
160 icon: Icon(Icons.search, size: 40), 189 icon: Icon(Icons.search, size: 40),
161 - onPressed: () { 190 + onPressed: () async {
191 + String saveMessage = await postMeicineList();
192 + if (saveMessage == "GET") {
193 + setState(() {});
194 + }
162 //검색 함수를 여기다가 195 //검색 함수를 여기다가
163 }, 196 },
164 ), 197 ),
...@@ -169,10 +202,38 @@ class _SearchMedicineState extends State<SearchMedicine> { ...@@ -169,10 +202,38 @@ class _SearchMedicineState extends State<SearchMedicine> {
169 SizedBox(height: 20), 202 SizedBox(height: 20),
170 Expanded( 203 Expanded(
171 child: ListView.separated( 204 child: ListView.separated(
172 - itemBuilder: (BuildContext context, int index) {}, 205 + itemBuilder: (BuildContext context, int index) {
206 + return Container(
207 + padding: EdgeInsets.all(8.0),
208 + decoration: BoxDecoration(border: Border.all()),
209 + child: ListTile(
210 + title: Text(
211 + 'Medicine: ' + _medicineList[index].name,
212 + style: TextStyle(
213 + color: Colors.black,
214 + fontSize: 20,
215 + fontFamily: 'Noto',
216 + fontWeight: FontWeight.bold),
217 + ),
218 + trailing: Icon(Icons.arrow_forward),
219 + onTap: () async {
220 + Navigator.push(
221 + context,
222 + MaterialPageRoute(
223 + builder: (BuildContext context) =>
224 + DetailMedicine(
225 + searchMedicine: _medicineList[index],
226 + bottleId: widget.bottleId,
227 + ),
228 + ));
229 + }),
230 + );
231 + },
173 separatorBuilder: (BuildContext contetx, int index) => 232 separatorBuilder: (BuildContext contetx, int index) =>
174 const Divider(), 233 const Divider(),
175 - itemCount: 0)) 234 + itemCount: _medicineList.length == null
235 + ? 0
236 + : _medicineList.length))
176 ], 237 ],
177 ), 238 ),
178 ), 239 ),
......
...@@ -4,7 +4,7 @@ import 'package:flutter/services.dart'; ...@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
4 import 'package:http/http.dart' as http; 4 import 'package:http/http.dart' as http;
5 import 'package:flutter_dotenv/flutter_dotenv.dart'; 5 import 'package:flutter_dotenv/flutter_dotenv.dart';
6 import 'package:shared_preferences/shared_preferences.dart'; 6 import 'package:shared_preferences/shared_preferences.dart';
7 -import './DashBoard.dart'; 7 +import '../DashBoard.dart';
8 import 'HubList.dart'; 8 import 'HubList.dart';
9 import 'RegsiterHub.dart'; 9 import 'RegsiterHub.dart';
10 10
......
...@@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; ...@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
3 import 'package:http/http.dart' as http; 3 import 'package:http/http.dart' as http;
4 import 'package:flutter_dotenv/flutter_dotenv.dart'; 4 import 'package:flutter_dotenv/flutter_dotenv.dart';
5 5
6 -import 'Homepage.dart'; 6 +import '../Homepage.dart';
7 7
8 class SignUpLocal extends StatefulWidget { 8 class SignUpLocal extends StatefulWidget {
9 @override 9 @override
......
1 +import 'Medicine.dart';
2 +
3 +class Data {
4 + final int totalItem;
5 + final List<Medicine> result;
6 +
7 + Data({this.totalItem, this.result});
8 +
9 + factory Data.fromJson(Map<String, dynamic> parsedJson) {
10 + var list = parsedJson['result'] as List;
11 + List<Medicine> resultList = list.map((i) => Medicine.fromJson(i)).toList();
12 +
13 + return Data(
14 + totalItem: parsedJson['totalItem'],
15 + result: resultList,
16 + );
17 + }
18 + Map<String, dynamic> toJson() => {
19 + "totalItem": totalItem,
20 + "result": result,
21 + };
22 +}
...@@ -32,7 +32,7 @@ dependencies: ...@@ -32,7 +32,7 @@ dependencies:
32 flutter_datetime_picker: ^1.3.4 32 flutter_datetime_picker: ^1.3.4
33 timezone: ^0.6.0 33 timezone: ^0.6.0
34 intl : ^0.16.1 34 intl : ^0.16.1
35 - shared_preferences: ^0.5.6+1 35 + shared_preferences: ^0.5.12+2
36 flutter_blue: ^0.7.2 36 flutter_blue: ^0.7.2
37 cupertino_icons: ^0.1.3 37 cupertino_icons: ^0.1.3
38 http: ^0.12.0+4 38 http: ^0.12.0+4
......