" edit page functionlity "
parent
cba9f8565a
commit
b7e0e14e25
|
@ -110,6 +110,44 @@
|
|||
align-items: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
.dropdown {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dropdown input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-list {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
z-index: 10;
|
||||
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.selected {
|
||||
|
||||
background-color: rgba(255, 255, 255, 0.425);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 375px) {
|
||||
|
||||
.backIcon {
|
||||
|
@ -123,6 +161,10 @@
|
|||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.selected {
|
||||
width: 100px;
|
||||
background-color: rgba(255, 255, 255, 0.425);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -142,7 +184,10 @@
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
.selected {
|
||||
width: 100px;
|
||||
background-color: rgba(255, 255, 255, 0.425);
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.edit-btn, .edit-btn-2 {
|
||||
|
@ -150,5 +195,10 @@
|
|||
height: 50px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.selected {
|
||||
width: 100px;
|
||||
background-color: rgba(255, 255, 255, 0.425);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,16 +9,27 @@ function ExpenseEditPage() {
|
|||
const navigate = useNavigate();
|
||||
const [currentDateTime, setCurrentDateTime] = useState("");
|
||||
const [amount, setAmount] = useState(location.state?.amount || "");
|
||||
const [category, setCategory] = useState(location.state?.category || "");
|
||||
const [categories] = useState(["Hair", "Clothing", "Food", "Books", "Electronics", "Other"]);
|
||||
|
||||
|
||||
const [selectedCategories, setSelectedCategories] = useState(
|
||||
Array.isArray(location.state?.category)
|
||||
? location.state.category
|
||||
: location.state?.category
|
||||
? [location.state.category]
|
||||
: []
|
||||
);
|
||||
|
||||
const [error, setError] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [dropdownVisible, setDropdownVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const now = new Date();
|
||||
const formattedDateTime = now.toLocaleString();
|
||||
setCurrentDateTime(formattedDateTime);
|
||||
|
||||
|
||||
|
||||
if (!location.state?.id) {
|
||||
const storedEntries = JSON.parse(localStorage.getItem("entries")) || [];
|
||||
const entryToEdit = storedEntries.find(
|
||||
|
@ -27,7 +38,13 @@ function ExpenseEditPage() {
|
|||
|
||||
if (entryToEdit) {
|
||||
setAmount(entryToEdit.amount);
|
||||
setCategory(entryToEdit.category);
|
||||
setSelectedCategories(
|
||||
Array.isArray(entryToEdit.category)
|
||||
? entryToEdit.category
|
||||
: entryToEdit.category
|
||||
? [entryToEdit.category]
|
||||
: []
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [location.state]);
|
||||
|
@ -44,7 +61,7 @@ function ExpenseEditPage() {
|
|||
id: location.state?.id,
|
||||
amount: amount,
|
||||
dateTime: currentDateTime,
|
||||
category: category,
|
||||
category: selectedCategories.join(", "),
|
||||
};
|
||||
|
||||
const storedEntries = JSON.parse(localStorage.getItem("entries")) || [];
|
||||
|
@ -53,11 +70,23 @@ function ExpenseEditPage() {
|
|||
);
|
||||
localStorage.setItem("entries", JSON.stringify(updatedEntries));
|
||||
|
||||
// console.log("Entry updated in local storage:", updatedEntry);
|
||||
navigate("/expense-successfully", { state: updatedEntry });
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setDropdownVisible(!dropdownVisible);
|
||||
};
|
||||
|
||||
const handleCategorySelect = (category) => {
|
||||
// Toggle category selection
|
||||
if (selectedCategories.includes(category)) {
|
||||
setSelectedCategories(selectedCategories.filter((cat) => cat !== category));
|
||||
} else {
|
||||
setSelectedCategories([...selectedCategories, category]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="incomeedit-containers">
|
||||
<div className="backIcon">
|
||||
|
@ -90,11 +119,27 @@ function ExpenseEditPage() {
|
|||
|
||||
<div className="edit-fields">
|
||||
<label>Category:</label>
|
||||
<input
|
||||
type="text"
|
||||
value={category}
|
||||
onChange={(e) => setCategory(e.target.value)}
|
||||
/>
|
||||
<div className="dropdown" onClick={toggleDropdown}>
|
||||
<input
|
||||
type="text"
|
||||
value={selectedCategories.join(", ") || ""}
|
||||
placeholder="Select Categories"
|
||||
readOnly
|
||||
/>
|
||||
{dropdownVisible && (
|
||||
<div className="dropdown-list">
|
||||
{categories.map((category) => (
|
||||
<div
|
||||
key={category}
|
||||
className={`dropdown-item ${selectedCategories.includes(category) ? "selected" : ""}`}
|
||||
onClick={() => handleCategorySelect(category)}
|
||||
>
|
||||
{category}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="edit-buttons">
|
||||
|
|
|
@ -7,8 +7,13 @@ const ExpenseLayout = () => {
|
|||
const [totalAmount, setTotalAmount] = useState(0);
|
||||
const [category, setCategory] = useState('');
|
||||
|
||||
const handleManualAmountChange = (amount) => {
|
||||
setTotalAmount(amount);
|
||||
const handleManualAmountChange = (value) => {
|
||||
const numericValue = parseFloat(value);
|
||||
if (!isNaN(numericValue)) {
|
||||
setTotalAmount(numericValue);
|
||||
} else {
|
||||
setTotalAmount(0);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -8,6 +8,7 @@ function TotalExpenseAmount({ totalAmount, category, setCategory, handleManualAm
|
|||
const { entryType } = location.state || {};
|
||||
const [entries, setEntries] = useState([]);
|
||||
const [categoryError, setCategoryError] = useState('');
|
||||
const [amountError, setAmountError] = useState(''); // State for amount error
|
||||
const [categories, setCategories] = useState(["Hair", "Clothing", "Food", "Books", "Electronics", "Other"]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
@ -25,10 +26,10 @@ function TotalExpenseAmount({ totalAmount, category, setCategory, handleManualAm
|
|||
|
||||
const handleAddEntry = () => {
|
||||
setCategoryError('');
|
||||
setAmountError(''); // Reset amount error
|
||||
|
||||
|
||||
if (amount <= 0) {
|
||||
alert('Amount is required and must be greater than zero');
|
||||
setAmountError('Amount is required and must be greater than zero'); // Set error message
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -126,6 +127,7 @@ function TotalExpenseAmount({ totalAmount, category, setCategory, handleManualAm
|
|||
onDoubleClick={handleAmountDoubleClick}
|
||||
placeholder="Enter Amount"
|
||||
/>
|
||||
{amountError && <span className="error-message">{amountError}</span>} {/* Amount error message */}
|
||||
</div>
|
||||
<div className="category-input">
|
||||
<label>Category:</label>
|
||||
|
|
|
@ -43,10 +43,10 @@ function ExpenseCategory() {
|
|||
setCategories(updatedCategories);
|
||||
setCustomCategoryCount(customCategoryCount + 1);
|
||||
localStorage.setItem('categories', JSON.stringify(updatedCategories));
|
||||
alert(`Category "${newCategory}" added!`);
|
||||
// alert(`Category "${newCategory}" added!`);
|
||||
setNewCategory('');
|
||||
} else {
|
||||
alert('You can only add up to three custom categories!');
|
||||
// alert('You can only add up to three custom categories!');
|
||||
}
|
||||
} else {
|
||||
alert('Category already exists!');
|
||||
|
@ -89,7 +89,6 @@ function ExpenseCategory() {
|
|||
))}
|
||||
</section>
|
||||
|
||||
{/* Input and button for adding new category */}
|
||||
{customCategoryCount < 3 && (
|
||||
<div className="add-category">
|
||||
<input
|
||||
|
|
|
@ -87,7 +87,7 @@ function ExpenseRecords() {
|
|||
|
||||
<div className="categories">
|
||||
<h3>Selected Categories:</h3>
|
||||
<p>{categories.join(', ')}</p>
|
||||
<p>{categories.join(',')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -16,13 +16,14 @@ function AmountPage() {
|
|||
|
||||
const handleCoinClick = (coinAmount) => {
|
||||
if (isClickable) {
|
||||
|
||||
|
||||
const currentAmount = totalAmount ? parseFloat(totalAmount) : 0;
|
||||
const newAmount = currentAmount + coinAmount;
|
||||
|
||||
setTotalAmount(newAmount);
|
||||
setLastAddedAmount(coinAmount);
|
||||
setIsClickable(false);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
setIsClickable(true);
|
||||
|
|
|
@ -10,7 +10,7 @@ function EntriesList() {
|
|||
const [entries, setEntries] = useState([]);
|
||||
const [editingEntryId, setEditingEntryId] = useState(null);
|
||||
const [editedAmount, setEditedAmount] = useState("");
|
||||
const [selectedCategory, setSelectedCategory] = useState([]);
|
||||
const [selectedCategory, setSelectedCategory] = useState([]); // Ensure this is initialized as an array
|
||||
const [repeatEntry, setRepeatEntry] = useState(null);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
|
||||
|
@ -33,7 +33,8 @@ function EntriesList() {
|
|||
const handleEditClick = (entry) => {
|
||||
setEditingEntryId(entry.id);
|
||||
setEditedAmount(entry.amount);
|
||||
setSelectedCategory(entry.category || []); // Ensure selectedCategory is an array
|
||||
// Ensure selectedCategory is always an array
|
||||
setSelectedCategory(Array.isArray(entry.category) ? entry.category : []);
|
||||
};
|
||||
|
||||
const handleSaveClick = (entry) => {
|
||||
|
@ -56,7 +57,7 @@ function EntriesList() {
|
|||
const newEntry = {
|
||||
id: new Date().getTime(),
|
||||
amount: repeatEntry.amount,
|
||||
category: repeatEntry.category, // Ensure this is an array
|
||||
category: repeatEntry.category || [], // Ensure this is an array
|
||||
type: repeatEntry.type,
|
||||
};
|
||||
|
||||
|
@ -76,9 +77,12 @@ function EntriesList() {
|
|||
};
|
||||
|
||||
const handleCategoryChange = (category) => {
|
||||
setSelectedCategory(prevCategories => {
|
||||
setSelectedCategory((prevCategories) => {
|
||||
// Ensure prevCategories is an array
|
||||
if (!Array.isArray(prevCategories)) return [category]; // Initialize as array if not
|
||||
|
||||
if (prevCategories.includes(category)) {
|
||||
return prevCategories.filter(cat => cat !== category); // Remove category if already selected
|
||||
return prevCategories.filter((cat) => cat !== category); // Remove category if already selected
|
||||
} else {
|
||||
return [...prevCategories, category]; // Add category if not selected
|
||||
}
|
||||
|
@ -133,7 +137,7 @@ function EntriesList() {
|
|||
<>
|
||||
<span className="entry-amount">₹{entry.amount}</span>
|
||||
<span className="entry-category">
|
||||
{entry.category.join(', ')} {/* Join array elements with a comma */}
|
||||
{Array.isArray(entry.category) ? entry.category.join(', ') : entry.category || "No Category"} {/* Safely check if it's an array */}
|
||||
</span>
|
||||
<div className="entry-icons">
|
||||
<FontAwesomeIcon
|
||||
|
|
|
@ -8,6 +8,7 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
const { entryType } = location.state || {};
|
||||
const [entries, setEntries] = useState([]);
|
||||
const [categoryError, setCategoryError] = useState('');
|
||||
const [amountError, setAmountError] = useState(''); // State for amount error
|
||||
const [categories, setCategories] = useState(["Hair", "Clothing", "Food", "Books", "Electronics", "Other"]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
@ -25,10 +26,10 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
|
||||
const handleAddEntry = () => {
|
||||
setCategoryError('');
|
||||
setAmountError(''); // Reset amount error
|
||||
|
||||
// Ensure amount is a number and greater than zero
|
||||
if (amount <= 0) {
|
||||
alert('Amount is required and must be greater than zero');
|
||||
setAmountError('Amount is required and must be greater than zero'); // Set error message
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,7 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
const handleSaveEntry = () => {
|
||||
const timestamp = handleAddEntry();
|
||||
if (timestamp) {
|
||||
navigate('/expense-totalsuccessfully', { state: { timestamp } });
|
||||
navigate('/totalsuccessfully', { state: { timestamp } });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -82,11 +83,11 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
};
|
||||
|
||||
const handleCategoryFocus = () => {
|
||||
navigate('/expenseCategory');
|
||||
navigate('/category');
|
||||
};
|
||||
|
||||
const handleAmountFocus = () => {
|
||||
navigate('/expenseAmount');
|
||||
navigate('/amount');
|
||||
};
|
||||
|
||||
const handleAmountMouseDown = (e) => {
|
||||
|
@ -120,12 +121,13 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
value={amount}
|
||||
onChange={(e) => {
|
||||
setAmount(e.target.value);
|
||||
handleManualAmountChange(e.target.value); // Ensure it's called properly
|
||||
handleManualAmountChange(e.target.value);
|
||||
}}
|
||||
onMouseDown={handleAmountMouseDown}
|
||||
onDoubleClick={handleAmountDoubleClick}
|
||||
placeholder="Enter Amount"
|
||||
/>
|
||||
{amountError && <span className="error-message">{amountError}</span>}
|
||||
</div>
|
||||
<div className="category-input">
|
||||
<label>Category:</label>
|
||||
|
@ -148,4 +150,5 @@ function TotalAmount({ totalAmount, category, setCategory , handleManualAmountCh
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TotalAmount;
|
||||
|
|
|
@ -41,10 +41,10 @@ function Category() {
|
|||
setCategories(updatedCategories);
|
||||
setCustomCategoryCount(customCategoryCount + 1);
|
||||
localStorage.setItem('categories', JSON.stringify(updatedCategories));
|
||||
alert(`Category "${newCategory}" added!`);
|
||||
// alert(`Category "${newCategory}" added!`);
|
||||
setNewCategory(''); // Clear input field after adding
|
||||
} else {
|
||||
alert('You can only add up to three custom categories!');
|
||||
// alert('You can only add up to three custom categories!');
|
||||
}
|
||||
} else {
|
||||
alert('Category already exists!');
|
||||
|
|
|
@ -7,27 +7,50 @@ import "../Common/IncomeEdit.css";
|
|||
function IncomeEdit() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Destructure state values passed from previous page
|
||||
const { id, amount: initialAmount, category: initialCategory, dateTime: initialDateTime } = location.state || {};
|
||||
|
||||
const [amount, setAmount] = useState(initialAmount || "");
|
||||
const [category, setCategory] = useState(initialCategory || "");
|
||||
const [currentDateTime, setCurrentDateTime] = useState(initialDateTime || "");
|
||||
|
||||
const [currentDateTime, setCurrentDateTime] = useState("");
|
||||
const [amount, setAmount] = useState(location.state?.amount || "");
|
||||
const [categories] = useState(["Hair", "Clothing", "Food", "Books", "Electronics", "Other"]);
|
||||
|
||||
// Ensure selectedCategories is initialized correctly
|
||||
const [selectedCategories, setSelectedCategories] = useState(
|
||||
Array.isArray(location.state?.category)
|
||||
? location.state.category
|
||||
: location.state?.category
|
||||
? [location.state.category]
|
||||
: []
|
||||
);
|
||||
|
||||
const [error, setError] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [dropdownVisible, setDropdownVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialDateTime) {
|
||||
const now = new Date();
|
||||
const formattedDateTime = now.toLocaleString();
|
||||
setCurrentDateTime(formattedDateTime);
|
||||
const now = new Date();
|
||||
const formattedDateTime = now.toLocaleString();
|
||||
setCurrentDateTime(formattedDateTime);
|
||||
|
||||
// Fetch entry to edit if no id is passed
|
||||
if (!location.state?.id) {
|
||||
const storedEntries = JSON.parse(localStorage.getItem("entries")) || [];
|
||||
const entryToEdit = storedEntries.find(
|
||||
(entry) => entry.id === location.state?.id
|
||||
);
|
||||
|
||||
if (entryToEdit) {
|
||||
setAmount(entryToEdit.amount);
|
||||
setSelectedCategories(
|
||||
Array.isArray(entryToEdit.category)
|
||||
? entryToEdit.category
|
||||
: entryToEdit.category
|
||||
? [entryToEdit.category]
|
||||
: []
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [initialDateTime]);
|
||||
}, [location.state]);
|
||||
|
||||
const handleBackClick = () => {
|
||||
navigate("/records"); // Navigate back to records
|
||||
navigate("/records");
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
|
@ -35,24 +58,35 @@ function IncomeEdit() {
|
|||
setError(null);
|
||||
|
||||
const updatedEntry = {
|
||||
id: id,
|
||||
id: location.state?.id,
|
||||
amount: amount,
|
||||
dateTime: currentDateTime,
|
||||
category: category,
|
||||
category: selectedCategories.join(", "),
|
||||
};
|
||||
|
||||
// Save updated entry to localStorage (or backend API if needed)
|
||||
const storedEntries = JSON.parse(localStorage.getItem("entries")) || [];
|
||||
const updatedEntries = storedEntries.map((entry) =>
|
||||
entry.id === updatedEntry.id ? updatedEntry : entry
|
||||
);
|
||||
localStorage.setItem("entries", JSON.stringify(updatedEntries));
|
||||
|
||||
// Navigate to success page
|
||||
navigate("/successPage", { state: updatedEntry });
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setDropdownVisible(!dropdownVisible);
|
||||
};
|
||||
|
||||
const handleCategorySelect = (category) => {
|
||||
|
||||
if (selectedCategories.includes(category)) {
|
||||
setSelectedCategories(selectedCategories.filter((cat) => cat !== category));
|
||||
} else {
|
||||
setSelectedCategories([...selectedCategories, category]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="incomeedit-containers">
|
||||
<div className="backIcon">
|
||||
|
@ -85,11 +119,27 @@ function IncomeEdit() {
|
|||
|
||||
<div className="edit-fields">
|
||||
<label>Category:</label>
|
||||
<input
|
||||
type="text"
|
||||
value={category}
|
||||
onChange={(e) => setCategory(e.target.value)}
|
||||
/>
|
||||
<div className="dropdown" onClick={toggleDropdown}>
|
||||
<input
|
||||
type="text"
|
||||
value={selectedCategories.join(", ") || ""}
|
||||
placeholder="Select Categories"
|
||||
readOnly
|
||||
/>
|
||||
{dropdownVisible && (
|
||||
<div className="dropdown-list">
|
||||
{categories.map((category) => (
|
||||
<div
|
||||
key={category}
|
||||
className={`dropdown-item ${selectedCategories.includes(category) ? "selected" : ""}`}
|
||||
onClick={() => handleCategorySelect(category)}
|
||||
>
|
||||
{category}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="edit-buttons">
|
||||
|
|
|
@ -7,14 +7,28 @@ const Layout = () => {
|
|||
const [totalAmount, setTotalAmount] = useState(0);
|
||||
const [category, setCategory] = useState('');
|
||||
|
||||
|
||||
const handleManualAmountChange = (value) => {
|
||||
const numericValue = parseFloat(value);
|
||||
if (!isNaN(numericValue)) {
|
||||
setTotalAmount(numericValue);
|
||||
} else {
|
||||
setTotalAmount(0);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="layout-container">
|
||||
<div className="page-content">
|
||||
|
||||
<Outlet context={[totalAmount, setTotalAmount, category, setCategory]} />
|
||||
|
||||
<Outlet context={[totalAmount, setTotalAmount, category, setCategory, handleManualAmountChange]} />
|
||||
</div>
|
||||
|
||||
<TotalAmount totalAmount={totalAmount} category={category} setCategory={setCategory} />
|
||||
<TotalAmount
|
||||
totalAmount={totalAmount}
|
||||
category={category}
|
||||
setCategory={setCategory}
|
||||
handleManualAmountChange={handleManualAmountChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue