Skip to content

Commit

Permalink
Merge pull request fortran-lang#79 from arteevraina/post-ratings-from…
Browse files Browse the repository at this point in the history
…-frontend

fix: added ability to post ratings to the package
  • Loading branch information
henilp105 committed May 25, 2024
2 parents 2d08417 + 333bd01 commit 5a095f3
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 9 deletions.
35 changes: 26 additions & 9 deletions frontend/src/pages/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from "../store/actions/packageActions";
import ShowUserListDialog from "./showUserListDialog";
import ReportPackageForm from "./reportPackageForm";
import RatePackageForm from "./ratePackageForm";
import { Button } from "react-bootstrap";
import PackageRatingGraph from "./packageRatingGraph";

Expand All @@ -37,6 +38,7 @@ const PackagePage = () => {
const [togglePackageMaintainersDialog, settogglePackageMaintainersDialog] =
useState(false);
const [showReportForm, setShowReportForm] = useState(false);
const [showRateForm, setRateForm] = useState(false);

const handleIconsClick = (value) => {
if (value === iconsActive) {
Expand Down Expand Up @@ -131,7 +133,7 @@ const PackagePage = () => {
<MDBRow>
<MDBCol size="9">{data.description}</MDBCol>

{sideBar(data, setShowReportForm)}
{sideBar(data, setShowReportForm, setRateForm)}
</MDBRow>
</MDBContainer>
</MDBTabsPane>
Expand Down Expand Up @@ -202,6 +204,12 @@ const PackagePage = () => {
</MDBContainer>
</MDBTabsPane>
</MDBTabsContent>
<RatePackageForm
namespace={namespace_name}
package={package_name}
show={showRateForm}
onHide={() => setRateForm(false)}
></RatePackageForm>
<ReportPackageForm
namespace={namespace_name}
package={package_name}
Expand Down Expand Up @@ -257,7 +265,7 @@ const ViewPackageMaintainersButton = ({
);
};

const sideBar = (data, setShowReportForm) => {
const sideBar = (data, setShowReportForm, setRateForm) => {
return (
<MDBCol size="3">
<p style={{ fontSize: 16, textAlign: "left" }}>Install (add to fpm.toml)</p>
Expand All @@ -278,13 +286,22 @@ const sideBar = (data, setShowReportForm) => {
<p style={{ fontSize: 16, textAlign: "left" }}>Last publish</p>
{updatedDays(data.updated_at)} days ago
<hr></hr>
<Button
variant="danger"
style={{ margin: 0 }}
onClick={() => setShowReportForm(true)}
>
Report
</Button>
<div>
<Button
variant="success"
style={{ margin: 0 }}
onClick={() => setRateForm(true)}
>
Rate
</Button>
<Button
variant="danger"
style={{ marginLeft: "4px" }}
onClick={() => setShowReportForm(true)}
>
Report
</Button>
</div>
</MDBCol>
);
};
Expand Down
90 changes: 90 additions & 0 deletions frontend/src/pages/ratePackageForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useEffect, useState } from "react";
import { Form, Button, Modal, Spinner } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { toast, ToastContainer } from "react-toastify";
import {
ratePackage,
resetErrorMessage,
} from "../store/actions/ratePackageActions";

const RatePackageForm = (props) => {
const dispatch = useDispatch();
const [rating, setRating] = useState("");
const accessToken = useSelector((state) => state.auth.accessToken);
const isLoading = useSelector((state) => state.ratePackage.isLoading);
const statusCode = useSelector((state) => state.ratePackage.statuscode);
const message = useSelector((state) => state.ratePackage.message);

const handleSubmit = async (e) => {
e.preventDefault();
dispatch(
ratePackage(
{ rating: rating, namespace: props.namespace, package: props.package },
accessToken
)
);
};

useEffect(() => {
if (statusCode === 200) {
toast.success(message);
} else {
toast.error(message);
}

dispatch(resetErrorMessage());
}, [statusCode]);

return (
<Form onSubmit={handleSubmit}>
<Modal {...props} size="md">
<Modal.Header closeButton>
<Modal.Title>Rate Package</Modal.Title>
</Modal.Header>
<ToastContainer
position="top-center"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
pauseOnHover
theme="light"
/>
<Modal.Body>
<Form.Group className="mb-3" controlId="formRatePackage">
<Form.Label>Please rate this package on a scale of 1-5</Form.Label>
<Form.Control
type="number"
placeholder="Enter rating"
min={1}
max={5}
value={rating}
onChange={(e) => setRating(e.target.value)}
/>
</Form.Group>
</Modal.Body>
<Modal.Footer>
{!isLoading ? (
<Button variant="primary" type="submit" onClick={handleSubmit}>
Rate
</Button>
) : (
<div style={{ margin: 0 }}>
<Spinner
className="spinner-border m-3"
animation="border"
role="status"
>
<span className="visually-hidden">Loading...</span>
</Spinner>
</div>
)}
</Modal.Footer>
</Modal>
</Form>
);
};

export default RatePackageForm;
51 changes: 51 additions & 0 deletions frontend/src/store/actions/ratePackageActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import axios from "axios";

export const RATE_PACKAGE_REQUEST = "RATE_PACKAGE_REQUEST";
export const RATE_PACKAGE_SUCCESS = "RATE_PACKAGE_SUCCESS";
export const RATE_PACKAGE_FAILURE = "RATE_PACKAGE_FAILURE";
export const RESET_ERROR_MESSAGE = "RESET_ERROR_MESSAGE";

export const ratePackage = (data, access_token) => async (dispatch) => {
let formData = new FormData();
formData.append("rating", data.rating);

let packageName = data.package;
let namespaceName = data.namespace;

try {
dispatch({
type: RATE_PACKAGE_REQUEST,
});

const result = await axios({
method: "post",
url: `${process.env.REACT_APP_REGISTRY_API_URL}/ratings/${namespaceName}/${packageName}`,
data: formData,
headers: {
Authorization: `Bearer ${access_token}`,
},
});

dispatch({
type: RATE_PACKAGE_SUCCESS,
payload: {
message: result.data.message,
statuscode: result.data.code,
},
});
} catch (error) {
dispatch({
type: RATE_PACKAGE_FAILURE,
payload: {
message: error.response.data.message,
statuscode: error.response.data.code,
},
});
}
};

export const resetErrorMessage = () => (dispatch) => {
dispatch({
type: RESET_ERROR_MESSAGE,
});
};
48 changes: 48 additions & 0 deletions frontend/src/store/reducers/ratePackageReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
RATE_PACKAGE_REQUEST,
RATE_PACKAGE_SUCCESS,
RATE_PACKAGE_FAILURE,
RESET_ERROR_MESSAGE,
} from "../actions/ratePackageActions";

const initialState = {
isLoading: false,
error: null,
message: null,
statuscode: 0,
};

const ratePackageReducer = (state = initialState, action) => {
switch (action.type) {
case RATE_PACKAGE_REQUEST:
return {
...state,
isLoading: true,
};
case RATE_PACKAGE_SUCCESS:
return {
...state,
isLoading: false,
message: action.payload.message,
statuscode: action.payload.statuscode,
};
case RATE_PACKAGE_FAILURE:
return {
...state,
isLoading: false,
message: action.payload.message,
statuscode: action.payload.statuscode,
};
case RESET_ERROR_MESSAGE:
return {
...state,
error: null,
message: null,
statuscode: 0,
};
default:
return state;
}
};

export default ratePackageReducer;
2 changes: 2 additions & 0 deletions frontend/src/store/reducers/rootReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import verifyEmailReducer from "./verifyEmailReducer";
import userListReducer from "./userListReducer";
import reportPackageReducer from "./reportPackageReducer";
import viewMalicousReportsReducer from "./viewMalicousReportsReducer";
import ratePackageReducer from "./ratePackageReducer";

const rootReducer = combineReducers({
auth: authReducer,
Expand All @@ -41,6 +42,7 @@ const rootReducer = combineReducers({
archives: archivesReducer,
reportPackage: reportPackageReducer,
malicousReport: viewMalicousReportsReducer,
ratePackage: ratePackageReducer,
});

export default rootReducer;

0 comments on commit 5a095f3

Please sign in to comment.