diff --git a/android/app/build.gradle b/android/app/build.gradle index 4acc0b4..5da2812 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -48,6 +48,14 @@ android { signingConfig signingConfigs.debug } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildToolsVersion '30.0.3' } flutter { @@ -55,5 +63,5 @@ flutter { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 55097b2..42925ea 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4..16df2db 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b7..b5eda03 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 09d4391..73b7153 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d..c2e1235 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372e..793e9fd 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..a5b623a --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #FFFFFFFF + \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index c505a86..b198b37 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.4.21' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:4.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..6807bd6 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 23 08:50:38 CEST 2017 +#Mon Jan 18 13:09:57 ICT 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip diff --git a/assets/icons/DrCorona1.svg b/assets/icons/DrCorona1.svg new file mode 100644 index 0000000..cd4f658 --- /dev/null +++ b/assets/icons/DrCorona1.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/DrCorona2.svg b/assets/icons/DrCorona2.svg new file mode 100644 index 0000000..6eac6a6 --- /dev/null +++ b/assets/icons/DrCorona2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/Intersection.svg b/assets/icons/Intersection.svg new file mode 100644 index 0000000..2ebbb41 --- /dev/null +++ b/assets/icons/Intersection.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/dropdown.svg b/assets/icons/dropdown.svg new file mode 100644 index 0000000..0ac35ea --- /dev/null +++ b/assets/icons/dropdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/forward.svg b/assets/icons/forward.svg new file mode 100644 index 0000000..8f8c565 --- /dev/null +++ b/assets/icons/forward.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/map.svg b/assets/icons/map.svg new file mode 100644 index 0000000..5f3c8be --- /dev/null +++ b/assets/icons/map.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/icons/maps-and-flags.svg b/assets/icons/maps-and-flags.svg new file mode 100644 index 0000000..9c56834 --- /dev/null +++ b/assets/icons/maps-and-flags.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/menu.svg b/assets/icons/menu.svg new file mode 100644 index 0000000..b1f09a5 --- /dev/null +++ b/assets/icons/menu.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/shape_small.svg b/assets/icons/shape_small.svg new file mode 100644 index 0000000..42ac1c8 --- /dev/null +++ b/assets/icons/shape_small.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/cough.png b/assets/images/cough.png new file mode 100644 index 0000000..5f15d62 Binary files /dev/null and b/assets/images/cough.png differ diff --git a/assets/images/fever.png b/assets/images/fever.png new file mode 100644 index 0000000..a86cc0c Binary files /dev/null and b/assets/images/fever.png differ diff --git a/assets/images/headache.png b/assets/images/headache.png new file mode 100644 index 0000000..b8aca8a Binary files /dev/null and b/assets/images/headache.png differ diff --git a/assets/images/map.png b/assets/images/map.png new file mode 100644 index 0000000..3c78a7c Binary files /dev/null and b/assets/images/map.png differ diff --git a/assets/images/virus.png b/assets/images/virus.png new file mode 100644 index 0000000..eafe6f9 Binary files /dev/null and b/assets/images/virus.png differ diff --git a/assets/images/wash_hands.png b/assets/images/wash_hands.png new file mode 100644 index 0000000..ea0ba75 Binary files /dev/null and b/assets/images/wash_hands.png differ diff --git a/assets/images/wear_mask.png b/assets/images/wear_mask.png new file mode 100644 index 0000000..014a024 Binary files /dev/null and b/assets/images/wear_mask.png differ diff --git a/assets/launcher/icon.png b/assets/launcher/icon.png new file mode 100644 index 0000000..e2a0c22 Binary files /dev/null and b/assets/launcher/icon.png differ diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart deleted file mode 100644 index 79dbbdb..0000000 --- a/integration_test/app_test.dart +++ /dev/null @@ -1,36 +0,0 @@ -// This is a basic Flutter integration test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import 'package:chonchai_chana/main.dart' as app; - -void main() => run(_testMain); - -void _testMain() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - app.main(); - - // Trigger a frame. - await tester.pumpAndSettle(); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/integration_test/driver.dart b/integration_test/driver.dart deleted file mode 100644 index a03bca0..0000000 --- a/integration_test/driver.dart +++ /dev/null @@ -1,8 +0,0 @@ -// This file is provided as a convenience for running integration tests via the -// flutter drive command. -// -// flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() => integrationDriver(); diff --git a/lib/constants.dart b/lib/constants.dart new file mode 100644 index 0000000..4a8d451 --- /dev/null +++ b/lib/constants.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +// Colors +const kBackgroundColor = Colors.white; +final kShadowColor = Color(0xFF888888).withOpacity(0.5); \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index d8a0526..1d683ae 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,113 +1,230 @@ +import 'package:chonchai_chana/constants.dart'; +import 'package:chonchai_chana/widgets/covid_info_item.dart'; +import 'package:chonchai_chana/widgets/my_header.dart'; +import 'package:chonchai_chana/widgets/symptom_card.dart'; + import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; void main() { - runApp(MyApp()); + runApp(MainApp()); } -class MyApp extends StatelessWidget { - // This widget is the root of your application. +class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Demo', + title: 'ชลชายชนะ', theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, + brightness: Brightness.dark, + textTheme: GoogleFonts.mitrTextTheme( + Theme.of(context).textTheme.copyWith( + headline6: TextStyle( + color: Colors.white, + fontSize: 24.0, + fontWeight: FontWeight.w600, + ), + headline5: TextStyle( + color: Colors.black, + fontSize: 20.0, + fontWeight: FontWeight.w500, + ), + bodyText2: TextStyle( + color: Colors.black, + fontSize: 16.0, + fontWeight: FontWeight.normal, + ), + caption: TextStyle( + color: Colors.black, + fontSize: 14.0, + fontWeight: FontWeight.normal, + ), + ), + ), + scaffoldBackgroundColor: kBackgroundColor, ), - home: MyHomePage(title: 'Flutter Demo Home Page'), + home: HomePage(title: 'ชลชายชนะ'), + debugShowCheckedModeBanner: false, ); } } -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". +class HomePage extends StatefulWidget { + HomePage({Key key, this.title}) : super(key: key); final String title; @override - _MyHomePageState createState() => _MyHomePageState(); + _HomePageState createState() => _HomePageState(); } -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - +class _HomePageState extends State { @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. + body: SingleChildScrollView( child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, + children: [ + MyHeader( + image: "assets/icons/DrCorona1.svg", + textTop: "มารู้จัก โควิด-19", + textBottom: "กันเถอะ", ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + "โรคโควิด 19 คืออะไร", + style: Theme.of(context).textTheme.headline5, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 16.0), + child: Text( + "โรคโควิด 19 คือโรคติดต่อซึ่งเกิดจากไวรัสโคโรนาชนิดที่มีการค้นพบล่าสุด" + " ไวรัสและโรคอุบัติเหตุใหม่นึ้ไม่เป็นที่รู้จักเลยก่อนที่จะมีการระบาดในเมืองอู่ฮั่น ประเทศจีนในเดือนธันวาคม ปี 2019" + " ขณะนี้โรคโควิด 19 มีการระบาดไปทั่ว ส่งผลกระทบแก่หลายประเทศทั่วโลก", + style: Theme.of(context).textTheme.bodyText2, + ), + ), + Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Text( + "อาการ", + style: Theme.of(context).textTheme.headline5, + ), + ), + Center( + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + spacing: 16.0, + runSpacing: 16.0, + alignment: WrapAlignment.spaceAround, + runAlignment: WrapAlignment.spaceAround, + children: [ + SymptomCard( + image: "assets/images/headache.png", + title: "ปวดหัว", + ), + SymptomCard( + image: "assets/images/cough.png", + title: "ไอ", + ), + SymptomCard( + image: "assets/images/fever.png", + title: "มีไข้สูงกว่า 37.5 องศา", + ), + ], + ), + ), + CovidInfoItem( + title: "ต้นกำเนิดของไวรัส", + info: + "• ต้นตอของไวรัสน่าจะมาจากการที่ไวรัสจากสัตว์ตัวกลางระบาดมาสู่คน\n" + "• ผู้ป่วยรายแรกเท่ากันที่ทราบกัน เริ่มมีอาการตั้งแต่ 1 ธันวาคม และไม่มีความเชื่อมโยงกับตลาดต้องสงสัยในเมืองอู่ฮั่น ประเทศจีน แต่ผู้ป่วยหลายรายอาจมีมาตั้งแต่ช่วงกลางเดือนพฤศจิกายนหรือก่อนหน้านั้น\n" + "• มีการเก็บตัวอย่างจากสิ่งแวดล้อมในตลาดไปส่งตรวจและพบเชื้อไวรัสและพบมากที่สุดในบริเวณที่ค้าสัตว์ป่าและสัตว์เลี้ยงในฟาร์ม\n" + "• ตลาดอาจเป็นต้นกำเนิดของไวรัส หรืออาจมีบทบาทในการขยายวงของการระบาดในระยะเริ่มแรก\n" + "• การเพิ่มจำนวนของไวรัสเกิดขึ้นในระบบทางเดินหายใจส่วนบนและในปอด มีงานวิจัยในช่วงแรกระบุว่า การเพิ่มจำนวนของไวรัสได้ในระบบทางเดินอาหาร แต่การติดต่อโดยระบบทางเดินอาหารยังไม่เป็นที่ยืนยัน\n" + "• ช่วงพีคของการแพร่เชื้อน่าจะเกิดขึ้นในช่วงแรกที่แสดงอาการและลดลงหลังจากนั้น\n" + "• การแพร่เชื้อก่อนแสดงอาการอาจเกิดขึ้นได้ อย่างไรก็ตาม หากไม่มีอาการไอ(กลไกหลักในการขับไวรัสออกมา) อาจจำกัดการแพร่เชื้อในช่วงนั้น\n", + ), + CovidInfoItem( + title: "เหตุการณ์ระบาดเป็นวงกว้าง", + info: + "เหตุการณ์ระบาดเป็นวงกว้างเกิดเมื่อคนหนึ่งคนแพร่เชื้อไวรัสไปสู่คนกลุ่มใหญ่ผิดปกติ สถานการณ์ที่จะทวีความรุนแรงของการระบาดเป็นวงกว้างรวมถึง\n" + "• การชุมนุมขนาดใหญ่\n" + "• ประชากรสูงอายุ\n" + "• ประชากรไร้ถิ่นฐาน\n" + "• การสัมผัสโรคจากต่างประเทศ\n" + "• ความหนาแน่นของเขตเมือง\n" + "• ระบบสาธารณสุขไม่เข็มแข็ง\n" + "• รัฐบาลขาดความโปร่งใส\n" + "• สื่อขาดเสรีภาพ", + ), + CovidInfoItem( + title: "มาตรการทางสาธารณสุข", + info: + "• การกักกัน คือ การจำกัดกิจกรรมต่างๆหรือการแยกผู้ที่ไม่ป่วย แต่อาจมีประวัติส้มผัสใกล้ชิดกับผู้ป่วยโควิด 19 จุดประสงค์คือเพื่อป้องกันการแพร่ระบาดของโรคในห้วงเวลาที่คนเริ่มมีอาการ\n" + "• การแยกกัก หมายถึง การแยกผู้ป่วยที่มีอาการของโรคโควิด 19 และอาจแพร่เชื้อได้ จึงทำเพื่อป้องกันการแพร่ระบาดของโรค\n" + "• การเว้นระยะ คือ การอยู่ห่างกันและกัน องค์การอนามัยโลกแนะนำให้เว้นระยะอย่าง 1 เมตรจากผู้อื่น ส่วนนี้เป็นมาตรการทั่วไปที่ทุกคนควรทำถึงแม้ว่าจะแข็งแรง\n" + "• การติดตามผู้สัมผัสโรค ทำเพื่อระบุหาคนที่อาจมีประวัติสัมผัสโรคเพื่อที่จะแยกกักออกไปโดยเร็ว", + ), + CovidInfoItem( + title: "ลักษณะจำเพาะของโรค", + info: "อัตราการแพร่เชื้อและความรุนแรง\n" + "1. Basic Reproductive Rate(RO) คือ ค่าเฉลี่ยที่ผู้ป่วย 1 คน จะแพร่เชื้อให้ผู้อื่นในกลุ่มประชากรที่มีความไวต่อการรับเชื้อ ค่า RO ของโรคโควิด 19 อยู่ประมาณ 2 และ 4\n" + "2. Clinical Onset Interval คือ ช่วงเวลาแสดงอาการในผู้ป่วยรายต่อๆ กันในห่วงโซ่ของการแพร่ระบาด ในงานวิจัยส่วนใหญ่ เวลาเฉลี่ยอยู่ที่ 4 และ 5 วัน\n" + "3. Case Fatality Ratio (CFR) หรืออัตราการเสียชีวิต คือ สัดส่วนของผู้ป่วยที่ถึงแก่ชีวิตอัตราคร่าวๆของทั่วโลกอยู่ที่ 7% (ธันวาคม 2019-พฤษฎาคม 2020)", + ), + CovidInfoItem( + title: "กลุ่มเสี่ยง", + info: + "1. เสี่ยงต่ำ งานวิจัยระบุว่า เด็กและคนหนุ่มสาวติดเชื้อและแพร่เชื้อได้ อย่างไรก็ตามเด็กมักจะไม่มีอาการรุนแรง\n" + "2. เสี่ยงสูง ความเสี่ยงต่ออาการรุนแรงของโรคเพิ่มตามอายุและในผู้ที่มีโรคประจำตัว เช่น ความดันโลหิตสูง ดรคเบาหวาน โรคหลอดเลือดหัวใจ โรคระบบทางเดินหายใจเรื้อรังและโรคมะเร็ง", + ), + CovidInfoItem( + title: "ภูมิคุ้มกัน", + info: "1. ระยะสั้น\n" + "(a) ลดลงอย่างต่อเนื่อง\n" + "(b) ผู้ป่วยอาจยังแพร่เชื้อได้แม้มีอาการดีขึ้น สิ่งนี้มีนัยสำคัญต่อการควบคุมป้องกันโรคในบริบทสถานพยาบาลและในการจำหน่ายผู้ป่วย ผู้ป่วยบางรายยังคงต้องแยกกักตัวเองต่อที่บ้านหลังจากได้รับการจำหน่ายแล้ว\n" + "\n" + "2. ระยะยาว\n" + "(a) ขณะนี้ ยังไม่มีหลักฐานเพียงพอเกี่ยวกับประสิทธิภาพหรือระยะเวลาของภูมิคุ้มกันที่สร้างจากสารแอนติบอดี้ที่จะรับประกันความเที่ยงตรงของสิ่งที่เรียกว่า “พาสปอร์ตภูมิคุ้มกัน” หรือ “ใบรับประกันว่าไม่มีความเสี่ยง”\n" + "(b) มีข้อกังวลว่า ผู้คนอาจเข้าใจว่าตนเองมีภูมิคุ้มกันต่อการติดเชื้อครั้งที่สอง และละเลยการปฎิบัติตามคำแนะนำทางสุขภาพ ซึ่งอาจเป็นการเพิ่มความเสี่ยงให้เกิดการระบาดต่อเนื่อง\n" + "\n" + "ภูมิคุ้มกัน คือ สารแอนติบอดี้ต้านเชื้อโควิด 19 (ทั้ง IgG และ IgM) จะปรากฏขึ้น 6 ถึง 12 วันนับจากเริ่มแสดงอาการ หลังจากนั้น เชื้อไวรัสจะค่อยๆลดลงอย่างต่อเนื่อง ผู้ป่วยอาจยังแพร่เชื้อได้แม้มีอาการดีขึ้นและยังคงต้องแยกตัวเองต่อที่บ้านหลังจากได้รับการจำหน่ายแล้ว", + ), + CovidInfoItem( + title: "การตรวจ", + info: + "ไม่มีการตรวจโควิด 19 ชนิดใดได้รับการขึ้นทะเบียน ยกเว้นภายใต้ข้อกำหนดการใช้ในสภาวะฉุกเฉินเท่านั้น ทุกประเภทกำลังอยู่ระหว่างการประเมิน\n" + "1. Nucleic Acid Amplification Test (NAATs) ใช้เพื่อตรวจวินิจฉัยการติดเชื้อ (ว่าตรวจพบไวรัสหรือไม่) ในระยะเฉียบพลันของโรค การตรวจเทคนิคนี้ใช้เวลาระหว่าง 13 นาทีถึง 3 ชั่วโมง และจำหน่ายมีอุปกรณ์เครื่องมือเฉพาะ\n" + "2. การตรวจหาแอนติบอดี้ ด้วยการสร้างภูมิคุ้มกันจะใช้ตรวจหาแอนติบอดี้ IgM และ IgG ที่สร้างขึ้นมาต้านไวรัส ไม่มีประโยชน์ในการวินิจฉัยโรคเนื่องจากการตอบสนองของร่างกายไม่สามารถตรวจพบได้ในสัปดาห์แรกของการเจ็บป่วยการตรวจใช้เวลา 15 นาที และสามารถใช้ตรวจว่าใครเคยติดเชื้อมาก่อนการศึกษาในระดับประชากรด้วยเทคนิคตรวจแอนติบอดี้ขณะนี้ทำอยู่ใน 6 ประเทศ\n" + "3. การตรวจหาแอนติเจน ใช้ตรวจหาแอนติเจนของไวรัสและอาจเป็นประโยชน์ในการวินิจฉัยการติดเชื้อฉับพลัน การพัฒนาชุดตรวจทำอยู่ในหลายประเทศ", + ), + CovidInfoItem( + title: "การรักษา", + info: + "ขณะนี้ยังไม่มียาต้านไวรัสที่ได้รับการขึ้นทะเบียนให้ใช้รักษาโรคโควิด 19 แต่มีการทำวิจัยเพื่อพิจารณาว่ามียาตัวใดบ้างที่จะปรับวัตถุประสงค์การใช้เดิมเพื่อการรักษาโรคโควิด 19\n" + "\n" + "องค์การอนามัยโลกกำลังประสานงานร่วมมือในโครงการขนาดใหญ่ชื่อ Solidarity Trial ในหลายประเทศเพื่อประเมินยา/สูตรการรักษา 4 ชนิด ดังนี้\n" + "1. Remdesivir เดิมพัฒนาขึ้นเพื่ออีดบลา\n" + "2. Lopinavir/Ritonavir การผสมกันของยาต้านเอชไอวี\n" + "3. Lopinavir/Ritonavir + Interferon Beta ซึ่งมีคุณสมบัติต้านไวรัส\n" + "4. Choloroquine ยาต้านมาลาเรียที่มีคุณสมบัติต้านไวรัส", + ), + CovidInfoItem( + title: "มาตรการระดับบุคคล", + info: + "1. การรักษาสุขอนามัยของมือและมารยาทใน การไอ/จามเป็นสิ งสําคัญที่ ควรทํา ตลอดเวลาและเป็นวิธีที่ดีที่ สุดที่จะป้องกัน ตัวเองและผู้อื่น\n" + "2. เมื่อเป็นไปได้รักษาระยะอย่างน้อย 1 เมตร จากผู้อื่ น เนื่องจากผู้ติดเชื้อบางรายอาจ ยังไม่แสดงอาการหรือมีอาการไม่รุนแรง ดังนั้ นการเว้นระยะห่างจากทุกคนสําคัญ มากหากคุณอยู่ในพื้นที่ ที่มีการระบาดของ โรคโควิด19", + ), + CovidInfoItem( + title: "ผลกระทบทางเศรษฐกิจและสังคม", + info: + "• การระบาดไปทั่วในวงกว้างของโรคโควิด 19 และวิกฤตทางเศรษฐกิจที่เชื่อมโยงกับสถาณการณ์นี้ทำให้เกิดความท้าทายใหญ่หชวงในระดับโลกและระดับท้องถิ่น\n" + "• ผลกระทบทางสุขภาพ เศรษฐกิจและสังคมเกิดขึ้นกับกลุ่มคนทุกกลุ่ม แต่บ่อนทำลายกลุ่มประชากรเปราะบางมากที่สุด ซึ่งรวมถึง คนยากจน ผู้สูงอายุ ผู้พิการ เยาวชน และกลุ่มคนชาติพันธุ์\n" + "• วิกฤตทางโรคระบาดและเศรษฐกิจกระทบต่อกลุ่มประชากรเปราะบางอย่างไม่เป็นธรรม ซึ่งอาจจุดชนวนให้เกิดความไม่เท่าเทียมดันและความยากจนมากขึ้น\n" + "• วิกฤตโลกในครั้งนี้ต้องการประสารงาน ความเป็นอันหนึ่งอันเดียวกัน และ นโยบายทางเศรษฐกิจ สังคมและสาธารณสุขที่มีประสิทธิภาพ", + ), + Container( + padding: const EdgeInsets.symmetric(vertical: 32.0), + child: Text( + "อ้างอิง:\n" + "https://www.who.int/thailand/emergencies/novel-coronavirus-2019/q-a-on-covid-19", + ), + ), + ], + ), + ) ], ), ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. ); } } diff --git a/lib/widgets/covid_info_item.dart b/lib/widgets/covid_info_item.dart new file mode 100644 index 0000000..9839e99 --- /dev/null +++ b/lib/widgets/covid_info_item.dart @@ -0,0 +1,43 @@ +import 'package:expansion_card/expansion_card.dart'; +import 'package:flutter/material.dart'; + +class CovidInfoItem extends StatelessWidget { + final String title; + final String info; + + const CovidInfoItem({ + Key key, + this.title, + this.info, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Center( + child: ExpansionCard( + leading: Icon(Icons.info_outline, color: Colors.black), + title: Container( + child: Text( + title, + style: Theme.of(context).textTheme.headline5, + ), + ), + children: [ + Divider( + indent: 16.0, + endIndent: 16.0, + height: 16.0, + color: Colors.blue, + thickness: 3.0, + ), + Container( + padding: const EdgeInsets.only(left: 24.0), + child: Text( + info, + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/widgets/my_header.dart b/lib/widgets/my_header.dart new file mode 100644 index 0000000..40999fa --- /dev/null +++ b/lib/widgets/my_header.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class MyHeader extends StatefulWidget { + final String image; + final String textTop; + final String textBottom; + + const MyHeader({ + Key key, + this.image, + this.textTop, + this.textBottom, + }) : super(key: key); + + @override + _MyHeaderState createState() => _MyHeaderState(); +} + +class _MyHeaderState extends State { + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: _HeaderClipper(), + child: Container( + height: 280.0, + width: double.infinity, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + const Color(0xFF3383CD), + const Color(0xFF11249F), + ], + ), + image: const DecorationImage( + image: const AssetImage("assets/images/virus.png"), + ), + ), + child: SafeArea( + child: Stack( + children: [ + Positioned( + top: 40.0, + child: SvgPicture.asset( + widget.image, + width: 256.0, + fit: BoxFit.fitWidth, + alignment: Alignment.topCenter, + ), + ), + Positioned( + top: 56.0, + right: 24.0, + child: Text( + "${widget.textTop}\n${widget.textBottom}", + style: Theme.of(context).textTheme.headline6, + ), + ), + ], + ), + ), + ), + ); + } +} + +class _HeaderClipper extends CustomClipper { + @override + Path getClip(Size size) { + var path = Path(); + path.lineTo(0, size.height - 80); + path.quadraticBezierTo( + size.width / 2, + size.height, + size.width, + size.height - 80, + ); + path.lineTo(size.width, 0); + path.close(); + return path; + } + + @override + bool shouldReclip(CustomClipper oldClipper) { + return false; + } +} diff --git a/lib/widgets/symptom_card.dart b/lib/widgets/symptom_card.dart new file mode 100644 index 0000000..74e29c8 --- /dev/null +++ b/lib/widgets/symptom_card.dart @@ -0,0 +1,40 @@ +import 'package:chonchai_chana/constants.dart'; +import 'package:flutter/material.dart'; + +class SymptomCard extends StatelessWidget { + final String image; + final String title; + + const SymptomCard({ + Key key, + this.image, + this.title, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.0), + color: Colors.white, + boxShadow: [ + BoxShadow( + offset: const Offset(0.0, 8.0), + blurRadius: 8.0, + color: kShadowColor, + ), + ], + ), + child: Column( + children: [ + Image.asset(image, height: 80.0), + Text( + title, + style: Theme.of(context).textTheme.caption, + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 62bef60..5f60dba 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,20 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "12.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.40.6" archive: dependency: transitive description: @@ -57,13 +43,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.3" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" clock: dependency: transitive description: @@ -85,13 +64,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" - coverage: - dependency: transitive - description: - name: coverage - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.2" crypto: dependency: transitive description: @@ -106,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + expansion_card: + dependency: "direct main" + description: + name: expansion_card + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" fake_async: dependency: transitive description: @@ -113,6 +92,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.3" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" file: dependency: transitive description: @@ -125,61 +111,53 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_driver: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_test: + flutter_launcher_icons: dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - glob: - dependency: transitive description: - name: glob + name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - integration_test: + version: "0.8.1" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "0.19.2+1" + flutter_test: dependency: "direct dev" description: flutter source: sdk - version: "0.9.2+2" - io: - dependency: transitive + version: "0.0.0" + google_fonts: + dependency: "direct main" description: - name: io + name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" - js: + version: "1.1.1" + http: dependency: transitive description: - name: js + name: http url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.3" - json_rpc_2: + version: "0.12.2" + http_parser: dependency: transitive description: - name: json_rpc_2 + name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "2.2.2" - logging: + version: "3.1.4" + image: dependency: transitive description: - name: logging + name: image url: "https://pub.dartlang.org" source: hosted - version: "0.11.4" + version: "2.1.19" matcher: dependency: transitive description: @@ -194,34 +172,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.6" - node_interop: + path: dependency: transitive description: - name: node_interop + name: path url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" - node_io: + version: "1.8.0-nullsafety.3" + path_drawing: dependency: transitive description: - name: node_io + name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" - package_config: + version: "0.4.1+1" + path_parsing: dependency: transitive description: - name: package_config + name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" - path: + version: "0.1.4" + path_provider: dependency: transitive description: - name: path + name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.6.27" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+8" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" pedantic: dependency: transitive description: @@ -229,6 +235,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.10.0-nullsafety.3" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" platform: dependency: transitive description: @@ -236,13 +249,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0-nullsafety.4" - pool: + plugin_platform_interface: dependency: transitive description: - name: pool + name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.5.0-nullsafety.3" + version: "1.0.3" process: dependency: transitive description: @@ -250,32 +263,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0-nullsafety.4" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.4" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.10-nullsafety.3" source_span: dependency: transitive description: @@ -304,13 +296,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0-nullsafety.3" - sync_http: - dependency: transitive - description: - name: sync_http - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" term_glyph: dependency: transitive description: @@ -325,13 +310,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.19-nullsafety.6" - test_core: - dependency: transitive - description: - name: test_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.12-nullsafety.9" typed_data: dependency: transitive description: @@ -346,34 +324,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.5" - vm_service: - dependency: transitive - description: - name: vm_service - url: "https://pub.dartlang.org" - source: hosted - version: "5.5.0" - watcher: + win32: dependency: transitive description: - name: watcher + name: win32 url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+15" - web_socket_channel: + version: "1.7.4" + xdg_directories: dependency: transitive description: - name: web_socket_channel + name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" - webdriver: + version: "0.1.2" + xml: dependency: transitive description: - name: webdriver + name: xml url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "4.5.1" yaml: dependency: transitive description: @@ -383,3 +354,4 @@ packages: version: "2.2.1" sdks: dart: ">=2.12.0-0.0 <3.0.0" + flutter: ">=1.24.0-6.0.pre <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 414abef..cee07b9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,9 @@ dependencies: flutter: sdk: flutter + google_fonts: ^1.1.1 + flutter_svg: ^0.19.2+1 + expansion_card: ^0.1.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -32,8 +35,13 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - integration_test: - sdk: flutter + flutter_launcher_icons: ^0.8.1 + +flutter_icons: + android: true + ios: false + image_path: "assets/launcher/icon.png" + adaptive_icon_background: "#FFFFFFFF" # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -47,9 +55,9 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/icons/ + - assets/images/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/test/widget_test.dart b/test/widget_test.dart index b6e6109..2f520d4 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:chonchai_chana/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(MainApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget);