update
This commit is contained in:
parent
5164d55905
commit
6f54a6f9fc
65 changed files with 313 additions and 137 deletions
|
|
@ -7,7 +7,7 @@ import 'package:pharmacy_mobile/pages/add_stock_page.dart';
|
|||
import 'package:pharmacy_mobile/pages/add_type_page.dart';
|
||||
import 'package:pharmacy_mobile/pages/customer_page.dart';
|
||||
import 'package:pharmacy_mobile/pages/delete_stock_page.dart';
|
||||
import 'package:pharmacy_mobile/pages/list_stocks.dart';
|
||||
import 'package:pharmacy_mobile/pages/list_stocks_page.dart';
|
||||
import 'package:pharmacy_mobile/pages/login_page.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pharmacy_mobile/pages/main_page.dart';
|
||||
|
|
@ -95,10 +95,10 @@ final _router = GoRouter(
|
|||
],
|
||||
);
|
||||
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp.router(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
|
@ -19,6 +22,7 @@ import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
|||
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
|
||||
class AddMedicinePage extends StatefulWidget {
|
||||
const AddMedicinePage({super.key});
|
||||
|
|
@ -66,6 +70,17 @@ class _AddMedicinePageState extends State<AddMedicinePage> {
|
|||
}
|
||||
}
|
||||
|
||||
// Future<Uint8List> compressFile(XFile file) async {
|
||||
// var result = await FlutterImageCompress.compressWithFile(
|
||||
// file.path,
|
||||
// minWidth: 1020,
|
||||
// minHeight: 765,
|
||||
// quality: 90,
|
||||
// format: CompressFormat.webp,
|
||||
// );
|
||||
// return result;
|
||||
// }
|
||||
|
||||
void _getGenerics() async {
|
||||
_genericNameList = await _refGenericNames.getList();
|
||||
_checkResult(_genericNameList, 'Generics');
|
||||
|
|
@ -155,7 +170,7 @@ class _AddMedicinePageState extends State<AddMedicinePage> {
|
|||
return;
|
||||
}
|
||||
|
||||
imageUrl = await _storage.uploadImage(storageName, image, '$imageName.webp');
|
||||
imageUrl = await _storage.uploadImage(context, storageName, image, '$imageName.webp');
|
||||
|
||||
setState(() {
|
||||
if (imageUrl.isEmpty) {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ class _CustomerPageState extends State<CustomerPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<Widget> bottomBarPages = [
|
||||
CustomerMainPage(
|
||||
controller: _notchController,
|
||||
),
|
||||
const CustomerMainPage(),
|
||||
const CustomerSearchPage(),
|
||||
const CustomerCartPage(),
|
||||
const CustomerProfilePage()
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:gap/gap.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';
|
||||
import 'package:pharmacy_mobile/widgets/menu_widget2.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/title_widget.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
|
||||
|
||||
class CustomerMainPage extends StatefulWidget {
|
||||
final NotchBottomBarController? controller;
|
||||
const CustomerMainPage({super.key, this.controller});
|
||||
// final NotchBottomBarController? controller;
|
||||
const CustomerMainPage({super.key});
|
||||
|
||||
@override
|
||||
State<CustomerMainPage> createState() => _CustomerMainPageState();
|
||||
|
|
@ -44,10 +42,12 @@ class _CustomerMainPageState extends State<CustomerMainPage> {
|
|||
const Gap(32),
|
||||
const TextWidget(text: 'Menu'),
|
||||
const Gap(16),
|
||||
MenuWidget(
|
||||
icon: FontAwesomeIcons.eraser,
|
||||
text: 'Remove Stock',
|
||||
MenuWidget2(
|
||||
// icon: FontAwesomeIcons.diagramNext,
|
||||
text: 'Diagnose by ',
|
||||
description: 'aaa',
|
||||
onPressed: () => {context.push('/deletestock')},
|
||||
color: 'green',
|
||||
),
|
||||
const Gap(32),
|
||||
ButtonWidget(text: 'Log Out', onPressed: signOut)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,73 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:pharmacy_mobile/tables/ref_medicines.dart';
|
||||
import 'package:pharmacy_mobile/tables/storage.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/text_widget.dart';
|
||||
import 'package:pharmacy_mobile/widgets/title_widget.dart';
|
||||
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
|
||||
|
||||
class CustomerSearchPage extends StatelessWidget {
|
||||
final NotchBottomBarController? controller;
|
||||
const CustomerSearchPage({super.key, this.controller});
|
||||
class CustomerSearchPage extends StatefulWidget {
|
||||
// final NotchBottomBarController? controller;
|
||||
// final
|
||||
const CustomerSearchPage({super.key});
|
||||
|
||||
@override
|
||||
State<CustomerSearchPage> createState() => _CustomerSearchPageState();
|
||||
}
|
||||
|
||||
class _CustomerSearchPageState extends State<CustomerSearchPage> {
|
||||
final _searchController = TextEditingController();
|
||||
final _storage = Storage();
|
||||
final _refMedicines = RefMedicines();
|
||||
late String imageUrl = '';
|
||||
// List<String> imageUrl = [];
|
||||
|
||||
void getURL() async {
|
||||
final image = await _storage.getPublicURL('ref_medicines_images', 'cb6eafdb-d86f-460a-9571-44446570d4cb.webp');
|
||||
log(image);
|
||||
setState(() {
|
||||
imageUrl = image;
|
||||
});
|
||||
|
||||
final meds = await _refMedicines.getList2();
|
||||
log(meds.toString());
|
||||
}
|
||||
|
||||
// void getURLs() async {
|
||||
// try {
|
||||
// for (int i = 1; i <= 4; i++) {
|
||||
// final image = await _storage.getPublicURL(
|
||||
// context,
|
||||
// 'ref_medicines_images',
|
||||
// 'ca3e2949-4964-4d25-a274-2a18608b7bdb.webp', // Replace with your actual image path
|
||||
// );
|
||||
// log(image);
|
||||
// setState(() {
|
||||
// imageUrl.add(image);
|
||||
// });
|
||||
// }
|
||||
// } catch (e, stackTrace) {
|
||||
// log('Error getting URLs: $e', stackTrace: stackTrace);
|
||||
// }
|
||||
// }
|
||||
|
||||
void _filterList() {}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
getURL();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.dispose();
|
||||
imageUrl = '';
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -24,8 +84,36 @@ class CustomerSearchPage extends StatelessWidget {
|
|||
logoSize: 90,
|
||||
),
|
||||
const Gap(32),
|
||||
const TextWidget(text: 'Search'),
|
||||
const Gap(16),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32),
|
||||
child: Column(
|
||||
children: [
|
||||
InputWidget(label: '', controller: _searchController),
|
||||
const Gap(8),
|
||||
ButtonWidget(
|
||||
text: 'Search',
|
||||
onPressed: _filterList,
|
||||
width: 160,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Gap(32),
|
||||
Center(
|
||||
child: imageUrl.isNotEmpty
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12), // Add your desired border radius here
|
||||
child: Image.network(imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
width: 250,
|
||||
height: 250,
|
||||
cacheWidth: (250 * MediaQuery.of(context).devicePixelRatio).round()))
|
||||
: const CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 4,
|
||||
padding: EdgeInsets.all(8),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:pharmacy_mobile/widgets/button_widget.dart';
|
||||
import 'package:pharmacy_mobile/widgets/logo_widget.dart';
|
||||
import 'package:pharmacy_mobile/widgets/page_background_widget.dart';
|
||||
import 'package:pharmacy_mobile/widgets/slogan_widget.dart';
|
||||
import 'package:pharmacy_mobile/widgets/text_widget.dart';
|
||||
|
|
@ -29,8 +28,8 @@ class IndexPage extends StatelessWidget {
|
|||
const Gap(88),
|
||||
const TitleWidget(
|
||||
firstTextSize: 24,
|
||||
secondTextSize: 32,
|
||||
logoSize: 90,
|
||||
secondTextSize: 40,
|
||||
logoSize: 124,
|
||||
),
|
||||
const Gap(32),
|
||||
Padding(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class RefMedicines {
|
||||
final SupabaseClient _supabase = Supabase.instance.client;
|
||||
|
|
@ -17,14 +16,20 @@ class RefMedicines {
|
|||
return data.toList();
|
||||
}
|
||||
|
||||
Future<List> getListWithUUID() async {
|
||||
final data = await _supabase
|
||||
.from('ref_medicines')
|
||||
.select('ref_medicines_uuid, medicine_name')
|
||||
.order('medicine_name', ascending: true);
|
||||
return data.toList();
|
||||
}
|
||||
|
||||
Future<String> getUUID(String name) async {
|
||||
final data = await _supabase.from('ref_medicines').select('ref_medicines_uuid').eq('medicine_name', name);
|
||||
return data.first['ref_medicines_uuid'];
|
||||
}
|
||||
|
||||
Future<void> postMedicine(String uuid, String name, String muuid, String guuid, String tuuid) async {
|
||||
// final uuid = Uuid().v4();
|
||||
|
||||
final medicine = {
|
||||
'ref_medicines_uuid': uuid,
|
||||
'medicine_name': name,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:pharmacy_mobile/widgets/snackbar_widget.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
class Storage {
|
||||
|
|
@ -39,7 +42,7 @@ class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> uploadImage(String storage, XFile image, String name) async {
|
||||
Future<String> uploadImage(BuildContext context, String storage, XFile image, String name) async {
|
||||
try {
|
||||
final imageBytes = await image.readAsBytes();
|
||||
final imagePath = name;
|
||||
|
|
@ -48,8 +51,19 @@ class Storage {
|
|||
final imageUrl = _supabase.storage.from(storage).getPublicUrl(imagePath);
|
||||
return imageUrl;
|
||||
} catch (e) {
|
||||
log('Error uploading image: $e');
|
||||
// ignore: use_build_context_synchronously
|
||||
showNotification(context, 'Error uploading image: $e', false);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> downloadImage(String storage, String name) async {
|
||||
final Uint8List file = await _supabase.storage.from(storage).download(name);
|
||||
return file;
|
||||
}
|
||||
|
||||
Future<String> getPublicURL(String storage, String name) async {
|
||||
final String file = _supabase.storage.from(storage).getPublicUrl(name);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ class ButtonWidget extends StatelessWidget {
|
|||
final String text;
|
||||
final VoidCallback onPressed;
|
||||
final bool? outline;
|
||||
final double? width;
|
||||
|
||||
const ButtonWidget({super.key, required this.text, required this.onPressed, this.outline});
|
||||
const ButtonWidget({super.key, required this.text, required this.onPressed, this.outline, this.width});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -30,8 +31,10 @@ class ButtonWidget extends StatelessWidget {
|
|||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20), // rounded corners
|
||||
),
|
||||
minimumSize: Size(MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320,
|
||||
44), // minimum size
|
||||
minimumSize: Size(
|
||||
width ?? (MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320),
|
||||
44),
|
||||
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
),
|
||||
onPressed: onPressed,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ class _DatePickerWidgetState extends State<DatePickerWidget> {
|
|||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16),
|
||||
decoration: BoxDecoration(
|
||||
// border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
|
||||
border: Border.all(color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.transparent,
|
||||
|
|
|
|||
|
|
@ -16,16 +16,17 @@ class InputWidget extends StatelessWidget {
|
|||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('$label:',
|
||||
style: GoogleFonts.outfit(
|
||||
textStyle:
|
||||
const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 12, fontWeight: FontWeight.w500),
|
||||
)),
|
||||
if (label.isNotEmpty)
|
||||
Text('$label:',
|
||||
style: GoogleFonts.outfit(
|
||||
textStyle:
|
||||
const TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: 12, fontWeight: FontWeight.w500),
|
||||
)),
|
||||
const Gap(8),
|
||||
TextField(
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
filled: true, // Enable filling the background
|
||||
filled: true,
|
||||
fillColor: const Color.fromRGBO(255, 255, 255, 1),
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 24)),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class MenuWidget2 extends StatelessWidget {
|
|||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
gradient: LinearGradient(
|
||||
colors: _getColorList(color!),
|
||||
colors: _getColorList(color ?? ''),
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue