From 62bc1cb0e22420ffa4fedc6aab44b6dc31ee2fc8 Mon Sep 17 00:00:00 2001 From: Samsularifin01 <158025491+Samsularifin01@users.noreply.github.com> Date: Wed, 6 May 2026 23:45:59 +0700 Subject: [PATCH] connect the register api to the register_screen.dart file --- lib/models/register_request.dart | 25 ++++ lib/models/register_response.dart | 21 +++ lib/screens/signup_screen.dart | 35 ++++- lib/services/register_api_service.dart | 55 ++++++++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 128 ++++++++++++++++++ pubspec.yaml | 2 + 7 files changed, 263 insertions(+), 5 deletions(-) create mode 100644 lib/models/register_request.dart create mode 100644 lib/models/register_response.dart create mode 100644 lib/services/register_api_service.dart diff --git a/lib/models/register_request.dart b/lib/models/register_request.dart new file mode 100644 index 0000000..76d066c --- /dev/null +++ b/lib/models/register_request.dart @@ -0,0 +1,25 @@ +class RegisterRequest { + final String name; + final String email; + final String phone; + final String gender; + final String password; + + const RegisterRequest({ + required this.name, + required this.email, + required this.phone, + required this.gender, + required this.password, + }); + + Map toJson() { + return { + "name": name, + "email": email, + "phone": phone, + "gender": gender, + "password": password, + }; + } +} diff --git a/lib/models/register_response.dart b/lib/models/register_response.dart new file mode 100644 index 0000000..471ba84 --- /dev/null +++ b/lib/models/register_response.dart @@ -0,0 +1,21 @@ +class RegisterResponse { + final String status; + final String message; + final String? token; + + const RegisterResponse({ + required this.status, + required this.message, + this.token, + }); + + factory RegisterResponse.fromJson(Map json) { + return RegisterResponse( + status: json["status"]?.toString() ?? "error", + message: json["message"]?.toString() ?? "", + token: json["token"]?.toString(), + ); + } + + bool get isSuccess => status.toLowerCase() == "success"; +} diff --git a/lib/screens/signup_screen.dart b/lib/screens/signup_screen.dart index 7b1ffb3..7042ff2 100644 --- a/lib/screens/signup_screen.dart +++ b/lib/screens/signup_screen.dart @@ -3,6 +3,8 @@ import 'package:flutter/services.dart'; import '../widgets/custom_textfield.dart'; import '../widgets/custom_button.dart'; import '../services/tts_service.dart'; +import '../services/register_api_service.dart'; +import '../models/register_request.dart'; import '../utils/colors.dart'; class SignUpScreen extends StatefulWidget { @@ -19,6 +21,7 @@ class _SignUpScreenState extends State { final TextEditingController nameController = TextEditingController(); final TextEditingController phoneController = TextEditingController(); final TTSService tts = TTSService(); + final RegisterApiService registerApi = RegisterApiService(); String? selectedGender; String passwordStrength = ""; // Track password strength @@ -47,7 +50,7 @@ class _SignUpScreenState extends State { super.dispose(); } - void handleSignUp(BuildContext context) { + Future handleSignUp(BuildContext context) async { String name = nameController.text; String phone = phoneController.text; String email = emailController.text; @@ -99,8 +102,30 @@ class _SignUpScreenState extends State { return; } - tts.speak("Pendaftaran berhasil"); - Navigator.pop(context); + final RegisterRequest request = RegisterRequest( + name: name, + email: email, + phone: phone, + gender: selectedGender!.toLowerCase(), + password: password, + ); + + final response = await registerApi.register(request); + + if (!context.mounted) { + return; + } + + if (response.isSuccess) { + tts.speak(response.message.isNotEmpty + ? response.message + : "Pendaftaran berhasil"); + Navigator.pop(context); + } else { + tts.speak(response.message.isNotEmpty + ? response.message + : "Email sudah digunakan"); + } } // ============ FUNGSI UNTUK MENGHITUNG PASSWORD STRENGTH ============ @@ -293,9 +318,9 @@ class _SignUpScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - buildGenderOption("Laki-laki"), + buildGenderOption("laki-laki"), const Divider(color: Colors.white24, height: 8), - buildGenderOption("Perempuan"), + buildGenderOption("perempuan"), ], ), ), diff --git a/lib/services/register_api_service.dart b/lib/services/register_api_service.dart new file mode 100644 index 0000000..27df856 --- /dev/null +++ b/lib/services/register_api_service.dart @@ -0,0 +1,55 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:http/http.dart' as http; +import 'package:shared_preferences/shared_preferences.dart'; +import '../models/register_request.dart'; +import '../models/register_response.dart'; + +class RegisterApiService { + // Ubah nilai ini jika ingin memakai emulator Android (10.0.2.2). + static const bool _useAndroidEmulator = false; + + // Ganti IP ini dengan IP laptop/PC Anda saat menggunakan HP fisik (ADB). + static const String _deviceHost = "192.168.18.14:8000"; + + static String get _baseUrl { + if (Platform.isAndroid && _useAndroidEmulator) { + return "http://10.0.2.2:8000"; + } + return "http://$_deviceHost"; + } + static const String _tokenKey = "auth_token"; + + Future register(RegisterRequest request) async { + final Uri url = Uri.parse("$_baseUrl/register"); + + try { + final http.Response response = await http.post( + url, + headers: {"Content-Type": "application/json"}, + body: jsonEncode(request.toJson()), + ); + + final Map jsonBody = + jsonDecode(response.body) as Map; + final RegisterResponse registerResponse = + RegisterResponse.fromJson(jsonBody); + + if (registerResponse.isSuccess && registerResponse.token != null) { + await _saveToken(registerResponse.token!); + } + + return registerResponse; + } catch (error) { + return const RegisterResponse( + status: "error", + message: "Gagal terhubung ke server", + ); + } + } + + Future _saveToken(String token) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString(_tokenKey, token); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 1e6ac53..d9031b3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import flutter_tts +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 809b6a9..fa8680c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -184,6 +192,22 @@ packages: description: flutter source: sdk version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" image: dependency: transitive description: @@ -264,6 +288,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" petitparser: dependency: transitive description: @@ -272,6 +320,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -288,6 +344,62 @@ packages: url: "https://pub.dev" source: hosted version: "6.5.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "5bcf0772a761b04f8c6bf814721713de6f3e5d9d89caf8d3fe031b02a342379e" + url: "https://pub.dev" + source: hosted + version: "2.4.11" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -349,6 +461,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.3" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" vector_math: dependency: transitive description: @@ -373,6 +493,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d2b10c8..98107e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,8 +31,10 @@ dependencies: camera: ^0.10.5+5 flutter: sdk: flutter + http: ^1.2.2 flutter_tts: ^3.5.2 flutter_launcher_icons: ^0.14.4 + shared_preferences: ^2.2.3 dev_dependencies: flutter_lints: ^5.0.0