Skip to content

Commit

Permalink
reputation action component
Browse files Browse the repository at this point in the history
Signed-off-by: JonathanScialpi <[email protected]>
  • Loading branch information
JonathanScialpi committed Aug 15, 2022
1 parent db2e9d5 commit 36e0706
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function UpdateReputationActions(
const subFieldCropsArray: SubFieldCrop[] = subFieldsArray[subFieldIndex].properties.crops;
for(let subFieldCropIndex in subFieldCropsArray){
if(subFieldCropsArray[subFieldCropIndex].crop._id?.toString() === cropId &&
subFieldCropsArray[subFieldCropIndex].farmer === farmer &&
(subFieldCropsArray[subFieldCropIndex].farmer === farmer || subFieldCropsArray[subFieldCropIndex].farmer === "") &&
subFieldCropsArray[subFieldCropIndex].reputation_actions
){
statusUpdated = (subFieldCropsArray[subFieldCropIndex].reputation_actions![actionName] != actionStatus);
Expand Down
8 changes: 5 additions & 3 deletions backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import smsRoutes from "./routes/sms-route";
import foodTrustRoutes from "./routes/food-trust-route";
import cropTemplateRoutes from "./routes/crop-template-route";
import colony from "./routes/colony-route"
import fields from "./routes/field-route"

import { SocketIOManager, SocketIOManagerInstance } from "./sockets/socket.io";
import { Server } from "http";
Expand Down Expand Up @@ -63,6 +64,7 @@ app.use("/api/lot", lotRoutes);
app.use("/api/crop", cropRoutes);
app.use("/api/dashboard", dashboardRoutes);
app.use("/api/recommendations", recommendationsRoutes);
app.use("/api/fields", fields);

app.use("/api/weather", weatherRoutes);
app.use("/api/coopManager", coopManagerRoutes);
Expand All @@ -71,9 +73,9 @@ app.use("/api/messaging", messageLogRoutes);
app.use("/api/sms", smsRoutes);

// blockchain related routes
app.use("/api/foodtrust", foodTrustRoutes)
app.use("/api/cropTemplates", cropTemplateRoutes)
app.use("/api/colony", colony)
app.use("/api/foodtrust", foodTrustRoutes);
app.use("/api/cropTemplates", cropTemplateRoutes);
app.use("/api/colony", colony);

// Static Files
const publicPath = path.resolve("public");
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/crop-template-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ async function updateRepActions(req: Request, res: Response) {
const farmerEthAddress = await farmerSigner.getAddress();
await colony.pay(farmerEthAddress, ethers.utils.parseUnits(payment.toString()));

res.json(docs);
res.status(200).json(docs);
}else{
throw new Error('The request must be made with a different action status than what is existing.');
}
Expand Down
22 changes: 22 additions & 0 deletions backend/src/routes/field-route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Router, Request, Response } from "express";
import { Field, FieldModel } from "../db/entities/field";

const router = Router();

router.get("/getFieldByFarmerId/:farmer_id", async(req: Request, res: Response) => {
try{
const docs = await FieldModel.findOne({farmer_id: req.params.farmer_id})
.then(doc => {
return doc;
})
.catch(err => {
return err;
})
res.json(docs);
}catch(e){
console.error(e);
res.status(500).json(e);
}
});

export default router;
34 changes: 17 additions & 17 deletions backend/src/routes/messaging-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { TwilioInstance } from "./../integrations/twilio/twilio.service";
import { MessageLog, MessageLogModel } from "../db/entities/messageLog";
import { getFarmerIdsFromIndex, getIndexFromFarmerIds, MessageGroup, MessageGroupModel } from "../db/entities/messageGroup";
import { FarmerModel, Farmer } from "../db/entities/farmer";
import { MessageInterfaceSender } from "../integrations/messagingInterfaceSender";
// import { MessageInterfaceSender } from "../integrations/messagingInterfaceSender";

const router = Router();

const messageSender = new MessageInterfaceSender();
// const messageSender = new MessageInterfaceSender();

router.get("/", async (req, res) => {
const messages = await MessageLogModel.find({}).lean();
Expand All @@ -27,8 +27,8 @@ router.post("/sendSMSToFarmer", async (req, res) => {

try {
// const messageLog = await TwilioInstance.sendMessageToFarmer(farmer, message);
const messageLog = await messageSender.sendMessageToFarmer(farmer, message);
res.json(messageLog)
// const messageLog = await messageSender.sendMessageToFarmer(farmer, message);
// res.json(messageLog)
}
catch (e: any) {
res.status(500).send(e).end();
Expand Down Expand Up @@ -167,18 +167,18 @@ router.post('/new-thread', async (req, res) => {

try {
// const messageLogs = await TwilioInstance.sendMessageToGroup(group, body.message);
const messageLogs = await messageSender.sendMessageToGroup(group, body.message);
// const messageLogs = await messageSender.sendMessageToGroup(group, body.message);

const thread: ThreadsDTO = {
thread_id: index,
farmers,
isGroup: true,
preview: body.message,
messages: messageLogs
}
// const thread: ThreadsDTO = {
// thread_id: index,
// farmers,
// isGroup: true,
// preview: body.message,
// // messages: messageLogs
// }

// return res.json(messageLogs.map(it => it.messageRef));
return res.json(thread);
// return res.json(thread);
}
catch (e: any) {
res.status(500).send(e).end();
Expand Down Expand Up @@ -213,8 +213,8 @@ router.post('/thread', async (req, res) => {

try {
// const messageLogs = await TwilioInstance.sendMessageToGroup(group, body.message);
const messageLogs = await messageSender.sendMessageToGroup(group, body.message);
return res.json(messageLogs.map(it => it.messageRef));
// const messageLogs = await messageSender.sendMessageToGroup(group, body.message);
// return res.json(messageLogs.map(it => it.messageRef));
}
catch (e: any) {
res.status(500).send(e).end();
Expand All @@ -228,8 +228,8 @@ router.post('/thread', async (req, res) => {

try {
// const messageLog = await TwilioInstance.sendMessageToFarmer(farmer, message);
const messageLog = await messageSender.sendMessageToFarmer(farmer, message);
res.json(messageLog)
// const messageLog = await messageSender.sendMessageToFarmer(farmer, message);
// res.json(messageLog)
}
catch (e: any) {
res.status(500).send(e).end();
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions react-app/src/components/Crops/CropTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { CropTemplate, CropTemplateAPI} from "../../services/cropTemplate";
import { CropService } from "../../services/CropService";
import { Crop } from "../../services/crops";
import { getFarmer, Farmer } from "../../services/farmers";
import { Field } from "../../types/field";
import ReputationActions from "../Farmers/ReputationActions";

import { UpdateSubFieldWithCropTemplate, OrganizeReputationActions } from './helperFunctions';
import { ColonyAPI } from '../../services/colony';
Expand Down Expand Up @@ -274,6 +276,7 @@ const CropTemplateSelector = () => {
<Button type="button" style={{background: "green"}} onClick={handleSubmit}>Create New Template</Button>
</Column>
</Row>
<ReputationActions selectedCrop={selectedCrop}/>
</>
)
}
Expand Down
6 changes: 3 additions & 3 deletions react-app/src/components/Crops/helperFunctions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ export async function UpdateSubFieldWithCropTemplate(

// update field.subfields.properties.crops with reputation and croptemplate in mongodb
const res = await cropTemplateAPI.addCropTemplateToField(currentField);
console.log("updated field: ", res)
}
}

export function OrganizeReputationActions(field: any): Record<string, boolean>[]{
let reputationMaps: Record<string, boolean>[] = []

const subFieldsArray: any = field.subFields;

for(let subFieldIndex in subFieldsArray){
const subFieldCropsArray: any = subFieldsArray[subFieldIndex].properties.crops;

for(let subFieldCropIndex in subFieldCropsArray){
if(subFieldCropsArray[subFieldCropIndex].reputation_actions != null){
reputationMaps.push(subFieldCropsArray[subFieldCropIndex].reputation_actions!)
}
}
}

return reputationMaps
}
109 changes: 109 additions & 0 deletions react-app/src/components/Farmers/ReputationActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useEffect, useState } from "react";
import { Field } from "../../types/field";
import { Farmer, getAllFarmers } from "../../services/farmers";
import { Column, Row, Select, SelectItem, Toggle } from "carbon-addons-iot-react";
import { FieldAPI } from "../../services/fields";
import { CropTemplateAPI } from "../../services/cropTemplate"
import { OrganizeReputationActions } from '../Crops/helperFunctions';

const fieldAPI = new FieldAPI();
const cropTemplateAPI = new CropTemplateAPI();
const ReputationActions = (props: any) => {
const [field, setField] = useState<Field>();
const [farmer, setFarmer] = useState<string>();
const [farmerList, setFarmerList] = useState<Farmer[]>([]);
const [reputationActionMap, setReputationActionMap] = useState<any>({});

const handleClick = async(key: string) => {

const response = await cropTemplateAPI.updateRepActions(field, props.selectedCrop, farmer!, key, true);
if(response.status === 200){
let newReputationActionMap = [...reputationActionMap];
newReputationActionMap[0][key] = true;
setReputationActionMap(newReputationActionMap);
}
}

const getValueMap = (actionMap: any) => {
// console.log('actionMap: ', actionMap);
let actions = []
for(let key in actionMap[0]) {
actions.push(
<Row>
<Toggle
toggled={actionMap[0][key]}
id={key}
labelA="Incomplete"
labelB="Complete"
labelText={key}
onClick={() => handleClick(key)}
/>
</Row>
)
}
return(actions);
}

const getFarmerList = async() => {
const farmers = await getAllFarmers();
setFarmerList(farmers);
}

const handleFarmerSelection = async(event:any) => {
const fieldResponse = await fieldAPI.getFieldForFarmer(event.target.value);
setFarmer(event.target.value);
setField(fieldResponse);
setReputationActionMap(OrganizeReputationActions(fieldResponse));
}

useEffect(() => {
if(!farmerList.length){
getFarmerList();
}

},[])

return(
<>
<Row>
<Column>
<Select
defaultValue="select-crop"
helperText=""
id="select-1"
labelText="Farmers"
size="md"
onChange={handleFarmerSelection}
>
<SelectItem
disabled
hidden
text="Select A Farmer"
value="select-farmer"
/>
{
farmerList.map((item: Farmer) => {
return(
<SelectItem
text={item.name}
value={item._id}
/>
)
})
}
</Select>
</Column>
</Row>
{(Object.keys(reputationActionMap).length > 0) && getValueMap(reputationActionMap).map((item) => {
return(
<>
{item}
</>
)
})
}
</>
)
}

export default ReputationActions;
2 changes: 1 addition & 1 deletion react-app/src/services/cropTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class CropTemplateAPI{
actionName : actionName,
actionStatus : actionStatus
});
return data.data
return data
}

async addCropTemplateToField(field: any): Promise<any> {
Expand Down
10 changes: 10 additions & 0 deletions react-app/src/services/fields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import axios from 'axios';
import { Field } from '../types/field';
export class FieldAPI{
APIBase = "/api/fields/";

async getFieldForFarmer(farmer_id: any): Promise<Field> {
const data = await axios.get<Field>(this.APIBase + "getFieldByFarmerId/" + farmer_id);
return data.data;
}
}

0 comments on commit 36e0706

Please sign in to comment.