diff --git a/lib/main.dart b/lib/main.dart index 1ed5997..76ef74c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:pharmacy_mobile/pages/add_generics.dart'; import 'package:pharmacy_mobile/pages/add_medicine.dart'; // import 'package:pharmacy_mobile/auth/auth_gate.dart'; import 'package:pharmacy_mobile/pages/index_page.dart'; @@ -55,6 +56,11 @@ final _router = GoRouter( path: '/addmedicines', builder: (context, state) => AddMedicinePage(), ), + GoRoute( + name: 'addgenerics', + path: '/addgenerics', + builder: (context, state) => AddGenericsPage(), + ), ], ); diff --git a/lib/pages/add_generics.dart b/lib/pages/add_generics.dart new file mode 100644 index 0000000..a6d43e7 --- /dev/null +++ b/lib/pages/add_generics.dart @@ -0,0 +1,82 @@ +import 'dart:developer'; +import 'package:gap/gap.dart'; +import 'package:flutter/material.dart'; +// import 'package:pharmacy_mobile/auth/auth_service.dart'; +import 'package:pharmacy_mobile/tables/ref_categories.dart'; +import 'package:pharmacy_mobile/widgets/button_widget.dart'; +import 'package:pharmacy_mobile/widgets/dropdown_widget.dart'; +import 'package:pharmacy_mobile/widgets/input_widget.dart'; +import 'package:pharmacy_mobile/widgets/text_widget.dart'; +import 'package:pharmacy_mobile/widgets/title_widget.dart'; + +class AddGenericsPage extends StatefulWidget { + const AddGenericsPage({super.key}); + + @override + AddGenericsPageState createState() => AddGenericsPageState(); +} + +class AddGenericsPageState extends State { + // final _formKey = GlobalKey(); + final _refCategories = RefCategories(); + final _nameController = TextEditingController(); + late List _categoryList; + + @override + void initState() { + autoRun(); + super.initState(); + } + + void autoRun() async { + _categoryList = await _refCategories.getList(); + } + + void saveData() async {} + + @override + void dispose() { + _nameController.dispose(); + _categoryList = []; + // _genericNameController.dispose(); + // _typeController.dispose(); + // _manufactorerController.dispose(); + // _focusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + alignment: Alignment.center, + height: MediaQuery.of(context).size.height, + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [ + Color.fromRGBO(34, 51, 69, 1), + Color.fromRGBO(22, 32, 44, 1), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: Center( + child: Column( + children: [ + const Gap(120), + const TitleWidget(firstTextSize: 16, secondTextSize: 32), + const Gap(32), + const TextWidget(text: 'Add Generics'), + const Gap(16), + InputWidget(label: 'Name', controller: _nameController), + const Gap(16), + DropDownWidget(label: 'Category', list: _categoryList, listTitle: 'category_name'), + const Gap(16), + ButtonWidget(text: 'Add', onPressed: saveData) + ], + )), + ), + ); + } +} diff --git a/lib/pages/add_medicine.dart b/lib/pages/add_medicine.dart index 6d1788d..4b51e2e 100644 --- a/lib/pages/add_medicine.dart +++ b/lib/pages/add_medicine.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; -import 'package:google_fonts/google_fonts.dart'; +import 'package:pharmacy_mobile/widgets/input_widget.dart'; +// import 'package:google_fonts/google_fonts.dart'; import 'package:pharmacy_mobile/widgets/text_widget.dart'; import 'package:pharmacy_mobile/widgets/title_widget.dart'; @@ -12,6 +13,29 @@ class AddMedicinePage extends StatefulWidget { } class AddMedicinePageState extends State { + final _formKey = GlobalKey(); + // final _authService = AuthService(); + final _nameController = TextEditingController(); + final _genericNameController = TextEditingController(); + final _typeController = TextEditingController(); + final _manufactorerController = TextEditingController(); + final FocusNode _focusNode = FocusNode(); + + // @override + // void initState() { + // super.initState(); + // } + + @override + void dispose() { + _nameController.dispose(); + _genericNameController.dispose(); + _typeController.dispose(); + _manufactorerController.dispose(); + _focusNode.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -36,6 +60,15 @@ class AddMedicinePageState extends State { const Gap(32), const TextWidget(text: 'Add Medicine'), const Gap(16), + Form( + key: _formKey, + child: Center( + child: Column( + children: [ + InputWidget(label: 'Name', controller: _nameController), + ], + ), + )) ], ), ), diff --git a/lib/pages/index_page.dart b/lib/pages/index_page.dart index c3efd06..eb2fd72 100644 --- a/lib/pages/index_page.dart +++ b/lib/pages/index_page.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:google_fonts/google_fonts.dart'; +// import 'package:google_fonts/google_fonts.dart'; import 'package:gap/gap.dart'; import 'package:pharmacy_mobile/widgets/button_widget.dart'; +import 'package:pharmacy_mobile/widgets/text_widget.dart'; +import 'package:pharmacy_mobile/widgets/title_widget.dart'; class IndexPage extends StatelessWidget { const IndexPage({super.key}); @@ -21,8 +23,9 @@ class IndexPage extends StatelessWidget { decoration: const BoxDecoration( gradient: LinearGradient( colors: [ - Color.fromRGBO(34, 51, 69, 1), - Color.fromRGBO(22, 32, 44, 1), + Color.fromRGBO(165, 105, 189, 1), + Color.fromRGBO(142, 68, 173, 1), + Color.fromRGBO(165, 105, 189, 1), ], begin: Alignment.topCenter, end: Alignment.bottomCenter, @@ -33,20 +36,18 @@ class IndexPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ const Gap(120), - Text('Ofelia Franco-Alcala', - style: GoogleFonts.outfit( - textStyle: const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 32))), - Text('Pharmacy', - style: GoogleFonts.outfit( - textStyle: const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 40))), + const TitleWidget(firstTextSize: 32, secondTextSize: 40), const Gap(32), Padding( padding: const EdgeInsets.fromLTRB(0, 0, 16, 0), child: Image.asset('assets/ph_logo.webp', - width: 256, cacheWidth: (256 * MediaQuery.of(context).devicePixelRatio).round()), + width: 200, cacheWidth: (200 * MediaQuery.of(context).devicePixelRatio).round()), ), const Gap(32), - ButtonWidget(text: 'Login', onPressed: gotoLogin) + ButtonWidget(text: 'Login', onPressed: gotoLogin), + const MaxGap(500), + const TextWidget(text: 'Copyright © 2025 - Ofelia Franco-Alcala Pharmacy', size: 14), + const TextWidget(text: 'Developed By: Pat Alcala', size: 12) ], ), ), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index a6ff9d6..ca04212 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,14 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'package:gap/gap.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/text_widget.dart'; import 'package:pharmacy_mobile/widgets/title_widget.dart'; -import 'dart:developer'; import 'package:quickalert/quickalert.dart'; class LoginPage extends StatefulWidget { @@ -62,6 +60,7 @@ class _LoginPageState extends State { void dispose() { _emailController.dispose(); _passwordController.dispose(); + _focusNode.dispose(); super.dispose(); } @@ -99,15 +98,8 @@ class _LoginPageState extends State { child: Form( child: Column( children: [ - TextFormField( - controller: _emailController, - decoration: const InputDecoration( - labelText: 'Email', - border: OutlineInputBorder(), - ), - style: const TextStyle(color: Colors.white), - ), - const Gap(8), + InputWidget(label: 'Email', controller: _emailController), + const Gap(16), KeyboardListener( focusNode: _focusNode, onKeyEvent: (event) { @@ -115,17 +107,9 @@ class _LoginPageState extends State { _signIn(); } }, - child: TextFormField( - obscureText: true, - controller: _passwordController, - decoration: const InputDecoration( - labelText: 'Password', - border: OutlineInputBorder(), - ), - style: const TextStyle(color: Colors.white), - ), + child: InputWidget(label: 'Password', controller: _passwordController, password: true,), ), - const Gap(16), + const Gap(24), // TextButton(onPressed: () => {_signIn()}, child: const Text('Login')) ButtonWidget(text: 'Login', onPressed: _signIn) ], diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 9d26d3f..bf8a166 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'package:pharmacy_mobile/auth/auth_service.dart'; import 'package:pharmacy_mobile/widgets/button_widget.dart'; import 'package:pharmacy_mobile/widgets/menu_widget.dart'; @@ -25,6 +24,10 @@ class MainPage extends StatelessWidget { context.push('/addmedicines'); } + void gotoAddGenerics() { + context.push('/addgenerics'); + } + return Scaffold( body: Container( alignment: Alignment.center, @@ -56,6 +59,7 @@ class MainPage extends StatelessWidget { MenuWidget( icon: FontAwesomeIcons.squarePlus, text: 'Add Generics', + onPressed: gotoAddGenerics, ), const Gap(16), MenuWidget( diff --git a/lib/tables/ref_categories.dart b/lib/tables/ref_categories.dart new file mode 100644 index 0000000..183f85f --- /dev/null +++ b/lib/tables/ref_categories.dart @@ -0,0 +1,15 @@ +import 'package:supabase_flutter/supabase_flutter.dart'; + +class RefCategories { + final SupabaseClient _supabase = Supabase.instance.client; + + Future getList() async { + final data = await _supabase.from('ref_categories').select('category_name').order('category_name', ascending: true); + return data.toList(); + } + + Future getUUID(String name) async { + final data = await _supabase.from('ref_categories').select('ref_categories_uuid').eq('category_name', name); + return data.toString(); + } +} diff --git a/lib/widgets/button_widget.dart b/lib/widgets/button_widget.dart index 6fd2478..5f442c2 100644 --- a/lib/widgets/button_widget.dart +++ b/lib/widgets/button_widget.dart @@ -12,8 +12,8 @@ class ButtonWidget extends StatelessWidget { Widget build(BuildContext context) { return TextButton( style: TextButton.styleFrom( - foregroundColor: Colors.white, // text color - backgroundColor: const Color.fromARGB(255, 54, 140, 136), // background color + foregroundColor: Color(0xFF8E44AD), // text color + backgroundColor: const Color(0xFFE8DAEF), // background color side: const BorderSide(color: Color.fromARGB(55, 255, 255, 255)), // border color shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(26), // rounded corners diff --git a/lib/widgets/dropdown_widget.dart b/lib/widgets/dropdown_widget.dart new file mode 100644 index 0000000..952e49f --- /dev/null +++ b/lib/widgets/dropdown_widget.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class DropDownWidget extends StatelessWidget { + final String label; + final List list; + final String listTitle; + const DropDownWidget({super.key, required this.label, required this.list, required this.listTitle}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, + style: GoogleFonts.outfit( + textStyle: const TextStyle(color: Colors.white, fontSize: 16), + )), + const Gap(8), + DropdownMenu( + initialSelection: '', + dropdownMenuEntries: [ + for (var item in list) DropdownMenuEntry(label: item[listTitle].toString(), value: item[listTitle]) + ], + textStyle: TextStyle(color: Colors.white), + ), + + // DropdownButton( + // isExpanded: true, + // value: list, + // onChanged: (_) {}, + // items: list.map((item) { + // return DropdownMenuItem( + // value: item, + // child: Text(item, overflow: TextOverflow.ellipsis, maxLines: 1), + // ); + // }).toList(), + // ), + ], + ); + } +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart new file mode 100644 index 0000000..6f1d1a4 --- /dev/null +++ b/lib/widgets/input_widget.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class InputWidget extends StatelessWidget { + final String label; + final TextEditingController controller; + final bool? password; + + const InputWidget({super.key, required this.label, required this.controller, this.password}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, + style: GoogleFonts.outfit( + textStyle: const TextStyle(color: Colors.white, fontSize: 16), + )), + const Gap(8), + TextField( + controller: controller, + decoration: InputDecoration( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), + ), + style: GoogleFonts.outfit(textStyle: TextStyle(color: Colors.white, fontSize: 16)), + obscureText: password ?? false, + ), + ], + ); + } +} diff --git a/lib/widgets/text_widget.dart b/lib/widgets/text_widget.dart index 9bd7e10..0d3053b 100644 --- a/lib/widgets/text_widget.dart +++ b/lib/widgets/text_widget.dart @@ -3,12 +3,13 @@ import 'package:google_fonts/google_fonts.dart'; class TextWidget extends StatelessWidget { final String text; + final double? size; - const TextWidget({super.key, required this.text}); + const TextWidget({super.key, required this.text, this.size}); @override Widget build(BuildContext context) { return Text(text, - style: GoogleFonts.outfit(textStyle: const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 32))); + style: GoogleFonts.outfit(textStyle: TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: size ?? 32))); } }