Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/core/consts/routes_const.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AppNameRoutes {
static const String home = '/';
static const String login = '/login';
static const String onboarding = '/onboarding';
static const String register = '/register';
}
19 changes: 12 additions & 7 deletions lib/core/routes/routes.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:quentinha_app/core/consts/routes_const.dart';
import 'package:quentinha_app/presentation/view/register_page.dart';

import '../../presentation/view/home_page.dart';
import '../../presentation/view/login_page.dart';
import '../../presentation/view/onboarding_page.dart';

class AppRoutes {
static const String home = '/';
static const String login = '/login';
static const String onboarding = '/onboarding';


static GoRouter router(bool seenOnboarding) {
return GoRouter(
initialLocation: seenOnboarding ? home : onboarding,
initialLocation: seenOnboarding ? AppNameRoutes.home : AppNameRoutes.onboarding,
routes: [
GoRoute(
path: home,
path: AppNameRoutes.home,
name: 'home',
builder: (context, state) => const HomePage(),
),
GoRoute(
path: login,
path: AppNameRoutes.login,
name: 'login',
builder: (context, state) => const LoginPage(),
),
GoRoute(
path: onboarding,
path: AppNameRoutes.onboarding,
name: 'onboarding',
builder: (context, state) => const OnboardingPage(),
),
GoRoute(
path: AppNameRoutes.register,
name: 'register',
builder: (context, state) => const RegisterPage(),
),
],
errorBuilder: (context, state) => Scaffold(
body: Center(child: Text('Erro: ${state.error}')),
Expand Down
6 changes: 5 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:quentinha_app/core/consts/colors_const.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'core/routes/routes.dart';
Expand Down Expand Up @@ -26,8 +27,11 @@ class MyApp extends StatelessWidget {
selectionColor: Colors.orangeAccent, // texto selecionado
selectionHandleColor: Colors.orange, // "bolinha" do seletor
),
textTheme: GoogleFonts.robotoTextTheme(
Theme.of(context).textTheme,
),
),
title: 'Onboarding Demo',
title: 'Quentinhas App',
debugShowCheckedModeBanner: false,
routerConfig: AppRoutes.router(seenOnboarding),
);
Expand Down
45 changes: 45 additions & 0 deletions lib/presentation/components/password_field_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';

class PasswordField extends StatefulWidget {
final TextEditingController controller;
final String? Function(String?)? validator;

const PasswordField({
super.key,
required this.controller,
this.validator,
});

@override
State<PasswordField> createState() => _PasswordFieldState();
}

class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;

@override
Widget build(BuildContext context) {
return TextFormField(
controller: widget.controller,
obscureText: _obscureText,
validator: widget.validator,
decoration: InputDecoration(
hintText: '••••••••',
filled: true,
fillColor: Colors.grey[300],
suffixIcon: IconButton(
icon: Icon(_obscureText ? Icons.visibility_off : Icons.visibility),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
),
);
}
}
3 changes: 2 additions & 1 deletion lib/presentation/components/register_login_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:quentinha_app/core/consts/colors_const.dart';
import 'package:quentinha_app/core/consts/routes_const.dart';
import 'package:quentinha_app/core/consts/size_const.dart';

import '../../core/log/logger.dart';
Expand Down Expand Up @@ -104,7 +105,7 @@ class RegisterLoginPage extends StatelessWidget {
// Texto rodapé
TextButton(
onPressed: () {
context.go('/login');
context.go(AppNameRoutes.login);
AppLogger.i("Navegar para login");
},
child: const Text(
Expand Down
117 changes: 55 additions & 62 deletions lib/presentation/view/login_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:quentinha_app/core/consts/colors_const.dart';
import 'package:quentinha_app/core/consts/size_const.dart';
import 'package:quentinha_app/presentation/components/password_field_widget.dart';

import '../../core/consts/routes_const.dart';
import '../../core/log/logger.dart';

class LoginPage extends StatefulWidget {
const LoginPage({super.key});
Expand All @@ -11,7 +16,20 @@ class LoginPage extends StatefulWidget {
}

class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _passwordController = TextEditingController();
bool rememberAccount = false;

void _signOn() {
if (_formKey.currentState!.validate()) {
final senha = _passwordController.text;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Cadastro realizado com sucesso!")),
);
AppLogger.i("Senha cadastrada: $senha");
}
}

@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
Expand Down Expand Up @@ -59,6 +77,7 @@ class _LoginPageState extends State<LoginPage> {

// Formulário
Form(
key: _formKey,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight:
Expand All @@ -68,7 +87,10 @@ class _LoginPageState extends State<LoginPage> {
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(35), topRight: Radius.circular(35)),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(35),
topRight: Radius.circular(35),
),
boxShadow: [
BoxShadow(
color: Colors.black12,
Expand Down Expand Up @@ -101,21 +123,27 @@ class _LoginPageState extends State<LoginPage> {
),
),
),

const SizedBox(height: 20),

// Password
const Text("SENHA"),
const SizedBox(height: 8),
StatefulBuilder(
builder: (context, setState) {
// Move _obscureText outside the builder to persist its state
return _PasswordField();
PasswordField(
controller: _passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return "Digite a senha";
}
if (value.length < 6) {
return "A senha deve ter pelo menos 6 caracteres";
}
return null;
},
),

const SizedBox(height: 10),

// Remember + Forgot Password
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expand All @@ -124,14 +152,15 @@ class _LoginPageState extends State<LoginPage> {
children: [
Checkbox(
value: rememberAccount,
activeColor:
AppColors.primary,
activeColor: AppColors.primary,
onChanged: (bool? newValue) {
setState(() {
rememberAccount = newValue ?? false;
});

ScaffoldMessenger.of(context).showSnackBar(

ScaffoldMessenger.of(
context,
).showSnackBar(
SnackBar(
content: Text(
rememberAccount
Expand All @@ -155,23 +184,23 @@ class _LoginPageState extends State<LoginPage> {
),
],
),

const SizedBox(height: 20),

// Botão Login
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: () {},
onPressed: _signOn,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text(
"LOG IN",
"ENTRAR",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
Expand All @@ -180,16 +209,18 @@ class _LoginPageState extends State<LoginPage> {
),
),
),

const SizedBox(height: 20),

// Signup
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("Não tem conta? "),
GestureDetector(
onTap: () {},
onTap: () {
context.push(AppNameRoutes.register);
},
child: const Text(
"Inscreva-se",
style: TextStyle(
Expand All @@ -200,9 +231,9 @@ class _LoginPageState extends State<LoginPage> {
),
],
),

const SizedBox(height: 20),

// Divider Or
Row(
children: const [
Expand All @@ -214,9 +245,9 @@ class _LoginPageState extends State<LoginPage> {
Expanded(child: Divider()),
],
),

const SizedBox(height: 20),

// Social buttons
Row(
mainAxisAlignment: MainAxisAlignment.center,
Expand Down Expand Up @@ -271,41 +302,3 @@ class _LoginPageState extends State<LoginPage> {
);
}
}

// Custom password field widget to persist obscureText state
class _PasswordField extends StatefulWidget {
@override
State<_PasswordField> createState() => _PasswordFieldState();
}

class _PasswordFieldState extends State<_PasswordField> {
bool _obscureText = true;

@override
Widget build(BuildContext context) {
return TextField(
obscureText: _obscureText,
decoration: InputDecoration(
hintText: "••••••••",
filled: true,
fillColor: Colors.grey[300],
suffixIcon: IconButton(
icon: Icon(_obscureText ? Icons.visibility_off : Icons.visibility),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
),
);
}
}
3 changes: 2 additions & 1 deletion lib/presentation/view/onboarding_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:introduction_screen/introduction_screen.dart';
import 'package:quentinha_app/core/consts/colors_const.dart';
import 'package:quentinha_app/core/consts/routes_const.dart';
import 'package:quentinha_app/presentation/components/register_login_page.dart';
import 'package:shared_preferences/shared_preferences.dart';

Expand All @@ -18,7 +19,7 @@ class OnboardingPage extends StatelessWidget {
// Usando GoRouter para navegação
// Certifique-se de ter configurado a rota '/home' no seu GoRouter
// e de importar 'package:go_router/go_router.dart'
context.go('/home');
context.go(AppNameRoutes.home);
}

@override
Expand Down
Loading
Loading