GOAL WORKSHOP
Splash
Detail
Main
Tahapan
1. Testing Rest API
2. Membuat Aplikasi Mobile Android Dengan Flutter
3. Membuat Rest API dengan PHP *
Testing Rest API
Endpoint Popular
Endpoint Top
Endpoint Kategori
Endpoint Master Kategori
Endpoint Update HitCount
Extension vscode
Flutter get_cli
// To install:
pub global activate get_cli
// (to use this add the following to system PATH: [FlutterSDKInstallDir]\bin\cache\dart-sdk\bin
flutter pub global activate get_cli
// To create a flutter project in the current directory:
// Note: By default it will take the folder's name as project name
// You can name the project with `get create project:my_project`
// If the name has spaces use `get create project:"my cool project"`
get create project
// To generate the chosen structure on an existing project:
get init
// To create a page:
// (Pages have controller, view, and binding)
// Note: you can use any name, ex: `get create page:login`
// Nota: use this option if the chosen structure was Getx_pattern
get create page:home
// To create a screen
// (Screens have controller, view, and binding)
// Note: you can use any name, ex: `get screen page:login`
// Nota: use this option if the chosen structure was CLEAN (by Arktekko)
get create screen:home
// To create a new controller in a specific folder:
// Note: you don't need to reference the folder,
// Getx will search automatically for the home folder
// and add your controller there.
get create controller:dialogcontroller on home
// To create a new view in a specific folder:
// Note: you don't need to reference the folder,
// Getx will automatically search for the home folder
// and insert your view there.
get create view:dialogview on home
// To create a new provider in a specific folder:
get create provider:user on home
// To generate a localization file:
// Note: 'assets/locales' directory with your translation files in json format
get generate locales assets/locales
// To generate a class model:
// Note: 'assets/models/user.json' path of your template file in json format
// Note: on == folder output file
// Getx will automatically search for the home folder
// and insert your class model there.
get generate model on home with assets/models/user.json
//to generate the model without the provider
get generate model on home with assets/models/user.json --skipProvider
//Note: the URL must return a json format
get generate model on home from "https://api.github.com/users/CpdnCristiano"
// To install a package in your project (dependencies):
get install camera
// To install several packages from your project:
get install http path camera
// To install a package with specific version:
get install path:1.6.4
// You can also specify several packages with version numbers
// To install a dev package in your project (dependencies_dev):
get install flutter_launcher_icons --dev
// To remove a package from your project:
get remove http
// To remove several packages from your project:
get remove http path
// To update CLI:
get update
// or `get upgrade`
// Shows the current CLI version:
get -v
// or `get -version`
// For help
get help
pub global activate get_cli
Mengaktifkan get cli
Membuat Project
get create project
Pilih Flutter Project -> Swift -> Kotlin
Pilih null safe = Yes, dan Linter = Dart
Pilih GetX Pattern dan selanjutnya pilih Yes
Masuk kedalam project dan buka VsCode
Buka Terminal di VsCode, Jalankan
flutter run -v
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeView'),
centerTitle: true,
),
body: Center(
child: Text(
'HomeView is working',
style: TextStyle(fontSize: 20),
),
),
);
}
}
Flutter Package
dependencies:
animated_text_kit: ^4.2.1
cached_network_image: ^3.2.0
carousel_slider: ^4.0.0
cupertino_icons: ^1.0.2
flutter:
sdk: flutter
flutter_launcher_icons: ^0.9.2
flutter_staggered_grid_view: ^0.4.1
get: 4.6.1
http: ^0.13.4
jiffy: ^4.1.0
lottie: ^1.2.1
dev_dependencies:
flutter_lints: ^1.0.0
flutter_test:
sdk: flutter
lints: 1.0.1
flutter:
uses-material-design: true
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/images/logo.png"
# lokasi image lokal
assets:
- assets/images/logo.png
flutter pub get
flutter pub run flutter_launcher_icons:main
String appName = "VISIT BOGOR";
String token = "25d55ad283aa400af464c76d713c07ad";
String baseUrl = "http://flutter.id/apiwisata";
String logoUrl = "https://flutter.id/apiwisata/assets/logo.png";
String lottieLoading =
'https://assets9.lottiefiles.com/packages/lf20_x62chJ.json';
String lottieError =
'https://assets8.lottiefiles.com/packages/lf20_pNx6yH.json';
String lottieSPlash =
"https://assets1.lottiefiles.com/packages/lf20_1pxqjqps.json";
String lottieWelcome =
"https://assets3.lottiefiles.com/packages/lf20_puciaact.json";
Goal Splash Screen
Splash Screen
get create page:splash
import 'package:get/get.dart';
class SplashController extends GetxController {
var isLoading = true.obs;
void loadSplash() {
isLoading(true);
Future.delayed(const Duration(milliseconds: 5000), () {
Get.snackbar("visitbogor", "Welcome");
Get.toNamed("/home");
isLoading(false);
});
}
@override
void onInit() {
loadSplash();
super.onInit();
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import 'package:visitbogor/app/data/config.dart';
import '../controllers/splash_controller.dart';
class SplashView extends GetView<SplashController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Obx(() {
if (controller.isLoading.value) {
return Center(child: Lottie.network(lottieSPlash));
} else {
return Center(child: Lottie.network(lottieWelcome));
}
}));
}
}
Goal Home Screen
json 2 dart
{
"id_wisata": "1",
"kategori_name": "Kuliner",
"title": "Coffee Shop - kafe.in.ciapus",
"image": "https://flutter.id/apiwisata/assets/1.png",
"user_create": "ILHAM MAULANA",
"created_at": "2021-12-15",
"hit_count": "13"
},
import 'dart:convert';
//ubah ini
List<WisataModel> wisataModelFromJson(String str) => List<WisataModel>.from(
json.decode(str).map((x) => WisataModel.fromJson(x)));
//ubah ini
String wisataModelToJson(List<WisataModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class WisataModel {
WisataModel({
required this.idWisata,
required this.kategoriName,
required this.title,
required this.image,
required this.summary,
required this.userCreate,
required this.createdAt,
required this.hitCount,
});
String idWisata;
String kategoriName;
String title;
String image;
String summary;
String userCreate;
String createdAt;
String hitCount;
factory WisataModel.fromJson(Map<String, dynamic> json) => WisataModel(
idWisata: json["id_wisata"],
kategoriName: json["kategori_name"],
title: json["title"],
image: json["image"],
summary: json["summary"],
userCreate: json["user_create"],
createdAt: json["created_at"],
hitCount: json["hit_count"],
);
Map<String, dynamic> toJson() => {
// ignore: unnecessary_null_in_if_null_operators
"id_wisata": idWisata,
// ignore: unnecessary_null_in_if_null_operators
"kategori_name": kategoriName,
// ignore: unnecessary_null_in_if_null_operators
"title": title,
// ignore: unnecessary_null_in_if_null_operators
"image": image,
// ignore: unnecessary_null_in_if_null_operators
"summary": summary,
// ignore: unnecessary_null_in_if_null_operators
"user_create": userCreate,
// ignore: unnecessary_null_in_if_null_operators
"created_at": createdAt,
// ignore: unnecessary_null_in_if_null_operators
"hit_count": hitCount,
};
}
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class HeaderWidget extends StatelessWidget {
String title;
int type;
static const colorizeColors = [
Colors.purple,
Colors.blue,
Colors.yellow,
Colors.red,
];
static const colorizeTextStyle = TextStyle(
fontSize: 25,
fontWeight: FontWeight.w900,
fontFamily: 'avenir',
);
HeaderWidget({required this.type, required this.title});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: AnimatedTextKit(
animatedTexts: [
ColorizeAnimatedText(
title,
textStyle: colorizeTextStyle,
colors: colorizeColors,
),
ColorizeAnimatedText(
title,
textStyle: colorizeTextStyle,
colors: colorizeColors,
),
ColorizeAnimatedText(
title,
textStyle: colorizeTextStyle,
colors: colorizeColors,
),
],
isRepeatingAnimation: true,
onTap: () {
print("Tap Event");
},
),
),
],
),
);
}
}
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:visitbogor/app/data/config.dart';
import 'package:visitbogor/app/data/wisata_model.dart';
// ignore: must_be_immutable
class HomeTile extends StatelessWidget {
WisataModel data;
HomeTile({required this.data});
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
child: Padding(
padding: EdgeInsets.all(8),
child: Stack(
children: [
Container(
height: 180,
width: double.infinity,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
),
child: CachedNetworkImage(
imageUrl: data.image,
fit: BoxFit.cover,
placeholder: (context, url) => Lottie.network(lottieLoading),
errorWidget: (context, url, error) =>
Lottie.network(lottieError),
),
),
Positioned(
right: 5,
child: Container(
color: Colors.transparent,
child: Row(
children: [
Icon(
Icons.visibility,
color: Colors.white,
),
Text(
data.hitCount,
style: TextStyle(color: Colors.white),
)
],
),
),
),
Positioned(
bottom: 5,
child: Container(
padding: EdgeInsets.all(8),
child: Text(
data.title,
maxLines: 1,
style: TextStyle(
color: Colors.white,
fontFamily: 'avenir',
fontWeight: FontWeight.w800),
overflow: TextOverflow.ellipsis,
),
),
),
],
),
),
);
}
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:visitbogor/app/data/config.dart';
import 'package:visitbogor/app/data/wisata_model.dart';
class HomeServices {
static var client = http.Client();
static Future<List<WisataModel>?> fetchPopular() async {
//http://flutter.id/apiwisata?modul=popular&token=25d55ad283aa400af464c76d713c07ad
String url = baseUrl + "?modul=popular&token=" + token;
var response = await client.get(Uri.parse(url));
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
//print(json.toString());
var jsonString = jsonEncode(json['data']).toString();
return wisataModelFromJson(jsonString);
} else {
return null;
}
}
static Future<List<WisataModel>?> fetchTop() async {
String url = baseUrl + "?modul=top&token=" + token;
var response = await client.get(Uri.parse(url));
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
//print(json.toString());
var jsonString = jsonEncode(json['data']).toString();
return wisataModelFromJson(jsonString);
} else {
return null;
}
}
static Future<List<WisataModel>?> fetchKategori(String id) async {
String url = baseUrl + "?modul=kategori&id=" + id + "&token=" + token;
print(url.toString());
var response = await client.get(Uri.parse(url));
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
//print(json.toString());
var jsonString = jsonEncode(json['data']).toString();
return wisataModelFromJson(jsonString);
} else {
return null;
}
}
static updateCount(String id) async {
String url =
baseUrl + "?modul=hitcount&id=" + id.toString() + "&token=" + token;
var response = await client.get(Uri.parse(url));
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
//print(json.toString());
return json;
} else {
return null;
}
}
}
import 'package:get/get.dart';
import 'package:visitbogor/app/data/wisata_model.dart';
import 'package:visitbogor/app/modules/home/services/home_services.dart';
class HomeController extends GetxController {
var isLoading = true.obs;
var isLoading2 = true.obs;
var wisataList = <WisataModel>[].obs;
var popularList = <WisataModel>[].obs;
void fetchPopular() async {
try {
isLoading2(true);
var data = await HomeServices.fetchPopular();
if (data != null) {
popularList.value = data;
}
} finally {
isLoading2(false);
}
}
void fetchTop() async {
try {
isLoading(true);
var data = await HomeServices.fetchTop();
if (data != null) {
wisataList.value = data;
}
} finally {
isLoading(false);
}
}
void fetchKategori(String id) async {
try {
isLoading(true);
var data = await HomeServices.fetchKategori(id);
if (data != null) {
wisataList.value = data;
}
} finally {
isLoading(false);
}
}
void updateHitCount(String id) async {
await HomeServices.updateCount(id);
}
@override
void onInit() {
fetchPopular();
fetchTop();
super.onInit();
}
}
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import 'package:visitbogor/app/customwidget/header.dart';
import 'package:visitbogor/app/data/config.dart';
import 'package:visitbogor/app/modules/home/views/home_tile.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
//header
HeaderWidget(type: 1, title: appName),
//carousel
Expanded(
flex: 1,
child: Obx(() {
if (controller.isLoading2.value) {
return Center(
child: Lottie.network(lottieLoading),
);
} else {
return CarouselSlider.builder(
options: CarouselOptions(
autoPlay: true,
enlargeCenterPage: true,
viewportFraction: 1,
aspectRatio: 2.0,
initialPage: 2,
),
itemCount: controller.popularList.length,
itemBuilder: (BuildContext context, int index,
int pageViewIndex) =>
GestureDetector(
onTap: () {
controller.updateHitCount(
controller.popularList[index].idWisata);
Get.toNamed("/detail", arguments: [
{"data": controller.popularList[index]}
]);
},
child:
HomeTile(data: controller.popularList[index])),
);
}
}),
),
//pembatas
SizedBox(
height: 10,
),
//grid view
Expanded(
flex: 3,
child: Obx(() {
if (controller.isLoading.value) {
return Center(
child: Lottie.network(lottieLoading),
);
} else {
return StaggeredGridView.countBuilder(
crossAxisCount: 2,
itemCount: controller.wisataList.length,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
staggeredTileBuilder: (index) => StaggeredTile.fit(1),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
controller.updateHitCount(
controller.wisataList[index].idWisata);
Get.toNamed("/detail", arguments: [
{"data": controller.wisataList[index]}
]);
},
child: HomeTile(data: controller.wisataList[index]));
},
);
}
}),
),
],
),
),
);
}
}
Goal Detail Screen
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import 'package:visitbogor/app/customwidget/header.dart';
import 'package:visitbogor/app/data/config.dart';
import 'package:visitbogor/app/data/wisata_model.dart';
import '../controllers/detail_controller.dart';
import 'package:jiffy/jiffy.dart';
// ignore: must_be_immutable
class DetailView extends GetView<DetailController> {
WisataModel data = Get.arguments[0]['data'];
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 1,
child: Stack(
children: [
Container(
//padding: EdgeInsets.all(16),
height: double.infinity,
width: double.infinity,
child: CachedNetworkImage(
imageUrl: data.image,
fit: BoxFit.cover,
placeholder: (context, url) =>
Lottie.network(lottieLoading),
errorWidget: (context, url, error) =>
Lottie.network(lottieError),
),
),
Positioned(
top: 5,
child: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {
Get.toNamed("/home");
},
))
],
),
),
Expanded(
flex: 3,
child: ListView(
children: [
HeaderWidget(type: 2, title: data.title),
Padding(
padding: const EdgeInsets.all(16),
child: RichText(
text: TextSpan(
style: TextStyle(
color: Colors.black,
fontSize: 15,
fontFamily: 'avenir',
),
children: <TextSpan>[
TextSpan(
text: "Upload by :" +
data.userCreate.toLowerCase() +
", " +
Jiffy(data.createdAt, "yyyy-MM-dd").fromNow()),
TextSpan(text: "\n \n" + data.summary),
],
),
),
),
],
),
)
],
)),
);
}
}
Rest API
dbwisata
CREATE TABLE `kategori` (
`id_kategori` int NOT NULL,
`kategori_name` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `user` (
`id_user` int NOT NULL,
`fullname` varchar(100) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`token` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `wisata` (
`id_wisata` int NOT NULL,
`id_kategori` int DEFAULT NULL,
`title` varchar(200) DEFAULT NULL,
`image` varchar(300) DEFAULT NULL,
`summary` text,
`hit_count` int DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
File sql
-- phpMyAdmin SQL Dump
-- version 4.9.7
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: Dec 17, 2021 at 09:30 PM
-- Server version: 8.0.27
-- PHP Version: 7.3.33
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `dbwisata`
--
-- --------------------------------------------------------
--
-- Table structure for table `kategori`
--
CREATE TABLE `kategori` (
`id_kategori` int NOT NULL,
`kategori_name` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `kategori`
--
INSERT INTO `kategori` (`id_kategori`, `kategori_name`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'Kuliner', '2021-12-15 22:06:39', 1, '2021-12-15 22:06:41', 1),
(2, 'Wisata', '2021-12-15 22:07:11', 1, '2021-12-15 22:07:13', 1);
-- --------------------------------------------------------
--
-- Table structure for table `user`
--
CREATE TABLE `user` (
`id_user` int NOT NULL,
`fullname` varchar(100) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`token` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `user`
--
INSERT INTO `user` (`id_user`, `fullname`, `username`, `password`, `token`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'ILHAM MAULANA', 'i.maulana', '25d55ad283aa400af464c76d713c07ad', '25d55ad283aa400af464c76d713c07ad', '2021-12-15 00:00:00', 1, '2021-12-15 00:00:00', 1),
(2, 'RAIHAN MAULANA', 'r.maulana', '5e8667a439c68f5145dd2fcbecf02209', '5e8667a439c68f5145dd2fcbecf02209', '2021-12-15 00:00:00', 1, '2021-12-15 00:00:00', 1);
-- --------------------------------------------------------
--
-- Table structure for table `wisata`
--
CREATE TABLE `wisata` (
`id_wisata` int NOT NULL,
`id_kategori` int DEFAULT NULL,
`title` varchar(200) DEFAULT NULL,
`image` varchar(300) DEFAULT NULL,
`summary` text,
`hit_count` int DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`created_by` int DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `wisata`
--
INSERT INTO `wisata` (`id_wisata`, `id_kategori`, `title`, `image`, `summary`, `hit_count`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 1, 'kafe.in.ciapus', 'https://flutter.id/apiwisata/assets/1.png', 'OFFEE SHOP BARU INSTAGRAMABLE REKOMEN! Coffee Shop baru ini namanya @kafe.in.ciapus lokasinya ada di Kota Batu, Ciapus, tepatnya di Jl. Kapten Yusuf No.188C, Kota Batu, Ciapus, Bogor persis di samping SPBU. Konsepnya minimalis outdoor dengan banyak spot instagramable. Lagi ada PROMO Harga Spesial untuk menu signaturenya Kopi BTS CUMA 18rb dari harga 22rb. @kafe.in.ciapus ini konsep nya sangat unik dan instagramable banget! Area nya 70% oudoor dan punya banyak spot-spot foto terbaik untuk OOTD. Trus ada LIVE MUSIC lho setiap hari sabtu yang bisa kamu nikmati', 41, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(2, 2, 'Curug Cikuluwung', 'https://flutter.id/apiwisata/assets/2.png', 'Curug Cikuluwung memiliki air berwarna biru yang indah. Bahkan, ada yang menyebut bahwa tempat ini mirip Grand Canyon versi Indonesia dengan air mengalir. Disebut grand canyon karena adanya tebing batu yang ada di kiri sepanjang aliran sungai. Untuk biaya masuk kesini cukup dengan 35rb per orang ya visitors', 43, '2021-12-15 21:57:26', 1, '2021-12-15 21:57:29', 1),
(3, 2, 'Kayumas Vila', 'https://flutter.id/apiwisata/assets/3.png', 'Kayuman Vilas merupakan salah satu objek wisata berupa tempat penginapan di Bogor yang lagi banyak diminati nih visitors. Di sini kamu akan mendapatkan pengalaman menginap dengan suasana vibes ala Bali, selain itu di sini pesona alamnya sangat indah. Untuk menginap harga yang di tawarkan mulai dari 700rb untuk weekdays dan 800rb untuk weekend\r\n—\r\nKayumanvilas\r\nCimande, Kec. Caringin, Kabupaten Bogor, Jawa Barat 16730', 26, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(4, 2, 'Curug Walet', 'https://flutter.id/apiwisata/assets/4.png', 'Dinamakan curug walet karena daerah curug ini terdapat banyak burung walet, ada di dinding tebing bebatuan maupun pepohonan. Selain itu curug ini juga memiliki 3 tingkatan sehingga tempat ini memiliki keindahan curug yang berbeda\r\n—\r\nCurug Walet\r\nGn. Sari, Kec. Pamijahan, Bogor, Jawa Barat 16810', 20, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(5, 2, 'Danau Quarry Rumpin', 'https://flutter.id/apiwisata/assets/5.png', 'Danau Quarry Rumpin merupakan bekas pertambangan pasir. Danau indah ini mengandung bahan material batu dan pasir, sehingga dulunya tempat ini adalah bekas lahan pertambangan pasir. Namun saat ini lokasi tersebut sering dikunjungi para traveller karna keindahannya.\r\n—\r\nDanau Quarry Rumpin\r\nKp. Nuggaherang, Tegalega, Kec. Cigudeg, Bogor, Jawa Barat 16660', 34, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(6, 2, 'Telaga Saat', 'https://flutter.id/apiwisata/assets/6.png', 'Telaga saat ini berada di Desa Tugu Utara, Kecamatan Cisarua, Kabupaten Bogor. Jaraknya sekitar 36 km dari kota Bogor. Lokasinya cukup mudah dijangkau. Jika kamu membawa kendaraan, kamu cukup arahkan kendaraan ke kawasan puncak hingga sampai di Masjid Nurul Iman yang lokasinya berada sebelum masjid At Taawun. Nah, untuk bisa menikmati indahnya Telaga Saat, kamu akan dikenakan tiket masuk sebesar 25rb per orang.\r\n—\r\nTelaga Saat\r\nCibulao, RT.02/RW.06, Tugu Utara, Kec. Cisarua, Bogor, Jawa Barat 16750', 59, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(7, 2, 'Wisata Javana Sehat', 'https://flutter.id/apiwisata/assets/7.png', 'Wisata Javana Sehat adalah tempat camping di daerah puncak yang menyugukan pemandangan Gn.Gede Pangrango, Gn.Salak, hamparan kebun teh, perbukitan dan pemandangan Telaga saat. Jika ingin camping disini kamu hanya membayar 50rb aja loh visitors. Tidak hanya camping, disini kamu juga bisa melakukan outbound offroad\r\n—\r\nWisata Javana Sehat\r\nTugu Utara, Kec. Cisarua, Bogor, Jawa Barat 16750', 19, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(8, 2, 'The Highland Park Resort', 'https://flutter.id/apiwisata/assets/8.png', 'Glamping dengan konsep Mongolia dan Indian bisa kamu rasakan ketika kamu ke The Highland Park Resort nih visitors. Menginap disini kamu akan disuguhkan pemandangan Gunung Salah yang sangat indah. Lokasinya pun tidak jauh dari tol jagorawi, kurang lebih 30 menit untuk sampai ke tempat ini. Sudah pernah coba menginap disini visitors?\r\n—\r\nThe Highland Park Resort\r\nJl. Curug Nangka Sinarwangi, Sukajadi, Kec. Tamansari, Bogor, Jawa Barat 16610', 23, '2021-12-17 07:29:29', 1, '2021-12-17 07:29:29', 1),
(9, 1, 'Waroeng Uncal', 'https://flutter.id/apiwisata/assets/9.png', 'REKOMENDASI BASO ACI & SEBLAK PALING RAME DI BOGOR! Ada Waroeng Uncal yang memang udah jadi langganan kita banget nih visitors. Nah, ternyata @waroenguncal ada menu baru loh, yaitu seblak baso aci dan pentol ceker, kamu juga bisa pilih tingkat kepedasannya dari 1-5 dan level 1 sama dengan satu centong sayur sambal loh, kebayang kan pedasnya? Harganya juga terjangkau mulai dari 15rb aja.\r\n.\r\nKalo di @waroenguncal udah gausah di tanya lagi deh ada topping apa aja disini, karna mereka punya 20 macam pilihan topping yang enak-enak loh visitors. Untuk Seblak baso aci isiannya ada tulang balungan yang enak buat di grogoti bersama kuah seblak yang super pedas. Rasa rempah dan aroma daun jeruknya berasa banget. Jangan lupa juga ya untuk pesan baso acinya, yang best seller ada baso aci paket manjiw, kuah dan sambalnya juara banget belum ada lawan deh visitors! Oia, untuk minumannya yang best seller ada es seneng dan aneka sop durian yang menggunakan daging durian medan asli atau kamu mau cobain minuman barunya juga ada, kamu bisa cobain es alpukat milo. Yuk, datang langsung ke Waroeng Uncal atau kamu bisa pesan juga di Grabfood ya!', 3, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(10, 1, 'Lumpia basah SMANTI', 'https://flutter.id/apiwisata/assets/10.png', 'LUMPIA BASAH LEGEND DEPAN SMAN 3 BOGOR!! Lumpia ini sudah GENERASI KEDUA CITA RASA KHAS NYA TETAP SAMA, LUDES 500 PORSI PER HARI! Visitors masih ingat dengan lumpia basah SMANTI? Lumpia basah ini termasuk lumpia basah legend di Bogor, dulu yang berjualan adalah seorang bapak-bapak namun telah meninggal dunia dan dilanjutkan oleh keluarga nya, jadi bisa dibilang lumpia basah SMANTI yang sekarang ini adalah generasi kedua. Jangan khawatir, meskipun generasi kedua, cita rasa yang khas nya masih tetap terjaga.\r\n\r\nLumpia Basah SMANTI terkenal lezat dengan cita rasa khas dan gurih yang kuat. Di sini hanya ada satu menu lumpia basah seharga 10rb, ORIGINAL tidak ada topping lain, yang membedakan hanya tingkat kepedasan yang bisa kamu sesuaikan dengan selera masing-masing. Satu porsi lumpia basah terdiri dari bengkuang, tauge, dan telur orak arik yang dibungkus dengan kulit lumpia plus olesan saus yang terbuat dari tepung kanji dan gula merah. Lumpia basah SMANTI ini dari dulu hingga sekarang berlokasi di seberang SMAN 3 Bogor dan masih dijajakan dengan gerobak sederhana namun tidak pernah sepi pembeli. Tenang saja, meskipun sehari bisa habis 300 porsi kamu tidak perlu menunggu lama karena penyajian nya bisa dibilang cepat. Karena dijajakan oleh gerobak, biasanya tidak bisa makan ditempat hanya menyediakan untuk di bawa pulang ya! Daripada penasaran mending langsung aja ke lokasi Lumpia Basah SMANTI.', 8, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(11, 1, 'Bakmi Kane', 'https://flutter.id/apiwisata/assets/11.png', 'BUKA CABANG KE-3 DI BINAMARGA!! Bakmi Kane buka cabang baru nih visitors di Jl. Raya binamarga no.19A Baranangsiang Bogor atau tepatnya di sebelah SMAKBO. Siapa sih yang ga kenal dengan bakmi kekinian satu ini. Bakminya yang enak dan punya banyak varian ini emang udah paling mantep deh. Bakminya sendiri kamu bisa pilih yang asin atau manis. Tersedia juga berbagai macam variasi bakmi dengan level pedas yang kamu inginkan\r\n.\r\nCabang Bakmi Kane di Binamarga ini adalah cabang ketiganya visitors. Nah, di cabang baru ini pastinya tempatnya cozy, bersih dan nyaman banget. Udah gitu instagramable dan seru buat berfoto. Banyak spot bagus dan bikin betah nongkrong lama2. Selain varian bakminya, @bakmikane juga banyak menu lainnya dan aneka menu dessert yang unik. Semua menu di Bakmi kane halal ya. Yuk, langsung aja ke Bakmi Kane, bakmi kekinian paling enak di Bogor\r\n__\r\nBakmi kane @bakmikane\r\nJl. Raya Binamarga No.19A Baranangsiang Kec. Bogor Timur Kota Bogor (sebelah SMAKBO)\r\njam buka: setiap hari, 11.00-21.00\r\nRange Harga:\r\nFood: 10.000-38.500\r\nDessert: 22.000-28.000\r\nDrink: 5.000-27.000\r\nIn Frame:\r\n- Bakmi Kane Spesial 28rb\r\n- Bakmi Sambal Matah Spesial 28rb (tingkat kepedasan 0-6)\r\n- Nasi Bakso Mercon 29rb\r\n- Pangsit Goreng 15rb\r\n- Es Lychee Silky 27rb\r\n- Es Kopi Kane 18rb\r\n- Es Susu Matcha 20rb\r\n', 7, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(12, 1, 'baso mie agan', 'https://flutter.id/apiwisata/assets/12.png', 'Siapa nih yang udah kangen banget sama baso aci, baso mie dan mie yamin nya @basomieagan ? Langsung aja kunjungi store nya baso mie agan bangbarung dan taman cimanggu karena ada promo beli 3 gratis 1, Visitors! GRATIS 1 MIE YAMIN setiap pembelian 3 menu makanan apapun lho, promo ini berlaku hari Kamis 9 Des 2021 - Minggu 12 Des 2021 khusus dine-in dan takeaway ya. Untuk PROMO pembelian onlinenya, @basomieagan punya promo diskon upto 20% di GOFOOD dan GRABFOOD\r\n.\r\nMenu yang wajib kamu coba di @basomieagan ada baso urat kuah taichan dengan isian baso urat, baso aci, baso kecil, aneka cuanki, ceker, mie/bihun, sayur dengan kuah taichan yang pedesnya rekomen banget. Wajib juga cobain mie yamin pedasnya yg bisa pilih level kepedasan nya dari level petir hingga granat. Kalau ke @basomieagan wajib pesen mie yamin pentol pedas yaitu mie yamin plus pangsit basah dan 5 buah pentol pedas nya dijamin bikin kamu ketagihan. Yuk langsung aja cobain @basomieagan di kedua lokasinya atau pesan online melalui GoFood dan GrabFood!\r\n__\r\nBaso & Mie Agan @basomieagan\r\nPusat: Jl. Taman Cimanggu Raya No.25 Kedung Waringin, Tanah Sereal, Bogor\r\nCabang: Jalan bangbarung raya no.45, tegal gundil, bogor (samping alfamart bangbarung)\r\nJam Buka:\r\nSenin - Kamis 10:00 - 20:00 WIB\r\nJumat - Minggu 10:00 - 21:00 WIB\r\nRange Harga:\r\nMakanan: 15rb - 28rb\r\nMinuman: 3rb - 10rb\r\nIn Frame:\r\nBaso Aci Agan Special Daging + Urat 28k\r\nBaso Aci Agan Special Mercon 28k\r\nBaso Aci Agan 20k\r\nBaso Daging Mercon Kuah Taichan 28k\r\nMie Yamin Pentol 25k\r\nMie Yamin Petir 20k\r\nEs Jeruk 10k\r\nEs Teh Manis 6k', 18, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(13, 1, 'Kedai Kopi Abdi', 'https://flutter.id/apiwisata/assets/13.png', 'Kedai Kopi Abdi ini memiliki tempat nongkrong dengan view yang keren nih visitors, apalagi view malam disini kamu bisa melihat city light yang indah.\r\n—\r\nKedai Kopi Abdi\r\nCijeruk, Kec. Cijeruk, Bogor, Jawa Barat 16740', 9, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(14, 1, 'Cafe sudutemu', 'https://flutter.id/apiwisata/assets/14.png', 'CAFE UNTUK NONGKRONG REKOMEN! COZY, INTERNET KENCENG DAN MENU BERLIMPAH KEJU MOZZARELLA DI @sudutemu !!! Kalau kamu tanya cafe rekomen untuk nongkrong dengan suasana outdoor kece, internetnya kenceng, menu2nya enak dan harganya ramah di kantong jawabannya adalah @sudutemu rekomendasi dari visitbogor. Menu yang ada di sini mulai dari indomie juga ada lho, Visitors! Cocok banget buat kamu yang mau NONGKRONG LOW BUDGET. Menu signature dan paling favorit yg harus kamu coba di @sudutemu ada ALL STAR BBQ MOZZA platters berisi sosis, jagung, potato wedges, dan chicken strip lengkap dengan saus BBQ lezat yang bisa kamu pilih level kepedasan nya, menu ini cocok banget buat dinikmatin bareng-bareng Visitors!\r\n.\r\nLalu ada Cheezy Mix berisi sayap ayam, bratwurst, kentang dan saus serta mozzarela melted yg gurih banget! Di sudut temu menu makanan, minuman dan dessert nya rekomen banget untuk dicoba. Semakin seru lagi karena selain menu nya enak-enak, suasana nya cozy, lokasi nya strategis, WIFI nya kenceng dan banyak board games yang bisa dimainin bareng temen-temen bikin nongkrong semakin seru! Langsung aja ajak teman, pacar dan keluarga kamu untuk nongkrong seru di Sudut Temu yuk!\r\n__\r\nSudut Temu by Toastea @sudutemu\r\nJl. Cirahayu No.14 Baranangsiang Bogor (arah pintu parkiran motor botani square)\r\nJam Buka:\r\nSenin - Kamis 12:00 - 21:00 WIB\r\nJumat 13:00 - 22:00 WIB\r\nSabtu - Minggu 12:00 - 22:00 WIB\r\nContact: 081316669110\r\nPrice Range:\r\nFoods: 16K-37k\r\nDrinks: 5K-26k\r\nDessert: 20k - 28k\r\n*exclude tax\r\nIn frame:\r\nEbi curry rice\r\nKatsu curry rice\r\nCheezy winger\r\nBeef patty sizzling\r\nAll star + mozzarella\r\nMatcha latte\r\nChoco blast\r\nMatcha set pudding', 12, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1);
--
-- Indexes for dumped tables
--
--
-- Indexes for table `kategori`
--
ALTER TABLE `kategori`
ADD PRIMARY KEY (`id_kategori`);
--
-- Indexes for table `user`
--
ALTER TABLE `user`
ADD PRIMARY KEY (`id_user`);
--
-- Indexes for table `wisata`
--
ALTER TABLE `wisata`
ADD PRIMARY KEY (`id_wisata`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `kategori`
--
ALTER TABLE `kategori`
MODIFY `id_kategori` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
--
-- AUTO_INCREMENT for table `user`
--
ALTER TABLE `user`
MODIFY `id_user` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
--
-- AUTO_INCREMENT for table `wisata`
--
ALTER TABLE `wisata`
MODIFY `id_wisata` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=15;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
db.php
<?php
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','dbwisata');
$conn = mysqli_connect(HOST, USER, PASS, DB)or die('Unable to connect');
CREATE TABLE IF NOT EXISTS `kategori` (
`id_kategori` int(11) NOT NULL AUTO_INCREMENT,
`kategori_name` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id_kategori`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `kategori` (`id_kategori`, `kategori_name`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'Kuliner', '2021-12-15 22:06:39', 1, '2021-12-15 22:06:41', 1),
(2, 'Wisata', '2021-12-15 22:07:11', 1, '2021-12-15 22:07:13', 1);
CREATE TABLE IF NOT EXISTS `user` (
`id_user` int(11) NOT NULL AUTO_INCREMENT,
`fullname` varchar(100) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`token` varchar(200) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id_user`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `user` (`id_user`, `fullname`, `username`, `password`, `token`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'ILHAM MAULANA', 'i.maulana', '25d55ad283aa400af464c76d713c07ad', '25d55ad283aa400af464c76d713c07ad', '2021-12-15 00:00:00', 1, '2021-12-15 00:00:00', 1),
(2, 'RAIHAN MAULANA', 'r.maulana', '5e8667a439c68f5145dd2fcbecf02209', '5e8667a439c68f5145dd2fcbecf02209', '2021-12-15 00:00:00', 1, '2021-12-15 00:00:00', 1);
CREATE TABLE IF NOT EXISTS `wisata` (
`id_wisata` int(11) NOT NULL AUTO_INCREMENT,
`id_kategori` int(11) DEFAULT NULL,
`title` varchar(200) DEFAULT NULL,
`image` varchar(300) DEFAULT NULL,
`summary` text,
`hit_count` int(11) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id_wisata`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `wisata` (`id_wisata`, `id_kategori`, `title`, `image`, `summary`, `hit_count`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 1, 'Coffee Shop - kafe.in.ciapus', 'https://flutter.id/apiwisata/assets/1.png', 'OFFEE SHOP BARU INSTAGRAMABLE REKOMEN! Coffee Shop baru ini namanya @kafe.in.ciapus lokasinya ada di Kota Batu, Ciapus, tepatnya di Jl. Kapten Yusuf No.188C, Kota Batu, Ciapus, Bogor persis di samping SPBU. Konsepnya minimalis outdoor dengan banyak spot instagramable. Lagi ada PROMO Harga Spesial untuk menu signaturenya Kopi BTS CUMA 18rb dari harga 22rb. @kafe.in.ciapus ini konsep nya sangat unik dan instagramable banget! Area nya 70% oudoor dan punya banyak spot-spot foto terbaik untuk OOTD. Trus ada LIVE MUSIC lho setiap hari sabtu yang bisa kamu nikmati', 0, '2021-12-15 21:50:13', 1, '2021-12-15 21:50:15', 1),
(2, 2, 'Curug Cikuluwung', 'https://flutter.id/apiwisata/assets/2.png', 'Curug Cikuluwung memiliki air berwarna biru yang indah. Bahkan, ada yang menyebut bahwa tempat ini mirip Grand Canyon versi Indonesia dengan air mengalir. Disebut grand canyon karena adanya tebing batu yang ada di kiri sepanjang aliran sungai. Untuk biaya masuk kesini cukup dengan 35rb per orang ya visitors', 0, '2021-12-15 21:57:26', 1, '2021-12-15 21:57:29', 1);
Response Handler
<?php
require_once('db.php');
//response json ketika success
function resSuccess($status, $message,$count, $data){
$response = [
"status" => $status,
"message" => $message,
"hit_date" => date('Y-m-d H:i:s'),
"user_ip" => $_SERVER['REMOTE_ADDR'],
"count" => $count,
"data" => $data
];
header("Content-type: application/json");
echo json_encode($response);
}
//response json ketika error
function resError($status, $message){
$response = [
"status" => $status,
"message" => $message,
"hit_date" => date('Y-m-d H:i:s'),
"user_ip" => $_SERVER['REMOTE_ADDR'],
"count" => null,
"data" => null
];
header("Content-type: application/json");
echo json_encode($response);
}
Validasi Token
//mengecek token pada db
function validToken($conn,$token){
$q = "SELECT u.token
FROM user u
WHERE u.token='$token'
LIMIT 1";
$mq = mysqli_query($conn, $q);
$r = array();
$row = $mq->fetch_assoc();
if($row){
return true;
}else{
return false;
}
}
get data from database
//manampilkan Top 10 Wisata
function getTop($conn){
$q = "SELECT
w.id_wisata, k.kategori_name, w.title, w.image,w.summary,
u.fullname AS user_create, w.created_at, w.hit_count
FROM wisata w
LEFT JOIN kategori k ON w.id_kategori = k.id_kategori
LEFT JOIN user u ON w.created_by = u.id_user
ORDER BY w.created_at DESC
LIMIT 50";
$mq = mysqli_query($conn, $q);
$r = array();
while($row = mysqli_fetch_array($mq)){
array_push($r,array(
'id_wisata' => $row['id_wisata'],
'kategori_name' => $row['kategori_name'],
'title' => $row['title'],
'image' => $row['image'],
'summary' => $row['summary'],
'user_create' => $row['user_create'],
'created_at' => $row['created_at'],
'hit_count' => $row['hit_count']
));
}
return $r;
}
//manampilkan Popular Wisata
function getPopular($conn){
$q = "SELECT
w.id_wisata, k.kategori_name, w.title, w.image,w.summary,
u.fullname AS user_create, w.created_at, w.hit_count
FROM wisata w
LEFT JOIN kategori k ON w.id_kategori = k.id_kategori
LEFT JOIN user u ON w.created_by = u.id_user
ORDER BY w.hit_count DESC
LIMIT 50";
$mq = mysqli_query($conn, $q);
$r = array();
while($row = mysqli_fetch_array($mq)){
array_push($r,array(
'id_wisata' => $row['id_wisata'],
'kategori_name' => $row['kategori_name'],
'title' => $row['title'],
'image' => $row['image'],
'summary' => $row['summary'],
'user_create' => $row['user_create'],
'created_at' => $row['created_at'],
'hit_count' => $row['hit_count']
));
}
return $r;
}
//manampilkan Kategori Wisata
function getKategori($conn,$id_kategori){
$q = "SELECT
w.id_wisata, k.kategori_name, w.title, w.image,w.summary,
u.fullname AS user_create, w.created_at, w.hit_count
FROM wisata w
LEFT JOIN kategori k ON w.id_kategori = k.id_kategori
LEFT JOIN user u ON w.created_by = u.id_user
WHERE w.id_kategori='$id_kategori'
ORDER BY w.created_at DESC
LIMIT 50";
$mq = mysqli_query($conn, $q);
$r = array();
while($row = mysqli_fetch_array($mq)){
array_push($r,array(
'id_wisata' => $row['id_wisata'],
'kategori_name' => $row['kategori_name'],
'title' => $row['title'],
'image' => $row['image'],
'summary' => $row['summary'],
'user_create' => $row['user_create'],
'created_at' => $row['created_at'],
'hit_count' => $row['hit_count']
));
}
return $r;
}
//menambah hit count
function hitCount($conn,$id){
$q = "UPDATE wisata w
SET w.hit_count = w.hit_count+1
WHERE w.id_wisata='$id'
";
$mq = mysqli_query($conn, $q);
return $mq;
}
//manampilkan Master Kategori
function getMasterKategori($conn){
$q = "SELECT
k.id_kategori,k.kategori_name
FROM kategori k
ORDER BY k.kategori_name ASC
";
$mq = mysqli_query($conn, $q);
$r = array();
while($row = mysqli_fetch_array($mq)){
array_push($r,array(
'id_kategori' => $row['id_kategori'],
'kategori_name' => $row['kategori_name']
));
}
return $r;
}
Modul
//validasi & hasil rest api
isset($_GET['token']) ? $token = $_GET['token'] : $token="";
isset($_GET['modul']) ? $modul = $_GET['modul'] : $modul="";
isset($_GET['id']) ? $id = $_GET['id'] : $id="";
if(validToken($conn,$token)){
switch ($modul) {
case "top":
resSuccess(
"success",
"Success Get Top 10",
count(getTop($conn)),
getTop($conn)
);
break;
case "popular":
resSuccess(
"success",
"Success Get Popular",
count(getPopular($conn)),
getPopular($conn)
);
break;
case "kategori":
resSuccess(
"success",
"Success Get Kategori",
count(getKategori($conn,$id)),
getKategori($conn,$id)
);
break;
case "hitcount":
resSuccess(
"success",
"Success update hitcount",
1,
hitCount($conn,$id)
);
break;
case "masterkategori":
resSuccess(
"success",
"Success Get Master Kategori",
count(getMasterKategori($conn)),
getMasterKategori($conn)
);
break;
default:
resSuccess(
"success",
"Success Get Top 10",
count(getTop($conn)),
getTop($conn)
);
}
}else{
resError("error","Invalid Token");
}
WORKSHOP ANDROID IKAUBSI
# Materi Online
https://flutter.id/ikaubsi/
# Materi Offline (html)
https://flutter.id/apiwisata/assets/slide.zip
# Source Code Rest Api
https://flutter.id/apiwisata/assets/restapi.zip
# Source Code Flutter
https://flutter.id/apiwisata/assets/flutter.zip
# APK Workshop
https://flutter.id/apiwisata/assets/visitbogor_apk.zip
WorkshopAndroidIkaubsi
By Maulana Ilham
WorkshopAndroidIkaubsi
Improving User to Creator
- 898