name27 / flutter

0 stars 0 forks source link

Getx AuthController Documents #106

Open name27 opened 1 year ago

name27 commented 1 year ago

image image image image image

main.dart

import 'package:auth_cotroller_app/controller/auth_controller.dart';
import 'package:auth_cotroller_app/controller/login_controller.dart';
import 'package:auth_cotroller_app/controller/main_controller.dart';
import 'package:auth_cotroller_app/util/pages.dart';
import 'package:auth_cotroller_app/view/login_page.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialBinding: BindingsBuilder(() {
        Get.put(AuthController());
        Get.lazyPut(() => LoginController());
        Get.lazyPut(() => MainController());
      }),
      getPages: AppPages.pages,
      home: Scaffold(
        body: Center(
            child: TextButton(
                onPressed: () => Get.toNamed(LoginPage.route),
                child: const Text('Hello World'))),
      ),
    );
  }
}

main_page.dart

import 'package:auth_cotroller_app/controller/main_controller.dart';
import 'package:auth_cotroller_app/view/Screens/mainScreen.dart';
import 'package:auth_cotroller_app/view/Screens/myScreen.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MainPage extends GetView<MainController> {
  const MainPage({super.key});
  static String route = '/main';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20.0))),
          backgroundColor: const Color.fromARGB(255, 218, 176, 255),
          onPressed: controller.readDocuments,
          child: const Icon(
            Icons.refresh,
            color: Color.fromARGB(255, 63, 28, 122),
          ),
        ),
        bottomNavigationBar: Obx(
          () => BottomNavigationBar(
              onTap: controller.onPageTapped,
              currentIndex: controller.curPage.value,
              items: const [
                BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
                BottomNavigationBarItem(
                    icon: Icon(Icons.person), label: 'Home'),
              ]),
        ),
        body: SafeArea(
          child: PageView(
            controller: controller.pageController,
            children: const [MainScreen(), MyScreen()],
          ),
        ));
  }
}

mainScreen.dart

import 'package:auth_cotroller_app/controller/auth_controller.dart';
import 'package:auth_cotroller_app/controller/main_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MainScreen extends GetView<MainController> {
  const MainScreen({super.key});

  @override
  Widget build(BuildContext context) {
    var user = Get.find<AuthController>().user!;
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          '${user.record.username} 님 안녕하세요',
          style: const TextStyle(fontSize: 30),
        ),
        Obx(
          () => ListView.builder(
            shrinkWrap: true,
            itemCount: controller.userdata.length,
            itemBuilder: (context, index) => ListTile(
              title: Text(controller.userdata[index].title),
              subtitle: Text(controller.userdata[index].content),
            ),
          ),
        ),
        Obx(() {
          if (controller.attachmentUrl != '') {
            return Image.network(controller.attachmentUrl.toString());
          }
          return const SizedBox();
        })
      ],
    );
  }
}

myScreen.dart

import 'package:auth_cotroller_app/controller/auth_controller.dart';
import 'package:auth_cotroller_app/controller/main_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MyScreen extends GetView<MainController> {
  const MyScreen({super.key});

  @override
  Widget build(BuildContext context) {
    var user = Get.find<AuthController>().user!;
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      ListTile(
        leading: const CircleAvatar(
            //backgroundImage: NetworkImage(user),
            ),
        title: Text(user.record.username),
        subtitle: Text(user.record.name),
      ),
      ListTile(
        title: const Text('로그아웃하기'),
        leading: const Icon(Icons.logout),
        onTap: controller.logout,
      )
    ]);
  }
}

login_page.dart

import 'package:auth_cotroller_app/controller/login_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class LoginPage extends GetView<LoginController> {
  const LoginPage({super.key});
  static String route = '/login';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: controller.idController,
            ),
            TextField(
              controller: controller.pwController,
            ),
            ElevatedButton(
                onPressed: controller.login, child: const Text('Login'))
          ],
        ),
      ),
    );
  }
}

auth_controller.dart

import 'package:auth_cotroller_app/model/user.dart';
import 'package:auth_cotroller_app/util/api_routes.dart';
import 'package:auth_cotroller_app/view/login_page.dart';
import 'package:auth_cotroller_app/view/main_page.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart';

class AuthController extends GetxController {
  final Rxn<User> _user = Rxn();
  final RxnString _token = RxnString();
  Dio dio = Dio();

  User? get user => _user.value;
  String? get token => _token.value;

  login(String id, String pw) async {
    dio.options.baseUrl = 'http://52.79.115.43:8090';
    try {
      var res = await dio.post(
        ApiRoutes.authWithPassword,
        data: {
          'identity': id,
          'password': pw,
        },
      );
      if (res.statusCode == 200) {
        var user = User.fromMap(res.data);
        _token(user.token);
        _user(user);
      }
    } on DioError catch (e) {
      print(e.message);
      print(e.requestOptions.path);
    }
  }

  logout() {
    _user.value = null;
  }

  _handleAuthChanged(User? data) {
    if (data != null) {
      Get.toNamed(MainPage.route);
      return;
    }
    Get.toNamed(LoginPage.route);
    return;
  }

  @override
  void onInit() {
    super.onInit();
    ever(_user, _handleAuthChanged);
  }
}

login_controller.dart

import 'package:auth_cotroller_app/controller/auth_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class LoginController extends GetxController {
  var idController = TextEditingController();
  var pwController = TextEditingController();

  login() {
    Get.find<AuthController>().login(idController.text, pwController.text);
  }
}

main_controller.dart

import 'package:auth_cotroller_app/controller/auth_controller.dart';
import 'package:auth_cotroller_app/model/document.dart';
import 'package:auth_cotroller_app/util/api_routes.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MainController extends GetxController {
  var pageController = PageController();
  RxInt curPage = 0.obs;
  final RxList<Document> _userdata = RxList();
  Dio dio = Dio();
  RxInt userdataLength = 0.obs;
  RxString attachmentUrl = ''.obs;
  List<Document> get userdata => _userdata;

  onPageTapped(int v) {
    pageController.jumpToPage(v);
    curPage(v);
  }

  logout() {
    Get.find<AuthController>().logout();
  }

  readDocuments() async {
    _userdata.clear();
    var auth = Get.find<AuthController>();
    if (auth.token != null) {
      dio.options.baseUrl = 'http://52.79.115.43:8090';
      var res = await dio.get(ApiRoutes.authToken,
          options: Options(headers: {'authorization': auth.token}));
      try {
        if (res.statusCode == 200) {
          var items = List<Map<String, dynamic>>.from(res.data['items']);
          var datas = items.map((e) => Document.fromMap(e)).toList();
          if (_userdata.isEmpty) {
            _userdata.addAll(datas);
          }
          if (userdataLength < _userdata.length) {
            userdataLength(_userdata.length);
          }
          for (var data in _userdata) {
            if (data.attachment_url != null) {
              attachmentUrl(data.attachment_url);
            }
          }
        }
      } on DioError catch (e) {
        print(e.message);
      }
    }
  }
}

document.dart

// ignore_for_file: public_member_api_docs, sort_constructors_first, non_constant_identifier_names

class Document {
  String title;
  String content;
  String sec_level;
  String? attachment_url;
  Document({
    required this.title,
    required this.content,
    required this.sec_level,
    this.attachment_url,
  });

  factory Document.fromMap(Map<String, dynamic> map) {
    return Document(
      title: map['title'] as String,
      content: map['content'] as String,
      sec_level: map['sec_level'] as String,
      attachment_url:
          map['attachment_url'] != '' ? map['attachment_url'] : null,
    );
  }
}

record.dart

import 'dart:convert';

class Record {
  String id;
  String username;
  String email;
  String name;
  String avatar;
  Record({
    required this.id,
    required this.username,
    required this.email,
    required this.name,
    required this.avatar,
  });

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'id': id,
      'username': username,
      'email': email,
      'name': name,
      'avatar': avatar,
    };
  }

  factory Record.fromMap(Map<String, dynamic> map) {
    return Record(
      id: map['id'] as String,
      username: map['username'] as String,
      email: map['email'] as String,
      name: map['name'] as String,
      avatar: map['avatar'] as String,
    );
  }

  String toJson() => json.encode(toMap());

  factory Record.fromJson(String source) =>
      Record.fromMap(json.decode(source) as Map<String, dynamic>);
}

user.dart

// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

import 'package:auth_cotroller_app/model/record.dart';

class User {
  String token;
  Record record;
  User({
    required this.token,
    required this.record,
  });

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'token': token,
      'record': record.toMap(),
    };
  }

  factory User.fromMap(Map<String, dynamic> map) {
    return User(
      token: map['token'] as String,
      record: Record.fromMap(map['record'] as Map<String, dynamic>),
    );
  }

  String toJson() => json.encode(toMap());

  factory User.fromJson(String source) =>
      User.fromMap(json.decode(source) as Map<String, dynamic>);
}

api_routes.dart

class ApiRoutes{
  static const String authWithPassword = '/api/collections/users/auth-with-password';
  static const String authToken = '/api/collections/documents/records';
}

pages.dart

import 'package:auth_cotroller_app/util/routes.dart';
import 'package:auth_cotroller_app/view/login_page.dart';
import 'package:auth_cotroller_app/view/main_page.dart';
import 'package:get/get.dart';

class AppPages {
  static final pages = [
    GetPage(name: AppRoutes.main, page: () => const MainPage()),
    GetPage(name: AppRoutes.login, page: () => const LoginPage()),
  ];
}

routes.dart

import 'package:auth_cotroller_app/view/login_page.dart';
import 'package:auth_cotroller_app/view/main_page.dart';

class AppRoutes {
  static final main = MainPage.route;
  static final login = LoginPage.route;
}