feat: syn product

This commit is contained in:
efrilm
2025-08-03 00:35:00 +07:00
parent 576f687d21
commit 7678b4791d
28 changed files with 1922 additions and 948 deletions
@@ -28,9 +28,9 @@ class DetailProductDialog extends StatelessWidget {
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: CachedNetworkImage(
imageUrl: product.image!.contains('http')
? product.image!
: '${Variables.baseUrl}/${product.image}',
imageUrl: product.name!.contains('http')
? product.name!
: '${Variables.baseUrl}/${product.name}',
fit: BoxFit.cover,
width: 120,
height: 120,
@@ -88,20 +88,20 @@ class DetailProductDialog extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildItem(
product.category?.name ?? "-",
"-",
"Kategori",
),
// _buildItem(
// "${product.stock}",
// "Stok",
// valueColor: product.stock! < 50
// ? AppColors.red
// : product.stock! < 100
// ? Colors.yellow
// : AppColors.green,
// ),
_buildItem(
"${product.stock}",
"Stok",
valueColor: product.stock! < 50
? AppColors.red
: product.stock! < 100
? Colors.yellow
: AppColors.green,
),
_buildItem(
(product.price ?? "0").currencyFormatRpV2,
(product.price ?? 0).toString().currencyFormatRpV2,
"Harga",
valueColor: AppColors.primary,
),
@@ -142,11 +142,11 @@ class DetailProductDialog extends StatelessWidget {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: product.status == 1 ? AppColors.green : AppColors.red,
color: product.isActive == true ? AppColors.green : AppColors.red,
borderRadius: BorderRadius.circular(8),
),
child: Text(
product.status == 1 ? 'Aktif' : 'Tidak Aktif',
product.isActive == true ? 'Aktif' : 'Tidak Aktif',
style: const TextStyle(
color: Colors.white, fontSize: 12, fontWeight: FontWeight.w700),
),
@@ -57,12 +57,12 @@ class _FormProductDialogState extends State<FormProductDialog> {
// Pre-fill the form with existing product data
final product = widget.product!;
nameController!.text = product.name ?? '';
priceValue = int.tryParse(product.price ?? '0') ?? 0;
priceValue = product.price ?? 0;
priceController!.text = priceValue.currencyFormatRp;
stockController!.text = (product.stock ?? 0).toString();
isBestSeller = product.isFavorite == 1;
printType = product.printerType ?? 'kitchen';
imageUrl = product.image;
stockController!.text = '';
isBestSeller = false;
printType = 'kitchen';
imageUrl = '';
}
super.initState();
@@ -129,72 +129,72 @@ class _FormProductDialogState extends State<FormProductDialog> {
keyboardType: TextInputType.number,
),
const SpaceHeight(20.0),
const Text(
"Kategori",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
const SpaceHeight(12.0),
BlocBuilder<GetCategoriesBloc, GetCategoriesState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
},
success: (categories) {
// Set the selected category if in edit mode and not already set
if (isEditMode &&
selectCategory == null &&
widget.product?.category != null) {
try {
selectCategory = categories.firstWhere(
(cat) => cat.id == widget.product!.category!.id,
);
} catch (e) {
// If no exact match found, leave selectCategory as null
// This will show the hint text instead
log("No matching category found for product category ID: ${widget.product!.category!.id}");
}
}
// const Text(
// "Kategori",
// style: TextStyle(
// fontSize: 14,
// fontWeight: FontWeight.w700,
// ),
// ),
// const SpaceHeight(12.0),
// BlocBuilder<GetCategoriesBloc, GetCategoriesState>(
// builder: (context, state) {
// return state.maybeWhen(
// orElse: () {
// return const Center(
// child: CircularProgressIndicator(),
// );
// },
// success: (categories) {
// // Set the selected category if in edit mode and not already set
// if (isEditMode &&
// selectCategory == null &&
// widget.product?.category != null) {
// try {
// selectCategory = categories.firstWhere(
// (cat) => cat.id == widget.product!.category!.id,
// );
// } catch (e) {
// // If no exact match found, leave selectCategory as null
// // This will show the hint text instead
// log("No matching category found for product category ID: ${widget.product!.category!.id}");
// }
// }
return DropdownButtonHideUnderline(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
child: DropdownButton<CategoryModel>(
value: selectCategory,
hint: const Text("Pilih Kategori"),
isExpanded: true, // Untuk mengisi lebar container
onChanged: (newValue) {
if (newValue != null) {
selectCategory = newValue;
setState(() {});
log("selectCategory: ${selectCategory!.name}");
}
},
items: categories
.map<DropdownMenuItem<CategoryModel>>(
(CategoryModel category) {
return DropdownMenuItem<CategoryModel>(
value: category,
child: Text(category.name!),
);
}).toList(),
),
),
);
},
);
},
),
// return DropdownButtonHideUnderline(
// child: Container(
// decoration: BoxDecoration(
// border: Border.all(color: Colors.grey),
// borderRadius: BorderRadius.circular(12),
// ),
// padding: const EdgeInsets.symmetric(
// horizontal: 10, vertical: 5),
// child: DropdownButton<CategoryModel>(
// value: selectCategory,
// hint: const Text("Pilih Kategori"),
// isExpanded: true, // Untuk mengisi lebar container
// onChanged: (newValue) {
// if (newValue != null) {
// selectCategory = newValue;
// setState(() {});
// log("selectCategory: ${selectCategory!.name}");
// }
// },
// items: categories
// .map<DropdownMenuItem<CategoryModel>>(
// (CategoryModel category) {
// return DropdownMenuItem<CategoryModel>(
// value: category,
// child: Text(category.name!),
// );
// }).toList(),
// ),
// ),
// );
// },
// );
// },
// ),
const SpaceHeight(12.0),
const Text(
"Tipe Print",
@@ -296,23 +296,23 @@ class _FormProductDialogState extends State<FormProductDialog> {
return;
}
log("isBestSeller: $isBestSeller");
final String name = nameController!.text;
final int stock =
stockController!.text.toIntegerFromText;
// log("isBestSeller: $isBestSeller");
// final String name = nameController!.text;
// final int stock =
// stockController!.text.toIntegerFromText;
final Product product = widget.product!.copyWith(
name: name,
price: priceValue.toString(),
stock: stock,
categoryId: selectCategory!.id!,
isFavorite: isBestSeller ? 1 : 0,
printerType: printType,
);
// final Product product = widget.product!.copyWith(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// printerType: printType,
// );
context.read<UpdateProductBloc>().add(
UpdateProductEvent.updateProduct(
product, imageFile));
// context.read<UpdateProductBloc>().add(
// UpdateProductEvent.updateProduct(
// product, imageFile));
},
label: 'Ubah Produk',
);
@@ -354,33 +354,33 @@ class _FormProductDialogState extends State<FormProductDialog> {
orElse: () {
return Button.filled(
onPressed: () {
if (selectCategory == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select a category'),
backgroundColor: Colors.red,
),
);
return;
}
// if (selectCategory == null) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please select a category'),
// backgroundColor: Colors.red,
// ),
// );
// return;
// }
log("isBestSeller: $isBestSeller");
final String name = nameController!.text;
// log("isBestSeller: $isBestSeller");
// final String name = nameController!.text;
final int stock =
stockController!.text.toIntegerFromText;
final Product product = Product(
name: name,
price: priceValue.toString(),
stock: stock,
categoryId: selectCategory!.id!,
isFavorite: isBestSeller ? 1 : 0,
image: imageFile!.path,
printerType: printType,
);
context.read<AddProductBloc>().add(
AddProductEvent.addProduct(
product, imageFile!));
// final int stock =
// stockController!.text.toIntegerFromText;
// final Product product = Product(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// image: imageFile!.path,
// printerType: printType,
// );
// context.read<AddProductBloc>().add(
// AddProductEvent.addProduct(
// product, imageFile!));
},
label: 'Simpan Produk',
);
@@ -441,14 +441,14 @@ class _FormProductDialogOldState extends State<FormProductDialogOld> {
if (isEditMode) {
// Pre-fill the form with existing product data
final product = widget.product!;
nameController!.text = product.name ?? '';
priceValue = int.tryParse(product.price ?? '0') ?? 0;
priceController!.text = priceValue.currencyFormatRp;
stockController!.text = (product.stock ?? 0).toString();
isBestSeller = product.isFavorite == 1;
printType = product.printerType ?? 'kitchen';
imageUrl = product.image;
// final product = widget.product!;
// nameController!.text = product.name ?? '';
// priceValue = int.tryParse(product.price ?? '0') ?? 0;
// priceController!.text = priceValue.currencyFormatRp;
// stockController!.text = (product.stock ?? 0).toString();
// isBestSeller = product.isFavorite == 1;
// printType = product.printerType ?? 'kitchen';
// imageUrl = product.image;
}
super.initState();
@@ -542,19 +542,19 @@ class _FormProductDialogOldState extends State<FormProductDialogOld> {
},
success: (categories) {
// Set the selected category if in edit mode and not already set
if (isEditMode &&
selectCategory == null &&
widget.product?.category != null) {
try {
selectCategory = categories.firstWhere(
(cat) => cat.id == widget.product!.category!.id,
);
} catch (e) {
// If no exact match found, leave selectCategory as null
// This will show the hint text instead
log("No matching category found for product category ID: ${widget.product!.category!.id}");
}
}
// if (isEditMode &&
// selectCategory == null &&
// widget.product?.category != null) {
// try {
// selectCategory = categories.firstWhere(
// (cat) => cat.id == widget.product!.category!.id,
// );
// } catch (e) {
// // If no exact match found, leave selectCategory as null
// // This will show the hint text instead
// log("No matching category found for product category ID: ${widget.product!.category!.id}");
// }
// }
return DropdownButtonHideUnderline(
child: Container(
@@ -696,18 +696,18 @@ class _FormProductDialogOldState extends State<FormProductDialogOld> {
final int stock =
stockController!.text.toIntegerFromText;
final Product product = widget.product!.copyWith(
name: name,
price: priceValue.toString(),
stock: stock,
categoryId: selectCategory!.id!,
isFavorite: isBestSeller ? 1 : 0,
printerType: printType,
);
// final Product product = widget.product!.copyWith(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// printerType: printType,
// );
context.read<UpdateProductBloc>().add(
UpdateProductEvent.updateProduct(
product, imageFile));
// context.read<UpdateProductBloc>().add(
// UpdateProductEvent.updateProduct(
// product, imageFile));
},
label: 'Update Product',
);
@@ -764,18 +764,18 @@ class _FormProductDialogOldState extends State<FormProductDialogOld> {
final int stock =
stockController!.text.toIntegerFromText;
final Product product = Product(
name: name,
price: priceValue.toString(),
stock: stock,
categoryId: selectCategory!.id!,
isFavorite: isBestSeller ? 1 : 0,
image: imageFile!.path,
printerType: printType,
);
context.read<AddProductBloc>().add(
AddProductEvent.addProduct(
product, imageFile!));
// final Product product = Product(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// image: imageFile!.path,
// printerType: printType,
// );
// context.read<AddProductBloc>().add(
// AddProductEvent.addProduct(
// product, imageFile!));
},
label: 'Save Product',
);