update
This commit is contained in:
parent
cf2ce36f87
commit
50d2cba7f2
9 changed files with 156 additions and 83 deletions
|
|
@ -90,16 +90,9 @@ class MyApp extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
// initialRoute: '/',
|
theme: ThemeData(
|
||||||
// routes: {
|
useMaterial3: true,
|
||||||
// '/': (context) => const IndexPage(),
|
),
|
||||||
// '/login': (context) => const LoginPage(),
|
|
||||||
// },
|
|
||||||
// debugShowCheckedModeBanner: false,
|
|
||||||
// theme: ThemeData(
|
|
||||||
// colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
|
||||||
// useMaterial3: true,
|
|
||||||
// )
|
|
||||||
routerConfig: _router,
|
routerConfig: _router,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:pharmacy_mobile/tables/stocks.dart';
|
import 'package:pharmacy_mobile/tables/stocks.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/datatable_widget.dart';
|
import 'package:pharmacy_mobile/widgets/datatable_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
class ListStocksPage extends StatefulWidget {
|
class ListStocksPage extends StatefulWidget {
|
||||||
const ListStocksPage({super.key});
|
const ListStocksPage({super.key});
|
||||||
|
|
@ -20,18 +18,36 @@ class _ListStocksPageState extends State<ListStocksPage> {
|
||||||
final _stocks = Stocks();
|
final _stocks = Stocks();
|
||||||
|
|
||||||
late List _stockList = [];
|
late List _stockList = [];
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
List<DataRow> _createRows() {
|
List<DataRow> _createRows() {
|
||||||
|
final today = DateTime.now().toUtc();
|
||||||
|
|
||||||
return _stockList.map((item) {
|
return _stockList.map((item) {
|
||||||
final dateString = item['expiration_date'];
|
final dateString = item['expiration_date'];
|
||||||
final date = DateTime.parse(dateString);
|
final date = DateTime.parse(dateString).toUtc();
|
||||||
final formattedDate = DateFormat('MMMM d, yyyy').format(date);
|
final formattedDate = DateFormat('MMMM d, yyyy').format(date);
|
||||||
|
|
||||||
return DataRow(cells: [
|
if (date.isBefore(today)) {
|
||||||
DataCell(Text(item['medicine_name'])),
|
return DataRow(
|
||||||
DataCell(Text(item['quantity'].toString())),
|
cells: [
|
||||||
DataCell(Text(formattedDate)),
|
DataCell(Text(item['medicine_name'], style: const TextStyle(color: Color.fromRGBO(188, 59, 50, 1)))),
|
||||||
]);
|
DataCell(Text(item['quantity'].toString(), style: const TextStyle(color: Color.fromRGBO(188, 59, 50, 1)))),
|
||||||
|
DataCell(
|
||||||
|
Text(formattedDate,
|
||||||
|
style: const TextStyle(color: Color.fromRGBO(188, 59, 50, 1))), // Highlight expired items
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(Text(item['medicine_name'])),
|
||||||
|
DataCell(Text(item['quantity'].toString())),
|
||||||
|
DataCell(Text(formattedDate)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,8 +60,13 @@ class _ListStocksPageState extends State<ListStocksPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void autoRun() async {
|
void autoRun() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
_stockList = await _stocks.getList();
|
_stockList = await _stocks.getList();
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -63,14 +84,27 @@ class _ListStocksPageState extends State<ListStocksPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: PageBackgroundWidget(
|
body: PageBackgroundWidget(
|
||||||
child: Column(children: [
|
child: Column(
|
||||||
const Gap(104),
|
children: [
|
||||||
const TitleWidget(firstTextSize: 20, secondTextSize: 32),
|
const Gap(104),
|
||||||
const Gap(32),
|
const TitleWidget(firstTextSize: 20, secondTextSize: 32),
|
||||||
const TextWidget(text: 'List of Stocks'),
|
const Gap(32),
|
||||||
const Gap(16),
|
const TextWidget(text: 'List of Stocks'),
|
||||||
DataTableWidget(column: _createColumns(), row: _createRows()),
|
const Gap(16),
|
||||||
])));
|
if (_isLoading)
|
||||||
|
Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: Colors.white,
|
||||||
|
))
|
||||||
|
else
|
||||||
|
DataTableWidget(
|
||||||
|
column: _createColumns(),
|
||||||
|
row: _createRows(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:pharmacy_mobile/auth/auth_service.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/button_widget.dart';
|
import 'package:pharmacy_mobile/widgets/button_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/input_widget.dart';
|
import 'package:pharmacy_mobile/widgets/input_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
||||||
|
import 'package:pharmacy_mobile/widgets/snackbar_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
||||||
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
||||||
|
|
@ -37,13 +38,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
if (await InternetConnectionChecker.instance.hasConnection) {
|
if (await InternetConnectionChecker.instance.hasConnection) {
|
||||||
await _authService.signIn(email, password);
|
await _authService.signIn(email, password);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
showNotification(context, 'Login Successful', true);
|
||||||
content: Text('Login Successful'),
|
|
||||||
backgroundColor: const Color.fromRGBO(37, 106, 32, 1),
|
|
||||||
elevation: 4.0,
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
duration: Duration(seconds: 5),
|
|
||||||
));
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
@ -53,24 +48,12 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
showNotification(context, 'Error: No Internet Connection', false);
|
||||||
content: Text('No Internet Connection'),
|
|
||||||
backgroundColor: const Color.fromRGBO(188, 59, 50, 1),
|
|
||||||
elevation: 4.0,
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
duration: Duration(seconds: 5),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
showNotification(context, 'Error: $e', false);
|
||||||
content: Text('Error: $e'),
|
|
||||||
backgroundColor: const Color.fromRGBO(188, 59, 50, 1),
|
|
||||||
elevation: 4.0,
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
duration: Duration(seconds: 5),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isLoading = false);
|
setState(() => _isLoading = false);
|
||||||
|
|
@ -110,7 +93,8 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(32, 32, 32, 40),
|
padding: EdgeInsets.fromLTRB(32, 32, 32, 40),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color.fromRGBO(38, 17, 46, 0.859),
|
// color: const Color.fromRGBO(38, 17, 46, 0.859),
|
||||||
|
color: const Color.fromRGBO(57, 38, 62, 0.9),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:pharmacy_mobile/auth/auth_service.dart';
|
import 'package:pharmacy_mobile/auth/auth_service.dart';
|
||||||
import 'package:pharmacy_mobile/main.dart';
|
import 'package:pharmacy_mobile/widgets/button_widget.dart';
|
||||||
|
import 'package:pharmacy_mobile/widgets/input_widget.dart';
|
||||||
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
||||||
|
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
||||||
|
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
||||||
|
|
||||||
class RegisterPage extends StatefulWidget {
|
class RegisterPage extends StatefulWidget {
|
||||||
const RegisterPage({super.key});
|
const RegisterPage({super.key});
|
||||||
|
|
@ -17,6 +19,9 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
final _emailController = TextEditingController();
|
final _emailController = TextEditingController();
|
||||||
final _passwordController = TextEditingController();
|
final _passwordController = TextEditingController();
|
||||||
final _confirmPasswordController = TextEditingController();
|
final _confirmPasswordController = TextEditingController();
|
||||||
|
final FocusNode _focusNode = FocusNode();
|
||||||
|
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
Future<void> _signUp() async {
|
Future<void> _signUp() async {
|
||||||
final email = _emailController.text;
|
final email = _emailController.text;
|
||||||
|
|
@ -47,6 +52,8 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
_emailController.dispose();
|
_emailController.dispose();
|
||||||
_passwordController.dispose();
|
_passwordController.dispose();
|
||||||
_confirmPasswordController.dispose();
|
_confirmPasswordController.dispose();
|
||||||
|
_focusNode.dispose();
|
||||||
|
_isLoading = false;
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,8 +61,58 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: PageBackgroundWidget(
|
body: PageBackgroundWidget(
|
||||||
child: Column(
|
child: Center(
|
||||||
children: [],
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Gap(104),
|
||||||
|
const TitleWidget(firstTextSize: 20, secondTextSize: 32),
|
||||||
|
const Gap(32),
|
||||||
|
const TextWidget(text: 'Register'),
|
||||||
|
const Gap(16),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 32, right: 32),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(32, 32, 32, 40),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color.fromRGBO(57, 38, 62, 0.9),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color.fromRGBO(0, 0, 0, 0.4), // Subtle shadow to give depth
|
||||||
|
spreadRadius: 0,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
child: Form(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
InputWidget(label: 'Email', controller: _emailController),
|
||||||
|
const Gap(16),
|
||||||
|
InputWidget(
|
||||||
|
label: 'Password',
|
||||||
|
controller: _passwordController,
|
||||||
|
password: true,
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
InputWidget(
|
||||||
|
label: 'Confirm Password',
|
||||||
|
controller: _confirmPasswordController,
|
||||||
|
password: true,
|
||||||
|
),
|
||||||
|
const Gap(40),
|
||||||
|
// TextButton(onPressed: () => {_signIn()}, child: const Text('Login'))
|
||||||
|
if (_isLoading)
|
||||||
|
Center(child: CircularProgressIndicator(color: Colors.white))
|
||||||
|
else
|
||||||
|
ButtonWidget(text: 'Create Account', onPressed: _signUp)
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,29 +13,38 @@ class ButtonWidget extends StatelessWidget {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
style: outline == true
|
style: outline == true
|
||||||
? OutlinedButton.styleFrom(
|
? OutlinedButton.styleFrom(
|
||||||
foregroundColor: Color.fromRGBO(0, 0, 0, 1), // text color
|
foregroundColor: const Color.fromRGBO(0, 0, 0, 1),
|
||||||
side: const BorderSide(color: Color.fromRGBO(79, 51, 94, 1)), // border color
|
backgroundColor: Colors.transparent,
|
||||||
|
side: const BorderSide(color: Color.fromRGBO(198, 133, 232, 1)),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12), // rounded corners
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
minimumSize: Size(MediaQuery.of(context).size.width - 96, 44), // minimum size
|
minimumSize: Size(MediaQuery.of(context).size.width - 96, 44), // minimum size
|
||||||
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||||
)
|
)
|
||||||
: ElevatedButton.styleFrom(
|
: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Color.fromRGBO(0, 0, 0, 1), // text color
|
foregroundColor: const Color.fromRGBO(0, 0, 0, 1), // text color
|
||||||
backgroundColor: const Color.fromRGBO(198, 133, 232, 1), // background color
|
backgroundColor: const Color.fromRGBO(198, 133, 232, 1), // background color
|
||||||
side: const BorderSide(color: Color.fromRGBO(79, 51, 94, 1)), // border color
|
side: const BorderSide(color: Color.fromRGBO(79, 51, 94, 1)), // border color
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12), // rounded corners
|
borderRadius: BorderRadius.circular(12), // rounded corners
|
||||||
),
|
),
|
||||||
minimumSize: Size(MediaQuery.of(context).size.width - 96, 44), // minimum size
|
minimumSize: Size(MediaQuery.of(context).size.width - 96, 44), // minimum size
|
||||||
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Text(
|
child: Text(
|
||||||
text,
|
text,
|
||||||
style: GoogleFonts.outfit(textStyle: const TextStyle(fontSize: 14)),
|
style: _textStyle(outline),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextStyle _textStyle(bool? outline) {
|
||||||
|
if (outline == true) {
|
||||||
|
return GoogleFonts.outfit(textStyle: const TextStyle(fontSize: 14, color: Color.fromRGBO(198, 133, 232, 1)));
|
||||||
|
} else {
|
||||||
|
return GoogleFonts.outfit(textStyle: const TextStyle(fontSize: 14, color: Color.fromRGBO(0, 0, 0, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ class InputWidget extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text('$label:',
|
Text('$label:',
|
||||||
style: GoogleFonts.outfit(
|
style: GoogleFonts.outfit(
|
||||||
textStyle: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500),
|
textStyle:
|
||||||
|
const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 12, fontWeight: FontWeight.w500),
|
||||||
)),
|
)),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
TextField(
|
TextField(
|
||||||
|
|
|
||||||
13
lib/widgets/snackbar_widget.dart
Normal file
13
lib/widgets/snackbar_widget.dart
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
void showNotification(BuildContext context, String text, bool isPositive) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(text),
|
||||||
|
backgroundColor: isPositive ? const Color.fromRGBO(37, 106, 32, 1) : const Color.fromRGBO(188, 59, 50, 1),
|
||||||
|
elevation: 4.0,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
duration: const Duration(seconds: 3),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
18
pubspec.lock
18
pubspec.lock
|
|
@ -57,14 +57,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
bottom_picker:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: bottom_picker
|
|
||||||
sha256: "8ede549685825df389135bebc7984416ed95f24d4f19631d21ad25c9c23db482"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.10.1"
|
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -113,14 +105,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.6"
|
||||||
cupertino_icons:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cupertino_icons
|
|
||||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.8"
|
|
||||||
dbus:
|
dbus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -774,5 +758,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.6.0 <4.0.0"
|
dart: ">=3.6.1 <4.0.0"
|
||||||
flutter: ">=3.27.0"
|
flutter: ">=3.27.0"
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,18 @@ publish_to: "none"
|
||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.6.0
|
sdk: ^3.6.1
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
cupertino_icons: ^1.0.8
|
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
gap: ^3.0.1
|
gap: ^3.0.1
|
||||||
go_router: ^14.6.3
|
go_router: ^14.6.3
|
||||||
supabase_flutter: ^2.8.3
|
supabase_flutter: ^2.8.3
|
||||||
font_awesome_flutter: ^10.8.0
|
font_awesome_flutter: ^10.8.0
|
||||||
uuid: ^4.5.1
|
uuid: ^4.5.1
|
||||||
bottom_picker: ^2.10.1
|
|
||||||
intl: ^0.20.2
|
intl: ^0.20.2
|
||||||
visibility_detector: ^0.4.0+2
|
visibility_detector: ^0.4.0+2
|
||||||
internet_connection_checker: ^3.0.1
|
internet_connection_checker: ^3.0.1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue