Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

003 sep 27 compliance tracker control pane #38

882 changes: 748 additions & 134 deletions Clients/package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Clients/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@fontsource/roboto": "^5.1.0",
"@mui/icons-material": "^6.1.0",
"@mui/icons-material": "^6.1.2",
"@mui/lab": "^6.0.0-beta.10",
"@mui/material": "^6.1.1",
"@mui/styled-engine-sc": "^6.1.0",
"@mui/x-date-pickers": "^7.18.0",
"@reduxjs/toolkit": "^2.2.7",
"@svgr/rollup": "^8.1.0",
"@tiptap/react": "^2.8.0",
"@tiptap/starter-kit": "^2.8.0",
"dayjs": "^1.11.13",
"libphonenumber-js": "^1.11.9",
"react": "^18.3.1",
Expand Down
14 changes: 1 addition & 13 deletions Clients/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import Assessment from "./presentation/pages/Assessment";
import Vendors from "./presentation/pages/Vendors";
import Setting from "./presentation/pages/Setting";
import Team from "./presentation/pages/Team";
import {
complianceMetrics,
complianceDetails,
} from "./presentation/pages/ComplianceTracker/complianceData";

function App() {
const mode = useSelector((state: any) => state.ui?.mode || "light");
Expand All @@ -25,15 +21,7 @@ function App() {
<Routes>
<Route path="/" element={<Dashboard />}>
<Route path="/" element={<Home />} />
<Route
path="/compliance-tracker"
element={
<ComplianceTracker
complianceMetrics={complianceMetrics}
complianceDetails={complianceDetails}
/>
}
/>
<Route path="/compliance-tracker" element={<ComplianceTracker />} />
<Route path="/assessment" element={<Assessment />} />
<Route path="/vendors" element={<Vendors />} />
<Route path="/setting" element={<Setting />} />
Expand Down
3 changes: 3 additions & 0 deletions Clients/src/presentation/assets/icons/cloudUpload.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Clients/src/presentation/assets/icons/headingIcone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const DatePicker = ({
color={theme.palette.text.secondary}
fontSize={13}
fontWeight={500}
marginBottom={theme.spacing(3)}
marginBottom={theme.spacing(2)}
>
{label}
{isRequired ? (
Expand Down
134 changes: 134 additions & 0 deletions Clients/src/presentation/components/Inputs/Dropdowns/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { Grid, Stack, Typography, useTheme } from "@mui/material";
import { useState } from "react";
import Select from "../Select";
import DatePicker from "../Datepicker";
import Field from "../Field";

const DropDowns = () => {
const [status, setStatus] = useState<string | number>("");
const [approver, setApprover] = useState<string | number>("");
const [riskReview, setRiskReview] = useState<string | number>("");
const [owner, setOwner] = useState<string | number>("");
const [reviewer, setReviewer] = useState<string | number>("");
const theme = useTheme();

const inputStyles = { width: 200, height: 34 };

return (
<>
<Stack
display="flex"
flexDirection="row"
justifyContent="space-between"
alignItems="center"
>
<Select
id="status"
label="Status:"
value={status}
onChange={(e) => setStatus(e.target.value)}
items={[
{ _id: 10, name: "Waiting" },
{ _id: 20, name: "In progress" },
{ _id: 30, name: "Done" },
]}
sx={inputStyles}
/>

<Select
id="Approver"
label="Approver:"
value={approver}
onChange={(e) => setApprover(e.target.value)}
items={[
{ _id: 10, name: "Option 1" },
{ _id: 20, name: "Option 2" },
{ _id: 30, name: "Option 3" },
]}
sx={inputStyles}
/>

<Select
id="Risk review"
label="Risk review:"
value={riskReview}
onChange={(e) => setRiskReview(e.target.value)}
items={[
{ _id: 10, name: "Acceptable risk" },
{ _id: 20, name: "Residual risk" },
{ _id: 30, name: "Unacceptable risk" },
]}
sx={inputStyles}
/>
</Stack>

{/* Second Row */}
<Stack
display="flex"
flexDirection="row"
justifyContent="space-between"
alignItems="center"
sx={{ mt: 3 }}
>
<Select
id="Owner"
label="Owner:"
value={owner}
onChange={(e) => setOwner(e.target.value)}
items={[
{ _id: 10, name: "Option 1" },
{ _id: 20, name: "Option 2" },
{ _id: 30, name: "Option 3" },
]}
sx={inputStyles}
/>

<Select
id="Reviewer"
label="Reviewer:"
value={reviewer}
onChange={(e) => setReviewer(e.target.value)}
items={[
{ _id: 10, name: "Option 1" },
{ _id: 20, name: "Option 2" },
{ _id: 30, name: "Option 3" },
]}
sx={inputStyles}
/>

<DatePicker
label="Due date:"
sx={inputStyles}
/>
</Stack>
Comment on lines +65 to +103
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Add state management for DatePicker and consider accessibility improvements.

The second row of inputs is well-structured and consistent with the first row. However, there are a few points to address:

  1. The DatePicker component lacks state management. Consider adding a state variable and an onChange handler:
const [dueDate, setDueDate] = useState<Date | null>(null);

// In the JSX
<DatePicker
  label="Due date:"
  value={dueDate}
  onChange={(newValue) => setDueDate(newValue)}
  sx={inputStyles}
/>
  1. As with the first row, consider adding aria-label attributes to the Select and DatePicker components to enhance accessibility.

  2. The hardcoded options for Owner and Reviewer are identical. If this is intentional, consider extracting these options into a shared constant to reduce duplication.


<Typography
fontSize={13}
fontWeight={400}
sx={{ textAlign: "left", mt: 4, ml: 2 }}
>
Implementation details:
</Typography>
<Grid container sx={{ mt: 3 }}>
<Grid
item
xs={12}
sx={{
height: 73,
borderRadius: theme.shape.borderRadius,
"& .MuiInputBase-root": {
height: "73px",
},
"& .MuiOutlinedInput-input": {
paddingTop: "20px",
},
}}
>
<Field type="description" />
</Grid>
</Grid>
Comment on lines +105 to +129
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Clarify the purpose of the description Field and consider accessibility improvements.

The implementation details section is well-structured using Material-UI components. However, there are a few points to consider:

  1. The purpose of the Field component with type "description" is not immediately clear. Consider adding a comment or renaming the type to better reflect its purpose.

  2. The Field component lacks an associated state variable and onChange handler. If user input is expected, add appropriate state management:

const [description, setDescription] = useState('');

// In the JSX
<Field 
  type="description" 
  value={description}
  onChange={(e) => setDescription(e.target.value)}
/>
  1. To improve accessibility, consider adding a label or aria-label to the Field component that describes its purpose.

  2. The custom styling applied to the Grid item could potentially be moved to a separate styles object or theme to improve maintainability.

</>
);
};

export default DropDowns;
16 changes: 5 additions & 11 deletions Clients/src/presentation/components/Inputs/Field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
IconButton,
InputAdornment,
Stack,
SxProps,
TextField,
Theme,
Typography,
useTheme,
} from "@mui/material";
Expand All @@ -53,6 +55,7 @@ interface FieldProps {
error?: string;
disabled?: boolean;
width?: number | string;
sx?: SxProps<Theme>;
}

const Field = forwardRef(
Expand All @@ -73,6 +76,7 @@ const Field = forwardRef(
error,
disabled,
width,
sx,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

URL-specific styling detected and may be affected by recent changes.

The removal of conditional styling for the url type in the Field component may impact the following files:

  • Clients/src/presentation/components/Link/index.tsx
  • Clients/src/presentation/components/Sidebar/index.tsx
  • Clients/src/presentation/components/IconButton/index.tsx
  • Clients/src/presentation/components/Inputs/Field/index.tsx
  • Clients/src/presentation/components/Inputs/Image/index.tsx
🔗 Analysis chain

Verify the impact of removing URL-specific styling.

The addition of the sx prop to the TextField component is correct and enhances styling flexibility. However, it appears that the previous conditional styling for the url type has been removed.

Please ensure that this change doesn't negatively impact the styling of URL inputs. Consider running the following script to check for any URL-specific styling that might need to be preserved:

If necessary, consider preserving the URL-specific styling by adding it to the sx prop conditionally:

sx={{
  ...(type === 'url' ? {
    // Add URL-specific styling here
  } : {}),
  ...sx
}}

Also applies to: 160-160


Retrying the search for URL-specific styling with corrected file type handling.

Please run the following updated script to check for URL-specific styling in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for URL-specific styling in the codebase

# Search for URL-specific styling in CSS files
echo "Searching for URL-specific styling in CSS files:"
rg --type css 'url|http|https'

# Search for URL-specific styling in TSX files
echo "Searching for URL-specific styling in TSX files:"
rg --type tsx 'url|http|https'

Length of output: 307


Script:

#!/bin/bash
# Description: Check for URL-specific styling in the codebase

# Search for URL-specific styling in CSS files
echo "Searching for URL-specific styling in CSS files:"
rg --type css 'url|http|https'

# Search for URL-specific styling in TSX files
echo "Searching for URL-specific styling in TSX files:"
rg 'url|http|https' --glob '*.tsx'

Length of output: 1764

}: FieldProps,
ref: ForwardedRef<HTMLInputElement>
) => {
Expand Down Expand Up @@ -153,17 +157,7 @@ const Field = forwardRef(
},
},
}}
sx={
type === "url"
? {
"& .MuiInputBase-root": { padding: 0 },
"& .MuiStack-root": {
borderTopLeftRadius: theme.shape.borderRadius,
borderBottomLeftRadius: theme.shape.borderRadius,
},
}
: {}
}
sx={sx}
InputProps={{
startAdornment: type === "url" && (
<Stack
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Box, Typography, Tooltip, IconButton } from "@mui/material";
import React, { useState } from "react";
import CloudUpload from "../../../assets/icons/cloudUpload.svg";
import RichTextEditor from "../../../components/RichTextEditor/index";

interface AuditorFeedbackProps {
activeSection: string;
}

const AuditorFeedback: React.FC<AuditorFeedbackProps> = ({ activeSection }) => {
const [file, setFile] = useState<File | null>(null);

const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
setFile(e.target.files[0]);
}
};
Comment on lines +13 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding file validation and error handling.

The handleFileUpload function could benefit from additional error handling and file validation. This would improve the robustness of the file upload process.

Consider implementing the following improvements:

  1. Add file type validation
  2. Implement file size limits
  3. Handle potential errors during file selection

Would you like assistance in implementing these improvements?

🧰 Tools
🪛 Biome

[error] 14-14: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


const UploadFile = () => {
document.getElementById("file-upload")?.click();
};

const handleContentChange = (content: string) => {
console.log("Updated content: ", content);
};
Comment on lines +23 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Implement proper state management for content changes.

The handleContentChange function currently only logs the updated content to the console. For production use, you should implement proper state management to store and utilize the updated content.

Consider using the useState hook to manage the content state:

const [content, setContent] = useState('');

const handleContentChange = (newContent: string) => {
  setContent(newContent);
};

Would you like assistance in implementing this state management?


return (
<Box sx={{ width: "100%", padding: 2 }}>
<Typography sx={{ mb: 2 }}>
{activeSection === "Evidence" ? "Evidence:" : "Auditor Feedback:"}
</Typography>

{/* Use the RichTextEditor component */}
<RichTextEditor onContentChange={handleContentChange} />

{/* File Upload */}
<Box
sx={{
display: "flex",
flexDirection: "row-reverse",
border: "1px dotted",
borderColor: "#D0D5DD",
width: 472,
alignItems: "center",
cursor: "pointer",
}}
onClick={UploadFile}
>
<Typography sx={{ color: "black", padding: 5, marginLeft: 1, paddingLeft: 0 }}>
You can also drag and drop, or click to upload a feedback.
</Typography>
<Tooltip title="Attach a file">
<IconButton component="label">
<img
src={CloudUpload}
alt="Upload"
style={{ height: 19, width: 20 }}
/>
<input type="file" hidden id="file-upload" onChange={handleFileUpload} />
</IconButton>
</Tooltip>
</Box>
Comment on lines +37 to +62
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve accessibility for the file upload functionality.

The file upload area could be made more accessible to keyboard-only users and screen readers. Consider the following improvements:

  1. Add keyboard support for the file upload functionality.
  2. Include an aria-label or aria-description for the file upload area.
  3. Ensure that the upload icon has proper alternative text.

Here's an example of how you could improve accessibility:

<Box
  role="button"
  tabIndex={0}
  aria-label="Upload file"
  onKeyPress={(e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      UploadFile();
    }
  }}
  // ... other props
>
  {/* ... existing content */}
</Box>

Would you like assistance in implementing these accessibility improvements?


{file && (
<Typography variant="body2" sx={{ mt: 2 }}>
Attached file: {file.name}
</Typography>
)}
</Box>
);
Comment on lines +27 to +70
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring for improved maintainability and modularity.

The component structure is clear and follows React and Material-UI best practices. However, there are a few areas that could be improved:

  1. Move inline styles to a separate styles object for better maintainability.
  2. Extract the file upload area into a separate component for better modularity.
  3. Consider using Material-UI's makeStyles or styled API for consistent styling.

Here's an example of how you could refactor the styles:

import { makeStyles } from '@mui/styles';

const useStyles = makeStyles((theme) => ({
  fileUploadBox: {
    display: "flex",
    flexDirection: "row-reverse",
    border: "1px dotted",
    borderColor: "#D0D5DD",
    width: 472,
    alignItems: "center",
    cursor: "pointer",
  },
  // Add more styles here
}));

// In your component:
const classes = useStyles();

// Then use classes in your JSX:
<Box className={classes.fileUploadBox} onClick={UploadFile}>
  {/* ... */}
</Box>

Would you like assistance in implementing these refactoring suggestions?

};

export default AuditorFeedback;
Loading