initial version

This commit is contained in:
2023-08-23 10:11:10 -03:00
commit 304f895d25
23 changed files with 970 additions and 0 deletions
+12
View File
@@ -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';
}
+33
View File
@@ -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));
}
}
+53
View File
@@ -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;
}
+78
View File
@@ -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'),
),
]);
});
}
}
+37
View File
@@ -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');
}
}
}
+26
View File
@@ -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,
),
);
}
}
+84
View File
@@ -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;
}
}
+23
View File
@@ -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(),
],
),
);
}
}