initially setup
This commit is contained in:
parent
b2c68824dd
commit
701d1adc0b
70
src/components/common/Modal.jsx
Normal file
70
src/components/common/Modal.jsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import XIcon from "@/assets/XIcons";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import Button from "./Button";
|
||||||
|
|
||||||
|
const Modal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
onSubmit,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
footer,
|
||||||
|
actionLabel,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
onClose();
|
||||||
|
}, [disabled, onClose]);
|
||||||
|
|
||||||
|
const handleSubmit = useCallback(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
onSubmit();
|
||||||
|
}, [disabled, onSubmit]);
|
||||||
|
|
||||||
|
if (!isOpen) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="modal fade show"
|
||||||
|
style={{ display: "block", backgroundColor: "rgba(0,0,0,0.6)" }}
|
||||||
|
tabIndex="-1"
|
||||||
|
role="dialog"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
||||||
|
<div className="modal-content bg-dark text-white shadow-lg">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="modal-header border-0">
|
||||||
|
<h5 className="modal-title">{title}</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close btn-close-white"
|
||||||
|
onClick={handleClose}
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<XIcon color="white" size={20} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Body */}
|
||||||
|
<div className="modal-body">{body}</div>
|
||||||
|
|
||||||
|
{/* Footer */}
|
||||||
|
<div className="modal-footer border-0 d-flex flex-column gap-2">
|
||||||
|
<Button
|
||||||
|
disabled={disabled}
|
||||||
|
secondary
|
||||||
|
fullWidth
|
||||||
|
large
|
||||||
|
label={actionLabel}
|
||||||
|
onClick={handleSubmit}
|
||||||
|
/>
|
||||||
|
{footer}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
0
src/hooks/useOrganization.js
Normal file
0
src/hooks/useOrganization.js
Normal file
0
src/pages/Organization/OrganizationModal.jsx
Normal file
0
src/pages/Organization/OrganizationModal.jsx
Normal file
0
src/pages/Organization/OrganizationPage.jsx
Normal file
0
src/pages/Organization/OrganizationPage.jsx
Normal file
@ -1,93 +0,0 @@
|
|||||||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
|
||||||
import AttendanceRepository from '../../repositories/AttendanceRepository';
|
|
||||||
import {clearCacheKey} from '../apiDataManager';
|
|
||||||
|
|
||||||
// Fetch attendance data
|
|
||||||
export const fetchAttendanceData = createAsyncThunk(
|
|
||||||
'attendanceLogs/fetchAttendanceData',
|
|
||||||
async ( {projectId, fromDate, toDate}, thunkAPI ) =>
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
const response = await AttendanceRepository.getAttendanceFilteredByDate(projectId, fromDate, toDate);
|
|
||||||
return response?.data?.filter((log) => log.checkInTime !== null && log.activity !== 0);
|
|
||||||
} catch (error) {
|
|
||||||
return thunkAPI.rejectWithValue(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
export const markAttendance = createAsyncThunk(
|
|
||||||
'attendanceLogs/markAttendance', // Updated action type prefix
|
|
||||||
async ( formData, thunkAPI ) =>
|
|
||||||
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
let newRecordAttendance = {
|
|
||||||
Id: formData.id || null,
|
|
||||||
comment: formData.description,
|
|
||||||
employeeID: formData.employeeId,
|
|
||||||
projectID: formData.projectId,
|
|
||||||
date: new Date().toISOString(),
|
|
||||||
markTime: formData.markTime,
|
|
||||||
latitude: formData.latitude.toString(),
|
|
||||||
longitude: formData.longitude.toString(),
|
|
||||||
action: formData.action,
|
|
||||||
image: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await AttendanceRepository.markAttendance( newRecordAttendance );
|
|
||||||
return response.data;
|
|
||||||
} catch ( error )
|
|
||||||
{
|
|
||||||
const message = error?.response?.data?.message || error.message || "Error Occured During Api Call";
|
|
||||||
return thunkAPI.rejectWithValue(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Attendance Logs Slice
|
|
||||||
const attendanceLogsSlice = createSlice({
|
|
||||||
name: 'attendanceLogs', // Updated slice name
|
|
||||||
initialState: {
|
|
||||||
data: [],
|
|
||||||
loading: false,
|
|
||||||
error: null,
|
|
||||||
},
|
|
||||||
reducers: {
|
|
||||||
setAttendanceData: (state, action) => {
|
|
||||||
state.data = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraReducers: (builder) => {
|
|
||||||
builder
|
|
||||||
// Fetch attendance data
|
|
||||||
.addCase(fetchAttendanceData.pending, (state) => {
|
|
||||||
state.loading = true;
|
|
||||||
})
|
|
||||||
.addCase(fetchAttendanceData.fulfilled, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.data = action.payload;
|
|
||||||
})
|
|
||||||
.addCase(fetchAttendanceData.rejected, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = action.payload;
|
|
||||||
})
|
|
||||||
|
|
||||||
// Mark attendance - log attenace data
|
|
||||||
.addCase(markAttendance.fulfilled, (state, action) => {
|
|
||||||
const updatedRecord = action.payload;
|
|
||||||
const index = state.data.findIndex(item => item.id === updatedRecord.id);
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
state.data[index] = { ...state.data[index], ...updatedRecord };
|
|
||||||
} else {
|
|
||||||
state.data.push(updatedRecord);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { setAttendanceData } = attendanceLogsSlice.actions;
|
|
||||||
export default attendanceLogsSlice.reducer;
|
|
@ -1,38 +0,0 @@
|
|||||||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
|
||||||
import AttendanceRepository from '../../repositories/AttendanceRepository';
|
|
||||||
import {clearCacheKey} from '../apiDataManager';
|
|
||||||
|
|
||||||
export const markCurrentAttendance = createAsyncThunk(
|
|
||||||
'attendanceCurrentDate/markAttendance',
|
|
||||||
async ( formData, {getState, dispatch, rejectWithValue} ) =>
|
|
||||||
{
|
|
||||||
|
|
||||||
const { projectId } = getState().localVariables
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
// Create the new attendance record
|
|
||||||
const newRecordAttendance = {
|
|
||||||
Id: formData.id || null,
|
|
||||||
comment: formData.description,
|
|
||||||
employeeID: formData.employeeId,
|
|
||||||
projectId: projectId,
|
|
||||||
date: new Date().toISOString(),
|
|
||||||
markTime: formData.markTime,
|
|
||||||
latitude: formData.latitude.toString(),
|
|
||||||
longitude: formData.longitude.toString(),
|
|
||||||
action: formData.action,
|
|
||||||
image: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await AttendanceRepository.markAttendance(newRecordAttendance);
|
|
||||||
const markedAttendance = response.data
|
|
||||||
clearCacheKey("AttendanceLogs")
|
|
||||||
return markedAttendance;
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error marking attendance:', error);
|
|
||||||
return rejectWithValue(error.message); // Reject with error message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,56 +0,0 @@
|
|||||||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
|
||||||
import AttendanceRepository from '../../repositories/AttendanceRepository';
|
|
||||||
import { markAttendance } from './attedanceLogsSlice';
|
|
||||||
|
|
||||||
export const fetchEmployeeAttendanceData = createAsyncThunk(
|
|
||||||
'employeeAttendance/fetchEmployeeAttendanceData',
|
|
||||||
async ( {employeeId, fromDate, toDate}, thunkAPI ) =>
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
const response = await AttendanceRepository.getAttendanceByEmployee( employeeId, fromDate, toDate );
|
|
||||||
// return response?.data?.filter((log) => log.checkInTime !== null && log.activity !== 0);
|
|
||||||
return response.data
|
|
||||||
} catch (error) {
|
|
||||||
return thunkAPI.rejectWithValue(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const employeeAttendancesSlice = createSlice({
|
|
||||||
name: 'employeeAttendance', // Updated slice name
|
|
||||||
initialState: {
|
|
||||||
data: [],
|
|
||||||
loading: false,
|
|
||||||
error: null,
|
|
||||||
},
|
|
||||||
reducers: {
|
|
||||||
setEmployeeAttendanceData: (state, action) => {
|
|
||||||
state.data = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraReducers: (builder) => {
|
|
||||||
builder
|
|
||||||
// Fetch attendance data
|
|
||||||
.addCase(fetchEmployeeAttendanceData.pending, (state) => {
|
|
||||||
state.loading = true;
|
|
||||||
})
|
|
||||||
.addCase(fetchEmployeeAttendanceData.fulfilled, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.data = action.payload;
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
.addCase(fetchEmployeeAttendanceData.rejected, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = action.payload;
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { setEmployeeAttendanceData } = employeeAttendancesSlice.actions;
|
|
||||||
export default employeeAttendancesSlice.reducer;
|
|
Loading…
x
Reference in New Issue
Block a user