feat: Menambahkan fitur upload logo toko pada konfigurasi toko
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>master
parent
64e36aa691
commit
b255d0a137
|
@ -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 {
|
||||
|
@ -18,6 +20,12 @@ class _StoreInfoConfigDialogState extends State<StoreInfoConfigDialog> {
|
|||
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() {
|
||||
super.initState();
|
||||
|
@ -34,6 +42,7 @@ class _StoreInfoConfigDialogState extends State<StoreInfoConfigDialog> {
|
|||
_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<StoreInfoConfigDialog> {
|
|||
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<StoreInfoConfigDialog> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Fungsi untuk memilih gambar dari gallery
|
||||
Future<void> _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<StoreInfoConfigDialog> {
|
|||
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(
|
||||
|
|
|
@ -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<StoreInfoWidget> {
|
|||
String storeAddress = 'Jl. Merdeka No. 123';
|
||||
String adminName = 'Budi Santoso';
|
||||
String adminPhone = '08123456789';
|
||||
String? logoPath; // Path untuk logo toko
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -35,6 +37,7 @@ class _StoreInfoWidgetState extends State<StoreInfoWidget> {
|
|||
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
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -58,6 +61,27 @@ class _StoreInfoWidgetState extends State<StoreInfoWidget> {
|
|||
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,14 +91,16 @@ class _StoreInfoWidgetState extends State<StoreInfoWidget> {
|
|||
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),
|
||||
style: courierPrime, textAlign: TextAlign.center),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue