Skip to content

Commit

Permalink
feat (frontend): approve organization api integration (#1215)
Browse files Browse the repository at this point in the history
* fix managProject: UI fix

* feat manageOrganization: redirect to approveOrganization on org click on To Be Verified tab org list

* fix rejectOrganization: service for rejectOrganization add

* feat organizationApproval: state management to show approving/rejecting status, redirect to manage-org after approval success
  • Loading branch information
NSUWAL123 authored Feb 16, 2024
1 parent 2b71abc commit cbbaf03
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 16 deletions.
44 changes: 41 additions & 3 deletions src/frontend/src/api/OrganisationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ export const PatchOrganizationDataService: Function = (url: string, payload: any
};
};

export const ApproveOrganizationService: Function = (url: string, organizationId: string) => {
export const ApproveOrganizationService: Function = (url: string) => {
return async (dispatch) => {
const approveOrganization = async (url) => {
const approveOrganization = async (url: string) => {
try {
await axios.post(url, organizationId);
dispatch(OrganisationAction.SetOrganizationApproving(true));
await axios.post(url);
dispatch(
CommonActions.SetSnackBar({
open: true,
Expand All @@ -171,7 +172,11 @@ export const ApproveOrganizationService: Function = (url: string, organizationId
duration: 2000,
}),
);
dispatch(OrganisationAction.SetOrganizationApproving(false));
dispatch(OrganisationAction.SetOrganisationFormData({}));
dispatch(OrganisationAction.SetOrganizationApprovalStatus(true));
} catch (error) {
dispatch(OrganisationAction.SetOrganizationApproving(false));
dispatch(
CommonActions.SetSnackBar({
open: true,
Expand All @@ -185,3 +190,36 @@ export const ApproveOrganizationService: Function = (url: string, organizationId
await approveOrganization(url);
};
};

export const RejectOrganizationService: Function = (url: string) => {
return async (dispatch) => {
const rejectOrganization = async (url: string) => {
try {
dispatch(OrganisationAction.SetOrganizationRejecting(true));
await axios.delete(url);
dispatch(
CommonActions.SetSnackBar({
open: true,
message: 'Organization rejected successfully.',
variant: 'success',
duration: 2000,
}),
);
dispatch(OrganisationAction.SetOrganizationRejecting(false));
dispatch(OrganisationAction.SetOrganisationFormData({}));
dispatch(OrganisationAction.SetOrganizationApprovalStatus(true));
} catch (error) {
dispatch(OrganisationAction.SetOrganizationRejecting(false));
dispatch(
CommonActions.SetSnackBar({
open: true,
message: 'Failed to reject organization.',
variant: 'error',
duration: 2000,
}),
);
}
};
await rejectOrganization(url);
};
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import InputTextField from '@/components/common/InputTextField';
import TextArea from '@/components/common/TextArea';
import Button from '@/components/common/Button';
import { ApproveOrganizationService, GetIndividualOrganizationService } from '@/api/OrganisationService';
import {
ApproveOrganizationService,
GetIndividualOrganizationService,
RejectOrganizationService,
} from '@/api/OrganisationService';
import CoreModules from '@/shared/CoreModules';
import { OrganisationAction } from '@/store/slices/organisationSlice';

const OrganizationForm = () => {
const dispatch = useDispatch();
const params = useParams();
const navigate = useNavigate();
const organizationId = params.id;
const organisationFormData: any = CoreModules.useAppSelector((state) => state.organisation.organisationFormData);
const organizationApproving: any = CoreModules.useAppSelector(
(state) => state.organisation.organizationApprovalStatus.organizationApproving,
);
const organizationRejecting: any = CoreModules.useAppSelector(
(state) => state.organisation.organizationApprovalStatus.organizationRejecting,
);
const organizationApprovalSuccess: any = CoreModules.useAppSelector(
(state) => state.organisation.organizationApprovalStatus.isSuccess,
);

useEffect(() => {
if (organizationId) {
Expand All @@ -20,11 +35,27 @@ const OrganizationForm = () => {
}, [organizationId]);

const approveOrganization = () => {
dispatch(
ApproveOrganizationService(`${import.meta.env.VITE_API_URL}/organisation/approve`, { org_id: organizationId }),
);
if (organizationId) {
dispatch(
ApproveOrganizationService(
`${import.meta.env.VITE_API_URL}/organisation/approve/?org_id=${parseInt(organizationId)}`,
),
);
}
};

const rejectOrganization = () => {
dispatch(RejectOrganizationService(`${import.meta.env.VITE_API_URL}/organisation/${organizationId}`));
};

// redirect to manage-organization page after approve/reject success
useEffect(() => {
if (organizationApprovalSuccess) {
dispatch(OrganisationAction.SetOrganizationApprovalStatus(false));
navigate('/organisation');
}
}, [organizationApprovalSuccess]);

return (
<div className="fmtm-max-w-[50rem] fmtm-bg-white fmtm-py-5 lg:fmtm-py-10 fmtm-px-5 lg:fmtm-px-9 fmtm-mx-auto">
<div className="fmtm-flex fmtm-justify-center">
Expand All @@ -40,6 +71,7 @@ const OrganizationForm = () => {
value={organisationFormData?.name}
onChange={() => {}}
fieldType="text"
disabled
/>
<InputTextField
id="email"
Expand All @@ -48,6 +80,7 @@ const OrganizationForm = () => {
value={organisationFormData?.email}
onChange={() => {}}
fieldType="text"
disabled
/>
<InputTextField
id="url"
Expand All @@ -56,6 +89,7 @@ const OrganizationForm = () => {
value={organisationFormData?.url}
onChange={() => {}}
fieldType="text"
disabled
/>
<TextArea
id="description"
Expand All @@ -64,6 +98,7 @@ const OrganizationForm = () => {
rows={3}
value={organisationFormData?.description}
onChange={() => {}}
disabled
/>
<InputTextField
id="odk_central_url"
Expand All @@ -72,6 +107,7 @@ const OrganizationForm = () => {
value={organisationFormData?.odk_central_url}
onChange={() => {}}
fieldType="text"
disabled
/>
<InputTextField
id="url"
Expand All @@ -80,6 +116,7 @@ const OrganizationForm = () => {
value={organisationFormData?.organization_type}
onChange={() => {}}
fieldType="text"
disabled
/>
<div>
<p className="fmtm-text-[1rem] fmtm-font-semibold fmtm-mb-2">Logo</p>
Expand All @@ -97,8 +134,24 @@ const OrganizationForm = () => {
</div>
</div>
<div className="fmtm-flex fmtm-items-center fmtm-justify-center fmtm-gap-6 fmtm-mt-8 lg:fmtm-mt-16">
<Button btnText="Reject" btnType="other" className="fmtm-font-bold" onClick={() => {}} />
<Button btnText="Verify" btnType="primary" className="fmtm-font-bold" onClick={approveOrganization} />
<Button
btnText="Reject"
btnType="other"
className="fmtm-font-bold"
onClick={rejectOrganization}
isLoading={organizationRejecting}
loadingText="Rejecting..."
disabled={organizationApproving}
/>
<Button
btnText="Verify"
btnType="primary"
className="fmtm-font-bold"
onClick={approveOrganization}
isLoading={organizationApproving}
loadingText="Verifying..."
disabled={organizationRejecting}
/>
</div>
</div>
);
Expand Down
14 changes: 14 additions & 0 deletions src/frontend/src/store/slices/organisationSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const OrganisationSlice = CoreModules.createSlice({
participated_in: [],
},
consentApproval: false,
organizationApprovalStatus: {
isSuccess: false,
organizationApproving: false,
organizationRejecting: false,
},
},
reducers: {
GetOrganisationsData(state, action) {
Expand All @@ -41,6 +46,15 @@ const OrganisationSlice = CoreModules.createSlice({
SetIndividualOrganization(state, action) {
state.organisationFormData = action.payload;
},
SetOrganizationApproving(state, action) {
state.organizationApprovalStatus.organizationApproving = action.payload;
},
SetOrganizationRejecting(state, action) {
state.organizationApprovalStatus.organizationRejecting = action.payload;
},
SetOrganizationApprovalStatus(state, action) {
state.organizationApprovalStatus.isSuccess = action.payload;
},
},
});

Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/views/ManageProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const ManageProject = () => {
}, [decodedProjectId]);

return (
<div className="fmtm-flex fmtm-flex-col sm:fmtm-flex-row fmtm-bg-[#F5F5F5] fmtm-p-5 fmtm-gap-8 lg:fmtm-min-h-full">
<div className="fmtm-flex fmtm-flex-col sm:fmtm-flex-row fmtm-bg-[#F5F5F5] fmtm-p-5 fmtm-gap-8 fmtm-flex-1">
<div className="sm:fmtm-w-[15%] sm:fmtm-min-w-[7.3rem] fmtm-flex sm:fmtm-flex-col fmtm-items-center sm:fmtm-items-start fmtm-gap-4 sm:fmtm-gap-0 ">
<div
onClick={() => navigate(`/newproject_details/${params?.id}`)}
Expand Down
19 changes: 14 additions & 5 deletions src/frontend/src/views/Organisation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { OrganisationDataService } from '@/api/OrganisationService';
import { user_roles } from '@/types/enums';
import CustomizedImage from '@/utilities/CustomizedImage';
import { GetOrganisationDataModel } from '@/models/organisation/organisationModel';
import { useNavigate } from 'react-router-dom';

const Organisation = () => {
const cardStyle = {
Expand All @@ -17,11 +18,11 @@ const Organisation = () => {
borderRadius: '0px',
};

const url = 'https://fmtm.naxa.com.np/d907cf67fe587072a592.png';
const navigate = useNavigate();

const [searchKeyword, setSearchKeyword] = useState<string>('');
const [activeTab, setActiveTab] = useState<0 | 1>(0);
const [verifiedTab, setVerifiedTab] = useState<boolean>(false);
const [verifiedTab, setVerifiedTab] = useState<boolean>(true);
const token = CoreModules.useAppSelector((state) => state.login.loginToken);

const handleSearchChange = (event) => {
Expand All @@ -38,8 +39,16 @@ const Organisation = () => {
);

useEffect(() => {
dispatch(OrganisationDataService(`${import.meta.env.VITE_API_URL}/organisation/`));
}, []);
if (verifiedTab) {
dispatch(OrganisationDataService(`${import.meta.env.VITE_API_URL}/organisation/`));
} else {
dispatch(OrganisationDataService(`${import.meta.env.VITE_API_URL}/organisation/unapproved/`));
}
}, [verifiedTab]);

const approveOrganization = (id: number) => {
navigate(`/approve-organization/${id}`);
};

return (
<CoreModules.Box
Expand Down Expand Up @@ -177,7 +186,7 @@ const Organisation = () => {
</div>
<CoreModules.Box className="fmtm-grid fmtm-grid-cols-1 md:fmtm-grid-cols-2 lg:fmtm-grid-cols-3 fmtm-gap-5">
{filteredCardData?.map((data, index) => (
<CoreModules.Card key={index} sx={cardStyle}>
<CoreModules.Card key={index} sx={cardStyle} onClick={() => !verifiedTab && approveOrganization(data.id)}>
{data.logo ? (
<div className="fmtm-min-w-[60px] md:fmtm-min-w-[80px] lg:fmtm-min-w-[120px]">
<CoreModules.CardMedia component="img" src={data.logo} sx={{ width: ['60px', '80px', '120px'] }} />
Expand Down

0 comments on commit cbbaf03

Please sign in to comment.