Add cash management schema and immediate variance alerts
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -12,6 +11,8 @@ import { format } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useSupabaseEmployeeData } from "@/hooks/useSupabaseEmployeeData";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { Currency } from "@/lib/currency";
|
||||
import { useAuth } from "@/hooks/useAuth";
|
||||
|
||||
interface AdminDataEntryModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -21,14 +22,27 @@ interface AdminDataEntryModalProps {
|
||||
|
||||
export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminDataEntryModalProps) => {
|
||||
const { employees, addTransaction } = useSupabaseEmployeeData();
|
||||
const { user } = useAuth();
|
||||
const { toast } = useToast();
|
||||
|
||||
|
||||
const isEmployee = user?.role === 'employee';
|
||||
const lockedEmployeeId = isEmployee
|
||||
? employees.find(e => e.emp_id === user?.empId || e.email === user?.email)?.id
|
||||
: undefined;
|
||||
|
||||
const [selectedEmployeeId, setSelectedEmployeeId] = useState<string>('');
|
||||
const [collectionAmount, setCollectionAmount] = useState<string>('');
|
||||
const [depositAmount, setDepositAmount] = useState<string>('');
|
||||
const [currency, setCurrency] = useState<Currency>('USD');
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEmployee && lockedEmployeeId) {
|
||||
setSelectedEmployeeId(lockedEmployeeId);
|
||||
}
|
||||
}, [isEmployee, lockedEmployeeId, isOpen]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -59,7 +73,8 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
await addTransaction(selectedEmployeeId, {
|
||||
transaction_date: format(selectedDate, 'yyyy-MM-dd'),
|
||||
collection_amount: collection,
|
||||
deposit_amount: deposit
|
||||
deposit_amount: deposit,
|
||||
currency,
|
||||
});
|
||||
|
||||
toast({
|
||||
@@ -71,6 +86,7 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
setSelectedEmployeeId('');
|
||||
setCollectionAmount('');
|
||||
setDepositAmount('');
|
||||
setCurrency('USD');
|
||||
setSelectedDate(new Date());
|
||||
|
||||
onDataUpdate();
|
||||
@@ -89,6 +105,7 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
setSelectedEmployeeId('');
|
||||
setCollectionAmount('');
|
||||
setDepositAmount('');
|
||||
setCurrency('USD');
|
||||
setSelectedDate(new Date());
|
||||
onClose();
|
||||
};
|
||||
@@ -97,26 +114,40 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
<Dialog open={isOpen} onOpenChange={handleClose}>
|
||||
<DialogContent className="sm:max-w-[500px] bg-white">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-2xl font-bold text-slate-800">Insert Employee Data</DialogTitle>
|
||||
<DialogTitle className="text-2xl font-bold text-slate-800">
|
||||
{isEmployee ? "Submit Transaction" : "Insert Employee Data"}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6 mt-6">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="employee" className="text-sm font-medium text-slate-700">
|
||||
Select Employee
|
||||
{isEmployee ? "Employee" : "Select Employee"}
|
||||
</Label>
|
||||
<Select value={selectedEmployeeId} onValueChange={setSelectedEmployeeId}>
|
||||
<Select
|
||||
value={selectedEmployeeId}
|
||||
onValueChange={setSelectedEmployeeId}
|
||||
disabled={isEmployee}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Choose an employee" />
|
||||
<SelectValue placeholder={isEmployee ? "Your account" : "Choose an employee"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{employees.map(employee => (
|
||||
{(isEmployee && lockedEmployeeId
|
||||
? employees.filter(e => e.id === lockedEmployeeId)
|
||||
: employees
|
||||
).map(employee => (
|
||||
<SelectItem key={employee.id} value={employee.id}>
|
||||
{employee.name} (ID: {employee.emp_id})
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{isEmployee && !lockedEmployeeId && (
|
||||
<p className="text-xs text-red-600">
|
||||
Your account is not linked to an employee record. Ask an admin to set your Employee ID.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
@@ -148,10 +179,23 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label className="text-sm font-medium text-slate-700">Currency</Label>
|
||||
<Select value={currency} onValueChange={(v) => setCurrency(v as Currency)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select currency" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="USD">US Dollar (USD)</SelectItem>
|
||||
<SelectItem value="LBP">Lebanese Pound (LBP)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="collection" className="text-sm font-medium text-slate-700">
|
||||
MM Collection Amount (₹)
|
||||
MM Collection Amount ({currency})
|
||||
</Label>
|
||||
<Input
|
||||
id="collection"
|
||||
@@ -160,7 +204,7 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
value={collectionAmount}
|
||||
onChange={(e) => setCollectionAmount(e.target.value)}
|
||||
className="text-right"
|
||||
step="0.01"
|
||||
step={currency === 'USD' ? '0.01' : '1'}
|
||||
min="0"
|
||||
disabled={loading}
|
||||
/>
|
||||
@@ -168,7 +212,7 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="deposit" className="text-sm font-medium text-slate-700">
|
||||
Deposit Amount (₹)
|
||||
Deposit Amount ({currency})
|
||||
</Label>
|
||||
<Input
|
||||
id="deposit"
|
||||
@@ -177,7 +221,7 @@ export const AdminDataEntryModal = ({ isOpen, onClose, onDataUpdate }: AdminData
|
||||
value={depositAmount}
|
||||
onChange={(e) => setDepositAmount(e.target.value)}
|
||||
className="text-right"
|
||||
step="0.01"
|
||||
step={currency === 'USD' ? '0.01' : '1'}
|
||||
min="0"
|
||||
disabled={loading}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user