Add profit analysis modal and cost tracking for products
Introduces a Profit Analysis modal for products, allowing users to view profit, margin, and markup calculations based on cost per unit and pricing tiers. Adds cost per unit input to the product modal, updates product types, and integrates the analysis modal into the products page and product table. This enhances product management with profit tracking and analysis features.
This commit is contained in:
@@ -27,6 +27,10 @@ const ImportProductsModal = dynamic(() => import("@/components/modals/import-pro
|
||||
loading: () => <div>Loading...</div>
|
||||
});
|
||||
|
||||
const ProfitAnalysisModal = dynamic(() => import("@/components/modals/profit-analysis-modal").then(mod => ({ default: mod.ProfitAnalysisModal })), {
|
||||
loading: () => <div>Loading...</div>
|
||||
});
|
||||
|
||||
function ProductTableSkeleton() {
|
||||
return (
|
||||
<Card>
|
||||
@@ -92,9 +96,12 @@ export default function ProductsPage() {
|
||||
category: "",
|
||||
pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
|
||||
image: null,
|
||||
costPerUnit: 0,
|
||||
});
|
||||
const [importModalOpen, setImportModalOpen] = useState(false);
|
||||
const [addProductOpen, setAddProductOpen] = useState(false);
|
||||
const [profitAnalysisOpen, setProfitAnalysisOpen] = useState(false);
|
||||
const [selectedProductForAnalysis, setSelectedProductForAnalysis] = useState<{id: string, name: string} | null>(null);
|
||||
|
||||
// Fetch products and categories
|
||||
useEffect(() => {
|
||||
@@ -269,6 +276,7 @@ export default function ProductsPage() {
|
||||
pricePerUnit: tier.pricePerUnit,
|
||||
}))
|
||||
: [{ minQuantity: 1, pricePerUnit: 0 }],
|
||||
costPerUnit: product.costPerUnit || 0,
|
||||
});
|
||||
setEditing(true);
|
||||
setAddProductOpen(true);
|
||||
@@ -286,6 +294,7 @@ export default function ProductsPage() {
|
||||
lowStockThreshold: 10,
|
||||
pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
|
||||
image: null,
|
||||
costPerUnit: 0,
|
||||
});
|
||||
setEditing(false);
|
||||
setModalOpen(true);
|
||||
@@ -331,12 +340,23 @@ export default function ProductsPage() {
|
||||
category: "",
|
||||
pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
|
||||
image: null,
|
||||
costPerUnit: 0,
|
||||
});
|
||||
if (setImagePreview) {
|
||||
setImagePreview(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleProfitAnalysis = (productId: string, productName: string) => {
|
||||
setSelectedProductForAnalysis({ id: productId, name: productName });
|
||||
setProfitAnalysisOpen(true);
|
||||
};
|
||||
|
||||
const handleProfitAnalysisClose = () => {
|
||||
setProfitAnalysisOpen(false);
|
||||
setSelectedProductForAnalysis(null);
|
||||
};
|
||||
|
||||
// Handle toggle product enabled status
|
||||
const handleToggleEnabled = async (productId: string, enabled: boolean) => {
|
||||
try {
|
||||
@@ -413,6 +433,7 @@ export default function ProductsPage() {
|
||||
onEdit={handleEditProduct}
|
||||
onDelete={handleDeleteProduct}
|
||||
onToggleEnabled={handleToggleEnabled}
|
||||
onProfitAnalysis={handleProfitAnalysis}
|
||||
getCategoryNameById={getCategoryNameById}
|
||||
/>
|
||||
|
||||
@@ -437,6 +458,15 @@ export default function ProductsPage() {
|
||||
setProducts(products);
|
||||
}}
|
||||
/>
|
||||
|
||||
{selectedProductForAnalysis && (
|
||||
<ProfitAnalysisModal
|
||||
open={profitAnalysisOpen}
|
||||
onClose={handleProfitAnalysisClose}
|
||||
productId={selectedProductForAnalysis.id}
|
||||
productName={selectedProductForAnalysis.name}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user