From 9bff9c7fc27793b1ec9f0b823c31708548c87889 Mon Sep 17 00:00:00 2001 From: ='fauz <='fauzgabriel@gmail.com> Date: Mon, 7 Jul 2025 17:31:26 +0700 Subject: [PATCH] game html dan DIO --- .gitignore | 1 + assets/html/furikake/index.html | 10 ++--- assets/html/index.html | 12 +++--- assets/html/memory/memory.html | 5 +-- lib/main.dart | 2 +- lib/models/users.dart | 31 +++++++++++++++ lib/screen/pustaka/list_detail_screen.dart | 4 +- lib/screen/pustaka/list_education.dart | 44 ++++++++++++++++++++++ lib/screen/pustaka_screen.dart | 18 +++++---- lib/util/api_client.dart | 36 ++++++++++++++++++ pubspec.lock | 16 ++++++++ pubspec.yaml | 1 + 12 files changed, 157 insertions(+), 23 deletions(-) create mode 100644 lib/models/users.dart create mode 100644 lib/util/api_client.dart diff --git a/.gitignore b/.gitignore index 79c113f..7b27cd5 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +pubspec.lock diff --git a/assets/html/furikake/index.html b/assets/html/furikake/index.html index 6654826..3b03420 100644 --- a/assets/html/furikake/index.html +++ b/assets/html/furikake/index.html @@ -224,19 +224,19 @@ figcaption {
- Nori + Nori

Nori (Rumput Laut)

- Biji Wijen + Biji Wijen

Biji Wijen

- Katsuobushi + Katsuobushi

Katsuobushi (Ikan Kering)

- Garam dan Gula + Garam dan Gula

Garam & Gula

@@ -259,7 +259,7 @@ figcaption {
- Contoh produk furikake + Contoh produk furikake
Berbagai varian produk furikake yang tersedia di pasaran
diff --git a/assets/html/index.html b/assets/html/index.html index 16b8143..a3f0ed8 100644 --- a/assets/html/index.html +++ b/assets/html/index.html @@ -177,23 +177,23 @@
- Karbohidrat + Karbohidrat

Karbohidrat
Sumber energi seperti nasi, roti, dan kentang.

- Protein + Protein

Protein
Untuk membangun otot, misalnya ikan, telur, dan tahu.

- Lemak + Lemak

Lemak
Memberikan tenaga, seperti dari kacang-kacangan dan minyak sehat.

- Vitamin dan Mineral + Vitamin dan Mineral

Vitamin dan mineral
Dari sayur dan buah yang membantu tubuh bekerja dengan baik.

- Serat dan Air + Serat dan Air

Serat dan air
Membantu pencernaan dan menjaga tubuh tetap segar!

@@ -209,7 +209,7 @@
  • 🍽️ Seperempat piring: Protein (seperti ayam atau tempe)
  • 🍽️ Sedikit lemak sehat
  • - Piring Gizi Seimbang + Piring Gizi Seimbang
    Isi Piringku

    Selain itu, kita tidak boleh makan terlalu banyak atau terlalu sedikit, karena bisa membuat tubuh tidak sehat. Makan berlebihan bisa menyebabkan obesitas, sedangkan makan terlalu sedikit bisa membuat tubuh lemas dan kurang gizi.

    diff --git a/assets/html/memory/memory.html b/assets/html/memory/memory.html index 6c12d93..49d037b 100644 --- a/assets/html/memory/memory.html +++ b/assets/html/memory/memory.html @@ -82,7 +82,7 @@ shuffled.forEach((img, i) => { const card = document.createElement('div'); card.className = 'card hidden'; - card.style.backgroundImage = 'url("freekake.png")'; + card.style.backgroundImage = 'url("../freekake.png")'; card.style.backgroundSize = 'contain'; card.style.backgroundRepeat = 'no-repeat'; card.style.backgroundPosition = 'center'; @@ -111,7 +111,7 @@ function hideCard(i) { const el = board.children[i]; el.classList.add('hidden'); - el.style.backgroundImage = 'url("freekake.png")'; + el.style.backgroundImage = 'url("../freekake.png")'; el.style.backgroundSize = 'contain'; el.style.backgroundRepeat = 'no-repeat'; el.style.backgroundPosition = 'center'; @@ -156,7 +156,6 @@ if (selected.length === 2) checkMatch(); }); - // 🔍 Expose render and notify Flutter window.render = render; if (window.flutter_inappwebview) { diff --git a/lib/main.dart b/lib/main.dart index 83003bf..9c141c4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,7 +13,7 @@ void main() async { await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, // bisa dihapus jika hanya ingin satu arah + DeviceOrientation.portraitDown, ]); runApp(const MyApp()); diff --git a/lib/models/users.dart b/lib/models/users.dart new file mode 100644 index 0000000..2a7dda6 --- /dev/null +++ b/lib/models/users.dart @@ -0,0 +1,31 @@ +class Users { + int id; + // String nama; + // String tgl; + // String? alamat; + + Users({ + required this.id, + // required this.nama, this.alamat, required this.tgl + }); + + Map toMap() { + return { + "id": id, + // "nama": nama, "alamat": this.alamat, "tgl": this.tgl + }; + } + + factory Users.fromJson(Map map) { + return Users( + id: map['id'], + // nama: map['nama'], + // alamat: map['alamat'], + // tgl: map['tanggal'], + ); + } + + String toString() { + return 'Users{id:$id,}'; + } +} diff --git a/lib/screen/pustaka/list_detail_screen.dart b/lib/screen/pustaka/list_detail_screen.dart index 7451f1e..4d2f6d9 100644 --- a/lib/screen/pustaka/list_detail_screen.dart +++ b/lib/screen/pustaka/list_detail_screen.dart @@ -52,11 +52,13 @@ class _ListDetailScreenState extends State { await controller.loadData( data: html, baseUrl: WebUri( - "http://localhost/$base", + "file:///android_asset/flutter_assets/$base", ), // agar path relatif seperti img1/* jalan mimeType: 'text/html', encoding: 'utf-8', ); + debugPrint("http://localhost/$base"); + debugPrint("file:///android_asset/flutter_assets/$base"); }, onLoadStop: (controller, url) async { debugPrint("🚀 onLoadStop called. URL: $url"); diff --git a/lib/screen/pustaka/list_education.dart b/lib/screen/pustaka/list_education.dart index 1e6e6bc..8c492d1 100644 --- a/lib/screen/pustaka/list_education.dart +++ b/lib/screen/pustaka/list_education.dart @@ -6,10 +6,13 @@ import 'package:flutter/services.dart'; import 'package:freekake/components/card_list.dart'; import 'package:freekake/components/collection_container%20copy.dart'; import 'package:freekake/helpers/color_helper.dart'; +import 'package:freekake/models/users.dart'; import 'package:freekake/screen/pustaka/list_detail_screen.dart'; +import 'package:freekake/util/api_client.dart'; import 'package:list_detail_extension/list_detail_extension.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:dio/dio.dart'; class ListEducation extends StatefulWidget { final String? selectedCategory; @@ -27,6 +30,12 @@ class _ListEducationState extends State { String? selectedCategory; final listDetailExtension = ListDetailExtension(); + // Data fetch + final ApiClient _apiClient = ApiClient(); + List _posts = []; + bool _isLoading = true; + String _error = ''; + Future _initExtension() async { await listDetailExtension.load(); } @@ -165,6 +174,41 @@ class _ListEducationState extends State { }); } + Future _fetchPosts() async { + try { + setState(() { + _isLoading = true; + _error = ''; + }); + + // Melakukan permintaan GET ke endpoint + final Response response = await _apiClient.dio.get('auth/users'); + + if (response.statusCode == 200) { + // Konversi data JSON ke List + List postJson = response.data; + _posts = postJson.map((json) => Users.fromJson(json)).toList(); + } else { + _error = 'Gagal memuat data: ${response.statusCode}'; + } + } on DioException catch (e) { + if (e.response != null) { + _error = + 'Server Error: ${e.response?.statusCode} - ${e.response?.statusMessage}'; + } else { + _error = 'Network Error: ${e.message}'; + } + print('DioError: $e'); + } catch (e) { + _error = 'Terjadi kesalahan tidak terduga: $e'; + print('General Error: $e'); + } finally { + setState(() { + _isLoading = false; + }); + } + } + @override Widget build(BuildContext context) { final List> collections = [ diff --git a/lib/screen/pustaka_screen.dart b/lib/screen/pustaka_screen.dart index 507f9be..955bc77 100644 --- a/lib/screen/pustaka_screen.dart +++ b/lib/screen/pustaka_screen.dart @@ -328,13 +328,17 @@ class _PustakaScreenState extends State { Positioned(bottom: 0, left: 0, right: 0, child: MainMenu()), ], ), - Positioned( - bottom: bottomPadding * 98, - left: (screenWidth - buttonScanSize) / 2, - child: Transform.translate( - offset: Offset(0, -20), - child: ScanButton(), - ), + Stack( + children: [ + Positioned( + bottom: bottomPadding * 98, + left: (screenWidth - buttonScanSize) / 2, + child: Transform.translate( + offset: Offset(0, -20), + child: ScanButton(), + ), + ), + ], ), ], ); diff --git a/lib/util/api_client.dart b/lib/util/api_client.dart new file mode 100644 index 0000000..7929d5d --- /dev/null +++ b/lib/util/api_client.dart @@ -0,0 +1,36 @@ +import 'package:dio/dio.dart'; + +class ApiClient { + final Dio _dio = Dio(); + final String _baseUrl = 'https://api.freekake.com/'; + + ApiClient() { + _dio.options.baseUrl = _baseUrl; + _dio.options.connectTimeout = const Duration(seconds: 5); + _dio.options.receiveTimeout = const Duration(seconds: 3); + + _dio.interceptors.add( + InterceptorsWrapper( + onRequest: (options, handler) { + print('REQUEST[${options.method}] => PATH: ${options.path}'); + // options.headers['Authorization'] = 'Bearer your_token_here'; + return handler.next(options); + }, + onResponse: (response, handler) { + print( + 'RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}', + ); + return handler.next(response); + }, + onError: (DioException e, handler) { + print( + 'ERROR[${e.response?.statusCode}] => PATH: ${e.requestOptions.path}', + ); + return handler.next(e); + }, + ), + ); + } + + Dio get dio => _dio; +} diff --git a/pubspec.lock b/pubspec.lock index 32499ef..4f11e9c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -129,6 +129,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.3" + dio: + dependency: "direct main" + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://pub.dev" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" dropdown_button2: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 615ac79..fde2f11 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: ref: main desktop_webview_window: ^0.2.3 flutter_inappwebview: ^6.0.0 + dio: ^5.0.0 # arcore_flutter_plugin: ^0.2.0-alpha # flutter_unity_widget: ^2022.2.1 # arcore_flutter_plugin: