refactor power

This commit is contained in:
2026-04-07 11:55:01 +02:00
parent 130780cbb8
commit f4d3ec4bca
12 changed files with 157 additions and 74 deletions

View File

@@ -1,6 +1,6 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flux/data/enums.dart'; import 'package:flux/core/enums/enums.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'dart:async'; import 'dart:async';

View File

@@ -1,6 +1,6 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flux/data/enums.dart'; import 'package:flux/core/enums/enums.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';

View File

@@ -1,9 +1,8 @@
// lib/ui/auth/auth_screen.dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/features/auth/bloc/auth_bloc.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/widgets/flux_text_field.dart'; import 'package:flux/core/widgets/flux_text_field.dart';
import 'package:flux/features/auth/bloc/auth_bloc.dart';
class AuthScreen extends StatefulWidget { class AuthScreen extends StatefulWidget {
const AuthScreen({super.key}); const AuthScreen({super.key});
@@ -15,86 +14,166 @@ class AuthScreen extends StatefulWidget {
class _AuthScreenState extends State<AuthScreen> { class _AuthScreenState extends State<AuthScreen> {
final _emailController = TextEditingController(); final _emailController = TextEditingController();
final _passwordController = TextEditingController(); final _passwordController = TextEditingController();
final _storeController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocConsumer<AuthBloc, AuthState>( return Scaffold(
body: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) { listener: (context, state) {
if (state.status == AuthStatus.failure) { if (state.status == AuthStatus.failure) {
// Mostra l'errore che arriva da Supabase (es. "Invalid login credentials")
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.error!), backgroundColor: Colors.red), SnackBar(
content: Text(state.error ?? 'Errore di autenticazione'),
backgroundColor: Colors.redAccent,
),
); );
} }
}, },
builder: (context, state) { builder: (context, state) {
return Column( final isLoading = state.status == AuthStatus.loading;
return SafeArea(
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
FluxTextField( // --- LOGO FLUX ---
label: 'Email', _buildLogo(context),
icon: Icons.email, const SizedBox(height: 60),
controller: _emailController,
// --- TITOLO DINAMICO ---
Text(
state.isLoginMode ? 'BENTORNATO' : 'CREA ACCOUNT',
style: TextStyle(
color: context.primaryText,
fontSize: 24,
fontWeight: FontWeight.w900,
letterSpacing: 1.5,
), ),
),
const SizedBox(height: 8),
Text(
state.isLoginMode
? 'Accedi per gestire il tuo business'
: 'Inizia oggi a digitalizzare il tuo negozio',
textAlign: TextAlign.center,
style: TextStyle(color: context.secondaryText),
),
const SizedBox(height: 40),
// --- CAMPI INPUT ---
FluxTextField(
label: 'Email Aziendale',
icon: Icons.email_outlined,
controller: _emailController,
keyboardType: TextInputType.emailAddress,
),
const SizedBox(height: 20),
FluxTextField( FluxTextField(
label: 'Password', label: 'Password',
icon: Icons.lock, icon: Icons.lock_outline,
isPassword: true, isPassword: true,
controller: _passwordController, controller: _passwordController,
), ),
if (!state.isLoginMode)
FluxTextField(
label: 'Codice Negozio',
icon: Icons.store,
controller: _storeController,
),
ElevatedButton( const SizedBox(height: 40),
onPressed: state.status == AuthStatus.loading
// --- BOTTONE PRINCIPALE ---
SizedBox(
width: double.infinity,
height: 56,
child: ElevatedButton(
onPressed: isLoading
? null ? null
: () { : () {
context.read<AuthBloc>().add( context.read<AuthBloc>().add(
LoginRequested( LoginRequested(
email: _emailController.text.trim(), email: _emailController.text.trim(),
password: _passwordController.text.trim(), password: _passwordController.text.trim(),
storeCode: _storeController.text.trim(),
), ),
); );
}, },
child: state.status == AuthStatus.loading child: isLoading
? const CircularProgressIndicator() ? const SizedBox(
height: 24,
width: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: Text(state.isLoginMode ? 'ACCEDI' : 'REGISTRATI'), : Text(state.isLoginMode ? 'ACCEDI' : 'REGISTRATI'),
), ),
),
// --- SWITCH LOGIN/SIGNUP ---
const SizedBox(height: 24),
TextButton(
onPressed: isLoading
? null
: () {
context.read<AuthBloc>().add(ToggleAuthMode());
},
child: RichText(
text: TextSpan(
text: state.isLoginMode
? "Non hai un account? "
: "Hai già un account? ",
style: TextStyle(color: context.secondaryText),
children: [
TextSpan(
text: state.isLoginMode ? "Registrati" : "Accedi",
style: TextStyle(
color: context.accent,
fontWeight: FontWeight.bold,
),
),
], ],
),
),
),
],
),
),
),
); );
}, },
),
); );
} }
@override Widget _buildLogo(BuildContext context) {
void dispose() {
_emailController.dispose();
_passwordController.dispose();
_storeController.dispose();
super.dispose();
}
}
class _FluxLogo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
Icon( Container(
Icons.all_inclusive, padding: const EdgeInsets.all(20),
size: 80, decoration: BoxDecoration(
color: context.accent.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: Icon(
Icons.all_inclusive_rounded, // Simbolo dell'infinito/Flux
size: 60,
color: context.accent, color: context.accent,
), // Simbolo Flux/Infinito ),
),
const SizedBox(height: 16),
Text( Text(
'FLUX', 'FLUX',
style: Theme.of(context).textTheme.headlineMedium?.copyWith( style: TextStyle(
color: context.primaryText,
fontSize: 32,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
letterSpacing: 8, letterSpacing: 10,
), ),
), ),
], ],

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/blocs/company/company_bloc.dart'; import 'package:flux/features/company/bloc/company_bloc.dart';
import 'package:flux/blocs/session/session_bloc.dart'; import 'package:flux/core/blocs/session/session_bloc.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/widgets/flux_text_field.dart'; import 'package:flux/core/widgets/flux_text_field.dart';

View File

@@ -1,8 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/blocs/session/session_bloc.dart'; import 'package:flux/core/blocs/session/session_bloc.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/theme/bloc/theme_bloc.dart'; import 'package:flux/core/theme/bloc/theme_bloc.dart';
import 'package:flux/features/auth/bloc/auth_bloc.dart';
import 'package:flux/features/auth/ui/auth_screen.dart'; import 'package:flux/features/auth/ui/auth_screen.dart';
import 'package:flux/features/company/ui/create_company_screen.dart'; import 'package:flux/features/company/ui/create_company_screen.dart';
import 'package:flux/features/store/ui/create_store_screen.dart'; import 'package:flux/features/store/ui/create_store_screen.dart';
@@ -29,10 +30,13 @@ void main() async {
runApp( runApp(
MultiBlocProvider( MultiBlocProvider(
providers: [ providers: [
BlocProvider(create: (context) => ThemeBloc()..add(LoadThemeEvent())), BlocProvider<ThemeBloc>(
create: (context) => ThemeBloc()..add(LoadThemeEvent()),
),
BlocProvider<SessionBloc>( BlocProvider<SessionBloc>(
create: (context) => SessionBloc()..add(AppStarted()), create: (context) => SessionBloc()..add(AppStarted()),
), ),
BlocProvider<AuthBloc>(create: (context) => AuthBloc()),
], ],
child: const FluxApp(), child: const FluxApp(),
), ),

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/data/enums.dart'; import 'package:flux/core/enums/enums.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/theme/bloc/theme_bloc.dart'; import 'package:flux/core/theme/bloc/theme_bloc.dart';