️ This Gitlab will be shut down at 2021-12-31 23:59:59.
Students and staff can migrate to gitlab.utwente.nl.
SNT members can migrate to gitlab.snt.utwente.nl.
Contact bestuur@snt.utwente.nl for more information.

Migrate your projects today!
Export your project using the webinterface or use a script.

Commit df809977 authored by TJHeeringa's avatar TJHeeringa

Updated SpecificDataForm; removed old membersIncoming

parent 60dfb4e2
......@@ -11,7 +11,7 @@ import SpecificDataField from "../Fields/SpecificDataField";
import Wrapper from "../Fields/Wrapper";
export const SpecificDataForm = ({ specificData: propSpecificData, association, membership, onDataUpdate }) => {
export const SpecificDataForm = ({ specificData: propSpecificData, association, membership, onUpdate }) => {
const alerthandler = useAlertHandler();
const API = useAPI();
......@@ -52,7 +52,7 @@ export const SpecificDataForm = ({ specificData: propSpecificData, association,
method: "PATCH",
object: specificDataChanges[dataField.url],
on_succes: (data) => {
onDataUpdate(data);
onUpdate(data);
alerthandler.success("Saved data field");
},
on_failure: (err) => {
......@@ -66,7 +66,7 @@ export const SpecificDataForm = ({ specificData: propSpecificData, association,
method: "POST",
object: {...specificDataChanges[dataField.url], association: association.url, data_field: dataField.url, membership: membership.url},
on_succes: (data) => {
onDataUpdate(data);
onUpdate(data);
alerthandler.success("Saved data field");
},
on_failure: (err) => {
......@@ -104,6 +104,7 @@ export const SpecificDataForm = ({ specificData: propSpecificData, association,
field={dataField}
value={specificDataWithChanges[dataField.url] ? specificDataWithChanges[dataField.url].value : ""}
onChange={(field_url, value)=>handleDataChange("value", value, field_url)}
disabled={dataField.board_only && !association.is_board}
/>
</Wrapper>
)) }
......
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import PropTypes from "prop-types";
import React, {useState} from "react";
import React, {useCallback, useMemo, useState} from "react";
const InfoForm = ({association, infoFormObject: propInfoFormObject, infoOrForm, InfoComponent, FormComponent, ...props}) => {
const [infoFormObject, setInfoFormObject] = useState(propInfoFormObject.association ? propInfoFormObject : {...propInfoFormObject, association: association.url});
import Wrapper from "../Fields/Wrapper";
import useInfoFormState from "../Hooks/useInfoFormState";
import Block from "../PageLayout/Content/Block";
const defaultFieldAndValueToStateChanges = (field, value) => ({[field]: value});
const InfoForm = ({infoFormObject: propInfoFormObject, InfoComponent, FormComponent, fieldAndValueToStateChanges, title, onUpdate: propOnUpdate, onDelete: propOnDelete, onCreate: propOnCreate, onCancel: propOnCancel, ...props}) => {
const [infoFormObjectChanges, setInfoFormObjectChanges] = useState({});
const infoFormObject = useMemo(()=>({...propInfoFormObject, infoFormObjectChanges}),[propInfoFormObject, infoFormObjectChanges]);
const [formType, toggleFormType] = useInfoFormState("info");
const handleInfoFormObjectChange = (field, value) => {
setInfoFormObject(prevState => ({...prevState, [field]:value}));
setInfoFormObjectChanges(prevState => ({...prevState, ...fieldAndValueToStateChanges(field, value)}));
};
if (infoOrForm === "info") {
return (
<InfoComponent
info={infoFormObject}
/>
);
} else {
return (
<FormComponent
association={association}
formObject={infoFormObject}
handleFormObjectChange={handleInfoFormObjectChange}
{...props}
/>
);
}
const onUpdate = useCallback((data)=>{
toggleFormType();
setInfoFormObjectChanges({});
return propOnUpdate(data);
}, [toggleFormType, propOnUpdate]);
const onDelete = useCallback((data)=>{
toggleFormType();
setInfoFormObjectChanges({});
return propOnDelete(data);
}, [toggleFormType, propOnDelete]);
const onCreate = useCallback((data)=>{
toggleFormType();
setInfoFormObjectChanges({});
return propOnCreate(data);
}, [toggleFormType, propOnCreate]);
const onCancel = useCallback(()=>{
toggleFormType();
setInfoFormObjectChanges({});
return propOnCancel();
}, [toggleFormType, propOnCancel]);
return (
<Block>
<Wrapper>
<Typography>{ title }</Typography>
<div>
<Button variant={"contained"} onClick={toggleFormType}>{ formType === "info" ? "Edit" : "View" }</Button>
</div>
</Wrapper>
<hr className={"box-title-separator"}/>
{ formType === "info"
? (
<InfoComponent
info={infoFormObject}
{...props}
/>
) : (
<FormComponent
formObject={infoFormObject}
handleFormObjectChange={handleInfoFormObjectChange}
onCreate={onCreate}
onUpdate={onUpdate}
onDelete={onDelete}
onCancel={onCancel}
{...props}
/>
) }
</Block>
);
};
InfoForm.propTypes = {
infoOrForm: PropTypes.string.isRequired,
infoFormObject: PropTypes.object
infoFormObject: PropTypes.object,
InfoComponent: PropTypes.node.isRequired,
FormComponent: PropTypes.node.isRequired,
fieldAndValueToStateChanges: PropTypes.func,
title: PropTypes.string.isRequired,
onCreate: PropTypes.func.isRequired,
onUpdate: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
};
InfoForm.defaultProps = {
infoFormObject: {
}
infoFormObject: {},
fieldAndValueToStateChanges: defaultFieldAndValueToStateChanges
};
export default InfoForm;
......@@ -4,7 +4,7 @@ import React, {useState} from "react";
import {MembershipForm} from "../Forms/MembershipForm";
import MembershipInfo from "../Info/MembershipInfo";
export const Membership = ({membership: propMembership, infoOrForm, ...props}) => {
export const Membership = ({membership: propMembership, infoOrForm, toggleInfoOrForm, ...props}) => {
const [membershipChanges, setMembershipChanges] = useState({});
const membership = {...propMembership, ...membershipChanges};
......@@ -13,6 +13,7 @@ export const Membership = ({membership: propMembership, infoOrForm, ...props}) =
};
const cancelChanges = () => {
setMembershipChanges({});
toggleInfoOrForm();
};
if (infoOrForm === "info") {
......@@ -35,10 +36,12 @@ export const Membership = ({membership: propMembership, infoOrForm, ...props}) =
Membership.propTypes = {
infoOrForm: PropTypes.string.isRequired,
membership: PropTypes.object
membership: PropTypes.object,
toggleInfoOrForm: PropTypes.func
};
Membership.defaultProps = {
membership: {
}
},
toggleInfoOrForm: ()=>{},
};
\ No newline at end of file
......@@ -5,7 +5,7 @@ import {makeStyles} from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import * as moment from "moment/moment";
import PropTypes from "prop-types";
import React, {useMemo} from "react";
import React, {useCallback, useMemo} from "react";
import {useHistory} from "react-router-dom";
import Sushi from "../../../../img/Sushi-11-me.jpg"; // Import using relative path
......@@ -38,7 +38,7 @@ const useStyles = makeStyles((theme) => ({
}));
const MembersDetail = ({ association, current_member, onMembershipUpdate, onProfileUpdate, onDataUpdate }) => {
const MembersDetail = ({ association, current_member, onMembershipUpdate, onProfileUpdate, onDataUpdate: propOnDataUpdate }) => {
const classes = useStyles();
const API = useAPI();
......@@ -148,7 +148,11 @@ const MembersDetail = ({ association, current_member, onMembershipUpdate, onProf
});
};
console.log(current_member, isClaimed);
const onDataCancel = useCallback(toggleSpecificDataInfoFormState, [toggleSpecificDataInfoFormState]);
const onDataUpdate = useCallback((data)=>{
propOnDataUpdate(data);
toggleSpecificDataInfoFormState();
}, [toggleSpecificDataInfoFormState, propOnDataUpdate]);
return (
<>
......@@ -218,7 +222,8 @@ const MembersDetail = ({ association, current_member, onMembershipUpdate, onProf
association={association}
specificData={membership.association_specific_data}
membership={membership}
onDataUpdate={onDataUpdate}
onUpdate={onDataUpdate}
onCancel={onDataCancel}
/>
: <SpecificData specific_data={membership.association_specific_data}/>
}
......
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import { ShortProfile } from "App/Components/Info/ShortProfile";
import PropTypes from "prop-types";
import React, {useCallback, useEffect, useMemo, useState} from "react";
import Container from "react-bootstrap/Container";
import { Button } from "reactstrap";
import React, {useEffect, useMemo} from "react";
import ConfirmationModal from "../../Components/Modals/ConfirmationModal";
import Block from "../../Components/PageLayout/Content/Block";
import MemberTable from "../../Components/Tables/MemberTable";
import {useAlertHandler} from "../../Contexts/AlertHandler";
import {useAPI} from "../../Contexts/API";
import {useMembers} from "../../Contexts/Members";
import ConfirmationModal from "../../Components/Modals/ConfirmationModal";
const initialHeaders = ["given_name", "surname", "study", "phase", "membertype", "type", "date_joined"];
const messages = {
......@@ -51,12 +45,12 @@ const Popup = ({ row, onChange, onApplyChanges, onCancelChanges, open }) => {
);
};
export const MembersIncoming2 = ({ association }) => {
const MembersIncoming = () => {
const API = useAPI();
const alerthandler = useAlertHandler();
const MembersAPI = useMembers();
const onAccept = (differences, original_row, edited_row, edited_row_index) => {
const onEdit = (differences, original_row, edited_row, edited_row_index) => {
API.callv4({
url: edited_row.urls.membership,
method: "PATCH",
......@@ -79,7 +73,7 @@ export const MembersIncoming2 = ({ association }) => {
initial_headers={initialHeaders}
messages={messages}
allowEdit={true}
onEdit={onAccept}
onEdit={onEdit}
showSelect={false}
showGrouping={false}
editThroughPopup={true}
......@@ -89,94 +83,4 @@ export const MembersIncoming2 = ({ association }) => {
);
};
const MembersIncoming = ({ association }) => {
const API = useAPI();
const [pendingMemberships, setPendingMemberships] = useState([]);
const refreshPendingMemberships = () => {
API.callv4({
url: "/memberships",
queryParams: {
association__slug: association.slug,
limit: 5000,
status: "Pending"
},
method: "GET",
on_succes: (data) => {
setPendingMemberships(data.results);},
on_failure: () => {}
});
};
useEffect(refreshPendingMemberships, ["run on mount only"]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<Container>
<Block>
<Typography variant={"h5"}>Incoming Requests</Typography>
<hr className={"box-title-separator"}/>
<Grid>
{ pendingMemberships.map((pendingMembership, id) => (
<IncomingRequest
key={id}
membership={pendingMembership}
postPatch={refreshPendingMemberships}
/>
)) }
</Grid>
</Block>
</Container>
);
};
MembersIncoming.propTypes = {
association: PropTypes.object.isRequired
};
export default MembersIncoming;
const IncomingRequest = ({ membership, postPatch }) => {
const API = useAPI();
const alerthandler = useAlertHandler();
const updateStatus = (status) => {
API.callv4({
url: membership.url,
method: "PATCH",
object: {"status": status},
on_succes: () => {
alerthandler.handleAlertHandler("success", status+": "+membership.profile.given_name);
postPatch();
},
on_failure: () => {
alerthandler.handleAlertHandler("Action failed");
}
});
};
const reject = () => updateStatus("Rejected");
const accept = () => updateStatus("Accepted");
return (
<Grid container justify={"space-between"}>
<Grid item>
<ShortProfile
profile={membership.profile}
/>
</Grid>
<Grid item>
<Button onClick={accept} color={"success"}><FontAwesomeIcon icon={"check"}/></Button>
&nbsp;
<Button onClick= {reject} color={"danger"}><FontAwesomeIcon icon={"times"}/></Button>
</Grid>
</Grid>
);
};
IncomingRequest.propTypes = {
membership: PropTypes.object.isRequired,
postPatch: PropTypes.func.isRequired
};
export default MembersIncoming;
\ No newline at end of file
......@@ -7,7 +7,7 @@ import EmailLists from "App/Pages/Email/EmailLists";
import EmailSender from "App/Pages/Email/EmailSender";
import EmailUsers from "App/Pages/Email/EmailUsers";
import { MembersDisputedWithRouter } from "App/Pages/Members/MembersDisputed";
import MembersIncoming, {MembersIncoming2} from "App/Pages/Members/MembersIncoming";
import MembersIncoming from "App/Pages/Members/MembersIncoming";
import MembersLeaving from "App/Pages/Members/MembersLeaving";
import MembershipEnd from "App/Pages/Profile/MembershipEnd";
import PropTypes from "prop-types";
......@@ -172,9 +172,6 @@ const BoardMemberRoutes = (props) => {
queryParam={{status: "Pending"}}
immediatelyLoadMembers={true}
>
<MembersIncoming2
association={association}
/>
<MembersIncoming
association={association}
/>
......
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