feat: Menambahkan fitur upload logo toko pada konfigurasi toko

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
master
a2nr 2025-09-01 20:05:48 +07:00
parent 64e36aa691
commit b255d0a137
2 changed files with 126 additions and 9 deletions

View File

@ -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(

View File

@ -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),
],
),
),