UNPKG

hiuphub-gamified

Version:

app of gamified

270 lines (240 loc) 8.25 kB
import PropTypes from "prop-types"; import React, { useState, useRef, useEffect } from "react"; import api from "../../api"; import * as constants from "../../common/constants"; import TipBox from "../../components/Common/TipBox"; export default function AddReputation(props) { const { activities } = props; const [state, setState] = useState({ reputations: [{ title: "", subscore: 0 }], loader: "", message: "", tipBoxStatus: false, tipBoxType: "success", }); const timer = useRef(); useEffect(() => { return () => { clearTimeout(timer.current); }; }, []); const vanisTipBox = () => { timer.current = setTimeout(() => { setState(state => ({ ...state, tipBoxStatus: false, message: "" })); }, 7000); }; const closeTipBox = () => { setState(state => ({ ...state, tipBoxStatus: false, message: "" })); }; const saveReputations = async () => { let url = "/reputationpoints/v1"; const data = { reputationPoints: state.reputations.filter( reputation => reputation.title ), }; if (!data.reputationPoints.length || state.loader === constants.SAVING) { return; } setState(state => ({ ...state, loader: constants.SAVING })); try { const result = await api.post(url, data); console.log({ result }); setState(state => ({ ...state, loader: "", tipBoxStatus: true, tipBoxType: "success", message: "Sucessfully saved Reputation Point.", })); props.onResponse(result.data); vanisTipBox(); timer.current = setTimeout(() => { props.closeModal(); }, 2000); } catch (err) { const error = err.message || err; console.log({ error }); setState(state => ({ ...state, loader: "", tipBoxStatus: true, message: error, tipBoxType: "error", title: "", subscore: 0, })); vanisTipBox(); } }; const addPoint = (e, title) => { e.persist(); let value = e.target.value; let reputations = []; if (e.target.name === "title") { let changeValue = false; reputations = state.reputations.map(reputation => { if (reputation.title === value) { changeValue = true; return reputation; } else if (reputation.title && reputation.title === title) { const isAlreadyExists = state.reputations.find( reputation => reputation.title === value ); if (!isAlreadyExists) { changeValue = true; return { title: value, subscore: reputation.subscore }; } } return reputation; }); if (!changeValue) reputations = [ ...reputations.slice(0, -1), { title: value, subscore: reputations[state.reputations.length - 1].subscore || 0, }, ]; } else if (e.target.name === "subscore") { value = Math.floor(value); if (e.target.value === "") value = ""; let isAlreadyExists = false; reputations = state.reputations.map(reputation => { if (reputation.title === title) { isAlreadyExists = true; return { title, subscore: value }; } return reputation; }); if (!isAlreadyExists) reputations = [...reputations.slice(0, -1)]; } setState(state => ({ ...state, reputations })); }; const removeReputation = title => { const reputations = state.reputations.filter( reputation => reputation.title !== title ); setState(state => ({ ...state, reputations })); }; const addNextActivity = () => { const hasEmptyActivity = state.reputations.find( reputation => !reputation.title ); if (!hasEmptyActivity) { setState(state => ({ ...state, reputations: [...state.reputations, { title: "", subscore: 0 }], })); } }; if (!activities.length) return <span>Activities required</span>; const { tipBoxStatus, message, tipBoxType } = state; return ( <div className="row h-100"> <div className="col-lg-12 col-md-12 col-sm-12"> <section className="mb-4 d-flex justify-content-between align-items-center"> <span> Add <span className="fw-bold">Reputation</span> </span> </section> {tipBoxStatus && ( <TipBox tipBoxType={tipBoxType} onClose={closeTipBox} message={message} status={tipBoxStatus} /> )} <div className="d-flex flex-column h-100"> {state.reputations.map(reputation => ( <div className="border-0 bg-transparent" key={reputation.title + reputation.subscore} > <div className="p-0"> <div className="g-2 row"> {reputation.title ? ( <div className="d-flex flex-row-reverse"> <span className="btn btn-sm text-danger p-0 px-1" onClick={() => removeReputation(reputation.title)} style={{ cursor: "pointer" }} > Remove </span> </div> ) : null} <div className="col-lg-7 col-md-12 col-sm-12"> <div className="mb-3 form-floating"> <select aria-label="Select Reputation Title" className="border-radius-lg form-select" id="floatingSelect" name="title" onChange={e => addPoint(e, reputation.title)} value={reputation.title} > <option value="">Select title</option> {activities.map(activity => ( <option key={activity._id} value={activity.name}> {activity.name} </option> ))} </select> <label htmlFor="floatingSelect"> Select Reputation Title </label> </div> </div> <div className="col-lg-5 col-md-12 col-sm-12"> <div className="mb-3 form-floating"> <input type="number" placeholder="Enter subscore point" id="floatingInput" className="border-radius-lg form-control" name="subscore" min="0" value={reputation.subscore} onChange={e => addPoint(e, reputation.title)} /> <label htmlFor="floatingInput">Reputation Point</label> </div> </div> </div> </div> </div> ))} <div> <div className="text-start"> <button type="button" className="btn btn-dark" onClick={addNextActivity} > Add </button> </div> </div> <div className="mt-auto"> <div className="text-end"> <button type="button" className="btn btn-dark" onClick={saveReputations} > {state.loader === constants.SAVING ? "Saving" : "Save"} </button> </div> </div> </div> </div> </div> ); } AddReputation.propTypes = { activities: PropTypes.array.isRequired, onCloseModal: PropTypes.func.isRequired, onResponse: PropTypes.func.isRequired, };