hgkj
This commit is contained in:
@@ -1,8 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flux/theme.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flux/theme/theme.dart';
|
||||||
|
import 'package:flux/theme/theme_bloc.dart';
|
||||||
import 'package:flux/ui/home_screen.dart';
|
import 'package:flux/ui/home_screen.dart';
|
||||||
|
import 'package:flux/ui/settings/settings.dart';
|
||||||
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
void main() {
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
final GetIt getIt = GetIt.instance;
|
||||||
|
getIt.registerSingleton<SharedPreferences>(
|
||||||
|
await SharedPreferences.getInstance(),
|
||||||
|
);
|
||||||
|
getIt.registerSingleton<AppSettings>(AppSettings());
|
||||||
runApp(const MainApp());
|
runApp(const MainApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,11 +22,34 @@ class MainApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
AppTheme appTheme = GetIt.I.get<AppSettings>().appTheme;
|
||||||
|
ThemeData themeData;
|
||||||
|
switch (appTheme) {
|
||||||
|
case AppTheme.dark:
|
||||||
|
themeData = fluxDarkTheme;
|
||||||
|
break;
|
||||||
|
case AppTheme.light:
|
||||||
|
themeData = fluxLightTheme;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
themeData = ThemeMode.system == ThemeMode.dark
|
||||||
|
? fluxDarkTheme
|
||||||
|
: fluxLightTheme;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'FLUX Gestionale',
|
title: 'FLUX Gestionale',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: fluxDarkTheme, // Applica il tema FLUX
|
theme: themeData, // Applica il tema FLUX
|
||||||
home: const HomeScreen(),
|
home: MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => ThemeBloc(initialAppTheme: appTheme),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
child: const HomeScreen(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
// lib/theme.dart
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
|
|
||||||
class FluxColors {
|
|
||||||
// Palette Tech Dark da loghi generati
|
|
||||||
static const Color background = Color(0xFF0A0E17); // Nero profondo/Blu scuro
|
|
||||||
static const Color surface = Color(0xFF161B22); // Pannelli scuri
|
|
||||||
static const Color primaryBlue = Color(0xFF007BFF); // Blu Elettrico del logo
|
|
||||||
static const Color accentTurquoise = Color(0xFF17A2B8); // Turchese del flusso
|
|
||||||
static const Color textPrimary = Colors.white;
|
|
||||||
static const Color textSecondary = Color(0xFF8B949E); // Grigio fumo
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeData fluxDarkTheme = ThemeData(
|
|
||||||
useMaterial3: true,
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
primaryColor: FluxColors.primaryBlue,
|
|
||||||
scaffoldBackgroundColor: FluxColors.background,
|
|
||||||
colorScheme: const ColorScheme.dark(
|
|
||||||
primary: FluxColors.primaryBlue,
|
|
||||||
secondary: FluxColors.accentTurquoise,
|
|
||||||
surface: FluxColors.surface,
|
|
||||||
background: FluxColors.background,
|
|
||||||
onPrimary: Colors.white,
|
|
||||||
onSurface: FluxColors.textPrimary,
|
|
||||||
),
|
|
||||||
|
|
||||||
// Font moderno sans-serif (es. Montserrat o Poppins coerente con descrizione)
|
|
||||||
textTheme: GoogleFonts.poppinsTextTheme(ThemeData.dark().textTheme).copyWith(
|
|
||||||
headlineMedium: GoogleFonts.poppins(
|
|
||||||
color: FluxColors.textPrimary,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
letterSpacing: 0.5,
|
|
||||||
),
|
|
||||||
titleLarge: GoogleFonts.poppins(
|
|
||||||
color: FluxColors.textPrimary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
bodyMedium: GoogleFonts.poppins(color: FluxColors.textSecondary),
|
|
||||||
),
|
|
||||||
|
|
||||||
appBarTheme: const AppBarTheme(
|
|
||||||
backgroundColor: FluxColors.background,
|
|
||||||
elevation: 0,
|
|
||||||
centerTitle: false,
|
|
||||||
titleTextStyle: TextStyle(
|
|
||||||
color: FluxColors.textPrimary,
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
cardTheme: const CardThemeData(
|
|
||||||
color: FluxColors.surface,
|
|
||||||
elevation: 2,
|
|
||||||
margin: EdgeInsets.all(8),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Stile per i pulsanti (es. "Nuova Operazione")
|
|
||||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: FluxColors.primaryBlue,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
|
||||||
textStyle: GoogleFonts.poppins(fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
189
lib/theme/theme.dart
Normal file
189
lib/theme/theme.dart
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
// lib/theme.dart
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
class FluxColors {
|
||||||
|
// === Palette comune (dal logo) ===
|
||||||
|
static const Color primaryBlue = Color(
|
||||||
|
0xFF007BFF,
|
||||||
|
); // Blu Elettrico (Affidabilità)
|
||||||
|
static const Color accentTurquoise = Color(
|
||||||
|
0xFF17A2B8,
|
||||||
|
); // Turchese (Flusso/Tech)
|
||||||
|
|
||||||
|
// === Palette Tech Dark (esistente) ===
|
||||||
|
static const Color darkBackground = Color(0xFF0A0E17);
|
||||||
|
static const Color darkSurface = Color(0xFF161B22);
|
||||||
|
static const Color darkTextPrimary = Colors.white;
|
||||||
|
static const Color darkTextSecondary = Color(0xFF8B949E);
|
||||||
|
|
||||||
|
// === Palette Tech Light (NUOVA) ===
|
||||||
|
static const Color lightBackground = Color(
|
||||||
|
0xFFF0F2F5,
|
||||||
|
); // Grigio chiarissimo "pulito"
|
||||||
|
static const Color lightSurface = Colors.white; // Pannelli bianchi puri
|
||||||
|
static const Color lightTextPrimary = Color(
|
||||||
|
0xFF1C1E21,
|
||||||
|
); // Quasi nero per contrasto
|
||||||
|
static const Color lightTextSecondary = Color(0xFF606770); // Grigio medio
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Configurazione Tipografica Comune ---
|
||||||
|
TextTheme _buildFluxTextTheme(
|
||||||
|
TextTheme base,
|
||||||
|
Color primaryColor,
|
||||||
|
Color secondaryColor,
|
||||||
|
) {
|
||||||
|
return GoogleFonts.poppinsTextTheme(base).copyWith(
|
||||||
|
headlineMedium: GoogleFonts.poppins(
|
||||||
|
color: primaryColor,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: 0.5,
|
||||||
|
),
|
||||||
|
titleLarge: GoogleFonts.poppins(
|
||||||
|
color: primaryColor,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
titleSmall: GoogleFonts.poppins(
|
||||||
|
color:
|
||||||
|
FluxColors.accentTurquoise, // Sempre turchese per i titoli di sezione
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: 1.2,
|
||||||
|
),
|
||||||
|
bodyMedium: GoogleFonts.poppins(color: secondaryColor),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// === TEMA SCURO (esistente, ottimizzato) ===
|
||||||
|
// ==========================================
|
||||||
|
ThemeData fluxDarkTheme = ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
primaryColor: FluxColors.primaryBlue,
|
||||||
|
scaffoldBackgroundColor: FluxColors.darkBackground,
|
||||||
|
colorScheme: const ColorScheme.dark(
|
||||||
|
primary: FluxColors.primaryBlue,
|
||||||
|
secondary: FluxColors.accentTurquoise,
|
||||||
|
surface: FluxColors.darkSurface,
|
||||||
|
onPrimary: Colors.white,
|
||||||
|
onSurface: FluxColors.darkTextPrimary,
|
||||||
|
),
|
||||||
|
|
||||||
|
textTheme: _buildFluxTextTheme(
|
||||||
|
ThemeData.dark().textTheme,
|
||||||
|
FluxColors.darkTextPrimary,
|
||||||
|
FluxColors.darkTextSecondary,
|
||||||
|
),
|
||||||
|
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
backgroundColor: FluxColors.darkBackground,
|
||||||
|
elevation: 0,
|
||||||
|
centerTitle: false,
|
||||||
|
iconTheme: IconThemeData(color: FluxColors.darkTextPrimary),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: FluxColors.darkTextPrimary,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardTheme: const CardThemeData(
|
||||||
|
color: FluxColors.darkSurface,
|
||||||
|
elevation: 2,
|
||||||
|
margin: EdgeInsets.all(8),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: FluxColors.primaryBlue,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
elevation: 3,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Colore delle icone non attive nella BottomNav
|
||||||
|
unselectedWidgetColor: FluxColors.darkTextSecondary,
|
||||||
|
);
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// === TEMA CHIARO (NUOVO) ===
|
||||||
|
// ==========================================
|
||||||
|
ThemeData fluxLightTheme = ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
primaryColor: FluxColors.primaryBlue,
|
||||||
|
// Sfondo chiarissimo per staccare dalle card bianche
|
||||||
|
scaffoldBackgroundColor: FluxColors.lightBackground,
|
||||||
|
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: FluxColors.primaryBlue,
|
||||||
|
secondary: FluxColors.accentTurquoise,
|
||||||
|
surface: FluxColors.lightSurface,
|
||||||
|
onPrimary: Colors.white,
|
||||||
|
onSurface: FluxColors.lightTextPrimary,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Applica la stessa tipografia ma con colori scuri
|
||||||
|
textTheme: _buildFluxTextTheme(
|
||||||
|
ThemeData.light().textTheme,
|
||||||
|
FluxColors.lightTextPrimary,
|
||||||
|
FluxColors.lightTextSecondary,
|
||||||
|
),
|
||||||
|
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
backgroundColor: FluxColors.lightSurface, // AppBar bianca
|
||||||
|
elevation: 1, // Leggera ombra per staccare dallo sfondo
|
||||||
|
centerTitle: false,
|
||||||
|
iconTheme: IconThemeData(color: FluxColors.lightTextPrimary),
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: FluxColors.lightTextPrimary,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardTheme: const CardThemeData(
|
||||||
|
color: FluxColors.lightSurface, // Card bianca pura
|
||||||
|
elevation: 4, // Ombra più marcata su sfondo chiaro
|
||||||
|
margin: EdgeInsets.all(8),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Il pulsante principale rimane Blu Elettrico, molto visibile
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: FluxColors.primaryBlue,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
elevation: 4,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// TabBar (usata nelle Anagrafiche) ottimizzata per il chiaro
|
||||||
|
tabBarTheme: const TabBarThemeData(
|
||||||
|
labelColor: FluxColors.primaryBlue,
|
||||||
|
unselectedLabelColor: FluxColors.lightTextSecondary,
|
||||||
|
indicatorColor: FluxColors.accentTurquoise,
|
||||||
|
indicatorSize: TabBarIndicatorSize.label,
|
||||||
|
),
|
||||||
|
|
||||||
|
// BottomNavigationBar (usata nella HomeScreen)
|
||||||
|
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||||
|
backgroundColor: FluxColors.lightSurface,
|
||||||
|
selectedItemColor: FluxColors.primaryBlue,
|
||||||
|
unselectedItemColor: FluxColors.lightTextSecondary,
|
||||||
|
elevation: 8,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Colore delle icone generiche
|
||||||
|
iconTheme: const IconThemeData(color: FluxColors.lightTextSecondary),
|
||||||
|
);
|
||||||
17
lib/theme/theme_bloc.dart
Normal file
17
lib/theme/theme_bloc.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
part 'theme_events.dart';
|
||||||
|
part 'theme_state.dart';
|
||||||
|
|
||||||
|
class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
|
||||||
|
final AppTheme initialAppTheme;
|
||||||
|
ThemeBloc({required this.initialAppTheme})
|
||||||
|
: super(
|
||||||
|
ThemeState(status: ThemeStatus.success, appTheme: initialAppTheme),
|
||||||
|
) {
|
||||||
|
on<ChangeThemeEvent>((event, emit) async {
|
||||||
|
emit(state.copyWith(appTheme: event.appTheme));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
17
lib/theme/theme_events.dart
Normal file
17
lib/theme/theme_events.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
part of 'theme_bloc.dart';
|
||||||
|
|
||||||
|
abstract class ThemeEvent extends Equatable {
|
||||||
|
const ThemeEvent();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeThemeEvent extends ThemeEvent {
|
||||||
|
const ChangeThemeEvent({required this.appTheme});
|
||||||
|
|
||||||
|
final AppTheme appTheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [appTheme];
|
||||||
|
}
|
||||||
30
lib/theme/theme_state.dart
Normal file
30
lib/theme/theme_state.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
part of 'theme_bloc.dart';
|
||||||
|
|
||||||
|
enum ThemeStatus { initial, success }
|
||||||
|
|
||||||
|
enum AppTheme {
|
||||||
|
dark(name: 'dark'),
|
||||||
|
light(name: 'light'),
|
||||||
|
system(name: 'system');
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const AppTheme({required this.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThemeState extends Equatable {
|
||||||
|
const ThemeState({required this.status, required this.appTheme});
|
||||||
|
|
||||||
|
final ThemeStatus status;
|
||||||
|
final AppTheme appTheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [status, appTheme];
|
||||||
|
|
||||||
|
ThemeState copyWith({ThemeStatus? status, AppTheme? appTheme}) {
|
||||||
|
return ThemeState(
|
||||||
|
status: status ?? this.status,
|
||||||
|
appTheme: appTheme ?? this.appTheme,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flux/theme.dart';
|
import 'package:flux/theme/theme.dart';
|
||||||
|
|
||||||
class AnagraficheMainView extends StatelessWidget {
|
class AnagraficheMainView extends StatelessWidget {
|
||||||
const AnagraficheMainView({super.key});
|
const AnagraficheMainView({super.key});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flux/theme.dart';
|
import 'package:flux/theme/theme.dart';
|
||||||
|
|
||||||
class DashboardView extends StatelessWidget {
|
class DashboardView extends StatelessWidget {
|
||||||
const DashboardView({super.key});
|
const DashboardView({super.key});
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flux/theme.dart';
|
import 'package:flux/theme/theme.dart';
|
||||||
|
import 'package:flux/theme/theme_bloc.dart';
|
||||||
import 'package:flux/ui/anagrafiche/anagrafiche_main_view.dart';
|
import 'package:flux/ui/anagrafiche/anagrafiche_main_view.dart';
|
||||||
import 'package:flux/ui/dashboard/dashboard_view.dart';
|
import 'package:flux/ui/dashboard/dashboard_view.dart';
|
||||||
import 'package:flux/ui/settings/settings_view.dart';
|
import 'package:flux/ui/settings/settings_view.dart';
|
||||||
@@ -29,38 +31,46 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return BlocBuilder<ThemeBloc, ThemeState>(
|
||||||
body: Center(child: _widgetOptions.elementAt(_selectedIndex)),
|
builder: (context, state) {
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
return Scaffold(
|
||||||
items: const <BottomNavigationBarItem>[
|
body: Center(child: _widgetOptions.elementAt(_selectedIndex)),
|
||||||
BottomNavigationBarItem(
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
icon: Icon(Icons.dashboard_outlined),
|
items: const <BottomNavigationBarItem>[
|
||||||
activeIcon: Icon(Icons.dashboard),
|
BottomNavigationBarItem(
|
||||||
label: 'Dashboard',
|
icon: Icon(Icons.dashboard_outlined),
|
||||||
|
activeIcon: Icon(Icons.dashboard),
|
||||||
|
label: 'Dashboard',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.history_edu_outlined),
|
||||||
|
activeIcon: Icon(Icons.history_edu),
|
||||||
|
label: 'Operazioni',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.people_alt_outlined),
|
||||||
|
activeIcon: Icon(Icons.people_alt),
|
||||||
|
label: 'Anagrafiche',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.settings_outlined),
|
||||||
|
activeIcon: Icon(Icons.settings),
|
||||||
|
label: 'Impostazioni',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
currentIndex: _selectedIndex,
|
||||||
|
selectedItemColor: FluxColors.accentTurquoise,
|
||||||
|
unselectedItemColor: state.themeMode == ThemeMode.dark
|
||||||
|
? FluxColors.darkTextSecondary
|
||||||
|
: FluxColors.lightTextSecondary,
|
||||||
|
backgroundColor: state.themeMode == ThemeMode.dark
|
||||||
|
? FluxColors.darkSurface
|
||||||
|
: FluxColors.lightSurface,
|
||||||
|
type: BottomNavigationBarType.fixed,
|
||||||
|
onTap: _onItemTapped,
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
);
|
||||||
icon: Icon(Icons.history_edu_outlined),
|
},
|
||||||
activeIcon: Icon(Icons.history_edu),
|
|
||||||
label: 'Operazioni',
|
|
||||||
),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(Icons.people_alt_outlined),
|
|
||||||
activeIcon: Icon(Icons.people_alt),
|
|
||||||
label: 'Anagrafiche',
|
|
||||||
),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(Icons.settings_outlined),
|
|
||||||
activeIcon: Icon(Icons.settings),
|
|
||||||
label: 'Impostazioni',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentIndex: _selectedIndex,
|
|
||||||
selectedItemColor: FluxColors.accentTurquoise,
|
|
||||||
unselectedItemColor: FluxColors.textSecondary,
|
|
||||||
backgroundColor: FluxColors.surface,
|
|
||||||
type: BottomNavigationBarType.fixed,
|
|
||||||
onTap: _onItemTapped,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
lib/ui/settings/settings.dart
Normal file
39
lib/ui/settings/settings.dart
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import 'package:flux/theme/theme_bloc.dart';
|
||||||
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class AppSettings {
|
||||||
|
late AppTheme _appTheme;
|
||||||
|
late SharedPreferences _prefs;
|
||||||
|
|
||||||
|
// Singleton
|
||||||
|
|
||||||
|
static final AppSettings _instance = AppSettings._internal();
|
||||||
|
|
||||||
|
factory AppSettings() {
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSettings._internal() {
|
||||||
|
_prefs = GetIt.I.get<SharedPreferences>();
|
||||||
|
String theme = _prefs.getString('theme') ?? 'light';
|
||||||
|
switch (theme) {
|
||||||
|
case 'dark':
|
||||||
|
_appTheme = AppTheme.dark;
|
||||||
|
break;
|
||||||
|
case 'light':
|
||||||
|
_appTheme = AppTheme.light;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_appTheme = AppTheme.system;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppTheme get appTheme => _appTheme;
|
||||||
|
|
||||||
|
void setAppTheme(AppTheme theme) {
|
||||||
|
_appTheme = theme;
|
||||||
|
_prefs.setString('theme', theme.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// lib/ui/impostazioni/impostazioni_view.dart
|
// lib/ui/impostazioni/impostazioni_view.dart
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flux/theme.dart';
|
import 'package:flux/theme/theme.dart';
|
||||||
|
|
||||||
class SettingsView extends StatelessWidget {
|
class SettingsView extends StatelessWidget {
|
||||||
const SettingsView({super.key});
|
const SettingsView({super.key});
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.28.0"
|
version: "0.28.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
|
sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ dependencies:
|
|||||||
get_it: ^9.2.1
|
get_it: ^9.2.1
|
||||||
google_fonts: ^8.0.2
|
google_fonts: ^8.0.2
|
||||||
intl: ^0.20.2
|
intl: ^0.20.2
|
||||||
|
shared_preferences: ^2.5.5
|
||||||
supabase_flutter: ^2.12.2
|
supabase_flutter: ^2.12.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user