You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.3 KiB
Dart
193 lines
5.3 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:expense_planner/widgets/chart.dart';
|
|
import 'package:expense_planner/widgets/new_transaction.dart';
|
|
import 'package:expense_planner/widgets/transaction_list.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'models/transaction.dart';
|
|
|
|
void main() {
|
|
Intl.defaultLocale = 'fr';
|
|
runApp(const MyApp());
|
|
}
|
|
|
|
class MyApp extends StatelessWidget {
|
|
const MyApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'Flutter Demo',
|
|
localizationsDelegates: const [
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
debugShowCheckedModeBanner: false,
|
|
theme: ThemeData(
|
|
primarySwatch: Colors.purple,
|
|
scaffoldBackgroundColor: Colors.grey[200],
|
|
fontFamily: 'Quicksand',
|
|
textTheme: const TextTheme(
|
|
titleMedium: TextStyle(
|
|
fontFamily: 'OpenSans',
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 17,
|
|
),
|
|
),
|
|
appBarTheme: const AppBarTheme(
|
|
centerTitle: true,
|
|
titleTextStyle: TextStyle(
|
|
fontFamily: 'OpenSans',
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
)),
|
|
),
|
|
home: MyHomePage(),
|
|
);
|
|
}
|
|
}
|
|
|
|
class MyHomePage extends StatefulWidget {
|
|
MyHomePage({super.key});
|
|
|
|
@override
|
|
State<MyHomePage> createState() => _MyHomePageState();
|
|
}
|
|
|
|
class _MyHomePageState extends State<MyHomePage> {
|
|
final List<Transaction> _userTransactions = [
|
|
Transaction(
|
|
id: '1',
|
|
title: 'Foo',
|
|
amount: 10,
|
|
date: DateTime.now().subtract(Duration(days: 2))),
|
|
Transaction(
|
|
id: '2',
|
|
title: 'Bar',
|
|
amount: 10,
|
|
date: DateTime.now().subtract(Duration(days: 1))),
|
|
Transaction(
|
|
id: '3',
|
|
title: 'Baz',
|
|
amount: 10,
|
|
date: DateTime.now().subtract(Duration(days: 0))),
|
|
];
|
|
bool _showChart = false;
|
|
|
|
List<Transaction> get _recentTransactions {
|
|
return _userTransactions
|
|
.where((transaction) => transaction.date
|
|
.isAfter(DateTime.now().subtract(Duration(days: 7))))
|
|
.toList();
|
|
}
|
|
|
|
void _addNewTransaction(String title, double amount, DateTime date) {
|
|
final newTransaction = Transaction(
|
|
id: DateTime.now().toString(),
|
|
title: title,
|
|
amount: amount,
|
|
date: date);
|
|
|
|
setState(() {
|
|
_userTransactions.add(newTransaction);
|
|
});
|
|
}
|
|
|
|
void _deleteTransaction(String id) {
|
|
setState(() {
|
|
_userTransactions
|
|
.removeWhere((Transaction transaction) => transaction.id == id);
|
|
});
|
|
}
|
|
|
|
void _startAddNewTransaction(BuildContext ctx) {
|
|
showModalBottomSheet(
|
|
context: ctx,
|
|
builder: (_) {
|
|
return GestureDetector(
|
|
onTap: () {},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: NewTransaction(_addNewTransaction),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final mediaQuery = MediaQuery.of(context);
|
|
|
|
final isLandscape = mediaQuery.orientation == Orientation.landscape;
|
|
|
|
final appBar = AppBar(
|
|
title: const Text(
|
|
'Expense Planner',
|
|
),
|
|
actions: [
|
|
IconButton(
|
|
onPressed: () => _startAddNewTransaction(context),
|
|
icon: const Icon(Icons.add)),
|
|
],
|
|
);
|
|
|
|
final transactionsListWidget = SizedBox(
|
|
height: (mediaQuery.size.height -
|
|
appBar.preferredSize.height -
|
|
mediaQuery.padding.top) *
|
|
0.6,
|
|
child: TransactionList(_userTransactions, _deleteTransaction),
|
|
);
|
|
|
|
final chartWidget = SizedBox(
|
|
height: (mediaQuery.size.height -
|
|
appBar.preferredSize.height -
|
|
mediaQuery.padding.top) *
|
|
(mediaQuery.orientation == Orientation.portrait ? 0.3 : 0.7),
|
|
child: Chart(
|
|
transactions: _recentTransactions,
|
|
),
|
|
);
|
|
|
|
return Scaffold(
|
|
appBar: appBar,
|
|
floatingActionButton: Platform.isIOS
|
|
? Container()
|
|
: FloatingActionButton(
|
|
onPressed: () => _startAddNewTransaction(context),
|
|
child: const Icon(Icons.add),
|
|
),
|
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
|
body: SafeArea(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
if (isLandscape)
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
const Text('Show chart'),
|
|
Switch.adaptive(
|
|
value: _showChart,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
_showChart = newValue;
|
|
});
|
|
}),
|
|
],
|
|
),
|
|
if (!isLandscape) ...[chartWidget, transactionsListWidget],
|
|
if (isLandscape) _showChart ? chartWidget : transactionsListWidget
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|