You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

239 lines
7.6 KiB

import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
import '../Components/appDrawer.dart';
import '../Components/app_bar.dart';
import '../Models/produit.dart';
import '../Services/productDatabase.dart';
class AddProductPage extends StatefulWidget {
const AddProductPage({super.key});
@override
_AddProductPageState createState() => _AddProductPageState();
}
class _AddProductPageState extends State<AddProductPage> {
final TextEditingController _nameController = TextEditingController();
final TextEditingController _priceController = TextEditingController();
final TextEditingController _imageController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
final List<String> _categories = ['Sucré', 'Salé', 'Jus', 'Gateaux'];
String? _selectedCategory;
File? _pickedImage;
String? _qrData;
late ProductDatabase _productDatabase;
@override
void initState() {
super.initState();
_productDatabase = ProductDatabase.instance;
_productDatabase.initDatabase();
_nameController.addListener(_updateQrData);
}
@override
void dispose() {
_nameController.removeListener(_updateQrData);
_nameController.dispose();
_priceController.dispose();
_imageController.dispose();
_descriptionController.dispose();
super.dispose();
}
void _updateQrData() {
if (_nameController.text.isNotEmpty) {
final reference = 'PROD_PREVIEW_${_nameController.text}_${DateTime.now().millisecondsSinceEpoch}';
setState(() {
_qrData = 'https://tonsite.com/$reference';
});
}
}
Future<void> _selectImage() async {
final result = await FilePicker.platform.pickFiles(type: FileType.image);
if (result != null && result.files.single.path != null) {
setState(() {
_pickedImage = File(result.files.single.path!);
_imageController.text = _pickedImage!.path;
});
}
}
Future<String> _generateAndSaveQRCode(String reference) async {
final validation = QrValidator.validate(
data: 'https://tonsite.com/$reference',
version: QrVersions.auto,
errorCorrectionLevel: QrErrorCorrectLevel.L,
);
final qrCode = validation.qrCode!;
final painter = QrPainter.withQr(
qr: qrCode,
color: Colors.black,
emptyColor: Colors.white,
gapless: true,
);
final directory = await getApplicationDocumentsDirectory();
final path = '${directory.path}/$reference.png';
final picData = await painter.toImageData(2048, format: ImageByteFormat.png);
await File(path).writeAsBytes(picData!.buffer.asUint8List());
return path;
}
void _addProduct() async {
final name = _nameController.text.trim();
final price = double.tryParse(_priceController.text.trim()) ?? 0.0;
final image = _imageController.text.trim();
final category = _selectedCategory;
final description = _descriptionController.text.trim();
if (name.isEmpty || price <= 0 || image.isEmpty || category == null) {
Get.snackbar('Erreur', 'Veuillez remplir tous les champs requis');
return;
}
final reference = 'PROD_${DateTime.now().millisecondsSinceEpoch}';
final qrPath = await _generateAndSaveQRCode(reference);
final product = Product(
name: name,
price: price,
image: image,
category: category,
description: description,
qrCode: qrPath,
reference: reference,
);
try {
await _productDatabase.createProduct(product);
Get.snackbar('Succès', 'Produit ajouté avec succès');
setState(() {
_nameController.clear();
_priceController.clear();
_imageController.clear();
_descriptionController.clear();
_selectedCategory = null;
_pickedImage = null;
_qrData = null;
});
} catch (e) {
Get.snackbar('Erreur', 'Ajout du produit échoué : $e');
}
}
Widget _displayImage() {
if (_pickedImage != null) {
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.file(
_pickedImage!,
width: 100,
height: 100,
fit: BoxFit.cover,
),
);
} else {
return Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8.0),
),
child: const Icon(Icons.image, size: 48, color: Colors.grey),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(title: 'Ajouter un produit'),
drawer: CustomDrawer(),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Ajouter un produit', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: 'Nom du produit', border: OutlineInputBorder()),
),
const SizedBox(height: 16),
TextField(
controller: _priceController,
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration: const InputDecoration(labelText: 'Prix', border: OutlineInputBorder()),
),
const SizedBox(height: 16),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: TextField(
controller: _imageController,
decoration: const InputDecoration(labelText: 'Chemin de l\'image', border: OutlineInputBorder()),
readOnly: true,
),
),
const SizedBox(width: 8),
ElevatedButton(onPressed: _selectImage, child: const Text('Sélectionner')),
],
),
const SizedBox(height: 16),
_displayImage(),
const SizedBox(height: 16),
DropdownButtonFormField<String>(
value: _selectedCategory,
items: _categories
.map((c) => DropdownMenuItem(value: c, child: Text(c)))
.toList(),
onChanged: (value) => setState(() => _selectedCategory = value),
decoration: const InputDecoration(labelText: 'Catégorie', border: OutlineInputBorder()),
),
const SizedBox(height: 16),
TextField(
controller: _descriptionController,
maxLines: 3,
decoration: const InputDecoration(labelText: 'Description', border: OutlineInputBorder()),
),
const SizedBox(height: 16),
if (_qrData != null) ...[
const Text('Aperçu du QR Code :'),
const SizedBox(height: 8),
Center(
child: QrImageView(
data: _qrData!,
version: QrVersions.auto,
size: 120,
),
),
],
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _addProduct,
child: const Text('Ajouter le produit'),
),
),
],
),
),
);
}
}