212 lines
8.0 KiB
Python
212 lines
8.0 KiB
Python
import os
|
|
|
|
file_path = "/Users/maddy/Projects/Kifi/kifi-app/lib/features/inventory/presentation/product_detail_screen.dart"
|
|
|
|
content = """import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:kifi_app/features/inventory/providers/products_provider.dart';
|
|
import 'package:kifi_app/core/network/dio_client.dart';
|
|
import 'package:kifi_app/features/inventory/domain/product.dart';
|
|
import 'package:kifi_app/features/inventory/presentation/add_product_screen.dart';
|
|
import 'package:kifi_app/features/inventory/presentation/stock_ledger_tab.dart';
|
|
import 'package:kifi_app/features/inventory/presentation/widgets/adjust_stock_sheet.dart';
|
|
|
|
class ProductDetailScreen extends ConsumerWidget {
|
|
final Product product;
|
|
|
|
const ProductDetailScreen({super.key, required this.product});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
// Watch products to get latest updates (like stock changes)
|
|
final productsState = ref.watch(productsProvider);
|
|
final currentProduct = productsState.value?.firstWhere((p) => p.id == product.id, orElse: () => product) ?? product;
|
|
|
|
return DefaultTabController(
|
|
length: 2,
|
|
child: Scaffold(
|
|
backgroundColor: Colors.grey[50],
|
|
appBar: AppBar(
|
|
elevation: 0,
|
|
backgroundColor: Colors.white,
|
|
foregroundColor: Colors.black,
|
|
title: Text(currentProduct.name, style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(Icons.edit, color: Colors.black),
|
|
onPressed: () {
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => AddProductScreen(product: currentProduct),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
bottom: const TabBar(
|
|
labelColor: Colors.blue,
|
|
unselectedLabelColor: Colors.grey,
|
|
indicatorColor: Colors.blue,
|
|
tabs: [
|
|
Tab(text: "Overview"),
|
|
Tab(text: "Stock Ledger"),
|
|
],
|
|
),
|
|
),
|
|
body: TabBarView(
|
|
children: [
|
|
_buildOverviewTab(context, currentProduct, ref),
|
|
StockLedgerTab(productId: currentProduct.id!),
|
|
],
|
|
),
|
|
floatingActionButton: FloatingActionButton.extended(
|
|
onPressed: () {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
backgroundColor: Colors.transparent,
|
|
builder: (context) => AdjustStockSheet(productId: currentProduct.id!),
|
|
);
|
|
},
|
|
backgroundColor: Colors.blue,
|
|
icon: const Icon(Icons.inventory),
|
|
label: const Text("Adjust Stock"),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildOverviewTab(BuildContext context, Product p, WidgetRef ref) {
|
|
return SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Image Header
|
|
if (p.imageIds.isNotEmpty)
|
|
Container(
|
|
height: 200,
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(12),
|
|
color: Colors.grey[200],
|
|
),
|
|
clipBehavior: Clip.antiAlias,
|
|
child: FutureBuilder<String?>(
|
|
future: DioClient().storage.read(key: 'jwt_token'),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return const Center(child: CircularProgressIndicator());
|
|
}
|
|
final token = snapshot.data;
|
|
if (token == null) {
|
|
return const Icon(Icons.image, size: 50, color: Colors.grey);
|
|
}
|
|
return Image.network(
|
|
'${DioClient().dio.options.baseUrl}/inventory/products/${p.id}/images/${p.imageIds.first}/content',
|
|
fit: BoxFit.cover,
|
|
headers: {'Authorization': 'Bearer $token'},
|
|
errorBuilder: (context, error, stackTrace) => const Icon(Icons.image, size: 50, color: Colors.grey),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// Stock Summary Card
|
|
Card(
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: Colors.blue.withOpacity(0.1),
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: const Icon(Icons.inventory_2, color: Colors.blue),
|
|
),
|
|
const SizedBox(width: 16),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text("Current Stock", style: TextStyle(color: Colors.grey[600], fontSize: 14)),
|
|
Text(
|
|
"${p.currentStock ?? 0}",
|
|
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 24),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
// Details Card
|
|
Card(
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Metal Details", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
|
|
const Divider(),
|
|
_buildDetailRow("SKU / HUID", p.sku ?? "-"),
|
|
_buildDetailRow("Gross Weight", "${p.weight ?? 0} g"),
|
|
_buildDetailRow("Purity Factor", "${p.purityFactor ?? 1.0}"),
|
|
_buildDetailRow("Wastage", "${p.wastagePercentage ?? 0}%"),
|
|
_buildDetailRow("Net Weight", "${(p.weight ?? 0) * (1 - (p.wastagePercentage ?? 0) / 100)} g"),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 16),
|
|
// Pricing Card
|
|
Card(
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Pricing Details", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
|
|
const Divider(),
|
|
_buildDetailRow("Making Charges", "₹${p.makingCharges?.toStringAsFixed(2) ?? '0.00'} (${p.makingChargesType})"),
|
|
_buildDetailRow("HSN Code", p.hsnCode ?? "-"),
|
|
_buildDetailRow("GST Rate", "${p.gstRate?.toStringAsFixed(1) ?? '0'}%"),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDetailRow(String label, String value) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(label, style: TextStyle(color: Colors.grey[600])),
|
|
Text(value, style: const TextStyle(fontWeight: FontWeight.w500)),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
"""
|
|
|
|
with open(file_path, "w") as f:
|
|
f.write(content)
|