Source Code Flutter
Source Code Flutter
Oleh Kelompok A1 :
2. Design UI Awal
Awal design UI dibuat pada FIGMA
3. DATABASE
Database secara teknis merupakan sebuah sebutan yang digunakan untuk menyimpan sebuah
data pada suatu lokasi, pada projek ini menggunakan database mysql phpmyadmin yang
menggunakan xampp sebagai media koneksi karena menggunakan xampp maka database
disimpan pada localhost saja sehingga membuat orang selain host tidak bisa mengakses data,
pada database projek ini digunakan untuk mengontrol user yang masuk atau login maupun
register yang dilakukan oleh admin. Pada database kami membuat 6 tabel data yang saling
memiliki relasi.
4. CRUD
CRUD merupakan bagian dari database yaitu CREATE, READ, UPDATE dan DELET. Pada
projek menggunakan CRUD untuk membuat akun, login dengan tabel database sebagai
berikut:
5. API
API adalah mekanisme yang memungkinkan dua komponen perangkat lunak untuk saling
berkomunikasi menggunakan serangkaian definisi dan protokol. API sendiri dapat berupa
dummy data maupun data – data yang lain, API dapat dikoneksikan pada berbagai
Programming seperti flutter/dart sehingga pada projek ini kami menggunakan API untuk
menampilkan berita pada aplikasi “MIROTA”. API yang kami gunakan bersumber dari
Postman yang di konversi dari Bahasa pemograman json menjadi Bahasa pemograman dart
dengan bantuan “app.quictype.io”
6. State Management
Menurut sepengetahuan kami mengenai state management yaitu seperti statefull dan stateless
yang biasa kami gunakan, namun state management digunakan untuk memisahkan mana
yang antara logic dan view.
7. Hasil
8. Source Code
⮚ Main.dart
import 'package:flutter/material.dart';
import 'package:presensi/home-page.dart';
import 'package:presensi/login-page.dart';
import 'package:presensi/simpan-page.dart';
void main() {
runApp(MyApp());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LoginPage(),
);
}
}
⮚ login-page.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:presensi/home-page.dart';
import 'package:http/http.dart' as myHttp;
import 'package:presensi/models/login-response.dart';
import 'package:shared_preferences/shared_preferences.dart';
@override
State<LoginPage> createState() => _LoginPageState();
}
@override
void initState() {
// TODO: implement initState
super.initState();
_token = _prefs.then((SharedPreferences prefs) {
return prefs.getString("token") ?? "";
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(child: Text("LOGIN")),
SizedBox(height: 20),
Text("Email"),
TextField(
controller: emailController,
),
SizedBox(height: 20),
Text("Password"),
TextField(
controller: passwordController,
obscureText: true,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
login(emailController.text, passwordController.text);
},
child: Text("Masuk"))
],
),
),
)),
);
}
}
⮚ home-page.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:presensi/models/home-response.dart';
import 'package:presensi/simpan-page.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as myHttp;
@override
State<HomePage> createState() => _HomePageState();
}
@override
void initState() {
// TODO: implement initState
super.initState();
_token = _prefs.then((SharedPreferences prefs) {
return prefs.getString("token") ?? "";
});
_name = _prefs.then((SharedPreferences prefs) {
return prefs.getString("name") ?? "";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FutureBuilder(
future: _name,
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return CircularProgressIndicator();
} else {
if (snapshot.hasData) {
print(snapshot.data);
return Text(snapshot.data!,
style: TextStyle(fontSize: 18));
} else {
return Text("-", style: TextStyle(fontSize: 18));
}
}
}),
SizedBox(
height: 20,
),
Container(
width: 400,
decoration: BoxDecoration(color: Colors.blue[800]),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(children: [
Text(hariIni?.tanggal ?? '-',
style:
TextStyle(color: Colors.white, fontSize: 16)),
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(hariIni?.masuk ?? '-',
style: TextStyle(
color: Colors.white, fontSize: 24)),
Text("Masuk",
style: TextStyle(
color: Colors.white, fontSize: 16))
],
),
Column(
children: [
Text(hariIni?.pulang ?? '-',
style: TextStyle(
color: Colors.white, fontSize: 24)),
Text("Pulang",
style: TextStyle(
color: Colors.white, fontSize: 16))
],
)
],
)
]),
),
),
SizedBox(height: 20),
Text("Riwayat Presensi"),
Expanded(
child: ListView.builder(
itemCount: riwayat.length,
itemBuilder: (context, index) => Card(
child: ListTile(
leading: Text(riwayat[index].tanggal),
title: Row(children: [
Column(
children: [
Text(riwayat[index].masuk,
style: TextStyle(fontSize: 18)),
Text("Masuk", style: TextStyle(fontSize: 14))
],
),
SizedBox(width: 20),
Column(
children: [
Text(riwayat[index].pulang,
style: TextStyle(fontSize: 18)),
Text("Pulang", style: TextStyle(fontSize: 14))
],
),
]),
),
),
),
),
],
),
));
}
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => SimpanPage()))
.then((value) {
setState(() {});
});
},
child: Icon(Icons.add),
),
);
}
}
⮚ simpan-page.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:location/location.dart';
import 'package:presensi/models/save-presensi-response.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
@override
void initState() {
super.initState();
});
bool serviceEnable;
PermissionStatus permissionGranted;
if (!serviceEnable) {
if (!serviceEnable) {
return null;
if (permissionGranted == PermissionStatus.denied) {
if (permissionGranted != PermissionStatus.granted) {
return null;
SavePresensiResponseModel savePresensiResponseModel;
"longitude": longitude.toString()
};
Uri.parse("https://punyawa.com/presensi/public/api/save-presensi"),
body: body,
headers: headers);
savePresensiResponseModel =
SavePresensiResponseModel.fromJson(json.decode(response.body));
if (savePresensiResponseModel.success) {
ScaffoldMessenger.of(context)
Navigator.pop(context);
} else {
ScaffoldMessenger.of(context)
}
@override
return Scaffold(
appBar: AppBar(
title: Text("Presensi"),
),
body: FutureBuilder<LocationData?>(
future: _currenctLocation(),
if (snapshot.hasData) {
print("KODING : " +
currentLocation.latitude.toString() +
"|"+
currentLocation.longitude.toString());
return SafeArea(
child: Column(
children: [
Container(
height: 300,
child: SfMaps(
layers: [
MapTileLayer(
initialFocalLatLng: MapLatLng(
currentLocation.latitude!,
currentLocation.longitude!),
initialZoomLevel: 15,
initialMarkersCount: 1,
urlTemplate:
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
return MapMarker(
latitude: currentLocation.latitude!,
longitude: currentLocation.longitude!,
child: Icon(
Icons.location_on,
color: Colors.red,
),
);
},
],
),
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
savePresensi(currentLocation.latitude,
currentLocation.longitude);
},
],
));
} else {
return Center(
child: CircularProgressIndicator(),
);
}),
);
⮚ home-response.dart
import 'dart:convert';
HomeResponseModel homeResponseModelFromJson(String str) =>
HomeResponseModel.fromJson(json.decode(str));
json.encode(data.toJson());
class HomeResponseModel {
HomeResponseModel({
required this.success,
required this.data,
required this.message,
});
bool success;
List<Datum> data;
String message;
HomeResponseModel(
success: json["success"],
message: json["message"],
);
"message": message,
};
class Datum {
Datum({
required this.id,
required this.userId,
required this.latitude,
required this.longitude,
required this.tanggal,
required this.masuk,
required this.pulang,
required this.createdAt,
required this.updatedAt,
required this.isHariIni,
});
int id;
String userId;
String latitude;
String longitude;
String tanggal;
String masuk;
String pulang;
DateTime createdAt;
DateTime updatedAt;
bool isHariIni;
id: json["id"],
userId: json["user_id"],
latitude: json["latitude"],
longitude: json["longitude"],
tanggal: json["tanggal"],
masuk: json["masuk"],
pulang: json["pulang"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
isHariIni: json["is_hari_ini"],
);
"id": id,
"user_id": userId,
"latitude": latitude,
"longitude": longitude,
"tanggal": tanggal,
"masuk": masuk,
"pulang": pulang,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"is_hari_ini": isHariIni,
};
⮚ Login-Response.dart
// To parse this JSON data, do
//
// final loginResponseModel = loginResponseModelFromJson(jsonString);
import 'dart:convert';
class LoginResponseModel {
LoginResponseModel({
required this.success,
required this.message,
required this.data,
});
bool success;
String message;
Data data;
class Data {
Data({
required this.id,
required this.name,
required this.email,
required this.emailVerifiedAt,
required this.createdAt,
required this.updatedAt,
required this.token,
required this.tokenType,
});
int id;
String name;
String email;
dynamic emailVerifiedAt;
DateTime createdAt;
DateTime updatedAt;
String token;
String tokenType;
import 'dart:convert';
class SavePresensiResponseModel {
SavePresensiResponseModel({
required this.success,
required this.data,
required this.message,
});
bool success;
Data data;
String message;
class Data {
Data({
required this.id,
required this.userId,
required this.latitude,
required this.longitude,
required this.tanggal,
required this.masuk,
required this.pulang,
required this.createdAt,
required this.updatedAt,
});
int id;
String userId;
String latitude;
String longitude;
DateTime tanggal;
String masuk;
dynamic pulang;
DateTime createdAt;
DateTime updatedAt;
9. Eror
Dalam Aplikasi ini kami mendapatkan eror dimana aplikasi Mirota tidak bisa berjalan
dengan yang diharapkan hal ini terjadi dikarenakan beberpa kendalan diantaranya
dikarenakan konfigurasi tipe data yang masih belum sinkron dan perbedaan tipe data yang
disajikan antara database dengan flutter seperti gambar dibawah ini
10. Kesimpulan
Kami mengakui dalam pembuatan proyek ini masih banyak kurang dan jauh dari kayta
sempurna, hal ini dikarenakan kurangnya pengalaman dan belum pahamnya kami
terhadap materi flutter, namun kami akan perbaiki semua dikemudian hari yang nantinya
akan bisa membuat aplikasi yang bisa sesuai dengan kontrak perjanjian sebelumnya
Lampiran :
Semua file dalam kodingan ini akan kamki sertakan dalam bentuk winrar