initial version
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final GlobalKey<ScaffoldMessengerState> snackbarKey = GlobalKey<ScaffoldMessengerState>();
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
String baseURL = '';
|
||||
String apiVersion = '';
|
||||
|
||||
class Endpoints {
|
||||
static final String version = '$baseURL/version';
|
||||
static final String login = '$baseURL/login';
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
import 'package:pcasttv/globals.dart';
|
||||
import 'package:pcasttv/pages/main_page.dart';
|
||||
import 'package:pcasttv/stores/login_store.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
void main() {
|
||||
runApp(
|
||||
VxState(
|
||||
store: LoginStore(),
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'PCastTV',
|
||||
debugShowCheckedModeBanner: false,
|
||||
scaffoldMessengerKey: snackbarKey,
|
||||
navigatorKey: navigatorKey,
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: const MainPage(),
|
||||
).animate().fadeIn(duration: const Duration(milliseconds: 400));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class LoginModel {
|
||||
String? message;
|
||||
String? token;
|
||||
int? userId;
|
||||
String? userName;
|
||||
String? userType;
|
||||
|
||||
LoginModel._();
|
||||
|
||||
bool get isLogged => token != null && token!.isNotEmpty;
|
||||
|
||||
String get loginMessage => message ?? "";
|
||||
|
||||
String get userRole => userType == "A"
|
||||
? "Administrador"
|
||||
: userType == "R"
|
||||
? "Revendedor"
|
||||
: "Usuário";
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'token': token,
|
||||
};
|
||||
}
|
||||
|
||||
static LoginModel instance = LoginModel._();
|
||||
|
||||
factory LoginModel.fromMap(Map<String, dynamic> map) {
|
||||
var authModel = LoginModel._();
|
||||
authModel.message = map['message'] as String;
|
||||
authModel.token = map['token'] as String;
|
||||
authModel.userId = map['userId'] as int;
|
||||
authModel.userName = map['userName'] as String;
|
||||
authModel.userType = map['userType'] as String;
|
||||
return authModel;
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory LoginModel.fromJson(String source) => LoginModel.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
bool operator ==(covariant LoginModel other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.token == token;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => token.hashCode;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pcasttv/globals.dart';
|
||||
|
||||
class MainPage extends StatefulWidget {
|
||||
const MainPage({super.key});
|
||||
|
||||
@override
|
||||
State<MainPage> createState() => _MainPageState();
|
||||
}
|
||||
|
||||
class _MainPageState extends State<MainPage> {
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
showLoginDialog();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
backgroundColor: Color.fromRGBO(166, 0, 249, 1),
|
||||
body: Column(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> showLoginDialog() {
|
||||
return showDialog(
|
||||
context: navigatorKey.currentContext!,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
scrollable: true,
|
||||
elevation: 20,
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
title: const Text('Login'),
|
||||
content: SizedBox(
|
||||
width: 500,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Form(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Email',
|
||||
icon: Icon(Icons.email),
|
||||
),
|
||||
),
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Senha',
|
||||
icon: Icon(Icons.lock),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text('Cancelar'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text('Entrar'),
|
||||
),
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:pcasttv/globals.dart';
|
||||
import 'package:pcasttv/models/login_model.dart';
|
||||
|
||||
class AuthService {
|
||||
Future<LoginModel> login(String email, String password) async {
|
||||
http.Response response;
|
||||
|
||||
final data = {
|
||||
"email": email,
|
||||
"password": password,
|
||||
};
|
||||
|
||||
try {
|
||||
response = await http.post(
|
||||
Uri.parse(Endpoints.login),
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body: jsonEncode(data),
|
||||
);
|
||||
|
||||
switch (response.statusCode) {
|
||||
case 200:
|
||||
var authModel = LoginModel.fromJson(utf8.decode(response.bodyBytes).toString());
|
||||
return authModel;
|
||||
default:
|
||||
throw Exception('Erro inesperado no login: ${response.statusCode} - ${response.body.toString()}');
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
throw Exception('Exception inesperada no login: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pcasttv/globals.dart';
|
||||
|
||||
class SnackBarService {
|
||||
static void showSnackBar({required String content, bool error = false}) {
|
||||
snackbarKey.currentState?.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
content,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
backgroundColor: error ? Colors.red : Colors.green,
|
||||
duration: const Duration(seconds: 3),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
elevation: 8.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import 'package:pcasttv/services/auth_service.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
class LoginStore extends VxStore {
|
||||
AuthService service = AuthService();
|
||||
|
||||
var isLogged = false;
|
||||
|
||||
String? message = '';
|
||||
|
||||
String email = '';
|
||||
String password = '';
|
||||
|
||||
String? token;
|
||||
int? userId;
|
||||
String? userName;
|
||||
String? userType;
|
||||
|
||||
Future<void> login() async {
|
||||
try {
|
||||
var response = await service.login(email, password);
|
||||
AuthMessage(response.message!);
|
||||
if (response.token != '' || response.message == '') {
|
||||
token = response.token;
|
||||
userId = response.userId;
|
||||
userName = response.userName;
|
||||
userType = response.userType;
|
||||
isLogged = true;
|
||||
AuthLogged(true);
|
||||
}
|
||||
} catch (e) {
|
||||
AuthMessage("SETEI NA STORE UMA EXCEPTION: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
message = null;
|
||||
token = null;
|
||||
userId = null;
|
||||
userName = null;
|
||||
userType = null;
|
||||
isLogged = false;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthLogged extends VxMutation<LoginStore> {
|
||||
final bool value;
|
||||
AuthLogged(this.value);
|
||||
|
||||
@override
|
||||
perform() {
|
||||
store!.isLogged = value;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthMessage extends VxMutation<LoginStore> {
|
||||
final String value;
|
||||
AuthMessage(this.value);
|
||||
|
||||
@override
|
||||
perform() {
|
||||
store!.message = value;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthEmail extends VxMutation<LoginStore> {
|
||||
final String value;
|
||||
AuthEmail(this.value);
|
||||
|
||||
@override
|
||||
perform() {
|
||||
store!.email = value;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthPassword extends VxMutation<LoginStore> {
|
||||
final String value;
|
||||
AuthPassword(this.value);
|
||||
|
||||
@override
|
||||
perform() {
|
||||
store!.password = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
class PublicEventsView extends StatefulWidget {
|
||||
const PublicEventsView({super.key});
|
||||
|
||||
@override
|
||||
State<PublicEventsView> createState() => _PublicEventsViewState();
|
||||
}
|
||||
|
||||
class _PublicEventsViewState extends State<PublicEventsView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
'Eventos públicos previstos para hoje'.text.white.xl4.bold.wider.make(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user