diff --git a/public/assets/vendor/css/core.css b/public/assets/vendor/css/core.css index 85124986..79538366 100644 --- a/public/assets/vendor/css/core.css +++ b/public/assets/vendor/css/core.css @@ -20475,7 +20475,7 @@ li:not(:first-child) .dropdown-item, } /* text-size */ .text-tiny{ - font-size: 13px; + font-size: 10px; } /* rtl:end:remove */ .text-primary { diff --git a/src/components/Expenses/ExpenseStatusLogs.jsx b/src/components/Expenses/ExpenseStatusLogs.jsx index 443b07ba..575508db 100644 --- a/src/components/Expenses/ExpenseStatusLogs.jsx +++ b/src/components/Expenses/ExpenseStatusLogs.jsx @@ -1,14 +1,19 @@ -import { useState } from "react"; +import { useState,useMemo } from "react"; import Avatar from "../common/Avatar"; import { formatUTCToLocalTime } from "../../utils/dateUtils"; + const ExpenseStatusLogs = ({ data }) => { const [visibleCount, setVisibleCount] = useState(4); - const logsToShow = [...(data?.expenseLogs || [])] - .sort((a, b) => new Date(b.updateAt) - new Date(a.updateAt)) - .slice(0, visibleCount); + const sortedLogs = useMemo(() => { + if (!data?.expenseLogs) return []; + return [...data.expenseLogs].sort( + (a, b) => new Date(b.updateAt) - new Date(a.updateAt) + ); + }, [data?.expenseLogs]); + const logsToShow = sortedLogs.slice(0, visibleCount); const handleShowMore = () => { setVisibleCount((prev) => prev + 4); @@ -17,11 +22,8 @@ const ExpenseStatusLogs = ({ data }) => { return ( <>
- {logsToShow.map((log, index) => ( -
+ {logsToShow.map((log) => ( +
{ />
-
-
-
-
- {`${log.updatedBy.firstName} ${log.updatedBy.lastName}`} - - {log.action} - - {formatUTCToLocalTime(log?.updateAt)} -
-
-
- {log.comment} -
+
+
+ {`${log.updatedBy.firstName} ${log.updatedBy.lastName}`} + + {log.action} + + + {formatUTCToLocalTime(log.updateAt,true)} + +
+
+ {log.comment}
@@ -50,7 +50,7 @@ const ExpenseStatusLogs = ({ data }) => { ))}
- {data?.expenseLogs?.length > visibleCount && ( + {sortedLogs.length > visibleCount && (
-
+
{" "}
-
-
- -
- {data?.gstNumber} + {data?.gstNumber && ( +
+
+ +
{data?.gstNumber}
-
- + )} {/* Row 4 */}
@@ -257,7 +256,7 @@ const ViewExpense = ({ ExpenseId }) => { > Created By : -
+
{
)} -
-
+
+
-
- {data?.paidBy?.firstName} {data?.paidBy?.lastName} +
+ + + {`${data.paidBy?.firstName ?? ""} ${ + data.paidBy?.lastName ?? "" + }`.trim() || "N/A"} +
@@ -363,7 +372,7 @@ const ViewExpense = ({ ExpenseId }) => { )}
)} -
+
{Array.isArray(data?.nextStatus) && data.nextStatus.length > 0 && ( <> diff --git a/src/components/common/DatePicker.jsx b/src/components/common/DatePicker.jsx index 9645fddb..bc0af783 100644 --- a/src/components/common/DatePicker.jsx +++ b/src/components/common/DatePicker.jsx @@ -22,22 +22,23 @@ const DatePicker = ({ }); useEffect(() => { - if (inputRef.current) { - flatpickr(inputRef.current, { - dateFormat: "d-m-Y", - allowInput: allowText, - defaultDate: value - ? flatpickr.parseDate(value, "Y-m-d") - : null, - maxDate:maxDate, - minDate:new Date(minDate?.split("T")[0]) ?? undefined, - onChange: function (selectedDates, dateStr) { - onChange(dateStr); - }, - ...rest - }); - } - }, [inputRef]); + if (inputRef.current) { + const parsedMinDate = minDate ? new Date(minDate.split("T")[0]) : undefined; + + flatpickr(inputRef.current, { + dateFormat: "d-m-Y", + allowInput: allowText, + defaultDate: value ? flatpickr.parseDate(value, "Y-m-d") : null, + maxDate: maxDate, + minDate: parsedMinDate, + onChange: function (selectedDates, dateStr) { + onChange(dateStr); + }, + ...rest + }); + } +}, [inputRef, minDate, maxDate]); + return (
diff --git a/src/hooks/usePositionTracker.js b/src/hooks/usePositionTracker.js index 43ed4e9d..9c180b1f 100644 --- a/src/hooks/usePositionTracker.js +++ b/src/hooks/usePositionTracker.js @@ -1,20 +1,27 @@ import { useState, useEffect } from 'react'; import showToast from '../services/toastService'; -export const usePositionTracker = () => { - const [coords, setCoords] = useState({ latitude: 0, longitude: 0 }); +let hasShownLocationErrorToast = false; // global flag - useEffect(() => { - const locationID = navigator.geolocation.watchPosition( - ({ coords }) => { - setCoords(coords); - }, - (error) => { - showToast("Please Allow Location","warn"); - }, - { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } - ); - return () => navigator.geolocation.clearWatch(locationID); - }, []); - return coords; - }; \ No newline at end of file +export const usePositionTracker = () => { + const [coords, setCoords] = useState({ latitude: 0, longitude: 0 }); + + useEffect(() => { + const locationID = navigator.geolocation.watchPosition( + ({ coords }) => { + setCoords(coords); + }, + (error) => { + if (!hasShownLocationErrorToast) { + showToast("Please Allow Location", "warn"); + hasShownLocationErrorToast = true; + } + }, + { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } + ); + + return () => navigator.geolocation.clearWatch(locationID); + }, []); + + return coords; +};