feat(admin-center): implement admin center settings retrieval and enhance holiday population logic

- Added a new API endpoint in AdminCenterController to fetch admin center settings, including organization details.
- Updated the admin center API router to include the new settings route.
- Enhanced the holiday controller to check for recent holiday population before attempting to repopulate, preventing duplicate entries.
- Improved the holiday calendar component to manage holiday population attempts and display loading states.
- Updated localization files to support new messages related to calculation methods and holiday settings.
This commit is contained in:
chamikaJ
2025-07-30 11:35:12 +05:30
parent 069ae6ccb1
commit 9dfc1fa375
19 changed files with 340 additions and 226 deletions

View File

@@ -55,6 +55,8 @@ const HolidayCalendar: React.FC<HolidayCalendarProps> = ({ themeMode, workingDay
const [editModalVisible, setEditModalVisible] = useState(false);
const [selectedHoliday, setSelectedHoliday] = useState<IHolidayCalendarEvent | null>(null);
const [currentDate, setCurrentDate] = useState<Dayjs>(dayjs());
const [isPopulatingHolidays, setIsPopulatingHolidays] = useState(false);
const [hasAttemptedPopulation, setHasAttemptedPopulation] = useState(false);
const fetchHolidayTypes = async () => {
try {
@@ -69,9 +71,18 @@ const HolidayCalendar: React.FC<HolidayCalendarProps> = ({ themeMode, workingDay
const populateHolidaysIfNeeded = async () => {
// Check if we have holiday settings with a country code but no holidays
if (holidaySettings?.country_code && holidays.length === 0) {
// Also check if we haven't already attempted population and we're not currently populating
if (
holidaySettings?.country_code &&
holidays.length === 0 &&
!hasAttemptedPopulation &&
!isPopulatingHolidays
) {
try {
console.log('🔄 No holidays found, attempting to populate official holidays...');
setIsPopulatingHolidays(true);
setHasAttemptedPopulation(true);
const populateRes = await holidayApiService.populateCountryHolidays();
if (populateRes.done) {
console.log('✅ Official holidays populated successfully');
@@ -80,6 +91,8 @@ const HolidayCalendar: React.FC<HolidayCalendarProps> = ({ themeMode, workingDay
}
} catch (error) {
console.warn('⚠️ Could not populate official holidays:', error);
} finally {
setIsPopulatingHolidays(false);
}
}
};
@@ -110,7 +123,12 @@ const HolidayCalendar: React.FC<HolidayCalendarProps> = ({ themeMode, workingDay
// Check if we need to populate holidays when holiday settings are loaded
useEffect(() => {
populateHolidaysIfNeeded();
}, [holidaySettings, holidays.length]);
}, [holidaySettings]);
// Reset population attempt state when holiday settings change
useEffect(() => {
setHasAttemptedPopulation(false);
}, [holidaySettings?.country_code]);
const customHolidays = useMemo(() => {
return holidays.filter(holiday => holiday.source === 'custom');
@@ -300,6 +318,11 @@ const HolidayCalendar: React.FC<HolidayCalendarProps> = ({ themeMode, workingDay
{holidaySettings.country_code}
{holidaySettings.state_code && ` (${holidaySettings.state_code})`}
</span>
{isPopulatingHolidays && (
<span style={{ marginLeft: 8, color: '#faad14' }}>
🔄 Populating official holidays...
</span>
)}
</Typography.Text>
)}
</div>

View File

@@ -400,7 +400,7 @@ const RateCardDrawer = ({
handleDeleteRole(index);
}}
>
<Tooltip title="Delete">
<Tooltip title={t('deleteTooltip') || 'Delete'}>
<Button size="small" icon={<DeleteOutlined />} />
</Tooltip>
</Popconfirm>
@@ -504,10 +504,10 @@ const RateCardDrawer = ({
action={
<Space direction="horizontal">
<Button size="small" type="primary" onClick={handleConfirmSave}>
Save
{t('saveButton') || 'Save'}
</Button>
<Button size="small" danger onClick={handleConfirmDiscard}>
Discard
{t('discardButton') || 'Discard'}
</Button>
</Space>
}
@@ -568,8 +568,10 @@ const RateCardDrawer = ({
<Alert
message={
isManDaysMethod
? `Organization is using man days calculation (${organization.hours_per_day || 8}h/day). Rates above represent daily rates.`
: 'Organization is using hourly calculation. Rates above represent hourly rates.'
? t('manDaysCalculationMessage', {
hours: organization.hours_per_day || 8
}) || `Organization is using man days calculation (${organization.hours_per_day || 8}h/day). Rates above represent daily rates.`
: t('hourlyCalculationMessage') || 'Organization is using hourly calculation. Rates above represent hourly rates.'
}
type="info"
showIcon