Commit 10a0fed8 authored by Priyanka Burri's avatar Priyanka Burri

Activity

parent f6fff81e
......@@ -7,6 +7,8 @@ import './App.css';
import PageNotFound from './pages/pagenotfound/PageNotFound';
import Exporttable from './pages/reportexport'
import AdminProfile from './pages/adminProfile';
import Admin from './pages/admin';
function App() {
return (
......@@ -21,7 +23,7 @@ function App() {
<Route path="/viewreportee" element={<Layout><Viewreportee/></Layout>}/>
{/* fetch reports */}
<Route path="/reportees" element={<Layout><Exporttable/></Layout>}/>
<Route path="/Admin" element={<Layout><Admin/></Layout>}/>
<Route path="/*" element={<PageNotFound/>}/>
</Routes>
......
import React, { useState } from "react";
import MyCreateModal from "./createMyModel";
export default function CreateActivityButton({handleRefresh}) {
const [showMyModal, setShowMyModal] = useState(false);
return (
<div className="bg-blue-400 bg-opacity-30 mr-4" onClick={(e) => e.stopPropagation()}>
<button
className="bg-blue-400 text-white px-2 py-2 rounded hover:scale-95 transition text-sm"
onClick={()=>setShowMyModal(true)}
>
Create Activity
</button>
{showMyModal?<MyCreateModal setShowMyModal={setShowMyModal} handleRefresh={handleRefresh}/>:null}
</div>
);
}
\ No newline at end of file
import React, { useEffect, useState, useCallback } from "react";
import axios from "axios";
import { base_url } from "../../utils/constants";
import { fetchData } from "../../pages/admin";
const MyCreateModal = ({ setShowMyModal,handleRefresh}) => {
const [formData, setFormData] = useState({
atype: "",
aName: "",
appreciate: "",
depreciate: "",
});
const [enableSubmit, setEnableSubmit] = useState(false);
const handleInputChange = useCallback(
(event) => {
const { name, value } = event.target;
setFormData({ ...formData, [name]: value });
},
[formData]
);
const handleRadioChange = useCallback(
(event) => {
const { name, value } = event.target;
setFormData({ ...formData, [name]: value === "true" });
},
[formData]
);
useEffect(() => {
const { atype, aName, appreciate, depreciate } = formData;
if (
atype !== "" &&
aName !== "" &&
(appreciate === true || appreciate === false) &&
(depreciate === true || depreciate === false)
) {
// All conditions met
setEnableSubmit(true);
} else {
setEnableSubmit(false);
}
}, [formData]);
const handleSubmit = async (event) => {
event.preventDefault();
try {
// console.log(formData.atype);
await axios.post(`${base_url}/addMasterActivity`, formData)
.then((res)=>fetchData())
setShowMyModal(false);
setFormData({
atype: "",
aName: "",
appreciate: "",
depreciate: "",
});
handleRefresh()
} catch (error) {
console.error("Error submitting form data:", error);
}
};
return (
<div className="absolute w-full h-full inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex items-center justify-center">
<div className="bg-white rounded-md lg:w-4/12 sm:w-100">
<div className="text-white py-3 pl-2 bg-blue-500 rounded-md text-start">
atype Type
</div>
<div>
<form
onSubmit={handleSubmit}
className="p-2 max-w-sm mx-auto text-[12px]"
>
<div className="flex items-center my-5">
<label htmlFor="atype">
SELECT atype<span className="text-[15px]">*</span>:{" "}
</label>
<select
id="atype"
name="atype"
value={formData.atype}
onChange={handleInputChange}
className="bg-gray-50 ml-2 w-6/12 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5"
>
<option value="">Select</option>
<option value="duties">Duties</option>
<option value="initiative">Initiative</option>
</select>
</div>
<div className="flex items-center">
<label className="font-medium mr-2">
atype Name<span className="text-[15px]">*</span>:
</label>
<input
type="text"
placeholder="Enter atype name"
name="aName"
value={formData.aName}
onChange={handleInputChange}
className="border border-gray-300 rounded p-2"
/>
</div>
<div className="flex items-center mb-1">
<label htmlFor="appreciate" className="font-medium">
Appreciate<span className="text-[15px]">*</span>:
</label>
<label htmlFor="appreciateTrue" className="font-medium ms-2">
True{" "}
</label>
<input
id="appreciateTrue"
type="radio"
value="true"
name="appreciate"
checked={formData.appreciate === true}
onChange={handleRadioChange}
className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
<label htmlFor="appreciateFalse" className="font-medium">
False{" "}
</label>
<input
id="appreciateFalse"
type="radio"
value="false"
name="appreciate"
checked={formData.appreciate === false}
onChange={handleRadioChange}
className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
</div>
<div className="flex items-center mb-1">
<label htmlFor="depreciate" className="font-medium">
Depreciate<span className="text-[15px]">*</span>:
</label>
<label htmlFor="depreciateTrue" className="font-medium ms-2">
True{" "}
</label>
<input
id="depreciateTrue"
type="radio"
value="true"
name="depreciate"
checked={formData.depreciate === true}
onChange={handleRadioChange}
className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
<label htmlFor="depreciateFalse" className="font-medium">
False{" "}
</label>
<input
id="depreciateFalse"
type="radio"
value="false"
name="depreciate"
checked={formData.depreciate === false}
onChange={handleRadioChange}
className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
</div>
<div className="flex items-center justify-end mb-3">
<button className="px-3 py-2 rounded-md bg-gray-700 text-white"
onClick={()=>setShowMyModal(false)}
>
Cancel
</button>
<button
type="submit"
className={`px-3 py-2 ml-5 rounded-md ${
enableSubmit
? "bg-blue-500 text-white"
: "bg-gray-400 text-white"
}`}
disabled={!enableSubmit}
title="Please fill all fields to submit"
>
Submit
</button>
</div>
</form>
</div>
</div>
</div>
);
};
export default MyCreateModal;
\ No newline at end of file
......@@ -48,13 +48,15 @@ import SetWindowSize from '../../utils/SetWindowSize';
import DashboardIcon from '../../assets/icons/dashboardIcon';
import ReportsIcon from '../../assets/icons/reportsIcon';
import AdminProfileIcon from '../../assets/icons/adminProfileIcon'; // Assuming you have an icon for Admin Profile
import Admin from "../../pages/admin";
const menus = [
{ title: "Dashboard", path: '/dashboard', selectPaths: ['dashboard'], icon: <DashboardIcon /> },
{ title: "My Reportees", path: '/myreportees', selectPaths: ['myreportees', 'viewreportee'], icon: <ReportsIcon /> },
{ title: "Reports", path: '/reportees', selectPaths:['reportees'], icon: <ReportsIcon /> },
{ title: "Activity List", path: '/admin', selectPaths:['admin'], icon: <ReportsIcon /> },
]
function Sidebar() {
const url = window.location.href;
const [windowWidth, windowHeight] = SetWindowSize();
......
......@@ -80,10 +80,10 @@ function Table({headers, data,loading, handleSorting }) {
(data?.length)?<tbody >
{
data?.map((item, index) => (
<tr key={item.id} className="bg-[#eef5ff] font-medium hover:bg-white " >
<tr key={item._id} id={item?._id}className="bg-[#eef5ff] font-medium hover:bg-white " >
{
headers?.map(({render, id}) => (
<td className="px-6 py-2 " >
<td className="px-6 py-2 capitalize" >
{render ? render(item[id]) : item[id] === "" ? "NA" : item[id] }
</td>
))
......
import React, { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux"; // Import useDispatch
import { base_url } from "../../utils/constants";
import CreateActivityButton from '../../components/modal/createActivityButton';
import axios from 'axios';
import Table from '../../components/table';
import Loading from "../../components/loading Component/Loading";
import { styles } from './styles.js';
import { convertToString } from "../../utils/commonFunctions";
import axiosApi from '../../api/axiosConfig'
// Define fetchData function
export const fetchData = async () => {
try {
const response = await axios.get(`${base_url}/activities`);
//setActivitiesList(response.data)
return response.data;
} catch (error) {
console.error('Error fetching data:', error);
throw error; // Rethrow the error for handling by the caller if needed
}
};
const Admin = () => {
const [activitiesList, setActivitiesList] = useState([]);
const [refresh,setRefresh]=useState(true)
const { loading } = useSelector((state) => state.reportees);
const dispatch = useDispatch(); // Initialize useDispatch
const handleRefresh=()=>{
setRefresh(!refresh)
}
useEffect(() => {
// Call fetchData when the component mounts
fetchData().then((res)=>setActivitiesList(res))
}, [refresh]);
const handleDelete = async (_id) => {
try {
//console.log("Deleting activity with id:", _id);
await axiosApi.put(`${base_url}/deleteMasterActivity`, { id: _id });
setRefresh(!refresh)
// console.log("Deleted successfully");
} catch (error) {
console.error("Error deleting activity:", _id);
console.error("Error:", error);
}
};
const headers = [
{ title: "Activity Type", id: "atype" },
{ title: "Activity Name", id: "aName" },
{ title: "Appreciate", id: "appreciate", render: (value) => convertToString(value) },
{ title: "Depreciate", id: "depreciate", render: (value) => convertToString(value) },
{
title: "Delete",
id: "_id",
render: (id) => (
<button
className="bg-red-400 text-white rounded-md px-1 py-1 flex items-center justify-center w-[40px]"
onClick={() => {
if (id) {
handleDelete(id);
//console.log(id)
} else {
console.error("Item or item._id is undefined");
}
}}
>
X
</button>
)
},
];
if (loading) return <Loading />;
return (
<div>
<div className={styles.createActivityContainer}>
<div className={styles.textBlueHeading}>
ACTIVITY LIST
</div>
<div className="flex" style={{ justifyContent: 'flex-end', marginBottom: "10px" }}>
<CreateActivityButton handleRefresh={handleRefresh} />
</div>
<Table headers={headers} loading={loading} data={activitiesList} />
</div>
</div>
);
};
export default Admin;
export const styles = {
createActivityContainer: "overflow-auto sm:rounded-lg p-4 bg-[#E9EDEE] ",
textBlueHeading: "text-blue-800 py-3 pl-2 text-center fond-bold text-2xl",
};
\ No newline at end of file
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
export const fetchUsers = createAsyncThunk("user/fetchUsers", async () => {
try {
const response = await axios.get("/addMasterActivity");
return response.data;
} catch (error) {
throw error;
}
});
export const addActivity = createAsyncThunk("user/addUser", async (values) => {
try {
const response = await axios.post(
"/addMasterActivity",
{
type: values.type,
aId: values.aId,
aId: values.aId,
appreciate: values.appreciate,
depreciate:values.depreciate,
},
{
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
}
);
return response.data;
} catch (error) {
throw error;
}
});
const activitiesSlice= createSlice({
name: "activities",
initialState: {
loading: false,
user: [],
error: "",
isSuccess: "",
},
extraReducers: (builder) => {
builder.addCase(fetchUsers.pending, (state) => {
state.loading = true;
});
builder.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.user = action.payload;
state.error = "";
});
builder.addCase(fetchUsers.rejected, (state, action) => {
state.loading = false;
state.user = [];
state.error = action.error.message;
});
builder.addCase(addActivity.pending, (state) => {
state.loading = true;
state.error = "";
});
builder.addCase(addActivity.fulfilled, (state, action) => {
state.loading = false;
state.user = [];
state.isSuccess = action.payload;
});
builder.addCase(addActivity.rejected, (state, action) => {
state.loading = false;
state.user = [];
state.error = action.error.message;
});
},
});
export default activitiesSlice.reducer;
......@@ -3,12 +3,14 @@ import reporteesReducer from './reporteesSlice';
import userReducer from './userSlice';
import reportReducer from './viewreporteeSlice';
import exporttableReducer from './exporttableslice';
import activitiesReducer from './activitiesSlice'
const rootReducer = combineReducers({
userDetails: userReducer,
reportees: reporteesReducer,
reports: reportReducer,
totalreportees: exporttableReducer
totalreportees: exporttableReducer,
activities: activitiesReducer,
});
export default rootReducer;
\ No newline at end of file
......@@ -34,4 +34,9 @@ export const convertUTCToLocal = (utcDate) => {
const localTimeMillis = utcDateObj.getTime() + utcDateObj.getTimezoneOffset() * 60 * 1000;
const localDateObj = new Date(localTimeMillis);
return moment(localDateObj).format('DD-MM-YYYY')
}
export const convertToString = (value) =>{
return String(value);
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment