Flutter consume api login

/// Struktur project Flutter: /// lib/ /// ├── main.dart /// ├── screens/ /// │ ├── login_screen.dart /// │ ├── menu_screen.dart /// │ └── reservasi_screen.dart /// ├── services/ /// │ └── api_service.dart /// └── models/ /// ├── meja_model.dart /// └── menu_model.dart // ==== main.dart ==== import 'package:flutter/material.dart'; import 'screens/login_screen.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Reservasi Meja', home: LoginScreen(), ); } } // ==== screens/login_screen.dart ==== import 'package:flutter/material.dart'; import '../services/api_service.dart'; import 'menu_screen.dart'; class LoginScreen extends StatefulWidget { @override _LoginScreenState createState() => _LoginScreenState(); } class _LoginScreenState extends State { final usernameController = TextEditingController(); final passwordController = TextEditingController(); void login() async { final token = await ApiService.login( usernameController.text, passwordController.text, ); if (token != null) { Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => MenuScreen(token: token)), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Login gagal')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Login')), body: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ TextField(controller: usernameController, decoration: InputDecoration(labelText: 'Username')), TextField(controller: passwordController, decoration: InputDecoration(labelText: 'Password'), obscureText: true), SizedBox(height: 20), ElevatedButton(onPressed: login, child: Text('Login')), ], ), ), ); } } // ==== screens/menu_screen.dart ==== import 'package:flutter/material.dart'; import '../services/api_service.dart'; import '../models/menu_model.dart'; import 'reservasi_screen.dart'; class MenuScreen extends StatelessWidget { final String token; const MenuScreen({super.key, required this.token}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Daftar Menu')), body: FutureBuilder( future: ApiService.getMenu(token), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator()); if (!snapshot.hasData || snapshot.data!.isEmpty) return Center(child: Text('Tidak ada menu')); final menuList = snapshot.data!; return ListView( children: [ ...menuList.map((m) => ListTile( title: Text(m.nama), subtitle: Text('Rp ${m.harga}'), )), ElevatedButton( child: Text('Pesan Meja'), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => ReservasiScreen(token: token)), ), ) ], ); }, ), ); } } // ==== screens/reservasi_screen.dart ==== import 'package:flutter/material.dart'; import '../services/api_service.dart'; import '../models/meja_model.dart'; class ReservasiScreen extends StatelessWidget { final String token; const ReservasiScreen({super.key, required this.token}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Reservasi Meja')), body: FutureBuilder( future: ApiService.getMeja(token), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator()); if (!snapshot.hasData) return Center(child: Text('Gagal ambil data')); return ListView( children: snapshot.data! .map((meja) => ListTile( title: Text('Meja ${meja.noMeja} - ${meja.status}'), subtitle: Text('Kapasitas: ${meja.kapasitas} orang'), trailing: ElevatedButton( child: Text('Pesan'), onPressed: () => ApiService.updateMeja(token, meja.id!, 'dipesan'), ), )) .toList(), ); }, ), ); } } // ==== models/menu_model.dart ==== class MenuModel { final int id; final String nama; final int harga; MenuModel({required this.id, required this.nama, required this.harga}); factory MenuModel.fromJson(Map json) { return MenuModel( id: json['id'], nama: jso

Apr 10, 2025 - 13:34
 0
Flutter consume api login
/// Struktur project Flutter:
/// lib/
/// ├── main.dart
/// ├── screens/
/// │   ├── login_screen.dart
/// │   ├── menu_screen.dart
/// │   └── reservasi_screen.dart
/// ├── services/
/// │   └── api_service.dart
/// └── models/
///     ├── meja_model.dart
///     └── menu_model.dart

// ==== main.dart ====
import 'package:flutter/material.dart';
import 'screens/login_screen.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Reservasi Meja',
      home: LoginScreen(),
    );
  }
}

// ==== screens/login_screen.dart ====
import 'package:flutter/material.dart';
import '../services/api_service.dart';
import 'menu_screen.dart';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State {
  final usernameController = TextEditingController();
  final passwordController = TextEditingController();

  void login() async {
    final token = await ApiService.login(
      usernameController.text,
      passwordController.text,
    );
    if (token != null) {
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (_) => MenuScreen(token: token)),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Login gagal')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          children: [
            TextField(controller: usernameController, decoration: InputDecoration(labelText: 'Username')),
            TextField(controller: passwordController, decoration: InputDecoration(labelText: 'Password'), obscureText: true),
            SizedBox(height: 20),
            ElevatedButton(onPressed: login, child: Text('Login')),
          ],
        ),
      ),
    );
  }
}

// ==== screens/menu_screen.dart ====
import 'package:flutter/material.dart';
import '../services/api_service.dart';
import '../models/menu_model.dart';
import 'reservasi_screen.dart';

class MenuScreen extends StatelessWidget {
  final String token;
  const MenuScreen({super.key, required this.token});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Daftar Menu')),
      body: FutureBuilder>(
        future: ApiService.getMenu(token),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator());
          if (!snapshot.hasData || snapshot.data!.isEmpty) return Center(child: Text('Tidak ada menu'));
          final menuList = snapshot.data!;

          return ListView(
            children: [
              ...menuList.map((m) => ListTile(
                    title: Text(m.nama),
                    subtitle: Text('Rp ${m.harga}'),
                  )),
              ElevatedButton(
                child: Text('Pesan Meja'),
                onPressed: () => Navigator.push(
                  context,
                  MaterialPageRoute(builder: (_) => ReservasiScreen(token: token)),
                ),
              )
            ],
          );
        },
      ),
    );
  }
}

// ==== screens/reservasi_screen.dart ====
import 'package:flutter/material.dart';
import '../services/api_service.dart';
import '../models/meja_model.dart';

class ReservasiScreen extends StatelessWidget {
  final String token;
  const ReservasiScreen({super.key, required this.token});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Reservasi Meja')),
      body: FutureBuilder>(
        future: ApiService.getMeja(token),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator());
          if (!snapshot.hasData) return Center(child: Text('Gagal ambil data'));

          return ListView(
            children: snapshot.data!
                .map((meja) => ListTile(
                      title: Text('Meja ${meja.noMeja} - ${meja.status}'),
                      subtitle: Text('Kapasitas: ${meja.kapasitas} orang'),
                      trailing: ElevatedButton(
                        child: Text('Pesan'),
                        onPressed: () => ApiService.updateMeja(token, meja.id!, 'dipesan'),
                      ),
                    ))
                .toList(),
          );
        },
      ),
    );
  }
}

// ==== models/menu_model.dart ====
class MenuModel {
  final int id;
  final String nama;
  final int harga;

  MenuModel({required this.id, required this.nama, required this.harga});

  factory MenuModel.fromJson(Map json) {
    return MenuModel(
      id: json['id'],
      nama: json['nama'],
      harga: json['harga'],
    );
  }
}

// ==== models/meja_model.dart ====
class MejaModel {
  final int? id;
  final int noMeja;
  final int kapasitas;
  final String status;

  MejaModel({this.id, required this.noMeja, required this.kapasitas, required this.status});

  factory MejaModel.fromJson(Map json) {
    return MejaModel(
      id: json['id'],
      noMeja: json['no_meja'],
      kapasitas: json['kapasitas'],
      status: json['status'],
    );
  }
}

// ==== services/api_service.dart ====
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/menu_model.dart';
import '../models/meja_model.dart';

class ApiService {
  static const baseUrl = 'http://127.0.0.1:8000/api';

  static Future login(String username, String password) async {
    final response = await http.post(
      Uri.parse('$baseUrl/login/'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'username': username, 'password': password}),
    );
    if (response.statusCode == 200) {
      final json = jsonDecode(response.body);
      return json['access'];
    }
    return null;
  }

  static Future> getMenu(String token) async {
    final response = await http.get(
      Uri.parse('$baseUrl/menu/'),
      headers: {'Authorization': 'Bearer $token'},
    );
    if (response.statusCode == 200) {
      final List data = jsonDecode(response.body);
      return data.map((e) => MenuModel.fromJson(e)).toList();
    }
    return [];
  }

  static Future> getMeja(String token) async {
    final response = await http.get(
      Uri.parse('$baseUrl/meja/'),
      headers: {'Authorization': 'Bearer $token'},
    );
    if (response.statusCode == 200) {
      final List data = jsonDecode(response.body);
      return data.map((e) => MejaModel.fromJson(e)).toList();
    }
    return [];
  }

  static Future updateMeja(String token, int id, String status) async {
    await http.patch(
      Uri.parse('$baseUrl/meja/$id/'),
      headers: {
        'Authorization': 'Bearer $token',
        'Content-Type': 'application/json',
      },
      body: jsonEncode({"status": status}),
    );
  }
}

ataww


//registrasi


import 'package:flutter/material.dart';
import '../services/api_service.dart';
import 'login_screen.dart';

class RegistrationScreen extends StatefulWidget {
  @override
  _RegistrationScreenState createState() => _RegistrationScreenState();
}

class _RegistrationScreenState extends State {
  final usernameController = TextEditingController();
  final passwordController = TextEditingController();
  final emailController = TextEditingController();
  final phoneController = TextEditingController();
  final addressController = TextEditingController();
  bool isLoading = false;

  void register() async {
    setState(() {
      isLoading = true;
    });

    final success = await ApiService.register(
      usernameController.text,
      passwordController.text,
      emailController.text,
      phoneController.text,
      addressController.text,
    );

    setState(() {
      isLoading = false;
    });

    if (success) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Registrasi berhasil! Silahkan login')),
      );
      Navigator.pushReplacement(
        context, 
        MaterialPageRoute(builder: (_) => LoginScreen()),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Registrasi gagal')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Registrasi')),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: SingleChildScrollView(
          child: Column(
            children: [
              TextField(controller: usernameController, decoration: InputDecoration(labelText: 'Username')),
              TextField(controller: passwordController, decoration: InputDecoration(labelText: 'Password'), obscureText: true),
              TextField(controller: emailController, decoration: InputDecoration(labelText: 'Email')),
              TextField(controller: phoneController, decoration: InputDecoration(labelText: 'Nomor HP')),
              TextField(controller: addressController, decoration: InputDecoration(labelText: 'Alamat')),
              SizedBox(height: 20),
              isLoading 
                ? CircularProgressIndicator() 
                : ElevatedButton(onPressed: register, child: Text('Daftar')),
              TextButton(
                onPressed: () {
                  Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(builder: (_) => LoginScreen()),
                  );
                },
                child: Text('Sudah punya akun? Login'),
              )
            ],
          ),
        ),
      ),
    );
  }
}

login

import 'package:flutter/material.dart';
import '../services/api_service.dart';
import 'menu_screen.dart';
import 'registration_screen.dart';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State {
  final usernameController = TextEditingController();
  final passwordController = TextEditingController();
  bool isLoading = false;

  void login() async {
    setState(() {
      isLoading = true;
    });

    final token = await ApiService.login(
      usernameController.text,
      passwordController.text,
    );

    setState(() {
      isLoading = false;
    });

    if (token != null) {
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (_) => MenuScreen(token: token)),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Login gagal')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(controller: usernameController, decoration: InputDecoration(labelText: 'Username')),
            TextField(controller: passwordController, decoration: InputDecoration(labelText: 'Password'), obscureText: true),
            SizedBox(height: 20),
            isLoading 
              ? CircularProgressIndicator() 
              : ElevatedButton(onPressed: login, child: Text('Login')),
            TextButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (_) => RegistrationScreen()),
                );
              },
              child: Text('Belum punya akun? Daftar'),
            )
          ],
        ),
      ),
    );
  }
}