diff --git a/lib/widgets/store_info_config_dialog.dart b/lib/widgets/store_info_config_dialog.dart index cd61ac0..e0156f3 100644 --- a/lib/widgets/store_info_config_dialog.dart +++ b/lib/widgets/store_info_config_dialog.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:image_picker/image_picker.dart'; +import 'dart:io'; /// Widget untuk dialog konfigurasi informasi toko class StoreInfoConfigDialog extends StatefulWidget { @@ -17,6 +19,12 @@ class _StoreInfoConfigDialogState extends State { final TextEditingController _storeAddressController = TextEditingController(); final TextEditingController _adminNameController = TextEditingController(); final TextEditingController _adminPhoneController = TextEditingController(); + + // Variabel untuk menyimpan path logo + String? _logoPath; + + // Image picker instance + final ImagePicker _picker = ImagePicker(); @override void initState() { @@ -34,6 +42,7 @@ class _StoreInfoConfigDialogState extends State { _storeAddressController.text = prefs.getString('store_address') ?? 'Jl. Merdeka No. 123'; _adminNameController.text = prefs.getString('admin_name') ?? 'Budi Santoso'; _adminPhoneController.text = prefs.getString('admin_phone') ?? '08123456789'; + _logoPath = prefs.getString('store_logo_path'); // Memuat path logo }); } @@ -46,6 +55,12 @@ class _StoreInfoConfigDialogState extends State { await prefs.setString('store_address', _storeAddressController.text); await prefs.setString('admin_name', _adminNameController.text); await prefs.setString('admin_phone', _adminPhoneController.text); + // Menyimpan path logo + if (_logoPath != null) { + await prefs.setString('store_logo_path', _logoPath!); + } else { + await prefs.remove('store_logo_path'); + } if (mounted) { Navigator.of(context).pop(true); // Kembali dengan nilai true jika berhasil disimpan @@ -53,6 +68,31 @@ class _StoreInfoConfigDialogState extends State { } } + /// Fungsi untuk memilih gambar dari gallery + Future _pickImage() async { + try { + final XFile? image = await _picker.pickImage(source: ImageSource.gallery); + if (image != null) { + setState(() { + _logoPath = image.path; + }); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Gagal memilih gambar: $e')), + ); + } + } + } + + /// Fungsi untuk menghapus logo + void _removeLogo() { + setState(() { + _logoPath = null; + }); + } + @override void dispose() { _storeNameController.dispose(); @@ -72,6 +112,57 @@ class _StoreInfoConfigDialogState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ + // Preview logo + if (_logoPath != null) + Column( + children: [ + Container( + height: 100, + width: 100, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(8), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.file( + File(_logoPath!), + fit: BoxFit.contain, + errorBuilder: (context, error, stackTrace) { + return const Icon(Icons.error); + }, + ), + ), + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: _pickImage, + child: const Text('Ganti Logo'), + ), + TextButton( + onPressed: _removeLogo, + child: const Text('Hapus Logo'), + ), + ], + ), + const SizedBox(height: 16), + ], + ) + else + Column( + children: [ + // Tombol untuk memilih logo jika belum ada + ElevatedButton.icon( + onPressed: _pickImage, + icon: const Icon(Icons.add_photo_alternate), + label: const Text('Pilih Logo Toko'), + ), + const SizedBox(height: 16), + ], + ), TextFormField( controller: _storeNameController, decoration: const InputDecoration( diff --git a/lib/widgets/store_info_widget.dart b/lib/widgets/store_info_widget.dart index 0093fde..2339698 100644 --- a/lib/widgets/store_info_widget.dart +++ b/lib/widgets/store_info_widget.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; +import 'dart:io'; /// Widget untuk menampilkan informasi toko dan admin /// Dapat di-tap untuk membuka dialog konfigurasi @@ -19,6 +20,7 @@ class _StoreInfoWidgetState extends State { String storeAddress = 'Jl. Merdeka No. 123'; String adminName = 'Budi Santoso'; String adminPhone = '08123456789'; + String? logoPath; // Path untuk logo toko @override void initState() { @@ -29,12 +31,13 @@ class _StoreInfoWidgetState extends State { /// Memuat informasi toko dari shared preferences Future _loadStoreInfo() async { final prefs = await SharedPreferences.getInstance(); - + setState(() { storeName = prefs.getString('store_name') ?? 'TOKO SEMBAKO MURAH'; storeAddress = prefs.getString('store_address') ?? 'Jl. Merdeka No. 123'; adminName = prefs.getString('admin_name') ?? 'Budi Santoso'; adminPhone = prefs.getString('admin_phone') ?? '08123456789'; + logoPath = prefs.getString('store_logo_path'); // Memuat path logo }); } @@ -42,7 +45,7 @@ class _StoreInfoWidgetState extends State { Widget build(BuildContext context) { // Load data every time the widget is built to ensure it's up-to-date _loadStoreInfo(); - + final courierPrime = GoogleFonts.courierPrime( textStyle: const TextStyle( fontSize: 14, @@ -58,6 +61,27 @@ class _StoreInfoWidgetState extends State { color: Colors.white, child: Column( children: [ + // Menampilkan logo jika tersedia + if (logoPath != null) + Container( + height: 80, + width: 80, + margin: const EdgeInsets.only(bottom: 8), + child: Image.file( + File(logoPath!), + fit: BoxFit.contain, + errorBuilder: (context, error, stackTrace) { + // Jika gagal memuat gambar, tampilkan placeholder + return Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(4), + ), + child: const Icon(Icons.image_not_supported, size: 40), + ); + }, + ), + ), Text( storeName, style: courierPrime.copyWith( @@ -67,15 +91,17 @@ class _StoreInfoWidgetState extends State { textAlign: TextAlign.center, ), const SizedBox(height: 4), - Text(storeAddress, style: courierPrime, textAlign: TextAlign.center), + Text(storeAddress, + style: courierPrime, textAlign: TextAlign.center), const SizedBox(height: 4), - Text('Admin: $adminName', style: courierPrime, textAlign: TextAlign.center), - Text('Telp: $adminPhone', style: courierPrime, textAlign: TextAlign.center), + Text('Admin: $adminName', + style: courierPrime, textAlign: TextAlign.center), + Text('Telp: $adminPhone', + style: courierPrime, textAlign: TextAlign.center), const SizedBox(height: 4), - Text('Tanggal: ${DateFormat('dd/MM/yyyy').format(DateTime.now())}', - style: courierPrime, - textAlign: TextAlign.center), - ], + Text('Tanggal: ${DateFormat('dd/MM/yyyy').format(DateTime.now())}', + style: courierPrime, textAlign: TextAlign.center), + ], ), ), );