init project

This commit is contained in:
Ybehrooz
2025-10-11 20:29:31 +03:30
commit 8f73fac2db
25 changed files with 24492 additions and 0 deletions

View File

@@ -0,0 +1,299 @@
import React, { useState } from 'react';
const InventoryManagement = () => {
const [inventory, setInventory] = useState([
{
id: 1,
product: 'لپ‌تاپ ایسوس',
code: 'LAP001',
currentStock: 5,
minStock: 2,
maxStock: 20,
unit: 'عدد',
lastUpdate: '1403/01/15'
},
{
id: 2,
product: 'موبایل سامسونگ',
code: 'MOB002',
currentStock: 12,
minStock: 5,
maxStock: 50,
unit: 'عدد',
lastUpdate: '1403/01/14'
},
{
id: 3,
product: 'کتاب برنامه‌نویسی',
code: 'BOK003',
currentStock: 25,
minStock: 10,
maxStock: 100,
unit: 'جلد',
lastUpdate: '1403/01/13'
}
]);
const [showAdjustmentForm, setShowAdjustmentForm] = useState(false);
const [selectedProduct, setSelectedProduct] = useState(null);
const [adjustmentData, setAdjustmentData] = useState({
type: 'افزایش',
quantity: '',
reason: ''
});
const handleAdjustmentChange = (e) => {
const { name, value } = e.target;
setAdjustmentData(prev => ({
...prev,
[name]: value
}));
};
const handleStockAdjustment = (e) => {
e.preventDefault();
const adjustmentQuantity = parseInt(adjustmentData.quantity);
const newStock = adjustmentData.type === 'افزایش'
? selectedProduct.currentStock + adjustmentQuantity
: selectedProduct.currentStock - adjustmentQuantity;
if (newStock < 0) {
alert('موجودی نمی‌تواند منفی باشد!');
return;
}
setInventory(inventory.map(item =>
item.id === selectedProduct.id
? {
...item,
currentStock: newStock,
lastUpdate: new Date().toLocaleDateString('fa-IR')
}
: item
));
setShowAdjustmentForm(false);
setSelectedProduct(null);
setAdjustmentData({ type: 'افزایش', quantity: '', reason: '' });
};
const handleCancelAdjustment = () => {
setShowAdjustmentForm(false);
setSelectedProduct(null);
setAdjustmentData({ type: 'افزایش', quantity: '', reason: '' });
};
const getStockStatus = (current, min, max) => {
if (current <= min) return { status: 'کم', color: 'bg-red-100 text-red-800' };
if (current >= max) return { status: 'زیاد', color: 'bg-yellow-100 text-yellow-800' };
return { status: 'مناسب', color: 'bg-green-100 text-green-800' };
};
const lowStockItems = inventory.filter(item => item.currentStock <= item.minStock);
const totalValue = inventory.reduce((sum, item) => {
// Assuming average price for calculation
const avgPrice = item.product === 'لپ‌تاپ ایسوس' ? 15000000 :
item.product === 'موبایل سامسونگ' ? 8000000 : 150000;
return sum + (item.currentStock * avgPrice);
}, 0);
const formatPrice = (price) => {
return new Intl.NumberFormat('fa-IR').format(price) + ' ریال';
};
return (
<div className="farsi-text">
<div className="flex justify-between items-center mb-6">
<h1 className="text-3xl font-bold text-gray-900">مدیریت انبار</h1>
<button
onClick={() => setShowAdjustmentForm(true)}
className="btn-primary"
>
تنظیم موجودی
</button>
</div>
{/* Inventory Summary */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
<div className="card">
<div className="flex items-center">
<div className="bg-blue-500 rounded-full p-3 text-white text-2xl ml-4">
📦
</div>
<div>
<p className="text-sm font-medium text-gray-600">کل کالاها</p>
<p className="text-2xl font-bold text-gray-900">{inventory.length}</p>
</div>
</div>
</div>
<div className="card">
<div className="flex items-center">
<div className="bg-red-500 rounded-full p-3 text-white text-2xl ml-4">
</div>
<div>
<p className="text-sm font-medium text-gray-600">کمبود موجودی</p>
<p className="text-2xl font-bold text-gray-900">{lowStockItems.length}</p>
</div>
</div>
</div>
<div className="card">
<div className="flex items-center">
<div className="bg-green-500 rounded-full p-3 text-white text-2xl ml-4">
💰
</div>
<div>
<p className="text-sm font-medium text-gray-600">ارزش کل انبار</p>
<p className="text-lg font-bold text-gray-900">{formatPrice(totalValue)}</p>
</div>
</div>
</div>
<div className="card">
<div className="flex items-center">
<div className="bg-purple-500 rounded-full p-3 text-white text-2xl ml-4">
📊
</div>
<div>
<p className="text-sm font-medium text-gray-600">کل موجودی</p>
<p className="text-2xl font-bold text-gray-900">
{inventory.reduce((sum, item) => sum + item.currentStock, 0)}
</p>
</div>
</div>
</div>
</div>
{/* Low Stock Alert */}
{lowStockItems.length > 0 && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
<h3 className="text-red-800 font-bold mb-2">هشدار کمبود موجودی</h3>
<div className="space-y-2">
{lowStockItems.map(item => (
<div key={item.id} className="text-red-700">
{item.product} - موجودی فعلی: {item.currentStock} {item.unit} (حداقل: {item.minStock})
</div>
))}
</div>
</div>
)}
{/* Stock Adjustment Form Modal */}
{showAdjustmentForm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 w-full max-w-md">
<h2 className="text-xl font-bold mb-4">تنظیم موجودی</h2>
<form onSubmit={handleStockAdjustment} className="space-y-4">
<div>
<label className="form-label">کالا</label>
<select
value={selectedProduct?.id || ''}
onChange={(e) => {
const product = inventory.find(item => item.id === parseInt(e.target.value));
setSelectedProduct(product);
}}
className="form-input"
required
>
<option value="">انتخاب کنید</option>
{inventory.map(item => (
<option key={item.id} value={item.id}>
{item.product} (موجودی فعلی: {item.currentStock})
</option>
))}
</select>
</div>
<div>
<label className="form-label">نوع تنظیم</label>
<select
name="type"
value={adjustmentData.type}
onChange={handleAdjustmentChange}
className="form-input"
>
<option value="افزایش">افزایش موجودی</option>
<option value="کاهش">کاهش موجودی</option>
</select>
</div>
<div>
<label className="form-label">تعداد</label>
<input
type="number"
name="quantity"
value={adjustmentData.quantity}
onChange={handleAdjustmentChange}
className="form-input"
required
min="1"
/>
</div>
<div>
<label className="form-label">دلیل</label>
<textarea
name="reason"
value={adjustmentData.reason}
onChange={handleAdjustmentChange}
className="form-input"
rows="3"
placeholder="دلیل تنظیم موجودی..."
/>
</div>
<div className="flex space-x-2 space-x-reverse">
<button type="submit" className="btn-success flex-1">
اعمال تغییرات
</button>
<button type="button" onClick={handleCancelAdjustment} className="btn-secondary flex-1">
انصراف
</button>
</div>
</form>
</div>
</div>
)}
{/* Inventory Table */}
<div className="card">
<div className="overflow-x-auto">
<table className="table">
<thead>
<tr>
<th>نام کالا</th>
<th>کد کالا</th>
<th>موجودی فعلی</th>
<th>حداقل</th>
<th>حداکثر</th>
<th>وضعیت</th>
<th>آخرین بروزرسانی</th>
</tr>
</thead>
<tbody>
{inventory.map(item => {
const stockStatus = getStockStatus(item.currentStock, item.minStock, item.maxStock);
return (
<tr key={item.id}>
<td>{item.product}</td>
<td>
<span className="bg-gray-100 px-2 py-1 rounded text-sm">
{item.code}
</span>
</td>
<td className="font-bold">{item.currentStock} {item.unit}</td>
<td>{item.minStock} {item.unit}</td>
<td>{item.maxStock} {item.unit}</td>
<td>
<span className={`px-2 py-1 rounded-full text-xs ${stockStatus.color}`}>
{stockStatus.status}
</span>
</td>
<td>{item.lastUpdate}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
);
};
export default InventoryManagement;