diff --git a/ipi-survey-platform/src/pages/Admin/configuration/QuarterlyWindows.jsx b/ipi-survey-platform/src/pages/Admin/configuration/QuarterlyWindows.jsx
index de35901..3f920b3 100644
--- a/ipi-survey-platform/src/pages/Admin/configuration/QuarterlyWindows.jsx
+++ b/ipi-survey-platform/src/pages/Admin/configuration/QuarterlyWindows.jsx
@@ -90,25 +90,25 @@ const QuarterlyWindows = () => {
const [isLoading, setIsLoading] = React.useState(false);
const [validationErrors, setValidationErrors] = React.useState({});
const [toastData, setToastData] = React.useState(null);
- const [isSaving, setIsSaving] = React.useState(false); // Add this line
+ const [isSaving, setIsSaving] = React.useState(false); // Add this line
const [sortConfig, setSortConfig] = React.useState({
key: null,
direction: 'asc'
});
const extractText = (node) => {
- if (typeof node === "string") return node;
- if (typeof node === "number") return String(node);
-
- if (node?.props?.children) {
- if (Array.isArray(node.props.children)) {
- return node.props.children.map(extractText).join(" ");
+ if (typeof node === "string") return node;
+ if (typeof node === "number") return String(node);
+
+ if (node?.props?.children) {
+ if (Array.isArray(node.props.children)) {
+ return node.props.children.map(extractText).join(" ");
+ }
+ return extractText(node.props.children);
}
- return extractText(node.props.children);
- }
-
- return "";
-};
+
+ return "";
+ };
// Format date to yyyy-MM-dd for input fields
const formatDateForInput = (dateString) => {
@@ -172,29 +172,29 @@ const QuarterlyWindows = () => {
const getSortedData = (data) => {
if (!sortConfig.key) return data;
-
+
return [...data].sort((a, b) => {
let aValue = a[sortConfig.key];
let bValue = b[sortConfig.key];
-
+
// Handle numeric comparisons
if (['year', 'assigned', 'responded', 'not_responded', 'submissionCount'].includes(sortConfig.key)) {
aValue = Number(aValue) || 0;
bValue = Number(bValue) || 0;
return sortConfig.direction === 'asc' ? aValue - bValue : bValue - aValue;
}
-
+
// Handle date comparisons
if (['startDate', 'endDate'].includes(sortConfig.key)) {
aValue = aValue ? new Date(aValue).getTime() : 0;
bValue = bValue ? new Date(bValue).getTime() : 0;
return sortConfig.direction === 'asc' ? aValue - bValue : bValue - aValue;
}
-
+
// Default string comparison
aValue = String(aValue || '').toLowerCase();
bValue = String(bValue || '').toLowerCase();
-
+
if (aValue < bValue) {
return sortConfig.direction === 'asc' ? -1 : 1;
}
@@ -206,88 +206,88 @@ const QuarterlyWindows = () => {
};
const headers = [
- {
- name: 'Survey Name',
+ {
+ name: 'Survey Name',
key: 'survey_name',
sortable: true,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Year',
+ {
+ name: 'Year',
key: 'year',
sortable: true,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Quarter',
+ {
+ name: 'Quarter',
key: 'quarter',
sortable: true,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Start Date',
+ {
+ name: 'Start Date',
key: 'startDate',
sortable: true,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'End Date',
+ {
+ name: 'End Date',
key: 'endDate',
sortable: true,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Grace Period',
+ {
+ name: 'Grace Period',
key: 'gracePeriod',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Assigned',
+ {
+ name: 'Assigned',
key: 'assigned',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Responded',
+ {
+ name: 'Responded',
key: 'responded',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Not Responded',
+ {
+ name: 'Not Responded',
key: 'not_responded',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Submission Count',
+ {
+ name: 'Submission Count',
key: 'submissionCount',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
- {
- name: 'Status',
+ {
+ name: 'Status',
key: 'status',
sortable: false,
- className: 'whitespace-nowrap text-left'
+ className: 'whitespace-nowrap text-left'
},
].map(header => {
if (!header.sortable) return { name: header.name, className: header.className };
-
+
const isActive = sortConfig.key === header.key;
const isAsc = sortConfig.direction === 'asc';
-
+
return {
name: (
-
handleSort(header.key)}
>
{header.name}
-
@@ -295,7 +295,7 @@ const QuarterlyWindows = () => {
className: header.className
};
});
-
+
const columnwidth = [
220, // Survey Name
100, // Year
@@ -309,16 +309,16 @@ const QuarterlyWindows = () => {
140, // Submission Count
120 // Actions
];
-
+
const filteredRows = React.useMemo(() => {
const term = searchTerm.trim().toLowerCase();
return quarterData.filter((item) => {
// Apply year filter
if (yearFilter !== 'all' && item.year !== yearFilter) return false;
-
+
// Apply quarter filter
if (quarterFilter !== 'all' && item.quarter !== quarterFilter) return false;
-
+
// Apply search term
if (!term) return true;
const haystack = [
@@ -345,18 +345,17 @@ const QuarterlyWindows = () => {
{children}
-
);
const sortedRows = getSortedData(filteredRows);
-
+
const rows = sortedRows.map((item) => [
item.survey_name || '-',
item.year,
@@ -364,13 +363,13 @@ const QuarterlyWindows = () => {
item.startDate ? formatDateForDisplay(item.startDate) : '-',
item.endDate ? formatDateForDisplay(item.endDate) : '-',
item.gracePeriod,
-
+
{item.assigned || '0'}
,
-
+
{item.responded || '0'}
,
-
+
{item.not_responded || '0'}
,
item.submissionCount,
@@ -381,19 +380,19 @@ const QuarterlyWindows = () => {
const yearOptions = React.useMemo(() => {
const currentYear = new Date().getFullYear();
const years = new Set(['all']);
-
+
// Add years from 2022 to current year
for (let y = 2022; y <= currentYear; y++) {
years.add(y.toString());
}
-
+
// Add any additional years that might be in the data
quarterData.forEach(item => {
if (item.year && !years.has(item.year)) {
years.add(item.year);
}
});
-
+
// Sort years in descending order (newest first)
return Array.from(years).sort((a, b) => {
if (a === 'all') return -1;
@@ -401,7 +400,7 @@ const QuarterlyWindows = () => {
return parseInt(b) - parseInt(a);
});
}, [quarterData]);
-
+
const quarterOptions = ['all', 'Q1', 'Q2', 'Q3', 'Q4'];
const openAddModal = () => {
@@ -420,18 +419,18 @@ const QuarterlyWindows = () => {
const openEditModal = async (index) => {
try {
setIsLoading(true);
-
+
// Calculate the actual index in the filtered data based on pagination
const actualIndex = (currentPage - 1) * pageSize + index;
const selected = filteredRows[actualIndex];
-
+
if (!selected || !selected.id) {
throw new Error('Invalid quarterly window selected');
}
-
+
// Fetch the latest data for this quarter
const response = await getQuarterlyWindowById(selected.id);
-
+
if (response && response.data) {
const quarterData = response.data;
const formData = {
@@ -449,7 +448,7 @@ const QuarterlyWindows = () => {
not_responded: quarterData.not_responded?.toString() || '0',
status: quarterData.is_active ? 'Active' : 'Inactive'
};
-
+
setEditingRow(actualIndex);
setForm(formData);
setOriginalForm(formData);
@@ -525,7 +524,7 @@ const QuarterlyWindows = () => {
const handleFormChange = (field) => (value) => {
setForm(prev => ({ ...prev, [field]: value }));
-
+
// Clear validation error when user starts typing
if (validationErrors[field]) {
setValidationErrors(prev => ({
@@ -535,125 +534,125 @@ const QuarterlyWindows = () => {
}
};
-const handleSave = async () => {
- try {
- if (!validateForm()) {
- return;
- }
-
- setIsSaving(true);
-
- const startDate = new Date(form.startDate);
- const endDate = new Date(form.endDate);
-
- const formattedData = {
- survey_name: form.survey_name || '',
- year: form.year ? parseInt(form.year, 10) : 0,
- quarter: form.quarter || '',
- start_date: startDate.toISOString().split('T')[0],
- end_date: endDate.toISOString().split('T')[0],
- grace_periods_days: form.gracePeriod ? parseInt(form.gracePeriod.split(' ')[0], 10) || 0 : 0,
- assigned: form.assigned || 0,
- responded: form.responded || 0,
- not_responded: form.not_responded || 0,
- is_active: form.status === 'Active',
- establishment: form.establishment || '-',
- };
-
- if (modalMode === 'add') {
- const response = await createQuarterlyWindow(formattedData);
- if (response.status === 'success') {
- // Fetch the latest data from the server
- const latestData = await getQuarterlyWindows();
- if (latestData.status === 'success' && Array.isArray(latestData.data)) {
- const formattedData = latestData.data.map(item => ({
- id: item.id,
- survey_name: item.survey_name || '',
- establishment: item.establishment || '-',
- year: item.year?.toString() || '',
- quarter: item.quarter || '',
- startDate: item.start_date || '',
- endDate: item.end_date || '',
- gracePeriod: item.grace_periods_days ? `${item.grace_periods_days} days` : '0 days',
- submissionCount: item.submission_count?.toString() || '-',
- assigned: item.assigned?.toString() || '0',
- responded: item.responded?.toString() || '0',
- not_responded: item.not_responded?.toString() || '0',
- status: item.is_active ? 'Active' : 'Inactive'
- }));
- setQuarterData(formattedData);
- }
-
- setToastData({
- message: 'Quarterly survey created successfully!',
- type: 'success'
- });
- } else {
- const errorMessage = response.message || 'Failed to add quarterly window';
- setToastData({
- message: errorMessage,
- type: 'error'
- });
- console.error('Failed to add quarterly window:', errorMessage);
- }
- } else if (modalMode === 'edit' && editingRow !== null) {
- const itemId = quarterData[editingRow]?.id;
- if (!itemId) {
- setToastData({
- message: 'Error: Could not find the item to update',
- type: 'error'
- });
- console.error('Error: Could not find the item to update');
+ const handleSave = async () => {
+ try {
+ if (!validateForm()) {
return;
}
- const response = await updateQuarterlyWindow(itemId, formattedData);
- if (response.status === 'success') {
- // Fetch the latest data from the server
- const latestData = await getQuarterlyWindows();
- if (latestData.status === 'success' && Array.isArray(latestData.data)) {
- const formattedData = latestData.data.map(item => ({
- id: item.id,
- survey_name: item.survey_name || '',
- establishment: item.establishment || '-',
- year: item.year?.toString() || '',
- quarter: item.quarter || '',
- startDate: item.start_date || '',
- endDate: item.end_date || '',
- gracePeriod: item.grace_periods_days ? `${item.grace_periods_days} days` : '0 days',
- submissionCount: item.submission_count?.toString() || '-',
- assigned: item.assigned?.toString() || '0',
- responded: item.responded?.toString() || '0',
- not_responded: item.not_responded?.toString() || '0',
- status: item.is_active ? 'Active' : 'Inactive'
- }));
- setQuarterData(formattedData);
+
+ setIsSaving(true);
+
+ const startDate = new Date(form.startDate);
+ const endDate = new Date(form.endDate);
+
+ const formattedData = {
+ survey_name: form.survey_name || '',
+ year: form.year ? parseInt(form.year, 10) : 0,
+ quarter: form.quarter || '',
+ start_date: startDate.toISOString().split('T')[0],
+ end_date: endDate.toISOString().split('T')[0],
+ grace_periods_days: form.gracePeriod ? parseInt(form.gracePeriod.split(' ')[0], 10) || 0 : 0,
+ assigned: form.assigned || 0,
+ responded: form.responded || 0,
+ not_responded: form.not_responded || 0,
+ is_active: form.status === 'Active',
+ establishment: form.establishment || '-',
+ };
+
+ if (modalMode === 'add') {
+ const response = await createQuarterlyWindow(formattedData);
+ if (response.status === 'success') {
+ // Fetch the latest data from the server
+ const latestData = await getQuarterlyWindows();
+ if (latestData.status === 'success' && Array.isArray(latestData.data)) {
+ const formattedData = latestData.data.map(item => ({
+ id: item.id,
+ survey_name: item.survey_name || '',
+ establishment: item.establishment || '-',
+ year: item.year?.toString() || '',
+ quarter: item.quarter || '',
+ startDate: item.start_date || '',
+ endDate: item.end_date || '',
+ gracePeriod: item.grace_periods_days ? `${item.grace_periods_days} days` : '0 days',
+ submissionCount: item.submission_count?.toString() || '-',
+ assigned: item.assigned?.toString() || '0',
+ responded: item.responded?.toString() || '0',
+ not_responded: item.not_responded?.toString() || '0',
+ status: item.is_active ? 'Active' : 'Inactive'
+ }));
+ setQuarterData(formattedData);
+ }
+
+ setToastData({
+ message: 'Quarterly survey created successfully!',
+ type: 'success'
+ });
+ } else {
+ const errorMessage = response.message || 'Failed to add quarterly window';
+ setToastData({
+ message: errorMessage,
+ type: 'error'
+ });
+ console.error('Failed to add quarterly window:', errorMessage);
+ }
+ } else if (modalMode === 'edit' && editingRow !== null) {
+ const itemId = quarterData[editingRow]?.id;
+ if (!itemId) {
+ setToastData({
+ message: 'Error: Could not find the item to update',
+ type: 'error'
+ });
+ console.error('Error: Could not find the item to update');
+ return;
+ }
+ const response = await updateQuarterlyWindow(itemId, formattedData);
+ if (response.status === 'success') {
+ // Fetch the latest data from the server
+ const latestData = await getQuarterlyWindows();
+ if (latestData.status === 'success' && Array.isArray(latestData.data)) {
+ const formattedData = latestData.data.map(item => ({
+ id: item.id,
+ survey_name: item.survey_name || '',
+ establishment: item.establishment || '-',
+ year: item.year?.toString() || '',
+ quarter: item.quarter || '',
+ startDate: item.start_date || '',
+ endDate: item.end_date || '',
+ gracePeriod: item.grace_periods_days ? `${item.grace_periods_days} days` : '0 days',
+ submissionCount: item.submission_count?.toString() || '-',
+ assigned: item.assigned?.toString() || '0',
+ responded: item.responded?.toString() || '0',
+ not_responded: item.not_responded?.toString() || '0',
+ status: item.is_active ? 'Active' : 'Inactive'
+ }));
+ setQuarterData(formattedData);
+ }
+
+ setToastData({
+ message: 'Quarterly survey updated successfully!',
+ type: 'success'
+ });
+ } else {
+ const errorMessage = response.message || 'Failed to update quarterly window';
+ setToastData({
+ message: errorMessage,
+ type: 'error'
+ });
+ console.error('Failed to update quarterly window:', errorMessage);
}
-
- setToastData({
- message: 'Quarterly survey updated successfully!',
- type: 'success'
- });
- } else {
- const errorMessage = response.message || 'Failed to update quarterly window';
- setToastData({
- message: errorMessage,
- type: 'error'
- });
- console.error('Failed to update quarterly window:', errorMessage);
}
+ handleCloseModal();
+ } catch (error) {
+ const errorMessage = error.response?.data?.message || error.message || 'An error occurred while saving';
+ setToastData({
+ message: errorMessage,
+ type: 'error'
+ });
+ console.error('Error saving quarterly window:', error);
+ } finally {
+ setIsSaving(false);
}
- handleCloseModal();
- } catch (error) {
- const errorMessage = error.response?.data?.message || error.message || 'An error occurred while saving';
- setToastData({
- message: errorMessage,
- type: 'error'
- });
- console.error('Error saving quarterly window:', error);
- } finally {
- setIsSaving(false);
- }
-};
+ };
return (
@@ -669,7 +668,7 @@ const handleSave = async () => {